diff options
author | Kuan-Lin Chen <kuanlinchentw@gmail.com> | 2018-05-19 08:57:57 +0000 |
---|---|---|
committer | Chung-Ju Wu <jasonwucj@gcc.gnu.org> | 2018-05-19 08:57:57 +0000 |
commit | 85a980769ebbe1b8b7de983a9ba20d714c7431c0 (patch) | |
tree | 8181124edca780d039889214a3cb55fb651ecd9d /gcc/config/nds32/nds32.md | |
parent | a76400f4e68030bf91bc20b39ed585e596e18ea5 (diff) | |
download | gcc-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.md | 82 |
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) |