diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-27 10:13:12 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-27 10:13:12 +0000 |
commit | e0e4357b88efe5dc53e50d341a09de4d02331200 (patch) | |
tree | cafff2748190357bac05d69d344e79b0e38d1e27 /gcc/config/rl78/rl78.md | |
parent | 7b48bf2011b4020c4a5a2d5d4149b03983f72cc2 (diff) | |
download | gcc-tarball-e0e4357b88efe5dc53e50d341a09de4d02331200.tar.gz |
gcc-6.1.0gcc-6.1.0
Diffstat (limited to 'gcc/config/rl78/rl78.md')
-rw-r--r-- | gcc/config/rl78/rl78.md | 357 |
1 files changed, 305 insertions, 52 deletions
diff --git a/gcc/config/rl78/rl78.md b/gcc/config/rl78/rl78.md index 2d73b01b64..739f6057b9 100644 --- a/gcc/config/rl78/rl78.md +++ b/gcc/config/rl78/rl78.md @@ -1,5 +1,5 @@ ;; Machine Description for Renesas RL78 processors -;; Copyright (C) 2011-2015 Free Software Foundation, Inc. +;; Copyright (C) 2011-2016 Free Software Foundation, Inc. ;; Contributed by Red Hat. ;; This file is part of GCC. @@ -107,7 +107,7 @@ ) (define_expand "eh_return" - [(match_operand:HI 0 "" "")] + [(match_operand:HI 0 "")] "" "rl78_expand_eh_epilogue (operands[0]); emit_barrier (); @@ -169,10 +169,10 @@ ;; non-immediate as well. (define_expand "nonlocal_goto" [(set (pc) - (unspec_volatile [(match_operand 0 "" "") ;; fp (ignore) - (match_operand 1 "" "vi") ;; target - (match_operand 2 "" "vi") ;; sp - (match_operand 3 "" "vi") ;; ? + (unspec_volatile [(match_operand 0 "") ;; fp (ignore) + (match_operand 1 "") ;; target + (match_operand 2 "") ;; sp + (match_operand 3 "") ;; ? ] UNS_NONLOCAL_GOTO)) ] "" @@ -200,6 +200,14 @@ " ) +(define_expand "es_addr" + [(unspec:SI [(reg:QI ES_REG) + (match_operand:HI 0 "") + ] UNS_ES_ADDR)] + "" + "" +) + ;;====================================================================== ;; ;; "macro" insns - cases where inline chunks of code are more @@ -235,17 +243,14 @@ (clobber (reg:HI BC_REG)) ] "rl78_real_insns_ok ()" - "@ - movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax - movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax - movw ax,%h1 \;addw ax,%h2 \;movw bc, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax \;movw ax,bc \;movw %h0, ax" + { return rl78_addsi3_internal (operands, which_alternative); } [(set_attr "valloc" "macax")] ) (define_expand "subsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=&vm") - (minus:SI (match_operand:SI 1 "general_operand" "vim") - (match_operand 2 "general_operand" "vim"))) + [(set (match_operand:SI 0 "nonimmediate_operand") + (minus:SI (match_operand:SI 1 "general_operand") + (match_operand 2 "general_operand"))) ] "" "emit_insn (gen_subsi3_internal_virt (operands[0], operands[1], operands[2])); @@ -280,37 +285,53 @@ ) (define_expand "mulqi3" - [(set (match_operand:QI 0 "register_operand" "") - (mult:QI (match_operand:QI 1 "general_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - ] + [(parallel + [(set (match_operand:QI 0 "register_operand") + (mult:QI (match_operand:QI 1 "general_operand") + (match_operand:QI 2 "nonmemory_operand"))) + (clobber (reg:HI AX_REG)) + ]) + ] "" ; mulu supported by all targets "" ) (define_expand "mulhi3" - [(set (match_operand:HI 0 "register_operand" "") - (mult:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "nonmemory_operand" ""))) + [(set (match_operand:HI 0 "register_operand") + (mult:HI (match_operand:HI 1 "general_operand") + (match_operand:HI 2 "nonmemory_operand"))) ] "! RL78_MUL_NONE" - "" + { + if (RL78_MUL_G14) + emit_insn (gen_mulhi3_g14 (operands[0], operands[1], operands[2])); + else /* RL78_MUL_G13 */ + emit_insn (gen_mulhi3_g13 (operands[0], operands[1], operands[2])); + DONE; + } ) (define_expand "mulsi3" - [(set (match_operand:SI 0 "register_operand" "=&v") - (mult:SI (match_operand:SI 1 "general_operand" "+vim") - (match_operand:SI 2 "nonmemory_operand" "vi"))) + [(set (match_operand:SI 0 "register_operand") + (mult:SI (match_operand:SI 1 "general_operand") + (match_operand:SI 2 "nonmemory_operand"))) ] "! RL78_MUL_NONE" - "" + { + if (RL78_MUL_G14) + emit_insn (gen_mulsi3_g14 (operands[0], operands[1], operands[2])); + else /* RL78_MUL_G13 */ + emit_insn (gen_mulsi3_g13 (operands[0], operands[1], operands[2])); + DONE; + } ) (define_insn "*mulqi3_rl78" [(set (match_operand:QI 0 "register_operand" "=&v") - (mult:QI (match_operand:QI 1 "general_operand" "+viU") + (mult:QI (match_operand:QI 1 "general_operand" "viU") (match_operand:QI 2 "general_operand" "vi"))) - ] + (clobber (reg:HI AX_REG)) + ] "" ; mulu supported by all targets "; mulqi macro %0 = %1 * %2 mov a, %h1 @@ -320,31 +341,34 @@ mov a, x mov %h0, a ; end of mulqi macro" -;; [(set_attr "valloc" "macax")] + [(set_attr "valloc" "macax")] ) -(define_insn "*mulhi3_rl78" +(define_insn "mulhi3_g14" [(set (match_operand:HI 0 "register_operand" "=&v") - (mult:HI (match_operand:HI 1 "general_operand" "+viU") + (mult:HI (match_operand:HI 1 "general_operand" "viU") (match_operand:HI 2 "general_operand" "vi"))) - ] - "RL78_MUL_RL78" - "; mulhi macro %0 = %1 * %2 + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] + "RL78_MUL_G14" + "; G14 mulhi macro %0 = %1 * %2 movw ax, %h1 movw bc, %h2 mulhu ; bcax = bc * ax movw %h0, ax ; end of mulhi macro" -;; [(set_attr "valloc" "macax")] + [(set_attr "valloc" "macax")] ) -(define_insn "*mulhi3_g13" +(define_insn "mulhi3_g13" [(set (match_operand:HI 0 "register_operand" "=&v") - (mult:HI (match_operand:HI 1 "general_operand" "+viU") + (mult:HI (match_operand:HI 1 "general_operand" "viU") (match_operand:HI 2 "general_operand" "vi"))) - ] + (clobber (reg:HI AX_REG)) + ] "RL78_MUL_G13" - "; mulhi macro %0 = %1 * %2 + "; G13 mulhi macro %0 = %1 * %2 mov a, #0x00 mov !0xf00e8, a ; MDUC movw ax, %h1 @@ -355,19 +379,21 @@ movw ax, 0xffff6 ; MDBL movw %h0, ax ; end of mulhi macro" -;; [(set_attr "valloc" "umul")] + [(set_attr "valloc" "macax")] ) ;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it ;; because we're only using the lower 16 bits (which is the upper 16 ;; bits of the result). -(define_insn "mulsi3_rl78" +(define_insn "mulsi3_g14" [(set (match_operand:SI 0 "register_operand" "=&v") - (mult:SI (match_operand:SI 1 "general_operand" "+viU") + (mult:SI (match_operand:SI 1 "general_operand" "viU") (match_operand:SI 2 "general_operand" "vi"))) - ] - "RL78_MUL_RL78" - "; mulsi macro %0 = %1 * %2 + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] + "RL78_MUL_G14" + "; G14 mulsi macro %0 = %1 * %2 movw ax, %h1 movw bc, %h2 MULHU ; bcax = bc * ax @@ -395,9 +421,11 @@ [(set (match_operand:SI 0 "register_operand" "=&v") (mult:SI (match_operand:SI 1 "general_operand" "viU") (match_operand:SI 2 "general_operand" "viU"))) - ] + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] "RL78_MUL_G13" - "; mulsi macro %0 = %1 * %2 + "; G13 mulsi macro %0 = %1 * %2 mov a, #0x00 mov !0xf00e8, a ; MDUC movw ax, %h1 @@ -432,12 +460,237 @@ movw %H0, ax ; end of mulsi macro" [(set_attr "valloc" "macax")] - ) +) -(define_expand "es_addr" - [(unspec:SI [(reg:QI ES_REG) - (match_operand:HI 0 "" "") - ] UNS_ES_ADDR)] - "" +(define_expand "udivmodhi4" + [(parallel + [(set (match_operand:HI 0 "register_operand") + (udiv:HI (match_operand:HI 1 "register_operand") + (match_operand:HI 2 "register_operand"))) + (set (match_operand:HI 3 "register_operand") + (umod:HI (match_dup 1) (match_dup 2))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI DE_REG)) + ]) + ] + "RL78_MUL_G14" "" ) + +(define_insn "*udivmodhi4_g14" + [(set (match_operand:HI 0 "register_operand" "=v") + (udiv:HI (match_operand:HI 1 "register_operand" "v") + (match_operand:HI 2 "register_operand" "v"))) + (set (match_operand:HI 3 "register_operand" "=v") + (umod:HI (match_dup 1) (match_dup 2))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI DE_REG)) + ] + "RL78_MUL_G14" + { + if (find_reg_note (insn, REG_UNUSED, operands[3])) + return "; G14 udivhi macro %0 = %1 / %2 \n\ + movw ax, %h1 \n\ + movw de, %h2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divhu ; ax = ax / de \n\ + pop psw ; Restore saved interrupt status \n\ + movw %h0, ax \n\ + ; end of udivhi macro"; + else if (find_reg_note (insn, REG_UNUSED, operands[0])) + return "; G14 umodhi macro %3 = %1 %% %2 \n\ + movw ax, %h1 \n\ + movw de, %h2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divhu ; de = ax %% de \n\ + pop psw ; Restore saved interrupt status \n\ + movw ax, de \n\ + movw %h3, ax \n\ + ; end of umodhi macro"; + else + return "; G14 udivmodhi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ + movw ax, %h1 \n\ + movw de, %h2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divhu ; ax = ax / de, de = ax %% de \n\ + pop psw ; Restore saved interrupt status \n\ + movw %h0, ax \n\ + movw ax, de \n\ + movw %h3, ax \n\ + ; end of udivmodhi macro"; + } + [(set_attr "valloc" "divhi")] +) + +(define_expand "udivmodsi4" + [(parallel + [(set (match_operand:SI 0 "register_operand") + (udiv:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "register_operand"))) + (set (match_operand:SI 3 "register_operand") + (umod:SI (match_dup 1) (match_dup 2))) + ]) + ] + "! RL78_MUL_NONE && ! optimize_size" + { + if (RL78_MUL_G14) + emit_insn (gen_udivmodsi4_g14 (operands[0], operands[1], operands[2], operands[3])); + else /* RL78_MUL_G13 */ + emit_insn (gen_udivmodsi4_g13 (operands[0], operands[1], operands[2], operands[3])); + DONE; + } +) + +(define_insn "udivmodsi4_g14" + [(set (match_operand:SI 0 "register_operand" "=v") + (udiv:SI (match_operand:SI 1 "register_operand" "v") + (match_operand:SI 2 "register_operand" "v"))) + (set (match_operand:SI 3 "register_operand" "=v") + (umod:SI (match_dup 1) (match_dup 2))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + (clobber (reg:HI DE_REG)) + (clobber (reg:HI HL_REG)) + ] + "RL78_MUL_G14" + { + if (find_reg_note (insn, REG_UNUSED, operands[3])) + return "; G14 udivsi macro %0 = %1 / %2 \n\ + movw ax, %h1 \n\ + movw bc, %H1 \n\ + movw de, %h2 \n\ + movw hl, %H2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divwu ; bcax = bcax / hlde \n\ + pop psw ; Restore saved interrupt status \n\ + movw %h0, ax \n\ + movw ax, bc \n\ + movw %H0, ax \n\ + ; end of udivsi macro"; + else if (find_reg_note (insn, REG_UNUSED, operands[0])) + return "; G14 umodsi macro %3 = %1 %% %2 \n\ + movw ax, %h1 \n\ + movw bc, %H1 \n\ + movw de, %h2 \n\ + movw hl, %H2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divwu ; hlde = bcax %% hlde \n\ + pop psw ; Restore saved interrupt status \n\ + movw ax, de \n\ + movw %h3, ax \n\ + movw ax, hl \n\ + movw %H3, ax \n\ + ; end of umodsi macro"; + else + return "; G14 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ + movw ax, %h1 \n\ + movw bc, %H1 \n\ + movw de, %h2 \n\ + movw hl, %H2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divwu ; bcax = bcax / hlde, hlde = bcax %% hlde \n\ + pop psw ; Restore saved interrupt status \n\ + movw %h0, ax \n\ + movw ax, bc \n\ + movw %H0, ax \n\ + movw ax, de \n\ + movw %h3, ax \n\ + movw ax, hl \n\ + movw %H3, ax \n\ + ; end of udivmodsi macro"; + } + [(set_attr "valloc" "divsi")] +) + +;; Warning: these values match the silicon not the documentation. +;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH. +;; 0xFFFF6 is MDBL. 0xFFFF4 is MDBH. +;; 0xF00E0 is MDCL. 0xF00E2 is MDCH. +;; 0xF00E8 is MDUC. + +(define_insn "udivmodsi4_g13" + [(set (match_operand:SI 0 "register_operand" "=v") + (udiv:SI (match_operand:SI 1 "register_operand" "v") + (match_operand:SI 2 "register_operand" "v"))) + (set (match_operand:SI 3 "register_operand" "=v") + (umod:SI (match_dup 1) (match_dup 2))) + (clobber (reg:HI AX_REG)) + ] + "RL78_MUL_G13" + { + if (find_reg_note (insn, REG_UNUSED, operands[3])) + return "; G13 udivsi macro %0 = %1 / %2 \n\ + mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ + mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ + movw ax, %H1 \n\ + movw 0xffff2, ax ; MDAH \n\ + movw ax, %h1 \n\ + movw 0xffff0, ax ; MDAL \n\ + movw ax, %H2 \n\ + movw 0xffff4, ax ; MDBH \n\ + movw ax, %h2 \n\ + movw 0xffff6, ax ; MDBL \n\ + mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ + mov !0xf00e8, a ; This starts the division op \n\ +1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ + bt a.0, $1b \n\ + movw ax, 0xffff0 ; Read the quotient \n\ + movw %h0, ax \n\ + movw ax, 0xffff2 \n\ + movw %H0, ax \n\ + ; end of udivsi macro"; + else if (find_reg_note (insn, REG_UNUSED, operands[0])) + return "; G13 umodsi macro %3 = %1 %% %2 \n\ + mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ + mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ + movw ax, %H1 \n\ + movw 0xffff2, ax ; MDAH \n\ + movw ax, %h1 \n\ + movw 0xffff0, ax ; MDAL \n\ + movw ax, %H2 \n\ + movw 0xffff4, ax ; MDBH \n\ + movw ax, %h2 \n\ + movw 0xffff6, ax ; MDBL \n\ + mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ + mov !0xf00e8, a ; This starts the division op \n\ +1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ + bt a.0, $1b \n\ + movw ax, !0xf00e0 ; Read the remainder \n\ + movw %h3, ax \n\ + movw ax, !0xf00e2 \n\ + movw %H3, ax \n\ + ; end of umodsi macro"; + else + return "; G13 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ + mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ + mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ + movw ax, %H1 \n\ + movw 0xffff2, ax ; MDAH \n\ + movw ax, %h1 \n\ + movw 0xffff0, ax ; MDAL \n\ + movw ax, %H2 \n\ + movw 0xffff4, ax ; MDBH \n\ + movw ax, %h2 \n\ + movw 0xffff6, ax ; MDBL \n\ + mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ + mov !0xf00e8, a ; This starts the division op \n\ +1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ + bt a.0, $1b \n\ + movw ax, 0xffff0 ; Read the quotient \n\ + movw %h0, ax \n\ + movw ax, 0xffff2 \n\ + movw %H0, ax \n\ + movw ax, !0xf00e0 ; Read the remainder \n\ + movw %h3, ax \n\ + movw ax, !0xf00e2 \n\ + movw %H3, ax \n\ + ; end of udivmodsi macro"; + } + [(set_attr "valloc" "macax")] +) |