diff options
author | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-03 21:57:40 +0000 |
---|---|---|
committer | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-03 21:57:40 +0000 |
commit | 750dcfc587cb967b8573359029d09be04c1622f4 (patch) | |
tree | b65c48df3c7c3220b2fcf01d2911f9bc100b1295 | |
parent | 92a9c89ef418512c8d79001b185d50d4ee5f6c8a (diff) | |
download | gcc-750dcfc587cb967b8573359029d09be04c1622f4.tar.gz |
* config/rl78/rl78-real.md (*addqi_real): Allow SADDR types for
inc/dec.
(*addhi3_real): Likewise.
* config/rl78/rl78-virt.md (*inc<mode>3_virt): Additional
pattern to match incrementing memory.
* config/rl78/predicates.md (rl78_1_2_operand): New.
* config/rl78/rl78.c (rl78_force_nonfar_3): Allow far mem-mem if
it's the same and only mem.
(rl78_alloc_physical_registers_op2): If there's effectively only
one MEM, transcode it into HL.
(rl78_far_p): Reject addresses that aren't legitimate.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221164 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config/rl78/predicates.md | 15 | ||||
-rw-r--r-- | gcc/config/rl78/rl78-real.md | 8 | ||||
-rw-r--r-- | gcc/config/rl78/rl78-virt.md | 9 | ||||
-rw-r--r-- | gcc/config/rl78/rl78.c | 28 |
5 files changed, 67 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a562ee79d18..10f36fa3558 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2015-03-03 DJ Delorie <dj@redhat.com> + + * config/rl78/rl78-real.md (*addqi_real): Allow SADDR types for + inc/dec. + (*addhi3_real): Likewise. + * config/rl78/rl78-virt.md (*inc<mode>3_virt): Additional + pattern to match incrementing memory. + * config/rl78/predicates.md (rl78_1_2_operand): New. + * config/rl78/rl78.c (rl78_force_nonfar_3): Allow far mem-mem if + it's the same and only mem. + (rl78_alloc_physical_registers_op2): If there's effectively only + one MEM, transcode it into HL. + (rl78_far_p): Reject addresses that aren't legitimate. + 2015-03-03 Eric Botcazou <ebotcazou@adacore.com> * fold-const.c (round_up_loc): Cast divisor to HOST_WIDE_INT before diff --git a/gcc/config/rl78/predicates.md b/gcc/config/rl78/predicates.md index b89eed22400..66e7e44827d 100644 --- a/gcc/config/rl78/predicates.md +++ b/gcc/config/rl78/predicates.md @@ -58,6 +58,21 @@ (and (match_code "const_int") (match_test "IN_RANGE (INTVAL (op), 0, 255)"))) +(define_predicate "rl78_incdec_memory_operand" + (and (match_code "mem") + (match_test "rl78_far_p (op) +|| satisfies_constraint_Wsa (op) +|| satisfies_constraint_Whl (op) +|| satisfies_constraint_Wh1 (op) +|| satisfies_constraint_Wab (op)") + ) +) + +(define_predicate "rl78_1_2_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 1, 2) + || IN_RANGE (INTVAL (op), -2, -1)"))) + (define_predicate "rl78_24_operand" (and (match_code "const_int") (match_test "INTVAL (op) == 2 || INTVAL (op) == 4"))) diff --git a/gcc/config/rl78/rl78-real.md b/gcc/config/rl78/rl78-real.md index 8ec2f3d6a6f..cfd9742a5d7 100644 --- a/gcc/config/rl78/rl78-real.md +++ b/gcc/config/rl78/rl78-real.md @@ -113,14 +113,14 @@ ;;---------- Arithmetic ------------------------ (define_insn "*addqi3_real" - [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl,Wsa") + [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=rvWabWhlWh1Wsa,rvWabWhlWh1Wsa,a,*bcdehl,Wsa") (plus:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0,0") (match_operand:QI 2 "rl78_general_operand" "K,L,RWhlWh1Wabi,a,i"))) ] "rl78_real_insns_ok ()" "@ - inc\t%0 - dec\t%0 + inc\t%p0 + dec\t%p0 add\t%0, %2 add\t%0, %2 add\t%0, %2" @@ -128,7 +128,7 @@ ) (define_insn "*addhi3_real" - [(set (match_operand:HI 0 "rl78_nonimmediate_operand" "=vABDTWh1Wab,vABDTWh1Wab,v,v,A,S,S,A") + [(set (match_operand:HI 0 "rl78_nonimmediate_operand" "=vABDTWhlWh1WabWsa,vABDTWhlWh1WabWsa,v,v,A,S,S,A") (plus:HI (match_operand:HI 1 "rl78_general_operand" "%0,0,0,0,0,0,0,S") (match_operand:HI 2 "" "K,L,N,O,RWh1WhlWabiv,Int8Qs8,J,Ri"))) ] diff --git a/gcc/config/rl78/rl78-virt.md b/gcc/config/rl78/rl78-virt.md index fadcbc50433..c29db26da80 100644 --- a/gcc/config/rl78/rl78-virt.md +++ b/gcc/config/rl78/rl78-virt.md @@ -85,6 +85,15 @@ ;;---------- Arithmetic ------------------------ +(define_insn "*inc<mode>3_virt" + [(set (match_operand:QHI 0 "rl78_incdec_memory_operand" "=vm") + (plus:QHI (match_operand:QHI 1 "rl78_incdec_memory_operand" "0") + (match_operand:QHI 2 "rl78_1_2_operand" "KLNO"))) + ] + "rl78_virt_insns_ok ()" + "v.inc\t%0, %1, %2" +) + (define_insn "*add<mode>3_virt" [(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vY,S") (plus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "viY,0") diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index 40772dad03f..0c577c4414e 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -579,6 +579,13 @@ rl78_force_nonfar_3 (rtx *operands, rtx (*gen)(rtx,rtx,rtx)) int did = 0; rtx temp_reg = NULL; + /* As an exception, we allow two far operands if they're identical + and the third operand is not a MEM. This allows global variables + to be incremented, for example. */ + if (rtx_equal_p (operands[0], operands[1]) + && ! MEM_P (operands[2])) + return 0; + /* FIXME: Likewise. */ if (rl78_far_p (operands[1])) { @@ -970,6 +977,12 @@ rl78_far_p (rtx x) fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x); fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR); #endif + + /* Not all far addresses are legitimate, because the devirtualizer + can't handle them. */ + if (! rl78_as_legitimate_address (GET_MODE (x), XEXP (x, 0), false, ADDR_SPACE_FAR)) + return 0; + return GET_MODE_BITSIZE (rl78_addr_space_address_mode (MEM_ADDR_SPACE (x))) == 32; } @@ -3007,9 +3020,18 @@ rl78_alloc_physical_registers_op2 (rtx_insn * insn) if (rtx_equal_p (OP (0), OP (1))) { - OP (0) = - OP (1) = transcode_memory_rtx (OP (1), DE, insn); - OP (2) = transcode_memory_rtx (OP (2), HL, insn); + if (MEM_P (OP (2))) + { + OP (0) = + OP (1) = transcode_memory_rtx (OP (1), DE, insn); + OP (2) = transcode_memory_rtx (OP (2), HL, insn); + } + else + { + OP (0) = + OP (1) = transcode_memory_rtx (OP (1), HL, insn); + OP (2) = transcode_memory_rtx (OP (2), DE, insn); + } } else if (rtx_equal_p (OP (0), OP (2))) { |