Commit cf723ae8 by Tan Shengguo Committed by Chen Liqin

crti.asm: add pic support.

        * 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.

From-SVN: r117771
parent c05b4438
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> 2006-10-10 Brooks Moses <bmoses@stanford.edu>
* Makefile.def: Added pdf target handling. * Makefile.def: Added pdf target handling.
......
...@@ -909,6 +909,10 @@ case $basic_machine in ...@@ -909,6 +909,10 @@ case $basic_machine in
sb1el) sb1el)
basic_machine=mipsisa64sb1el-unknown basic_machine=mipsisa64sb1el-unknown
;; ;;
score | score-*)
basic_machine=score-sunplus
os=-elf
;;
sei) sei)
basic_machine=mips-sei basic_machine=mips-sei
os=-seiux os=-seiux
......
...@@ -35,7 +35,8 @@ ...@@ -35,7 +35,8 @@
# This file makes a stack frame for the contents of the .init and # This file makes a stack frame for the contents of the .init and
# .fini sections. # .fini sections.
.section .init,"ax", @progbits #ifndef __pic__
.section .init, "ax", @progbits
.weak _start .weak _start
.ent _start .ent _start
.frame r0, 0, r3, 0 .frame r0, 0, r3, 0
...@@ -81,5 +82,62 @@ _init: ...@@ -81,5 +82,62 @@ _init:
_fini: _fini:
addi r0, -32 addi r0, -32
sw r3, [r0, 20] 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
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
# This file makes sure that the .init and .fini sections do in # This file makes sure that the .init and .fini sections do in
# fact return. # fact return.
#ifndef __pic__
.section .init, "ax", @progbits .section .init, "ax", @progbits
lw r3, [r0, 20] lw r3, [r0, 20]
addi r0, 32 addi r0, 32
...@@ -44,4 +45,18 @@ ...@@ -44,4 +45,18 @@
lw r3, [r0, 20] lw r3, [r0, 20]
addi r0, 32 addi r0, 32
br r3 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
...@@ -60,63 +60,71 @@ ...@@ -60,63 +60,71 @@
#define CE_REG_CLASS_P(C) \ #define CE_REG_CLASS_P(C) \
((C) == HI_REG || (C) == LO_REG || (C) == CE_REGS) ((C) == HI_REG || (C) == LO_REG || (C) == CE_REGS)
static int score_arg_partial_bytes (const CUMULATIVE_ARGS *cum, static int score_arg_partial_bytes (const CUMULATIVE_ARGS *,
enum machine_mode mode, enum machine_mode, tree, int);
tree type, int named);
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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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, /* Implement TARGET_RETURN_IN_MEMORY. In S+core,
small structures are returned in a register. small structures are returned in a register.
...@@ -880,6 +888,160 @@ score_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, ...@@ -880,6 +888,160 @@ score_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
return 12; 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. */ /* Implement ASM_OUTPUT_EXTERNAL macro. */
int int
score_output_external (FILE *file ATTRIBUTE_UNUSED, score_output_external (FILE *file ATTRIBUTE_UNUSED,
......
...@@ -54,9 +54,10 @@ extern GTY(()) rtx cmp_op1; ...@@ -54,9 +54,10 @@ extern GTY(()) rtx cmp_op1;
builtin_define ("__scorebe__"); \ builtin_define ("__scorebe__"); \
if (TARGET_SCORE5U) \ if (TARGET_SCORE5U) \
builtin_define ("__score5u__"); \ builtin_define ("__score5u__"); \
else \
builtin_define ("__score7__"); \
} while (0) } while (0)
#define TARGET_DEFAULT MASK_SCORE7 #define TARGET_DEFAULT MASK_SCORE7
#define TARGET_VERSION \ #define TARGET_VERSION \
......
...@@ -114,7 +114,7 @@ ...@@ -114,7 +114,7 @@
(match_operand:HI 1 "general_operand" "i,d,m,d,*x,d,*a,d"))] (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 0: return mdp_limm (operands);
case 1: return mdp_move (operands); case 1: return mdp_move (operands);
...@@ -1076,10 +1076,23 @@ ...@@ -1076,10 +1076,23 @@
[(call (mem:SI (match_operand:SI 0 "call_insn_operand" "t,Z")) [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "t,Z"))
(match_operand 1 "" "")) (match_operand 1 "" ""))
(clobber (reg:SI RT_REGNUM))] (clobber (reg:SI RT_REGNUM))]
"SIBLING_CALL_P (insn) && !flag_pic" "SIBLING_CALL_P (insn)"
"@ {
br%S0 %0 if (!flag_pic)
j %0" 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")]) [(set_attr "type" "call")])
(define_expand "sibcall_value" (define_expand "sibcall_value"
...@@ -1097,10 +1110,23 @@ ...@@ -1097,10 +1110,23 @@
(call (mem:SI (match_operand:SI 1 "call_insn_operand" "t,Z")) (call (mem:SI (match_operand:SI 1 "call_insn_operand" "t,Z"))
(match_operand 2 "" ""))) (match_operand 2 "" "")))
(clobber (reg:SI RT_REGNUM))] (clobber (reg:SI RT_REGNUM))]
"SIBLING_CALL_P(insn) && !flag_pic" "SIBLING_CALL_P (insn)"
"@ {
br%S1 %1 if (!flag_pic)
j %1" 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")]) [(set_attr "type" "call")])
(define_expand "call" (define_expand "call"
...@@ -1126,7 +1152,12 @@ ...@@ -1126,7 +1152,12 @@
default: gcc_unreachable (); default: gcc_unreachable ();
} }
else 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")]) [(set_attr "type" "call")])
...@@ -1155,7 +1186,12 @@ ...@@ -1155,7 +1186,12 @@
default: gcc_unreachable (); default: gcc_unreachable ();
} }
else 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")]) [(set_attr "type" "call")])
...@@ -1198,7 +1234,7 @@ ...@@ -1198,7 +1234,7 @@
"" ""
"* "*
if (flag_pic) if (flag_pic)
return \"mv! r29, %0\;.cpadd r29\;br%S0 r29\"; return \"mv r29, %0\;.cpadd r29\;br r29\";
else else
return \"br%S0 %0\"; return \"br%S0 %0\";
" "
......
...@@ -35,7 +35,9 @@ dp-bit.c: $(srcdir)/config/fp-bit.c ...@@ -35,7 +35,9 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
# without the $gp register. # without the $gp register.
TARGET_LIBGCC2_CFLAGS = -G 0 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 EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
LIBGCC = stmp-multilib LIBGCC = stmp-multilib
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment