summaryrefslogtreecommitdiff
path: root/gcc/config/nds32/nds32.md
diff options
context:
space:
mode:
authorKuan-Lin Chen <kuanlinchentw@gmail.com>2018-05-19 08:57:57 +0000
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>2018-05-19 08:57:57 +0000
commit85a980769ebbe1b8b7de983a9ba20d714c7431c0 (patch)
tree8181124edca780d039889214a3cb55fb651ecd9d /gcc/config/nds32/nds32.md
parenta76400f4e68030bf91bc20b39ed585e596e18ea5 (diff)
downloadgcc-85a980769ebbe1b8b7de983a9ba20d714c7431c0.tar.gz
[NDS32] Implment indirect funciton call attribute.
* config/nds32/constants.md (unspec_element): Add UNSPEC_ICT. * config/nds32/nds32-md-auxiliary.c (symbolic_reference_mentioned_p): New. (nds32_legitimize_ict_address): New. (nds32_expand_ict_move): New. (nds32_indirect_call_referenced_p): New. (nds32_symbol_binds_local_p): Delete. (nds32_long_call_p): Modify. * config/nds32/nds32-opts.h (nds32_ict_model_type): New enum type. * config/nds32/nds32-protos.h (symbolic_reference_mentioned_p): Declare. (nds32_legitimize_ict_address): Declare. (nds32_expand_ict_move): Declare. (nds32_indirect_call_referenced_p): Declare. * config/nds32/nds32-relax-opt.c (nds32_ict_const_p): New. (nds32_relax_group): Use nds32_ict_const_p as condition. * config/nds32/nds32.c (nds32_attribute_table): Add "indirect_call". (nds32_asm_file_start): Output ict_model directive in asm code. (nds32_legitimate_address_p): Consider indirect call. (nds32_print_operand): Consider indirect call. (nds32_print_operand_address): Consider indirect call. (nds32_insert_attributes): Handle "indirect_call" attribute. (TARGET_LEGITIMATE_ADDRESS_P): Define. (TARGET_LEGITIMATE_CONSTANT_P): Define. (TARGET_CANNOT_FORCE_CONST_MEM): Define. (TARGET_DELEGITIMIZE_ADDRESS): Define. (TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA): Define. * config/nds32/nds32.h (SYMBOLIC_CONST_P): Define. (TARGET_ICT_MODEL_SMALL): Define. (TARGET_ICT_MODEL_LARGE): Define. * config/nds32/nds32.md (movsi): Consider ict model. (call, call_value): Consider ict model. (sibcall, sibcall_value): Consider ict model. * config/nds32/nds32.opt (mict-model): New option. * config/nds32/predicates.md (nds32_symbolic_operand): Consider ict model. Co-Authored-By: Chung-Ju Wu <jasonwucj@gmail.com> From-SVN: r260390
Diffstat (limited to 'gcc/config/nds32/nds32.md')
-rw-r--r--gcc/config/nds32/nds32.md82
1 files changed, 78 insertions, 4 deletions
diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md
index 6379212550e..a4f204b0ed2 100644
--- a/gcc/config/nds32/nds32.md
+++ b/gcc/config/nds32/nds32.md
@@ -215,6 +215,17 @@
low12_int));
DONE;
}
+
+ if ((REG_P (operands[0]) || GET_CODE (operands[0]) == SUBREG)
+ && SYMBOLIC_CONST_P (operands[1]))
+ {
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (operands[1]))
+ {
+ nds32_expand_ict_move (operands);
+ DONE;
+ }
+ }
})
(define_insn "*mov<mode>"
@@ -1479,7 +1490,26 @@
(clobber (reg:SI LP_REGNUM))
(clobber (reg:SI TA_REGNUM))])]
""
- ""
+ {
+ rtx insn;
+ rtx sym = XEXP (operands[0], 0);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, sym);
+ operands[0] = gen_const_mem (Pmode, reg);
+ }
+
+ if (flag_pic)
+ {
+ insn = emit_call_insn (gen_call_internal
+ (XEXP (operands[0], 0), GEN_INT (0)));
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ DONE;
+ }
+ }
)
(define_insn "call_internal"
@@ -1543,7 +1573,29 @@
(match_operand 2)))
(clobber (reg:SI LP_REGNUM))
(clobber (reg:SI TA_REGNUM))])]
- "")
+ ""
+ {
+ rtx insn;
+ rtx sym = XEXP (operands[1], 0);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, sym);
+ operands[1] = gen_const_mem (Pmode, reg);
+ }
+
+ if (flag_pic)
+ {
+ insn =
+ emit_call_insn (gen_call_value_internal
+ (operands[0], XEXP (operands[1], 0), GEN_INT (0)));
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ DONE;
+ }
+ }
+)
(define_insn "call_value_internal"
[(parallel [(set (match_operand 0)
@@ -1634,7 +1686,18 @@
(const_int 0))
(clobber (reg:SI TA_REGNUM))
(return)])]
- "")
+ ""
+{
+ rtx sym = XEXP (operands[0], 0);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, sym);
+ operands[0] = gen_const_mem (Pmode, reg);
+ }
+})
(define_insn "sibcall_internal"
[(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
@@ -1684,7 +1747,18 @@
(const_int 0)))
(clobber (reg:SI TA_REGNUM))
(return)])]
- "")
+ ""
+{
+ rtx sym = XEXP (operands[1], 0);
+
+ if (TARGET_ICT_MODEL_LARGE
+ && nds32_indirect_call_referenced_p (sym))
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, sym);
+ operands[1] = gen_const_mem (Pmode, reg);
+ }
+})
(define_insn "sibcall_value_internal"
[(parallel [(set (match_operand 0)