summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-03 21:57:40 +0000
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2015-03-03 21:57:40 +0000
commit750dcfc587cb967b8573359029d09be04c1622f4 (patch)
treeb65c48df3c7c3220b2fcf01d2911f9bc100b1295
parent92a9c89ef418512c8d79001b185d50d4ee5f6c8a (diff)
downloadgcc-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/ChangeLog14
-rw-r--r--gcc/config/rl78/predicates.md15
-rw-r--r--gcc/config/rl78/rl78-real.md8
-rw-r--r--gcc/config/rl78/rl78-virt.md9
-rw-r--r--gcc/config/rl78/rl78.c28
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)))
{