summaryrefslogtreecommitdiff
path: root/gcc/config/rl78/rl78.md
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-27 10:13:12 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-27 10:13:12 +0000
commite0e4357b88efe5dc53e50d341a09de4d02331200 (patch)
treecafff2748190357bac05d69d344e79b0e38d1e27 /gcc/config/rl78/rl78.md
parent7b48bf2011b4020c4a5a2d5d4149b03983f72cc2 (diff)
downloadgcc-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.md357
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")]
+)