Commit 735352d2 by Jeff Law

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
parent 7185a4eb
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> 2018-11-28 Sam Tebbs <sam.tebbs@arm.com>
* config/aarch64/aarch64.c (aarch64_process_target_attr): Replace * 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> 2018-11-28 Richard Biener <rguenther@suse.de>
...@@ -158,6 +158,10 @@ ...@@ -158,6 +158,10 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "!h8300_shift_needs_scratch_p (ival, QImode)"))) (match_test "!h8300_shift_needs_scratch_p (ival, QImode)")))
(define_constraint "C"
"@internal"
(match_code "symbol_ref"))
(define_constraint "S" (define_constraint "S"
"@internal" "@internal"
(and (match_code "const_int") (and (match_code "const_int")
......
...@@ -2064,16 +2064,30 @@ ...@@ -2064,16 +2064,30 @@
;; ??? Even though we use HImode here, this works on the H8/300H and H8S. ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
(define_insn "call" (define_expand "call"
[(call (match_operand:QI 0 "call_insn_operand" "or") [(call (match_operand:QI 0 "call_expander_operand" "")
(match_operand:HI 1 "general_operand" "g"))] (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 rtx xoperands[1];
&& (SYMBOL_REF_FLAGS (XEXP (operands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION)) xoperands[0] = gen_rtx_MEM (QImode, operands[0]);
return "jsr\\t@%0:8"; 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 else
return "jsr\\t%0"; output_asm_insn ("jsr\\t%0", xoperands);
return "";
} }
[(set_attr "type" "call") [(set_attr "type" "call")
(set (attr "length") (set (attr "length")
...@@ -2086,17 +2100,33 @@ ...@@ -2086,17 +2100,33 @@
;; ??? Even though we use HImode here, this works on the H8/300H and H8S. ;; ??? 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") [(set (match_operand 0 "" "=r")
(call (match_operand:QI 1 "call_insn_operand" "or") (call (mem:QI (match_operand 1 "call_insn_operand" "Cr"))
(match_operand:HI 2 "general_operand" "g")))] (match_operand:HI 2 "general_operand" "g")))]
"" ""
{ {
if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF rtx xoperands[2];
&& (SYMBOL_REF_FLAGS (XEXP (operands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION)) gcc_assert (GET_MODE (operands[1]) == Pmode);
return "jsr\\t@%1:8"; 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 else
return "jsr\\t%1"; output_asm_insn ("jsr\\t%1", xoperands);
return "";
} }
[(set_attr "type" "call") [(set_attr "type" "call")
(set (attr "length") (set (attr "length")
......
...@@ -216,7 +216,7 @@ ...@@ -216,7 +216,7 @@
;; Return true if OP is a valid call operand. ;; Return true if OP is a valid call operand.
(define_predicate "call_insn_operand" (define_predicate "call_expander_operand"
(match_code "mem") (match_code "mem")
{ {
if (GET_CODE (op) == MEM) if (GET_CODE (op) == MEM)
...@@ -224,31 +224,37 @@ ...@@ -224,31 +224,37 @@
rtx inside = XEXP (op, 0); rtx inside = XEXP (op, 0);
if (register_operand (inside, Pmode)) if (register_operand (inside, Pmode))
return 1; return 1;
if (CONSTANT_ADDRESS_P (inside)) if (SYMBOL_REF_P (inside))
return 1; return 1;
} }
return 0; 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 ;; Return true if OP is a valid call operand, and OP represents an
;; operand for a small call (4 bytes instead of 6 bytes). ;; operand for a small call (4 bytes instead of 6 bytes).
(define_predicate "small_call_insn_operand" (define_predicate "small_call_insn_operand"
(match_code "mem") (match_code "reg,symbol_ref")
{ {
if (GET_CODE (op) == MEM) /* Register indirect is a small call. */
{ if (register_operand (op, Pmode))
rtx inside = XEXP (op, 0); return 1;
/* Register indirect is a small call. */ /* A call through the function vector is a small call too. */
if (register_operand (inside, Pmode)) if (GET_CODE (op) == SYMBOL_REF
return 1; && (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. */ /* Otherwise it's a large call. */
return 0; return 0;
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment