Hi,
The following patch fixes issues in the div/mod emulation routines
for the RL78 target.

Hunk in divmodsi.S: This hunk adds a branch to 'main_loop_done_himode'
instead of a direct 'ret'. The 'ret' from here was causing the
hardware to crash as the registers were not being restored from stack
before return. This happened for long data division by 0.
Note: A 'br     $!' is used as a only using 'br $' gives error,
relocation truncated to fit: R_RL78_DIR8S_PCREL at link time in testcase.

This hunk also fixes an issue related to return register.
r10,r11 was returned for div instruction instead of r8,r9 register.

Hunk in divmodhi.S: Fixes issue related to return register.
r10 was returned for div instruction instead of r8 register.

Hunk in divmodqi.S: Returns a 0x00 instead of 0xff to keep results
consistent with other data types.

The hunks in divmodhi and divmodqi are not critical, however the
one in divmodsi is critical as the processor runs away to undefined
space and crashes.

This is regression tested for RL78 -msim. Please let me know if it is
OK to commit.

Best Regards,
Kaushik

Changelog:
2015-08-21  Kaushik Phatak  <kaushik.pha...@kpit.com>
    
        * config/rl78/divmodqi.S: Return 0x00 by default for div by 0.
        * config/rl78/divmodsi.S: Update return register to r8.
        * config/rl78/divmodhi.S: Update return register to r8,r9.
          Branch to main_loop_done_himode to pop registers before return.

Index: libgcc/config/rl78/divmodhi.S
===================================================================
--- libgcc/config/rl78/divmodhi.S       (revision 227024)
+++ libgcc/config/rl78/divmodhi.S       (working copy)
@@ -454,7 +454,11 @@
        movw    ax, den
        cmpw    ax, #0
        bnz     $den_not_zero\which
+       .if \need_result
+       movw    quot, #0
+       .else
        movw    num, #0
+       .endif
        ret
 
 den_not_zero\which:
Index: libgcc/config/rl78/divmodqi.S
===================================================================
--- libgcc/config/rl78/divmodqi.S       (revision 227024)
+++ libgcc/config/rl78/divmodqi.S       (working copy)
@@ -63,7 +63,7 @@
        ret
        
 den_is_zero\which:
-       mov     r8, #0xff
+       mov     r8, #0x00
        ret
 
        ;; These routines leave DE alone - the signed functions use DE
Index: libgcc/config/rl78/divmodsi.S
===================================================================
--- libgcc/config/rl78/divmodsi.S       (revision 227024)
+++ libgcc/config/rl78/divmodsi.S       (working copy)
@@ -688,9 +688,14 @@
        or      a, denB3        ; not x
        cmpw    ax, #0
        bnz     $den_not_zero\which
+       .if \need_result
+       movw    quotL, #0
+       movw    quotH, #0
+       .else
        movw    numL, #0
        movw    numH, #0
-       ret
+       .endif
+       br      $!main_loop_done_himode\which
 
 den_not_zero\which:
        .if \need_result

Attachment: rl78_divmod.patch
Description: rl78_divmod.patch

Reply via email to