aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>2018-11-28 10:26:03 -0700
committerJeff Law <law@gcc.gnu.org>2018-11-28 10:26:03 -0700
commit735352d2eede1e412cb89f45a5c3e0846bce39af (patch)
tree113cc356265a9752c29f2b99a0a79db25e5ca7ed
parent7185a4ebc2121b9bef7f8697ad432e55a4ab5d25 (diff)
downloadgcc-735352d2eede1e412cb89f45a5c3e0846bce39af.zip
gcc-735352d2eede1e412cb89f45a5c3e0846bce39af.tar.gz
gcc-735352d2eede1e412cb89f45a5c3e0846bce39af.tar.bz2
constraints.md: Add "C" constraint for call insns.
* config/h8300/constraints.md: Add "C" constraint for call insns. * config/h8300/h8300.md (call, call_value): Turn into a define_expand and define_insn pair. Move invalid call targets into a register in the expander and fix constraints in the matching pattern. * config/h8300/predicates.md (call_expander_operand): Renamed from call_insn_operand. Reject things we shouldn't be trying to handle. (call_insn_operand): New predicate for use by the call/call_value insns. (small_call_insn_operand): Update appropriately. From-SVN: r266571
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/h8300/constraints.md4
-rw-r--r--gcc/config/h8300/h8300.md58
-rw-r--r--gcc/config/h8300/predicates.md34
4 files changed, 81 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e4af6f..6456fac 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,7 +1,19 @@
+2018-11-28 Jeff Law <law@redhat.com>
+
+ * config/h8300/constraints.md: Add "C" constraint for call insns.
+ * config/h8300/h8300.md (call, call_value): Turn into a define_expand
+ and define_insn pair. Move invalid call targets into a register in
+ the expander and fix constraints in the matching pattern.
+ * config/h8300/predicates.md (call_expander_operand): Renamed from
+ call_insn_operand. Reject things we shouldn't be trying to handle.
+ (call_insn_operand): New predicate for use by the call/call_value
+ insns.
+ (small_call_insn_operand): Update appropriately.
+
2018-11-28 Sam Tebbs <sam.tebbs@arm.com>
* config/aarch64/aarch64.c (aarch64_process_target_attr): Replace
- calls to strtok with strtok_r.
+ calls to strtok with strtok_r.
2018-11-28 Richard Biener <rguenther@suse.de>
diff --git a/gcc/config/h8300/constraints.md b/gcc/config/h8300/constraints.md
index 9d0ac42..4175c83 100644
--- a/gcc/config/h8300/constraints.md
+++ b/gcc/config/h8300/constraints.md
@@ -158,6 +158,10 @@
(and (match_code "const_int")
(match_test "!h8300_shift_needs_scratch_p (ival, QImode)")))
+(define_constraint "C"
+ "@internal"
+ (match_code "symbol_ref"))
+
(define_constraint "S"
"@internal"
(and (match_code "const_int")
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 70f96c7..0686f25 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -2064,16 +2064,30 @@
;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
-(define_insn "call"
- [(call (match_operand:QI 0 "call_insn_operand" "or")
- (match_operand:HI 1 "general_operand" "g"))]
+(define_expand "call"
+ [(call (match_operand:QI 0 "call_expander_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ {
+ if (!register_operand (XEXP (operands[0], 0), Pmode)
+ && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
+ XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
+ })
+
+(define_insn "call_insn"
+ [(call (mem:QI (match_operand 0 "call_insn_operand" "Cr"))
+ (match_operand:HI 1 "general_operand" "g"))]
""
{
- if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
- && (SYMBOL_REF_FLAGS (XEXP (operands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
- return "jsr\\t@%0:8";
+ rtx xoperands[1];
+ xoperands[0] = gen_rtx_MEM (QImode, operands[0]);
+ gcc_assert (GET_MODE (operands[0]) == Pmode);
+ if (GET_CODE (XEXP (xoperands[0], 0)) == SYMBOL_REF
+ && (SYMBOL_REF_FLAGS (XEXP (xoperands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+ output_asm_insn ("jsr\\t@%0:8", xoperands);
else
- return "jsr\\t%0";
+ output_asm_insn ("jsr\\t%0", xoperands);
+ return "";
}
[(set_attr "type" "call")
(set (attr "length")
@@ -2086,17 +2100,33 @@
;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
-(define_insn "call_value"
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "call_expander_operand" "")
+ (match_operand:HI 2 "general_operand" "")))]
+ ""
+ {
+ if (!register_operand (XEXP (operands[1], 0), Pmode)
+ && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
+ XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
+ })
+
+(define_insn "call_value_insn"
[(set (match_operand 0 "" "=r")
- (call (match_operand:QI 1 "call_insn_operand" "or")
- (match_operand:HI 2 "general_operand" "g")))]
+ (call (mem:QI (match_operand 1 "call_insn_operand" "Cr"))
+ (match_operand:HI 2 "general_operand" "g")))]
""
{
- if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
- && (SYMBOL_REF_FLAGS (XEXP (operands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
- return "jsr\\t@%1:8";
+ rtx xoperands[2];
+ gcc_assert (GET_MODE (operands[1]) == Pmode);
+ xoperands[0] = operands[0];
+ xoperands[1] = gen_rtx_MEM (QImode, operands[1]);
+ if (GET_CODE (XEXP (xoperands[1], 0)) == SYMBOL_REF
+ && (SYMBOL_REF_FLAGS (XEXP (xoperands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+ output_asm_insn ("jsr\\t@%1:8", xoperands);
else
- return "jsr\\t%1";
+ output_asm_insn ("jsr\\t%1", xoperands);
+ return "";
}
[(set_attr "type" "call")
(set (attr "length")
diff --git a/gcc/config/h8300/predicates.md b/gcc/config/h8300/predicates.md
index 698cdee..217189a 100644
--- a/gcc/config/h8300/predicates.md
+++ b/gcc/config/h8300/predicates.md
@@ -216,7 +216,7 @@
;; Return true if OP is a valid call operand.
-(define_predicate "call_insn_operand"
+(define_predicate "call_expander_operand"
(match_code "mem")
{
if (GET_CODE (op) == MEM)
@@ -224,31 +224,37 @@
rtx inside = XEXP (op, 0);
if (register_operand (inside, Pmode))
return 1;
- if (CONSTANT_ADDRESS_P (inside))
+ if (SYMBOL_REF_P (inside))
return 1;
}
return 0;
})
+(define_predicate "call_insn_operand"
+ (match_code "reg,symbol_ref")
+{
+ if (register_operand (op, Pmode))
+ return 1;
+ if (SYMBOL_REF_P (op))
+ return 1;
+ return 0;
+})
+
;; Return true if OP is a valid call operand, and OP represents an
;; operand for a small call (4 bytes instead of 6 bytes).
(define_predicate "small_call_insn_operand"
- (match_code "mem")
+ (match_code "reg,symbol_ref")
{
- if (GET_CODE (op) == MEM)
- {
- rtx inside = XEXP (op, 0);
+ /* Register indirect is a small call. */
+ if (register_operand (op, Pmode))
+ return 1;
- /* Register indirect is a small call. */
- if (register_operand (inside, Pmode))
- return 1;
+ /* A call through the function vector is a small call too. */
+ if (GET_CODE (op) == SYMBOL_REF
+ && (SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+ return 1;
- /* A call through the function vector is a small call too. */
- if (GET_CODE (inside) == SYMBOL_REF
- && (SYMBOL_REF_FLAGS (inside) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
- return 1;
- }
/* Otherwise it's a large call. */
return 0;
})