diff options
author | liqin <liqin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-10-16 02:13:06 +0000 |
---|---|---|
committer | liqin <liqin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-10-16 02:13:06 +0000 |
commit | de79ba9f345763849a4fd285bc6c9508e4b209b5 (patch) | |
tree | 36ecf1de84b364717f7c04621ad8fbaf05e24bc5 | |
parent | 22ae655fb35b5428154b87f8e7ce2f4f39ecd041 (diff) | |
download | gcc-de79ba9f345763849a4fd285bc6c9508e4b209b5.tar.gz |
* config/score/crti.asm: add pic support.
* config/score/crtn.asm: add pic support.
* config/score/score.h: remove builtin_define("__pic__").
* config/score/score.c: add TARGET_RTX_COST macro.
* config/score/score.md: PIC support for call/sibcall pattern.
* config/score/mul-div.S: add pic support.
* config/score/t-score-elf: update MULTILIB_OPTIONS.
* ChangeLog: add shengguo as another score maintainer.
* config.sub: add score support in it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117771 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | ChangeLog | 4 | ||||
-rwxr-xr-x | config.sub | 4 | ||||
-rw-r--r-- | gcc/config/score/crti.asm | 60 | ||||
-rw-r--r-- | gcc/config/score/crtn.asm | 15 | ||||
-rw-r--r-- | gcc/config/score/mul-div.S | 472 | ||||
-rw-r--r-- | gcc/config/score/score.c | 204 | ||||
-rw-r--r-- | gcc/config/score/score.h | 3 | ||||
-rw-r--r-- | gcc/config/score/score.md | 60 | ||||
-rw-r--r-- | gcc/config/score/t-score-elf | 4 |
9 files changed, 645 insertions, 181 deletions
diff --git a/ChangeLog b/ChangeLog index 7ff76bfc077..841905daca0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2006-10-16 Tan Shengguo <shengguo@sunnorth.com.cn> + + * MAINTAINERS: Add Tan Shengguo as score port maintainer. + 2006-10-10 Brooks Moses <bmoses@stanford.edu> * Makefile.def: Added pdf target handling. diff --git a/config.sub b/config.sub index 4d936e23942..5f105723909 100755 --- a/config.sub +++ b/config.sub @@ -909,6 +909,10 @@ case $basic_machine in sb1el) basic_machine=mipsisa64sb1el-unknown ;; + score | score-*) + basic_machine=score-sunplus + os=-elf + ;; sei) basic_machine=mips-sei os=-seiux diff --git a/gcc/config/score/crti.asm b/gcc/config/score/crti.asm index 65ffb159919..2408596b213 100644 --- a/gcc/config/score/crti.asm +++ b/gcc/config/score/crti.asm @@ -35,7 +35,8 @@ # This file makes a stack frame for the contents of the .init and # .fini sections. -.section .init,"ax", @progbits +#ifndef __pic__ +.section .init, "ax", @progbits .weak _start .ent _start .frame r0, 0, r3, 0 @@ -81,5 +82,62 @@ _init: _fini: addi r0, -32 sw r3, [r0, 20] +#else +.section .init, "ax", @progbits + .set pic + .weak _start + .ent _start + .frame r0, 0, r3, 0 + .mask 0x00000000,0 +_start: + la r28, _gp + la r8, __bss_start + la r9, __bss_end__ + sub! r9, r8 + srli! r9, 2 + addi r9, -1 + mtsr r9, sr0 + li r9, 0 +1: + sw r9, [r8]+, 4 + bcnz 1b + la r0, _stack +# jl _init +# la r4, _end +# jl _init_argv + ldiu! r4, 0 + ldiu! r5, 0 +# jl main + la r29, main + brl r29 +# jl exit + la r29, exit + brl r29 + .end _start + + .weak _init_argv + .ent + .frame r0, 0, r3, 0 + .mask 0x00000000, 0 +_init_argv: + ldiu! r4, 0 + ldiu! r5, 0 + j main + .end _init_argv + + .globl _init + .type _init, %function +_init: + addi r0, -32 + sw r3, [r0, 20] + +.section .fini, "ax", @progbits + .globl _fini + .type _fini, %function +_fini: + addi r0, -32 + sw r3, [r0, 20] + +#endif diff --git a/gcc/config/score/crtn.asm b/gcc/config/score/crtn.asm index 97039fa24df..5048a99e435 100644 --- a/gcc/config/score/crtn.asm +++ b/gcc/config/score/crtn.asm @@ -35,6 +35,7 @@ # This file makes sure that the .init and .fini sections do in # fact return. +#ifndef __pic__ .section .init, "ax", @progbits lw r3, [r0, 20] addi r0, 32 @@ -44,4 +45,18 @@ lw r3, [r0, 20] addi r0, 32 br r3 +#else + .set pic +.section .init, "ax", @progbits + lw r3, [r0, 20] + addi r0, 32 + br r3 + + .set pic +.section .fini, "ax", @progbits + lw r3, [r0, 20] + addi r0, 32 + br r3 +#endif + diff --git a/gcc/config/score/mul-div.S b/gcc/config/score/mul-div.S index 37a2406b20a..4dabe96f974 100644 --- a/gcc/config/score/mul-div.S +++ b/gcc/config/score/mul-div.S @@ -29,196 +29,378 @@ #define t1 r9 #define t2 r10 #define t3 r11 - #define t4 r22 -#if defined(__scorebe__) -#define LIBGCC1_BIG_ENDIAN -#define out_H v0 -#define out_L v1 -#define in0_H a0 -#define in0_L a1 -#define in1_H a2 -#define in1_L a3 -#elif defined(__scorele__) -#define out_H v1 -#define out_L v0 -#define in0_H a1 -#define in0_L a0 -#define in1_H a3 -#define in1_L a2 -#else -#err "must specify S+core endian!" -#endif - +#ifndef __pic__ #if !defined(L_mulsi3) && !defined(L_divsi3) - .text - .global _flush_cache + .text + .global _flush_cache _flush_cache: - srli r9, r5, 4 - mv r8, r4 - mtsr r9, sr0 + srli r9, r5, 4 + mv r8, r4 + mtsr r9, sr0 1: - cache 0xe, [r8, 0] # write back invalid dcache - addi r8, 16 - bcnz 1b - mfcr r8, cr4 - bittst! r8, 0x3 # if LDM is enable, write back LDM - beq! 6f - ldi r10, 0 - cache 0xc, [r10, 0] + cache 0xe, [r8, 0] # write back invalid dcache + addi r8, 16 + bcnz 1b + mfcr r8, cr4 + bittst! r8, 0x3 # if LDM is enable, write back LDM + beq! 6f + ldi r10, 0 + cache 0xc, [r10, 0] 6: - bittst! r8, 0x2 # if LIM is enable, refill it - beq! 7f - cache 0x4, [r10, 0] + bittst! r8, 0x2 # if LIM is enable, refill it + beq! 7f + cache 0x4, [r10, 0] 7: - #nop! - #nop! - #nop! - #nop! - #nop! - mv r8, r4 - mtsr r9, sr0 + #nop! + #nop! + #nop! + #nop! + #nop! + mv r8, r4 + mtsr r9, sr0 2: - cache 0x2, [r8, 0] # invalid unlock icache - #nop! - #nop! - #nop! - #nop! - #nop! - addi r8, 16 - bcnz 2b - br r3 + cache 0x2, [r8, 0] # invalid unlock icache + #nop! + #nop! + #nop! + #nop! + #nop! + addi r8, 16 + bcnz 2b + br r3 #endif /* FUNCTION (U) INT32 v0 = __mulsi3 ((U) INT32 a0, (U) INT32 a1); REGISTERS: - use t0 - modify a0 - a1 -> become 0 + use t0 + modify a0 + a1 -> become 0 NOTE: - this seems to give better performance to just rotate and add. */ + this seems to give better performance to just rotate and add. */ #ifdef L_mulsi3 - .text - .global __umulsi3 - .global __mulsi3 - /* signed multiplication (32x32) */ - .ent __mulsi3 + .text + .global __umulsi3 + .global __mulsi3 + /* signed multiplication (32x32) */ + .ent __mulsi3 __umulsi3: __mulsi3: - li t1, 0 + li t1, 0 __mulsi3_loop: - andri.c t0, a1, 1 /* t0 = multiplier[0] */ - srli a1, a1, 1 /* a1 /= 2 */ - beq __mulsi3_loop2 /* skip if (t0 == 0) */ - add t1, t1, a0 /* add multiplicand */ + andri.c t0, a1, 1 # t0 = multiplier[0] + srli a1, a1, 1 # a1 /= 2 + beq __mulsi3_loop2 # skip if (t0 == 0) + add t1, t1, a0 # add multiplicand __mulsi3_loop2: - slli a0, a0, 1 /* multiplicand mul 2 */ - cmpi.c a1, 0 - bne __mulsi3_loop - mv r4, t1 - br ra - .end __mulsi3 + slli a0, a0, 1 # multiplicand mul 2 + cmpi.c a1, 0 + bne __mulsi3_loop + mv r4, t1 + br ra + .end __mulsi3 #endif /* L_mulsi3 */ - /* FUNCTION UINT32 (v0) = __udivsi3 (UINT32 (a0), UINT32 (a1)); INT32 (v0) = __divsi3 (INT32 (a0), INT32 (a1)); UINT32 (v0) = __umodsi3 (UINT32 (a0), UINT32 (a1)); INT32 (v0) = __modsi3 (INT32 (a0), INT32 (a1)); DESCRIPTION - performs 32-bit division/modulo. + performs 32-bit division/modulo. REGISTERS - used t0 bit-index - t1 - modify a0 becomes remainer */ + used t0 bit-index + t1 + modify a0 becomes remainer */ #ifdef L_divsi3 - .text - .global __udivsi3 - .global __umodsi3 - .global __divsi3 - .global __modsi3 - - /* unsigned division */ - .ent __udivsi3 + .text + .global __udivsi3 + .global __umodsi3 + .global __divsi3 + .global __modsi3 + + /* unsigned division */ + .ent __udivsi3 __udivsi3: - li t4, 0 - cmpi.c a1, 0 - beq __uds_exit - li t0, 1 - blt __uds_ok + li t4, 0 + cmpi.c a1, 0 + beq __uds_exit + li t0, 1 + blt __uds_ok __uds_normalize: - cmp.c a0, a1 - bcc __uds_ok - slli a1, a1, 1 - slli t0, t0, 1 - cmpi.c a1, 0 - bge __uds_normalize + cmp.c a0, a1 + bcc __uds_ok + slli a1, a1, 1 + slli t0, t0, 1 + cmpi.c a1, 0 + bge __uds_normalize __uds_ok: __uds_loop2: - cmp.c a0, a1 - bcc __uds_loop3 - sub a0, a0, a1 - or t4, t4, t0 + cmp.c a0, a1 + bcc __uds_loop3 + sub a0, a0, a1 + or t4, t4, t0 __uds_loop3: - srli t0, t0, 1 - srli a1, a1, 1 - cmpi.c t0, 0 - bne __uds_loop2 + srli t0, t0, 1 + srli a1, a1, 1 + cmpi.c t0, 0 + bne __uds_loop2 __uds_exit: - mv a1, a0 - mv r4, t4 - br ra - .end __udivsi3 + mv a1, a0 + mv r4, t4 + br ra + .end __udivsi3 - /* unsigned modulus */ - .ent __umodsi3 + /* unsigned modulus */ + .ent __umodsi3 __umodsi3: - mv t3, ra - jl __udivsi3 - mv r4, a1 - br t3 - .end __umodsi3 - - /* abs and div */ - .ent __orgsi3 + mv t3, ra + jl __udivsi3 + mv r4, a1 + br t3 + .end __umodsi3 + + /* abs and div */ + .ent __orgsi3 __orgsi3: - cmpi.c a0, 0 - bge __orgsi3_a0p - neg a0, a0 + cmpi.c a0, 0 + bge __orgsi3_a0p + neg a0, a0 __orgsi3_a0p: - cmpi.c a1, 0 - bge __udivsi3 - neg a1, a1 - b __udivsi3 /* goto udivsi3 */ - .end __orgsi3 - - /* signed division */ - .ent __divsi3 + cmpi.c a1, 0 + bge __udivsi3 + neg a1, a1 + b __udivsi3 # goto udivsi3 + .end __orgsi3 + + /* signed division */ + .ent __divsi3 __divsi3: - mv t3, ra - xor t2, a0, a1 - jl __orgsi3 + mv t3, ra + xor t2, a0, a1 + jl __orgsi3 __divsi3_adjust: - cmpi.c t2, 0 - bge __divsi3_exit - neg r4, r4 + cmpi.c t2, 0 + bge __divsi3_exit + neg r4, r4 __divsi3_exit: - br t3 - .end __divsi3 + br t3 + .end __divsi3 - /* signed modulus */ - .ent __modsi3 + /* signed modulus */ + .ent __modsi3 __modsi3: - mv t3, ra - mv t2, a0 - jl __orgsi3 - mv r4, a1 - b __divsi3_adjust - .end __modsi3 + mv t3, ra + mv t2, a0 + jl __orgsi3 + mv r4, a1 + b __divsi3_adjust + .end __modsi3 #endif /* L_divsi3 */ +#else /* -fPIC */ +#if !defined(L_mulsi3) && !defined(L_divsi3) + .set pic + .text + .global _flush_cache +_flush_cache: + addi r0, -8 # pic used + .cpload r29 # pic used + srli r9, r5, 4 + mv r8, r4 + mtsr r9, sr0 +1: + cache 0xe, [r8, 0] # write back invalid dcache + addi r8, 16 + bcnz 1b + mfcr r8, cr4 + bittst! r8, 0x3 # if LDM is enable, write back LDM + beq! 6f + ldi r10, 0 + cache 0xc, [r10, 0] +6: + bittst! r8, 0x2 # if LIM is enable, refill it + beq! 7f + cache 0x4, [r10, 0] +7: + #nop! + #nop! + #nop! + #nop! + #nop! + mv r8, r4 + mtsr r9, sr0 +2: + cache 0x2, [r8, 0] # invalid unlock icache + #nop! + #nop! + #nop! + #nop! + #nop! + addi r8, 16 + bcnz 2b + .cprestore 12 # pic used + addi r0, 8 # pic used + br r3 +#endif + +/* FUNCTION + (U) INT32 v0 = __mulsi3 ((U) INT32 a0, (U) INT32 a1); + REGISTERS: + use t0 + modify a0 + a1 -> become 0 + NOTE: + this seems to give better performance to just rotate and add. */ + +#ifdef L_mulsi3 + .set pic + .text + .global __umulsi3 + .global __mulsi3 + /* signed multiplication (32x32) */ + .ent __mulsi3 +__umulsi3: +__mulsi3: + addi r0, -8 # pic used + .cpload r29 # pic used + li t1, 0 +__mulsi3_loop: + andri.c t0, a1, 1 # t0 = multiplier[0] + srli a1, a1, 1 # a1 /= 2 + beq __mulsi3_loop2 # skip if (t0 == 0) + add t1, t1, a0 # add multiplicand +__mulsi3_loop2: + slli a0, a0, 1 # multiplicand mul 2 + cmpi.c a1, 0 + bne __mulsi3_loop + mv r4, t1 + .cprestore 12 # pic used + addi r0, 8 # pic used + br ra + .end __mulsi3 +#endif /* L_mulsi3 */ + +/* FUNCTION + UINT32 (v0) = __udivsi3 (UINT32 (a0), UINT32 (a1)); + INT32 (v0) = __divsi3 (INT32 (a0), INT32 (a1)); + UINT32 (v0) = __umodsi3 (UINT32 (a0), UINT32 (a1)); + INT32 (v0) = __modsi3 (INT32 (a0), INT32 (a1)); + DESCRIPTION + performs 32-bit division/modulo. + REGISTERS + used t0 bit-index + t1 + modify a0 becomes remainer */ +#ifdef L_divsi3 + .set pic + .text + .global __udivsi3 + .global __umodsi3 + .global __divsi3 + .global __modsi3 + /* unsigned division */ + .ent __udivsi3 +__udivsi3: + addi r0, -8 # pic used + .cpload r29 # pic used + li t4, 0 + cmpi.c a1, 0 + beq __uds_exit + li t0, 1 + blt __uds_ok +__uds_normalize: + cmp.c a0, a1 + bcc __uds_ok + slli a1, a1, 1 + slli t0, t0, 1 + cmpi.c a1, 0 + bge __uds_normalize +__uds_ok: +__uds_loop2: + cmp.c a0, a1 + bcc __uds_loop3 + sub a0, a0, a1 + or t4, t4, t0 +__uds_loop3: + srli t0, t0, 1 + srli a1, a1, 1 + cmpi.c t0, 0 + bne __uds_loop2 +__uds_exit: + mv a1, a0 + mv r4, t4 + .cprestore 12 # pic used + addi r0, 8 # pic used + br ra + .end __udivsi3 + + /* unsigned modulus */ + .ent __umodsi3 +__umodsi3: + addi r0, -8 # pic used + .cpload r29 # pic used + li t1, 0 + mv t3, ra +# jl __udivsi3 + la r29, __udivsi3 + brl r29 + mv r4, a1 + .cprestore 12 # pic used + addi r0, 8 # pic used + br t3 + .end __umodsi3 + + /* abs and div */ + .ent __orgsi3 +__orgsi3: + cmpi.c a0, 0 + bge __orgsi3_a0p + neg a0, a0 +__orgsi3_a0p: + cmpi.c a1, 0 + bge __udivsi3 + neg a1, a1 + b __udivsi3 # goto udivsi3 + .end __orgsi3 + + /* signed division */ + .ent __divsi3 +__divsi3: + addi r0, -8 # pic used + .cpload r29 # pic used + mv t3, ra + xor t2, a0, a1 +# jl __orgsi3 + la r29, __orgsi3 + brl r29 +__divsi3_adjust: + cmpi.c t2, 0 + bge __divsi3_exit + neg r4, r4 +__divsi3_exit: + .cprestore 12 # pic used + addi r0, 8 # pic used + br t3 + .end __divsi3 + + /* signed modulus */ + .ent __modsi3 +__modsi3: + addi r0, -8 # pic used + .cpload r29 # pic used + mv t3, ra + mv t2, a0 +# jl __orgsi3 + la r29, __orgsi3 + brl r29 + mv r4, a1 + b __divsi3_adjust + .end __modsi3 + +#endif /*L_divsi3 */ +#endif diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c index b7a581eee60..323d40d1cbd 100644 --- a/gcc/config/score/score.c +++ b/gcc/config/score/score.c @@ -60,63 +60,71 @@ #define CE_REG_CLASS_P(C) \ ((C) == HI_REG || (C) == LO_REG || (C) == CE_REGS) -static int score_arg_partial_bytes (const CUMULATIVE_ARGS *cum, - enum machine_mode mode, - tree type, int named); +static int score_arg_partial_bytes (const CUMULATIVE_ARGS *, + enum machine_mode, tree, int); + +static int score_symbol_insns (enum score_symbol_type); + +static int score_address_insns (rtx, enum machine_mode); + +static bool score_rtx_costs (rtx, int, int, int *); #undef TARGET_ASM_FILE_START -#define TARGET_ASM_FILE_START th_asm_file_start +#define TARGET_ASM_FILE_START th_asm_file_start #undef TARGET_ASM_FILE_END -#define TARGET_ASM_FILE_END th_asm_file_end +#define TARGET_ASM_FILE_END th_asm_file_end #undef TARGET_ASM_FUNCTION_PROLOGUE -#define TARGET_ASM_FUNCTION_PROLOGUE th_function_prologue +#define TARGET_ASM_FUNCTION_PROLOGUE th_function_prologue #undef TARGET_ASM_FUNCTION_EPILOGUE -#define TARGET_ASM_FUNCTION_EPILOGUE th_function_epilogue +#define TARGET_ASM_FUNCTION_EPILOGUE th_function_epilogue #undef TARGET_SCHED_ISSUE_RATE -#define TARGET_SCHED_ISSUE_RATE th_issue_rate +#define TARGET_SCHED_ISSUE_RATE th_issue_rate #undef TARGET_ASM_SELECT_RTX_SECTION -#define TARGET_ASM_SELECT_RTX_SECTION th_select_rtx_section +#define TARGET_ASM_SELECT_RTX_SECTION th_select_rtx_section #undef TARGET_IN_SMALL_DATA_P -#define TARGET_IN_SMALL_DATA_P th_in_small_data_p +#define TARGET_IN_SMALL_DATA_P th_in_small_data_p #undef TARGET_FUNCTION_OK_FOR_SIBCALL -#define TARGET_FUNCTION_OK_FOR_SIBCALL th_function_ok_for_sibcall +#define TARGET_FUNCTION_OK_FOR_SIBCALL th_function_ok_for_sibcall #undef TARGET_STRICT_ARGUMENT_NAMING -#define TARGET_STRICT_ARGUMENT_NAMING th_strict_argument_naming +#define TARGET_STRICT_ARGUMENT_NAMING th_strict_argument_naming #undef TARGET_ASM_OUTPUT_MI_THUNK -#define TARGET_ASM_OUTPUT_MI_THUNK th_output_mi_thunk +#define TARGET_ASM_OUTPUT_MI_THUNK th_output_mi_thunk #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK -#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true #undef TARGET_PROMOTE_FUNCTION_ARGS -#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true +#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true #undef TARGET_PROMOTE_FUNCTION_RETURN -#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true +#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true #undef TARGET_PROMOTE_PROTOTYPES -#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true +#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true #undef TARGET_MUST_PASS_IN_STACK -#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size +#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size #undef TARGET_ARG_PARTIAL_BYTES -#define TARGET_ARG_PARTIAL_BYTES score_arg_partial_bytes +#define TARGET_ARG_PARTIAL_BYTES score_arg_partial_bytes #undef TARGET_PASS_BY_REFERENCE -#define TARGET_PASS_BY_REFERENCE score_pass_by_reference +#define TARGET_PASS_BY_REFERENCE score_pass_by_reference #undef TARGET_RETURN_IN_MEMORY -#define TARGET_RETURN_IN_MEMORY score_return_in_memory +#define TARGET_RETURN_IN_MEMORY score_return_in_memory + +#undef TARGET_RTX_COSTS +#define TARGET_RTX_COSTS score_rtx_costs /* Implement TARGET_RETURN_IN_MEMORY. In S+core, small structures are returned in a register. @@ -880,6 +888,160 @@ score_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, return 12; } +/* Return the number of instructions needed to load a symbol of the + given type into a register. */ +static int +score_symbol_insns (enum score_symbol_type type) +{ + switch (type) + { + case SYMBOL_GENERAL: + return 2; + + case SYMBOL_SMALL_DATA: + return 1; + } + + gcc_unreachable (); +} + +/* Return the number of instructions needed to load or store a value + of mode MODE at X. Return 0 if X isn't valid for MODE. */ +static int +score_address_insns (rtx x, enum machine_mode mode) +{ + struct score_address_info addr; + int factor; + + if (mode == BLKmode) + /* BLKmode is used for single unaligned loads and stores. */ + factor = 1; + else + /* Each word of a multi-word value will be accessed individually. */ + factor = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + + if (mda_classify_address (&addr, mode, x, false)) + switch (addr.type) + { + case ADD_REG: + case ADD_CONST_INT: + return factor; + + case ADD_SYMBOLIC: + return factor * score_symbol_insns (addr.symbol_type); + } + return 0; +} + +/* Implement TARGET_RTX_COSTS macro. */ +static bool +score_rtx_costs (rtx x, int code, int outer_code, int *total) +{ + enum machine_mode mode = GET_MODE (x); + + switch (code) + { + case CONST_INT: + /* These can be used anywhere. */ + *total = 0; + return true; + + /* Otherwise fall through to the handling below because + we'll need to construct the constant. */ + case CONST: + case SYMBOL_REF: + case LABEL_REF: + case CONST_DOUBLE: + *total = COSTS_N_INSNS (1); + return true; + + case MEM: + { + /* If the address is legitimate, return the number of + instructions it needs, otherwise use the default handling. */ + int n = score_address_insns (XEXP (x, 0), GET_MODE (x)); + if (n > 0) + { + *total = COSTS_N_INSNS (n + 1); + return true; + } + return false; + } + + case FFS: + *total = COSTS_N_INSNS (6); + return true; + + case NOT: + *total = COSTS_N_INSNS (1); + return true; + + case AND: + case IOR: + case XOR: + if (mode == DImode) + { + *total = COSTS_N_INSNS (2); + return true; + } + return false; + + case ASHIFT: + case ASHIFTRT: + case LSHIFTRT: + if (mode == DImode) + { + *total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) + ? 4 : 12); + return true; + } + return false; + + case ABS: + *total = COSTS_N_INSNS (4); + return true; + + case PLUS: + case MINUS: + if (mode == DImode) + { + *total = COSTS_N_INSNS (4); + return true; + } + return false; + + case NEG: + if (mode == DImode) + { + *total = COSTS_N_INSNS (4); + return true; + } + return false; + + case MULT: + *total = COSTS_N_INSNS (12); + return true; + + case DIV: + case MOD: + case UDIV: + case UMOD: + *total = COSTS_N_INSNS (33); + return true; + + case SIGN_EXTEND: + *total = COSTS_N_INSNS (2); + return true; + + case ZERO_EXTEND: + *total = COSTS_N_INSNS (1); + return true; + + default: + return false; + } +} + /* Implement ASM_OUTPUT_EXTERNAL macro. */ int score_output_external (FILE *file ATTRIBUTE_UNUSED, diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h index 0a24a3f85e9..342901806fd 100644 --- a/gcc/config/score/score.h +++ b/gcc/config/score/score.h @@ -54,9 +54,10 @@ extern GTY(()) rtx cmp_op1; builtin_define ("__scorebe__"); \ if (TARGET_SCORE5U) \ builtin_define ("__score5u__"); \ + else \ + builtin_define ("__score7__"); \ } while (0) - #define TARGET_DEFAULT MASK_SCORE7 #define TARGET_VERSION \ diff --git a/gcc/config/score/score.md b/gcc/config/score/score.md index bc3d99f7126..856ea1065bd 100644 --- a/gcc/config/score/score.md +++ b/gcc/config/score/score.md @@ -114,7 +114,7 @@ (match_operand:HI 1 "general_operand" "i,d,m,d,*x,d,*a,d"))] "" { - switch(which_alternative) + switch (which_alternative) { case 0: return mdp_limm (operands); case 1: return mdp_move (operands); @@ -1076,10 +1076,23 @@ [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "t,Z")) (match_operand 1 "" "")) (clobber (reg:SI RT_REGNUM))] - "SIBLING_CALL_P (insn) && !flag_pic" - "@ - br%S0 %0 - j %0" + "SIBLING_CALL_P (insn)" +{ + if (!flag_pic) + switch (which_alternative) + { + case 0: return \"br%S0 %0\"; + case 1: return \"j %0\"; + default: gcc_unreachable (); + } + else + switch (which_alternative) + { + case 0: return \"mv r29, %0\;.cpadd r29\;br r29\"; + case 1: return \"la r29, %0\;br r29\"; + default: gcc_unreachable (); + } +} [(set_attr "type" "call")]) (define_expand "sibcall_value" @@ -1097,10 +1110,23 @@ (call (mem:SI (match_operand:SI 1 "call_insn_operand" "t,Z")) (match_operand 2 "" ""))) (clobber (reg:SI RT_REGNUM))] - "SIBLING_CALL_P(insn) && !flag_pic" - "@ - br%S1 %1 - j %1" + "SIBLING_CALL_P (insn)" +{ + if (!flag_pic) + switch (which_alternative) + { + case 0: return \"br%S1 %1\"; + case 1: return \"j %1\"; + default: gcc_unreachable (); + } + else + switch (which_alternative) + { + case 0: return \"mv r29, %1\;.cpadd r29\;br r29\"; + case 1: return \"la r29, %1\;br r29\"; + default: gcc_unreachable (); + } +} [(set_attr "type" "call")]) (define_expand "call" @@ -1126,7 +1152,12 @@ default: gcc_unreachable (); } else - return \"la r29, %0\;brl r29\"; + switch (which_alternative) + { + case 0: return \"mv r29, %0\;.cpadd r29\;brl r29\"; + case 1: return \"la r29, %0\;brl r29\"; + default: gcc_unreachable (); + } } [(set_attr "type" "call")]) @@ -1155,7 +1186,12 @@ default: gcc_unreachable (); } else - return \"la r29, %1\;brl r29\"; + switch (which_alternative) + { + case 0: return \"mv r29, %1\;.cpadd r29\;brl r29\"; + case 1: return \"la r29, %1\;brl r29\"; + default: gcc_unreachable (); + } } [(set_attr "type" "call")]) @@ -1198,7 +1234,7 @@ "" "* if (flag_pic) - return \"mv! r29, %0\;.cpadd r29\;br%S0 r29\"; + return \"mv r29, %0\;.cpadd r29\;br r29\"; else return \"br%S0 %0\"; " diff --git a/gcc/config/score/t-score-elf b/gcc/config/score/t-score-elf index 66424dddebd..2590b67686f 100644 --- a/gcc/config/score/t-score-elf +++ b/gcc/config/score/t-score-elf @@ -35,7 +35,9 @@ dp-bit.c: $(srcdir)/config/fp-bit.c # without the $gp register. TARGET_LIBGCC2_CFLAGS = -G 0 -MULTILIB_OPTIONS = mel mSCORE7 +MULTILIB_OPTIONS = fPIC mel mSCORE7 +MULTILIB_MATCHES = fPIC=fpic + EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o LIBGCC = stmp-multilib |