===================================================================
@@ -361,13 +361,13 @@
(define_memory_constraint "Ws1"
"es:word8[SP]"
(match_test "(rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op)))
|| satisfies_constraint_Cs1 (op)")
)
-(define_memory_constraint "Wfr"
+(define_constraint "Wfr"
"ES/CS far pointer"
(and (match_code "mem")
(match_test "rl78_far_p (op)"))
)
(define_memory_constraint "Wsa"
===================================================================
@@ -51,6 +51,8 @@ bool rl78_flags_already_set (rtx, rtx);
void rl78_output_symbol_ref (FILE *, rtx);
void rl78_output_labelref (FILE *, const char *);
int rl78_saddr_p (rtx x);
int rl78_sfr_p (rtx x);
void rl78_output_aligned_common (FILE *, tree, const char *,
int, int, int);
+
+int rl78_one_far_p (rtx *operands, int num_operands);
===================================================================
@@ -586,25 +586,25 @@
(if_then_else (eq (and (reg:QI A_REG)
(match_operand 0 "immediate_operand" "n"))
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
""
- "bf\tA.%B0, $%1"
+ "bt\tA.%B0, $1f\n\tbr !!%1\n\t1:"
[(set (attr "update_Z") (const_string "clobber"))]
)
(define_insn "bt"
[(set (pc)
(if_then_else (ne (and (reg:QI A_REG)
(match_operand 0 "immediate_operand" "n"))
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
""
- "bt\tA.%B0, $%1"
+ "bf\tA.%B0, $1f\n\tbr !!%1\n\t1:"
[(set (attr "update_Z") (const_string "clobber"))]
)
;; NOTE: These peepholes are fragile. They rely upon GCC generating
;; a specific sequence on insns, based upon examination of test code.
;; Improvements to GCC or using code other than the test code can result
===================================================================
@@ -39,14 +39,14 @@
"rl78_virt_insns_ok ()"
"v.mov %0, %1"
[(set_attr "valloc" "op1")]
)
(define_insn "*movqi_virt"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=vY,v,Wfr")
- (match_operand 1 "general_operand" "vInt8J,YWfr,vInt8J"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=vY,v,*Wfr,Y,*Wfr,*Wfr")
+ (match_operand 1 "general_operand" "vInt8JY,*Wfr,vInt8J,*Wfr,Y,*Wfr"))]
"rl78_virt_insns_ok ()"
"v.mov %0, %1"
[(set_attr "valloc" "op1")]
)
(define_insn "*movhi_virt_mm"
@@ -55,33 +55,33 @@
"rl78_virt_insns_ok ()"
"v.movw %0, %1"
[(set_attr "valloc" "op1")]
)
(define_insn "*movhi_virt"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=vS, Y, v, Wfr")
- (match_operand:HI 1 "general_operand" "viYS, viS, Wfr, vi"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=vS, Y, v, *Wfr")
+ (match_operand:HI 1 "general_operand" "viYS, viS, *Wfr, vi"))]
"rl78_virt_insns_ok ()"
"v.movw %0, %1"
[(set_attr "valloc" "op1")]
)
;;---------- Conversions ------------------------
(define_insn "*zero_extendqihi2_virt"
- [(set (match_operand:HI 0 "rl78_nonfar_nonimm_operand" "=vm")
- (zero_extend:HI (match_operand:QI 1 "general_operand" "vim")))]
- "rl78_virt_insns_ok ()"
+ [(set (match_operand:HI 0 "rl78_nonfar_nonimm_operand" "=vY,*Wfr")
+ (zero_extend:HI (match_operand:QI 1 "general_operand" "vim,viY")))]
+ "rl78_virt_insns_ok () && rl78_one_far_p (operands, 2)"
"v.zero_extend\t%0, %1"
[(set_attr "valloc" "op1")]
)
(define_insn "*extendqihi2_virt"
- [(set (match_operand:HI 0 "rl78_nonfar_nonimm_operand" "=vm")
- (sign_extend:HI (match_operand:QI 1 "general_operand" "vim")))]
- "rl78_virt_insns_ok ()"
+ [(set (match_operand:HI 0 "rl78_nonfar_nonimm_operand" "=vY,*Wfr")
+ (sign_extend:HI (match_operand:QI 1 "general_operand" "vim,viY")))]
+ "rl78_virt_insns_ok () && rl78_one_far_p (operands, 2)"
"v.sign_extend\t%0, %1"
[(set_attr "valloc" "op1")]
)
;;---------- Arithmetic ------------------------
@@ -92,26 +92,26 @@
]
"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")
- (match_operand:QHI 2 "rl78_general_operand" "vim,i")))
+ [(set (match_operand:QHI 0 "rl78_nonimmediate_operand" "=vY, S, *Wfr, vY")
+ (plus:QHI (match_operand:QHI 1 "rl78_general_operand" "%viY, 0, 0viY, *Wfr")
+ (match_operand:QHI 2 "rl78_general_operand" "vim, i, viY, viY")))
]
- "rl78_virt_insns_ok ()"
+ "rl78_virt_insns_ok () && rl78_one_far_p (operands, 3)"
"v.add\t%0, %1, %2"
)
(define_insn "*sub<mode>3_virt"
- [(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vm,S")
- (minus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "vim,0")
- (match_operand:QHI 2 "rl78_general_operand" "vim,i")))
+ [(set (match_operand:QHI 0 "rl78_nonimmediate_operand" "=vY, S, *Wfr, vY")
+ (minus:QHI (match_operand:QHI 1 "rl78_general_operand" "viY, 0, 0viY, *Wfr")
+ (match_operand:QHI 2 "rl78_general_operand" "vim, i, viY, viY")))
]
- "rl78_virt_insns_ok ()"
+ "rl78_virt_insns_ok () && rl78_one_far_p (operands, 3)"
"v.sub\t%0, %1, %2"
)
(define_insn "*umulhi3_shift_virt"
[(set (match_operand:HI 0 "register_operand" "=v")
(mult:HI (match_operand:HI 1 "rl78_nonfar_operand" "%vim")
@@ -128,35 +128,35 @@
"rl78_virt_insns_ok () && !TARGET_G10"
"v.mulu\t%0, %2"
[(set_attr "valloc" "umul")]
)
(define_insn "*andqi3_virt"
- [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=vm")
- (and:QI (match_operand:QI 1 "rl78_general_operand" "vim")
- (match_operand:QI 2 "rl78_general_operand" "vim")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=vm, *Wfr, vY")
+ (and:QI (match_operand:QI 1 "rl78_general_operand" "%vim, 0viY, *Wfr")
+ (match_operand:QI 2 "rl78_general_operand" "vim, viY, viY")))
]
- "rl78_virt_insns_ok ()"
+ "rl78_virt_insns_ok () && rl78_one_far_p (operands, 3)"
"v.and\t%0, %1, %2"
)
(define_insn "*iorqi3_virt"
- [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=vm")
- (ior:QI (match_operand:QI 1 "rl78_general_operand" "vim")
- (match_operand:QI 2 "rl78_general_operand" "vim")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=vm, *Wfr, vY")
+ (ior:QI (match_operand:QI 1 "rl78_general_operand" "%vim, 0viY, *Wfr")
+ (match_operand:QI 2 "rl78_general_operand" "vim, viY, viY")))
]
- "rl78_virt_insns_ok ()"
+ "rl78_virt_insns_ok () && rl78_one_far_p (operands, 3)"
"v.or\t%0, %1, %2"
)
(define_insn "*xorqi3_virt"
- [(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=v,vm,m")
- (xor:QI (match_operand:QI 1 "rl78_nonfar_operand" "%0,vm,vm")
- (match_operand 2 "rl78_general_operand" "i,vm,vim")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=vm, *Wfr, vY")
+ (xor:QI (match_operand:QI 1 "rl78_general_operand" "%vim, 0viY, *Wfr")
+ (match_operand 2 "rl78_general_operand" "vim, viY, viY")))
]
- "rl78_virt_insns_ok ()"
+ "rl78_virt_insns_ok () && rl78_one_far_p (operands, 3)"
"v.xor\t%0, %1, %2"
)
;;---------- Shifts ------------------------
(define_insn "*ashl<mode>3_virt"
===================================================================
@@ -607,12 +607,30 @@ rl78_force_nonfar_3 (rtx *operands, rtx
emit_insn (gen (operands[0], operands[1], operands[2]));
if (temp_reg)
emit_move_insn (temp_reg, operands[0]);
return 1;
}
+int
+rl78_one_far_p (rtx *operands, int n)
+{
+ rtx which = NULL;
+ int i, c = 0;
+
+ for (i = 0; i < n; i ++)
+ if (rl78_far_p (operands[i]))
+ {
+ if (which == NULL)
+ which = operands[i];
+ else if (rtx_equal_p (operands[i], which))
+ continue;
+ c ++;
+ }
+ return c <= 1;
+}
+
#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE rl78_can_eliminate
static bool
rl78_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to ATTRIBUTE_UNUSED)
{