From: Jeff Law Date: Wed, 28 Nov 2018 17:26:03 +0000 (-0700) Subject: constraints.md: Add "C" constraint for call insns. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=735352d2eede1e412cb89f45a5c3e0846bce39af;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e4af6f97f7..6456facbacb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,7 +1,19 @@ +2018-11-28 Jeff Law + + * 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 * 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 diff --git a/gcc/config/h8300/constraints.md b/gcc/config/h8300/constraints.md index 9d0ac42fdaa..4175c832ef3 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 70f96c7481f..0686f25d71d 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 698cdee1ddf..217189ad1f5 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; })