@@ -74,7 +74,6 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
7474 case OP_add :
7575 case OP_sub :
7676 case OP_mul :
77- case OP_div :
7877 case OP_lshift :
7978 case OP_rshift :
8079 case OP_bit_and :
@@ -85,11 +84,24 @@ void update_elf_offset(ph2_ir_t *ph2_ir)
8584 case OP_bit_not :
8685 elf_offset += 4 ;
8786 return ;
87+ case OP_div :
88+ if (hard_mul_div ) {
89+ elf_offset += 4 ;
90+ } else {
91+ elf_offset += 104 ;
92+ }
93+ return ;
94+ case OP_mod :
95+ if (hard_mul_div ) {
96+ elf_offset += 12 ;
97+ } else {
98+ elf_offset += 104 ;
99+ }
100+ return ;
88101 case OP_load_data_address :
89102 elf_offset += 8 ;
90103 return ;
91104 case OP_address_of_func :
92- case OP_mod :
93105 case OP_eq :
94106 case OP_neq :
95107 case OP_gt :
@@ -323,12 +335,76 @@ void emit_ph2_ir(ph2_ir_t *ph2_ir)
323335 emit (__mul (__AL , rd , rn , rm ));
324336 return ;
325337 case OP_div :
326- emit (__div (__AL , rd , rm , rn ));
338+ if (hard_mul_div ) {
339+ emit (__div (__AL , rd , rm , rn ));
340+ } else {
341+ /* Obtain absoulte values of dividend and divisor */
342+ emit (__srl_amt (__AL , 0 , arith_rs , __r8 , rn , 31 ));
343+ emit (__add_r (__AL , rn , rn , __r8 ));
344+ emit (__eor_r (__AL , rn , rn , __r8 ));
345+ emit (__srl_amt (__AL , 0 , arith_rs , __r9 , rm , 31 ));
346+ emit (__add_r (__AL , rm , rm , __r9 ));
347+ emit (__eor_r (__AL , rm , rm , __r9 ));
348+ emit (__eor_r (__AL , __r10 , __r8 , __r9 ));
349+ /* Unsigned integer division */
350+ emit (__zero (__r9 ));
351+ emit (__mov_i (__AL , __r8 , 1 ));
352+ emit (__cmp_i (__AL , rm , 0 ));
353+ emit (__b (__EQ , 52 ));
354+ emit (__cmp_i (__AL , rn , 0 ));
355+ emit (__b (__EQ , 44 ));
356+ emit (__cmp_r (__AL , rm , rn ));
357+ emit (__sll_amt (__CC , 0 , logic_ls , rm , rm , 1 ));
358+ emit (__sll_amt (__CC , 0 , logic_ls , __r8 , __r8 , 1 ));
359+ emit (__b (__CC , -12 ));
360+ emit (__cmp_r (__AL , rn , rm ));
361+ emit (__sub_r (__CS , rn , rn , rm ));
362+ emit (__add_r (__CS , __r9 , __r9 , __r8 ));
363+ emit (__srl_amt (__AL , 1 , logic_rs , __r8 , __r8 , 1 ));
364+ emit (__srl_amt (__CC , 0 , logic_rs , rm , rm , 1 ));
365+ emit (__b (__CC , -20 ));
366+ emit (__mov_r (__AL , rd , __r9 ));
367+ /* Handle the correct sign for quotient */
368+ emit (__cmp_i (__AL , __r10 , 0 ));
369+ emit (__rsb_i (__NE , rd , 0 , rd ));
370+ }
327371 return ;
328372 case OP_mod :
329- emit (__div (__AL , __r8 , rm , rn ));
330- emit (__mul (__AL , __r8 , rm , __r8 ));
331- emit (__sub_r (__AL , rd , rn , __r8 ));
373+ if (hard_mul_div ) {
374+ emit (__div (__AL , __r8 , rm , rn ));
375+ emit (__mul (__AL , __r8 , rm , __r8 ));
376+ emit (__sub_r (__AL , rd , rn , __r8 ));
377+ } else {
378+ /* Obtain absoulte values of dividend and divisor */
379+ emit (__srl_amt (__AL , 0 , arith_rs , __r8 , rn , 31 ));
380+ emit (__add_r (__AL , rn , rn , __r8 ));
381+ emit (__eor_r (__AL , rn , rn , __r8 ));
382+ emit (__srl_amt (__AL , 0 , arith_rs , __r9 , rm , 31 ));
383+ emit (__add_r (__AL , rm , rm , __r9 ));
384+ emit (__eor_r (__AL , rm , rm , __r9 ));
385+ emit (__mov_r (__AL , __r10 , __r8 ));
386+ /* Unsigned integer division */
387+ emit (__zero (__r9 ));
388+ emit (__mov_i (__AL , __r8 , 1 ));
389+ emit (__cmp_i (__AL , rm , 0 ));
390+ emit (__b (__EQ , 52 ));
391+ emit (__cmp_i (__AL , rn , 0 ));
392+ emit (__b (__EQ , 44 ));
393+ emit (__cmp_r (__AL , rm , rn ));
394+ emit (__sll_amt (__CC , 0 , logic_ls , rm , rm , 1 ));
395+ emit (__sll_amt (__CC , 0 , logic_ls , __r8 , __r8 , 1 ));
396+ emit (__b (__CC , -12 ));
397+ emit (__cmp_r (__AL , rn , rm ));
398+ emit (__sub_r (__CS , rn , rn , rm ));
399+ emit (__add_r (__CS , __r9 , __r9 , __r8 ));
400+ emit (__srl_amt (__AL , 1 , logic_rs , __r8 , __r8 , 1 ));
401+ emit (__srl_amt (__CC , 0 , logic_rs , rm , rm , 1 ));
402+ emit (__b (__CC , -20 ));
403+ emit (__mov_r (__AL , rd , rn ));
404+ /* Handle the correct sign for remainder */
405+ emit (__cmp_i (__AL , __r10 , 0 ));
406+ emit (__rsb_i (__NE , rd , 0 , rd ));
407+ }
332408 return ;
333409 case OP_lshift :
334410 emit (__sll (__AL , rd , rn , rm ));
0 commit comments