aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaz Kojima <kkojima@rr.iij4u.or.jp>2024-09-24 18:26:42 +0900
committerOleg Endo <olegendo@gcc.gnu.org>2024-09-25 10:20:31 +0900
commit4d28c5b1eb15cff97f07982c73770485e6eaa986 (patch)
tree6119170b33a7a6a518814ed78e4cffa94f4e6802
parentc5a639c84c15adf402d5b664184628ff809a5bb0 (diff)
downloadgcc-4d28c5b1eb15cff97f07982c73770485e6eaa986.zip
gcc-4d28c5b1eb15cff97f07982c73770485e6eaa986.tar.gz
gcc-4d28c5b1eb15cff97f07982c73770485e6eaa986.tar.bz2
SH: pin input args to hard-regs via predicates for sfuncs
Some sfuncs uses hard reg as input and clobber its raw reg pattern. It seems that LRA doesn't process this clobber pattern. Rewrite these patterns so as to work with LRA. gcc/ChangeLog: * config/sh/predicates.md (hard_reg_r4, hard_reg_r5, hard_reg_r6): New predicates. * config/sh/sh.md (udivsi3_i4, udivsi3_i4_single, udivsi3_i1): Rewrite with match_operand and match_dup. (block_lump_real, block_lump_real_i4): Ditto. (udivsi3): Adjust for it. * config/sh/sh-mem.cc (expand_block_move): Ditto.
-rw-r--r--gcc/config/sh/predicates.md19
-rw-r--r--gcc/config/sh/sh-mem.cc4
-rw-r--r--gcc/config/sh/sh.md101
3 files changed, 84 insertions, 40 deletions
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 3732cec..b10af71 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -818,3 +818,22 @@
return false;
})
+
+;; Predicats for the arguments of sfunc R4, R5 and R6.
+(define_predicate "hard_reg_r4"
+ (match_code "reg")
+{
+ return REGNO (op) == R4_REG;
+})
+
+(define_predicate "hard_reg_r5"
+ (match_code "reg")
+{
+ return REGNO (op) == R5_REG;
+})
+
+(define_predicate "hard_reg_r6"
+ (match_code "reg")
+{
+ return REGNO (op) == R6_REG;
+})
diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc
index e224199..751c826 100644
--- a/gcc/config/sh/sh-mem.cc
+++ b/gcc/config/sh/sh-mem.cc
@@ -134,7 +134,7 @@ expand_block_move (rtx *operands)
int dwords = bytes >> 3;
emit_insn (gen_move_insn (r6, GEN_INT (dwords - 1)));
- emit_insn (gen_block_lump_real_i4 (func_addr_rtx, lab));
+ emit_insn (gen_block_lump_real_i4 (func_addr_rtx, lab, r4, r5, r6));
return true;
}
else
@@ -178,7 +178,7 @@ expand_block_move (rtx *operands)
final_switch = 16 - ((bytes / 4) % 16);
while_loop = ((bytes / 4) / 16 - 1) * 16;
emit_insn (gen_move_insn (r6, GEN_INT (while_loop + final_switch)));
- emit_insn (gen_block_lump_real (func_addr_rtx, lab));
+ emit_insn (gen_block_lump_real (func_addr_rtx, lab, r4, r5, r6));
return true;
}
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index c69eda3..451ae0b 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -2194,13 +2194,24 @@
;; there is nothing to prevent reload from using r0 to reload the address.
;; This reload would clobber the value in r0 we are trying to store.
;; If we let reload allocate r0, then this problem can never happen.
+;;
+;; In addition to that, we also must pin the input regs to hard-regs via the
+;; predicates. When these insns are instantiated it also emits the
+;; accompanying mov insns to load the hard-regs. However, subsequent RTL
+;; passes might move things around and reassign the operands to pseudo regs
+;; which might get allocated to different (wrong) hard-regs eventually. To
+;; avoid that, only allow matching these insns if the operands are the
+;; expected hard-regs.
(define_insn "udivsi3_i1"
[(set (match_operand:SI 0 "register_operand" "=z,z")
- (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
+ (udiv:SI (match_operand:SI 3 "hard_reg_r4" "=r,r")
+ (match_operand:SI 4 "hard_reg_r5" "=r,r")))
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:SI R1_REG))
- (clobber (reg:SI R4_REG))
+ (clobber (match_dup 3))
+ (use (reg:SI R4_REG))
+ (use (reg:SI R5_REG))
(use (match_operand:SI 1 "arith_reg_operand" "r,r"))
(use (match_operand 2 "" "Z,Ccl"))]
"TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
@@ -2212,7 +2223,8 @@
(define_insn "udivsi3_i4"
[(set (match_operand:SI 0 "register_operand" "=y,y")
- (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
+ (udiv:SI (match_operand:SI 3 "hard_reg_r4" "=r,r")
+ (match_operand:SI 4 "hard_reg_r5" "=r,r")))
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:DF DR0_REG))
@@ -2220,9 +2232,11 @@
(clobber (reg:DF DR4_REG))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))
- (clobber (reg:SI R4_REG))
- (clobber (reg:SI R5_REG))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
(clobber (reg:SI FPSCR_STAT_REG))
+ (use (reg:SI R4_REG))
+ (use (reg:SI R5_REG))
(use (match_operand:SI 1 "arith_reg_operand" "r,r"))
(use (match_operand 2 "" "Z,Ccl"))
(use (reg:SI FPSCR_MODES_REG))]
@@ -2236,7 +2250,8 @@
(define_insn "udivsi3_i4_single"
[(set (match_operand:SI 0 "register_operand" "=y,y")
- (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
+ (udiv:SI (match_operand:SI 3 "hard_reg_r4" "=r,r")
+ (match_operand:SI 4 "hard_reg_r5" "=r,r")))
(clobber (reg:SI T_REG))
(clobber (reg:SI PR_REG))
(clobber (reg:DF DR0_REG))
@@ -2244,8 +2259,10 @@
(clobber (reg:DF DR4_REG))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))
- (clobber (reg:SI R4_REG))
- (clobber (reg:SI R5_REG))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (use (reg:SI R4_REG))
+ (use (reg:SI R5_REG))
(use (match_operand:SI 1 "arith_reg_operand" "r,r"))
(use (match_operand 2 "" "Z,Ccl"))]
"TARGET_FPU_ANY && TARGET_FPU_SINGLE"
@@ -2278,6 +2295,8 @@
{
rtx last;
rtx func_ptr = gen_reg_rtx (Pmode);
+ rtx r4 = gen_rtx_REG (SImode, R4_REG);
+ rtx r5 = gen_rtx_REG (SImode, R5_REG);
/* Emit the move of the address to a pseudo outside of the libcall. */
if (TARGET_DIVIDE_CALL_TABLE)
@@ -2305,9 +2324,9 @@
{
rtx lab = function_symbol (func_ptr, "__udivsi3_i4", SFUNC_STATIC).lab;
if (TARGET_FPU_SINGLE)
- last = gen_udivsi3_i4_single (operands[0], func_ptr, lab);
+ last = gen_udivsi3_i4_single (operands[0], func_ptr, lab, r4, r5);
else
- last = gen_udivsi3_i4 (operands[0], func_ptr, lab);
+ last = gen_udivsi3_i4 (operands[0], func_ptr, lab, r4, r5);
}
else if (TARGET_SH2A)
{
@@ -2319,10 +2338,10 @@
else
{
rtx lab = function_symbol (func_ptr, "__udivsi3", SFUNC_STATIC).lab;
- last = gen_udivsi3_i1 (operands[0], func_ptr, lab);
+ last = gen_udivsi3_i1 (operands[0], func_ptr, lab, r4, r5);
}
- emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
- emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
+ emit_move_insn (r4, operands[1]);
+ emit_move_insn (r5, operands[2]);
emit_insn (last);
DONE;
})
@@ -9084,17 +9103,20 @@
(set_attr "needs_delay_slot" "yes")])
(define_insn "block_lump_real"
- [(parallel [(set (mem:BLK (reg:SI R4_REG))
- (mem:BLK (reg:SI R5_REG)))
- (use (match_operand:SI 0 "arith_reg_operand" "r,r"))
- (use (match_operand 1 "" "Z,Ccl"))
- (use (reg:SI R6_REG))
- (clobber (reg:SI PR_REG))
- (clobber (reg:SI T_REG))
- (clobber (reg:SI R4_REG))
- (clobber (reg:SI R5_REG))
- (clobber (reg:SI R6_REG))
- (clobber (reg:SI R0_REG))])]
+ [(set (mem:BLK (match_operand:SI 2 "hard_reg_r4" "=r,r"))
+ (mem:BLK (match_operand:SI 3 "hard_reg_r5" "=r,r")))
+ (use (match_operand:SI 0 "arith_reg_operand" "r,r"))
+ (use (match_operand 1 "" "Z,Ccl"))
+ (use (match_operand:SI 4 "hard_reg_r6" "=r,r"))
+ (use (reg:SI R4_REG))
+ (use (reg:SI R5_REG))
+ (use (reg:SI R6_REG))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (clobber (reg:SI PR_REG))
+ (clobber (reg:SI T_REG))
+ (clobber (reg:SI R0_REG))]
"TARGET_SH1 && ! TARGET_HARD_SH4"
"@
jsr @%0%#
@@ -9119,20 +9141,23 @@
(set_attr "needs_delay_slot" "yes")])
(define_insn "block_lump_real_i4"
- [(parallel [(set (mem:BLK (reg:SI R4_REG))
- (mem:BLK (reg:SI R5_REG)))
- (use (match_operand:SI 0 "arith_reg_operand" "r,r"))
- (use (match_operand 1 "" "Z,Ccl"))
- (use (reg:SI R6_REG))
- (clobber (reg:SI PR_REG))
- (clobber (reg:SI T_REG))
- (clobber (reg:SI R4_REG))
- (clobber (reg:SI R5_REG))
- (clobber (reg:SI R6_REG))
- (clobber (reg:SI R0_REG))
- (clobber (reg:SI R1_REG))
- (clobber (reg:SI R2_REG))
- (clobber (reg:SI R3_REG))])]
+ [(set (mem:BLK (match_operand:SI 2 "hard_reg_r4" "=r,r"))
+ (mem:BLK (match_operand:SI 3 "hard_reg_r5" "=r,r")))
+ (use (match_operand:SI 0 "arith_reg_operand" "r,r"))
+ (use (match_operand 1 "" "Z,Ccl"))
+ (use (match_operand:SI 4 "hard_reg_r6" "=r,r"))
+ (use (reg:SI R4_REG))
+ (use (reg:SI R5_REG))
+ (use (reg:SI R6_REG))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (clobber (reg:SI PR_REG))
+ (clobber (reg:SI T_REG))
+ (clobber (reg:SI R0_REG))
+ (clobber (reg:SI R1_REG))
+ (clobber (reg:SI R2_REG))
+ (clobber (reg:SI R3_REG))]
"TARGET_HARD_SH4"
"@
jsr @%0%#