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
This commit is contained in:
parent
7185a4ebc2
commit
735352d2ee
4 changed files with 81 additions and 29 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue