summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliqin <liqin@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-16 02:13:06 +0000
committerliqin <liqin@138bc75d-0d04-0410-961f-82ee72b054a4>2006-10-16 02:13:06 +0000
commitde79ba9f345763849a4fd285bc6c9508e4b209b5 (patch)
tree36ecf1de84b364717f7c04621ad8fbaf05e24bc5
parent22ae655fb35b5428154b87f8e7ce2f4f39ecd041 (diff)
downloadgcc-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--ChangeLog4
-rwxr-xr-xconfig.sub4
-rw-r--r--gcc/config/score/crti.asm60
-rw-r--r--gcc/config/score/crtn.asm15
-rw-r--r--gcc/config/score/mul-div.S472
-rw-r--r--gcc/config/score/score.c204
-rw-r--r--gcc/config/score/score.h3
-rw-r--r--gcc/config/score/score.md60
-rw-r--r--gcc/config/score/t-score-elf4
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