t-score-elf (MULTILIB_OPTIONS): Change.

* config/score/t-score-elf (MULTILIB_OPTIONS): Change.
	* config/score/predicates.md (const_uimm5, sr0_operand, const_simm12,
	const_simm15, const_pow2, const_npow2): Added.
	* config/score/misc.md (insv, extv, extzv, movmemsi, 
	move_lbu_a/b, mov_lhu_a/b etc): Added and fix some bug.
	* config/score/score.c (score_address_cost, score_select_cc_mode): 
	Added.
	Change CONST_OK_FOR_LETTER_P/EXTRA_CONSTRAINT define.
	Update score_rtx_costs for MACRO TARGET_RTX_COSTS.
	Update score_print_operand.
	* config/score/score.h (DATA_ALIGNMENT, SELECT_CC_MODE): Added.
	Adjust register allocate order and update some macro define.
	* config/score/score-mdaux.c (mdx_unaligned_load, mdx_unsigned_store,
	mdx_block_move_straight, mdx_block_move_loop_head,
	mdx_block_move_loop_body, mdx_block_move_loop_foot, mdx_block_move_loop,
	mdx_block_move): Added.
	(mdx_movsicc, mdp_select_add_imm, mdp_select, mds_zero_extract_andi,
	mdp_limm): Updated and fix some bug and typo.
	* config/score/score.md (movqi/hi/si, add/sub/zero/ext): Updated.
	(movsf, movdf, doloop_end): Added.

From-SVN: r120570
This commit is contained in:
Chen Liqin 2007-01-08 04:47:33 +00:00 committed by Chen Liqin
parent 0979f01dee
commit 99fc25020d
16 changed files with 1506 additions and 409 deletions

View File

@ -1,3 +1,25 @@
2007-01-08 Chen Liqin <liqin@sunnorth.com.cn>
* config/score/t-score-elf (MULTILIB_OPTIONS): Change.
* config/score/predicates.md (const_uimm5, sr0_operand, const_simm12,
const_simm15, const_pow2, const_npow2): Added.
* config/score/misc.md (insv, extv, extzv, movmemsi,
move_lbu_a/b, mov_lhu_a/b etc): Added and fix some bug.
* config/score/score.c (score_address_cost, score_select_cc_mode):
Added.
Change CONST_OK_FOR_LETTER_P/EXTRA_CONSTRAINT define.
Update score_rtx_costs for MACRO TARGET_RTX_COSTS.
Update score_print_operand.
* config/score/score.h (DATA_ALIGNMENT, SELECT_CC_MODE): Added.
Adjust register allocate order and update some macro define.
* config/score/score-mdaux.c (mdx_unaligned_load, mdx_unsigned_store,
mdx_block_move_straight, mdx_block_move_loop_head,
mdx_block_move_loop_body, mdx_block_move_loop_foot, mdx_block_move_loop,
mdx_block_move): Added.
(mdx_movsicc, mdp_select_add_imm, mdp_select, mds_zero_extract_andi,
mdp_limm): Updated and fix some bug and typo.
* config/score/score.md (movqi/hi/si, add/sub/zero/ext): Updated.
(movsf, movdf, doloop_end): Added.
2007-01-08 Kazu Hirata <kazu@codesourcery.com>
* config/arm/arm.c, config/arm/arm.h, config/arm/arm.md,

View File

@ -43,8 +43,8 @@
.mask 0x00000000, 0
_start:
la r28, _gp
la r8, __bss_start
la r9, __bss_end__
la r8, _bss_start
la r9, _bss_end__
sub! r9, r8
srli! r9, 2
addi r9, -1
@ -91,8 +91,8 @@ _fini:
.mask 0x00000000,0
_start:
la r28, _gp
la r8, __bss_start
la r9, __bss_end__
la r8, _bss_start
la r9, _bss_end__
sub! r9, r8
srli! r9, 2
addi r9, -1
@ -102,15 +102,10 @@ _start:
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

View File

@ -59,4 +59,3 @@
br r3
#endif

View File

@ -84,8 +84,8 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(reg:CC CC_REGNUM) (const_int 0)])
(match_operand:SI 2 "register_operand" "d")
(match_operand:SI 3 "register_operand" "0")))]
(match_operand:SI 2 "arith_operand" "d")
(match_operand:SI 3 "arith_operand" "0")))]
""
"mv%C1 %0, %2"
[(set_attr "type" "cndmv")
@ -95,7 +95,7 @@
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ (unspec:SI
[(match_operand:SI 0 "register_operand" "*e,d")
(match_operand:SI 1 "const_bi_operand" "")]
(match_operand:SI 1 "const_uimm5" "")]
BITTST)
(const_int 0)))]
""
@ -106,3 +106,312 @@
(set_attr "up_c" "yes")
(set_attr "mode" "SI")])
(define_expand "extzv"
[(set (match_operand:SI 0 "register_operand" "")
(zero_extract (match_operand:SI 1 "memory_operand" "")
(match_operand:SI 2 "immediate_operand" "")
(match_operand:SI 3 "immediate_operand" "")))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
{
if (mdx_unaligned_load (operands))
DONE;
else
FAIL;
})
(define_expand "insv"
[(set (zero_extract (match_operand:SI 0 "memory_operand" "")
(match_operand:SI 1 "immediate_operand" "")
(match_operand:SI 2 "immediate_operand" ""))
(match_operand:SI 3 "register_operand" ""))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
{
if (mdx_unaligned_store (operands))
DONE;
else
FAIL;
})
(define_expand "extv"
[(set (match_operand:SI 0 "register_operand" "")
(sign_extract (match_operand:SI 1 "memory_operand" "")
(match_operand:SI 2 "immediate_operand" "")
(match_operand:SI 3 "immediate_operand" "")))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
{
if (mdx_unaligned_load (operands))
DONE;
else
FAIL;
})
(define_expand "movmemsi"
[(parallel [(set (match_operand:BLK 0 "general_operand")
(match_operand:BLK 1 "general_operand"))
(use (match_operand:SI 2 ""))
(use (match_operand:SI 3 "const_int_operand"))])]
"!TARGET_SCORE5U"
{
if (mdx_block_move (operands))
DONE;
else
FAIL;
})
(define_insn "move_lbu_a"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (match_operand:QI 3 "register_operand" "=d")
(mem:QI (match_dup 1)))]
"!TARGET_SCORE5U"
"lbu %3, [%1]+, %2"
[(set_attr "type" "load")
(set_attr "mode" "QI")])
(define_insn "move_lhu_a"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (match_operand:HI 3 "register_operand" "=d")
(mem:HI (match_dup 1)))]
"!TARGET_SCORE5U"
"lhu %3, [%1]+, %2"
[(set_attr "type" "load")
(set_attr "mode" "HI")])
(define_insn "move_lw_a"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (match_operand:SI 3 "register_operand" "=d")
(mem:SI (match_dup 1)))]
"!TARGET_SCORE5U"
"lw %3, [%1]+, %2"
[(set_attr "type" "load")
(set_attr "mode" "SI")])
(define_insn "move_sb_a"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (mem:QI (match_dup 1))
(match_operand:QI 3 "register_operand" "d"))]
"!TARGET_SCORE5U"
"sb %3, [%1]+, %2"
[(set_attr "type" "store")
(set_attr "mode" "QI")])
(define_insn "move_sh_a"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (mem:HI (match_dup 1))
(match_operand:HI 3 "register_operand" "d"))]
"!TARGET_SCORE5U"
"sh %3, [%1]+, %2"
[(set_attr "type" "store")
(set_attr "mode" "HI")])
(define_insn "move_sw_a"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (mem:SI (match_dup 1))
(match_operand:SI 3 "register_operand" "d"))]
"!TARGET_SCORE5U"
"sw %3, [%1]+, %2"
[(set_attr "type" "store")
(set_attr "mode" "SI")])
(define_insn "move_lbu_b"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (match_operand:QI 3 "register_operand" "=d")
(mem:QI (plus:SI (match_dup 1)
(match_dup 2))))]
"!TARGET_SCORE5U"
"lbu %3, [%1, %2]+"
[(set_attr "type" "load")
(set_attr "mode" "QI")])
(define_insn "move_lhu_b"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (match_operand:HI 3 "register_operand" "=d")
(mem:HI (plus:SI (match_dup 1)
(match_dup 2))))]
"!TARGET_SCORE5U"
"lhu %3, [%1, %2]+"
[(set_attr "type" "load")
(set_attr "mode" "HI")])
(define_insn "move_lw_b"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (match_operand:SI 3 "register_operand" "=d")
(mem:SI (plus:SI (match_dup 1)
(match_dup 2))))]
"!TARGET_SCORE5U"
"lw %3, [%1, %2]+"
[(set_attr "type" "load")
(set_attr "mode" "SI")])
(define_insn "move_sb_b"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (mem:QI (plus:SI (match_dup 1)
(match_dup 2)))
(match_operand:QI 3 "register_operand" "d"))]
"!TARGET_SCORE5U"
"sb %3, [%1, %2]+"
[(set_attr "type" "store")
(set_attr "mode" "QI")])
(define_insn "move_sh_b"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (mem:HI (plus:SI (match_dup 1)
(match_dup 2)))
(match_operand:HI 3 "register_operand" "d"))]
"!TARGET_SCORE5U"
"sh %3, [%1, %2]+"
[(set_attr "type" "store")
(set_attr "mode" "HI")])
(define_insn "move_sw_b"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_simm12" "")))
(set (mem:SI (plus:SI (match_dup 1)
(match_dup 2)))
(match_operand:SI 3 "register_operand" "d"))]
"!TARGET_SCORE5U"
"sw %3, [%1, %2]+"
[(set_attr "type" "store")
(set_attr "mode" "SI")])
(define_insn "move_lcb"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4)))
(set (reg:SI LC_REGNUM)
(unspec:SI [(mem:BLK (match_dup 1))] LCB))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
"lcb [%1]+"
[(set_attr "type" "load")
(set_attr "mode" "SI")])
(define_insn "move_lcw"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4)))
(set (match_operand:SI 2 "register_operand" "=d")
(unspec:SI [(mem:BLK (match_dup 1))
(reg:SI LC_REGNUM)] LCW))
(set (reg:SI LC_REGNUM)
(unspec:SI [(mem:BLK (match_dup 1))] LCB))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
"lcw %2, [%1]+"
[(set_attr "type" "load")
(set_attr "mode" "SI")])
(define_insn "move_lce"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4)))
(set (match_operand:SI 2 "register_operand" "=d")
(unspec:SI [(mem:BLK (match_dup 1))
(reg:SI LC_REGNUM)] LCE))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
"lce %2, [%1]+"
[(set_attr "type" "load")
(set_attr "mode" "SI")])
(define_insn "move_scb"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4)))
(set (mem:BLK (match_dup 1))
(unspec:BLK [(match_operand:SI 2 "register_operand" "d")] SCB))
(set (reg:SI SC_REGNUM)
(unspec:SI [(match_dup 2)] SCLC))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
"scb %2, [%1]+"
[(set_attr "type" "store")
(set_attr "mode" "SI")])
(define_insn "move_scw"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4)))
(set (mem:BLK (match_dup 1))
(unspec:BLK [(match_operand:SI 2 "register_operand" "d")
(reg:SI SC_REGNUM)] SCW))
(set (reg:SI SC_REGNUM)
(unspec:SI [(match_dup 2)] SCLC))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
"scw %2, [%1]+"
[(set_attr "type" "store")
(set_attr "mode" "SI")])
(define_insn "move_sce"
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4)))
(set (mem:BLK (match_dup 1))
(unspec:BLK [(reg:SI SC_REGNUM)] SCE))]
"!TARGET_SCORE5U && !TARGET_LITTLE_ENDIAN"
"sce [%1]+"
[(set_attr "type" "store")
(set_attr "mode" "SI")])
(define_insn "andsi3_extzh"
[(set (match_operand:SI 0 "register_operand" "=d")
(and:SI (match_operand:SI 1 "register_operand" "d")
(const_int 65535)))]
""
"extzh %0, %1"
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
(define_insn "bitclr_c"
[(set (match_operand:SI 0 "register_operand" "=e,d")
(and:SI (match_operand:SI 1 "register_operand" "0,d")
(match_operand:SI 2 "const_npow2")))
(clobber (reg:CC CC_REGNUM))]
""
"@
bitclr! %0, %F2
bitclr.c %0, %1, %F2"
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
(define_insn "bitset_c"
[(set (match_operand:SI 0 "register_operand" "=e,d")
(ior:SI (match_operand:SI 1 "register_operand" "0,d")
(match_operand:SI 2 "const_pow2")))
(clobber (reg:CC CC_REGNUM))]
""
"@
bitset! %0, %E2
bitset.c %0, %1, %E2"
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
(define_insn "bittgl_c"
[(set (match_operand:SI 0 "register_operand" "=e,d")
(xor:SI (match_operand:SI 1 "register_operand" "0,d")
(match_operand:SI 2 "const_pow2")))
(clobber (reg:CC CC_REGNUM))]
""
"@
bittgl! %0, %E2
bittgl.c %0, %1, %E2"
[(set_attr "type" "arith")
(set_attr "mode" "SI")])

View File

@ -242,7 +242,7 @@ _flush_cache:
#nop!
addi r8, 16
bcnz 2b
.cprestore 12 # pic used
.cprestore r0, 12 # pic used
addi r0, 8 # pic used
br r3
#endif
@ -278,7 +278,7 @@ __mulsi3_loop2:
cmpi.c a1, 0
bne __mulsi3_loop
mv r4, t1
.cprestore 12 # pic used
.cprestore r0, 12 # pic used
addi r0, 8 # pic used
br ra
.end __mulsi3
@ -334,7 +334,7 @@ __uds_loop3:
__uds_exit:
mv a1, a0
mv r4, t4
.cprestore 12 # pic used
.cprestore r0, 12 # pic used
addi r0, 8 # pic used
br ra
.end __udivsi3
@ -350,7 +350,7 @@ __umodsi3:
la r29, __udivsi3
brl r29
mv r4, a1
.cprestore 12 # pic used
.cprestore r0, 12 # pic used
addi r0, 8 # pic used
br t3
.end __umodsi3
@ -383,7 +383,7 @@ __divsi3_adjust:
bge __divsi3_exit
neg r4, r4
__divsi3_exit:
.cprestore 12 # pic used
.cprestore r0, 12 # pic used
addi r0, 8 # pic used
br t3
.end __divsi3

View File

@ -35,13 +35,11 @@
(ior (match_operand 0 "const_call_insn_operand")
(match_operand 0 "register_operand")))
(define_predicate "const_bi_operand"
(and (match_code "const_int")
(match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'J')")))
(define_predicate "pindex_off_operand"
(and (match_code "const_int")
(match_test "CONST_OK_FOR_LETTER_P (INTVAL (op), 'P')")))
(define_predicate "const_uimm5"
(match_code "const_int")
{
return IMM_IN_RANGE (INTVAL (op), 5, 0);
})
(define_predicate "hireg_operand"
(and (match_code "reg")
@ -51,6 +49,10 @@
(and (match_code "reg")
(match_test "REGNO (op) == LO_REGNUM")))
(define_predicate "sr0_operand"
(and (match_code "reg")
(match_test "REGNO (op) == CN_REGNUM")))
(define_predicate "g32reg_operand"
(and (match_code "reg")
(match_test "GP_REG_P (REGNO (op))")))
@ -61,3 +63,26 @@
(define_predicate "branch_nz_operator"
(match_code "eq,ne,lt,ge"))
(define_predicate "const_simm12"
(match_code "const_int")
{
return IMM_IN_RANGE (INTVAL (op), 12, 1);
})
(define_predicate "const_simm15"
(match_code "const_int")
{
return IMM_IN_RANGE (INTVAL (op), 15, 1);
})
(define_predicate "const_pow2"
(match_code "const_int")
{
return IMM_IS_POW_OF_2 ((unsigned HOST_WIDE_INT) INTVAL (op), 0, 31);
})
(define_predicate "const_npow2"
(match_code "const_int")
{
return IMM_IS_POW_OF_2 (~(unsigned HOST_WIDE_INT) INTVAL (op), 0, 31);
})

View File

@ -45,7 +45,7 @@ extern int target_flags;
#define CE_REG_P(REGNO) REG_CONTAIN (REGNO, CE_REG_FIRST, CE_REG_NUM)
#define UIMM_IN_RANGE(V, W) ((V) >= 0 && (V) < ((HOST_WIDE_INT)1 << (W)))
#define UIMM_IN_RANGE(V, W) ((V) >= 0 && (V) < ((HOST_WIDE_INT) 1 << (W)))
#define SIMM_IN_RANGE(V, W) \
((V) >= (-1 * ((HOST_WIDE_INT) 1 << ((W) - 1))) \
@ -54,6 +54,11 @@ extern int target_flags;
#define IMM_IN_RANGE(V, W, S) \
((S) ? SIMM_IN_RANGE (V, W) : UIMM_IN_RANGE (V, W))
#define IMM_IS_POW_OF_2(V, E1, E2) \
((V) >= ((unsigned HOST_WIDE_INT) 1 << (E1)) \
&& (V) <= ((unsigned HOST_WIDE_INT) 1 << (E2)) \
&& ((V) & ((V) - 1)) == 0)
#define SCORE_STACK_ALIGN(LOC) (((LOC) + 3) & ~3)
#define SCORE_MAX_FIRST_STACK_STEP (0x3ff0)

View File

@ -108,10 +108,9 @@ score_symbol_type score_classify_symbol (rtx x)
if (GET_CODE (x) == LABEL_REF)
return SYMBOL_GENERAL;
if (GET_CODE (x) != SYMBOL_REF)
gcc_unreachable ();
gcc_assert (GET_CODE (x) == SYMBOL_REF);
if (CONSTANT_POOL_ADDRESS_P(x))
if (CONSTANT_POOL_ADDRESS_P (x))
{
if (GET_MODE_SIZE (get_pool_mode (x)) <= SCORE_SDATA_MAX)
return SYMBOL_SMALL_DATA;
@ -185,14 +184,14 @@ mda_compute_frame_size (HOST_WIDE_INT size)
f->mask = 0;
f->var_size = SCORE_STACK_ALIGN (size);
f->args_size = current_function_outgoing_args_size;
f->cprestore_size = SCORE_STACK_ALIGN (STARTING_FRAME_OFFSET) - f->args_size;
f->cprestore_size = flag_pic ? UNITS_PER_WORD : 0;
if (f->var_size == 0 && current_function_is_leaf)
f->args_size = f->cprestore_size = 0;
if (f->args_size == 0 && current_function_calls_alloca)
f->args_size = UNITS_PER_WORD;
f->total_size = f->var_size + f->args_size;
f->total_size = f->var_size + f->args_size + f->cprestore_size;
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
{
if (score_save_reg_p (regno))
@ -205,7 +204,7 @@ mda_compute_frame_size (HOST_WIDE_INT size)
if (current_function_calls_eh_return)
{
unsigned int i;
for (i = 0; ; ++i)
for (i = 0;; ++i)
{
regno = EH_RETURN_DATA_REGNO (i);
if (regno == INVALID_REGNUM)
@ -215,7 +214,7 @@ mda_compute_frame_size (HOST_WIDE_INT size)
}
}
f->total_size += SCORE_STACK_ALIGN (f->gp_reg_size);
f->total_size += f->gp_reg_size;
f->num_gp = f->gp_reg_size / UNITS_PER_WORD;
if (f->mask)
@ -226,12 +225,7 @@ mda_compute_frame_size (HOST_WIDE_INT size)
f->gp_sp_offset = offset;
}
else
{
f->gp_sp_offset = 0;
}
if ((f->total_size == f->gp_reg_size) && flag_pic)
f->total_size += 8;
f->gp_sp_offset = 0;
return f;
}
@ -294,8 +288,13 @@ mdx_prologue (void)
if (frame_pointer_needed)
EMIT_PL (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
if (flag_pic)
emit_insn (gen_cprestore (GEN_INT (size + 4)));
if (flag_pic && f->cprestore_size)
{
if (frame_pointer_needed)
emit_insn (gen_cprestore_use_fp (GEN_INT (size - f->cprestore_size)));
else
emit_insn (gen_cprestore_use_sp (GEN_INT (size - f->cprestore_size)));
}
#undef EMIT_PL
}
@ -392,7 +391,7 @@ mda_classify_address (struct score_address_info *info,
info->offset = XEXP (x, 1);
return (mda_valid_base_register_p (info->reg, strict)
&& GET_CODE (info->offset) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (info->offset), 'O'));
&& IMM_IN_RANGE (INTVAL (info->offset), 15, 1));
case PRE_DEC:
case POST_DEC:
case PRE_INC:
@ -405,7 +404,7 @@ mda_classify_address (struct score_address_info *info,
return mda_valid_base_register_p (info->reg, strict);
case CONST_INT:
info->type = ADD_CONST_INT;
return CONST_OK_FOR_LETTER_P (INTVAL (x), 'O');
return IMM_IN_RANGE (INTVAL (x), 15, 1);
case CONST:
case LABEL_REF:
case SYMBOL_REF:
@ -443,7 +442,7 @@ mda_symbolic_constant_p (rtx x, enum score_symbol_type *symbol_type)
return 1;
/* if offset > 15bit, must reload */
if (!CONST_OK_FOR_LETTER_P (offset, 'O'))
if (!IMM_IN_RANGE (offset, 15, 1))
return 0;
switch (*symbol_type)
@ -459,11 +458,9 @@ mda_symbolic_constant_p (rtx x, enum score_symbol_type *symbol_type)
void
mdx_movsicc (rtx *ops)
{
enum machine_mode mode = CCmode;
if (GET_CODE (ops[1]) == EQ || GET_CODE (ops[1]) == NE)
mode = CC_NZmode;
enum machine_mode mode;
mode = score_select_cc_mode (GET_CODE (ops[1]), ops[2], ops[3]);
emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, CC_REGNUM),
gen_rtx_COMPARE (mode, cmp_op0, cmp_op1)));
}
@ -533,14 +530,15 @@ mds_movdi (rtx *ops)
void
mds_zero_extract_andi (rtx *ops)
{
if (INTVAL (ops[1]) == 1 && const_bi_operand (ops[2], SImode))
if (INTVAL (ops[1]) == 1 && const_uimm5 (ops[2], SImode))
emit_insn (gen_zero_extract_bittst (ops[0], ops[2]));
else
{
unsigned HOST_WIDE_INT mask;
mask = (0xffffffffU & ((1U << INTVAL (ops[1])) - 1U));
mask = mask << INTVAL (ops[2]);
emit_insn (gen_andsi3_cmp (ops[0], gen_int_mode (mask, SImode)));
emit_insn (gen_andsi3_cmp (ops[3], ops[0],
gen_int_mode (mask, SImode)));
}
}
@ -637,17 +635,20 @@ mdp_sinsn (rtx *ops, enum mda_mem_unit unit)
const char *
mdp_limm (rtx *ops)
{
gcc_assert (GET_CODE (ops[0]) == REG);
HOST_WIDE_INT v;
if (G16_REG_P (REGNO (ops[0]))
&& CONST_OK_FOR_LETTER_P (INTVAL (ops[1]), 'I'))
gcc_assert (GET_CODE (ops[0]) == REG);
gcc_assert (GET_CODE (ops[1]) == CONST_INT);
v = INTVAL (ops[1]);
if (G16_REG_P (REGNO (ops[0])) && IMM_IN_RANGE (v, 8, 0))
return "ldiu! %0, %c1";
else if (CONST_OK_FOR_LETTER_P (INTVAL (ops[1]), 'L'))
else if (IMM_IN_RANGE (v, 16, 1))
return "ldi %0, %c1";
else if (EXTRA_CONSTRAINT (ops[1], 'Q'))
else if ((v & 0xffff) == 0)
return "ldis %0, %U1";
else
return "li %0, %D1";
return "li %0, %c1";
}
/* Output asm insn for move. */
@ -670,69 +671,389 @@ mdp_move (rtx *ops)
return "mv %0, %1";
}
/* Score support add/sub with exponent immediate insn,
use to judge imm condition. */
static unsigned int
num_bits1 (unsigned HOST_WIDE_INT v)
/* Emit lcb/lce insns. */
bool
mdx_unaligned_load (rtx *ops)
{
int i, n = 0;
rtx dst = ops[0];
rtx src = ops[1];
rtx len = ops[2];
rtx off = ops[3];
rtx addr_reg;
for (i = 0; i < BITS_PER_WORD; i++)
n += BITSET_P (v, i) ? 1 : 0;
return n;
if (INTVAL (len) != BITS_PER_WORD
|| (INTVAL (off) % BITS_PER_UNIT) != 0)
return false;
gcc_assert (GET_MODE_SIZE (GET_MODE (dst)) == GET_MODE_SIZE (SImode));
addr_reg = copy_addr_to_reg (XEXP (src, 0));
emit_insn (gen_move_lcb (addr_reg, addr_reg));
emit_insn (gen_move_lce (addr_reg, addr_reg, dst));
return true;
}
/* Generate add insn, insn will affect condition flag. Optimize used. */
/* Emit scb/sce insns. */
bool
mdx_unaligned_store (rtx *ops)
{
rtx dst = ops[0];
rtx len = ops[1];
rtx off = ops[2];
rtx src = ops[3];
rtx addr_reg;
if (INTVAL(len) != BITS_PER_WORD
|| (INTVAL(off) % BITS_PER_UNIT) != 0)
return false;
gcc_assert (GET_MODE_SIZE (GET_MODE (src)) == GET_MODE_SIZE (SImode));
addr_reg = copy_addr_to_reg (XEXP (dst, 0));
emit_insn (gen_move_scb (addr_reg, addr_reg, src));
emit_insn (gen_move_sce (addr_reg, addr_reg));
return true;
}
/* If length is short, generate move insns straight. */
static void
mdx_block_move_straight (rtx dst, rtx src, HOST_WIDE_INT length)
{
HOST_WIDE_INT leftover;
int i, reg_count;
rtx *regs;
leftover = length % UNITS_PER_WORD;
length -= leftover;
reg_count = length / UNITS_PER_WORD;
regs = alloca (sizeof (rtx) * reg_count);
for (i = 0; i < reg_count; i++)
regs[i] = gen_reg_rtx (SImode);
/* Load from src to regs. */
if (MEM_ALIGN (src) >= BITS_PER_WORD)
{
HOST_WIDE_INT offset = 0;
for (i = 0; i < reg_count; offset += UNITS_PER_WORD, i++)
emit_move_insn (regs[i], adjust_address (src, SImode, offset));
}
else if (reg_count >= 1)
{
rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
emit_insn (gen_move_lcb (src_reg, src_reg));
for (i = 0; i < (reg_count - 1); i++)
emit_insn (gen_move_lcw (src_reg, src_reg, regs[i]));
emit_insn (gen_move_lce (src_reg, src_reg, regs[i]));
}
/* Store regs to dest. */
if (MEM_ALIGN (dst) >= BITS_PER_WORD)
{
HOST_WIDE_INT offset = 0;
for (i = 0; i < reg_count; offset += UNITS_PER_WORD, i++)
emit_move_insn (adjust_address (dst, SImode, offset), regs[i]);
}
else if (reg_count >= 1)
{
rtx dst_reg = copy_addr_to_reg (XEXP (dst, 0));
emit_insn (gen_move_scb (dst_reg, dst_reg, regs[0]));
for (i = 1; i < reg_count; i++)
emit_insn (gen_move_scw (dst_reg, dst_reg, regs[i]));
emit_insn (gen_move_sce (dst_reg, dst_reg));
}
/* Mop up any left-over bytes. */
if (leftover > 0)
{
src = adjust_address (src, BLKmode, length);
dst = adjust_address (dst, BLKmode, length);
move_by_pieces (dst, src, leftover,
MIN (MEM_ALIGN (src), MEM_ALIGN (dst)), 0);
}
}
/* Generate loop head when dst or src is unaligned. */
static void
mdx_block_move_loop_head (rtx dst_reg, HOST_WIDE_INT dst_align,
rtx src_reg, HOST_WIDE_INT src_align,
HOST_WIDE_INT length)
{
bool src_unaligned = (src_align < BITS_PER_WORD);
bool dst_unaligned = (dst_align < BITS_PER_WORD);
rtx temp = gen_reg_rtx (SImode);
gcc_assert (length == UNITS_PER_WORD);
if (src_unaligned)
{
emit_insn (gen_move_lcb (src_reg, src_reg));
emit_insn (gen_move_lcw (src_reg, src_reg, temp));
}
else
emit_insn (gen_move_lw_a (src_reg,
src_reg, gen_int_mode (4, SImode), temp));
if (dst_unaligned)
emit_insn (gen_move_scb (dst_reg, dst_reg, temp));
else
emit_insn (gen_move_sw_a (dst_reg,
dst_reg, gen_int_mode (4, SImode), temp));
}
/* Generate loop body, copy length bytes per iteration. */
static void
mdx_block_move_loop_body (rtx dst_reg, HOST_WIDE_INT dst_align,
rtx src_reg, HOST_WIDE_INT src_align,
HOST_WIDE_INT length)
{
int reg_count = length / UNITS_PER_WORD;
rtx *regs = alloca (sizeof (rtx) * reg_count);
int i;
bool src_unaligned = (src_align < BITS_PER_WORD);
bool dst_unaligned = (dst_align < BITS_PER_WORD);
for (i = 0; i < reg_count; i++)
regs[i] = gen_reg_rtx (SImode);
if (src_unaligned)
{
for (i = 0; i < reg_count; i++)
emit_insn (gen_move_lcw (src_reg, src_reg, regs[i]));
}
else
{
for (i = 0; i < reg_count; i++)
emit_insn (gen_move_lw_a (src_reg,
src_reg, gen_int_mode (4, SImode), regs[i]));
}
if (dst_unaligned)
{
for (i = 0; i < reg_count; i++)
emit_insn (gen_move_scw (dst_reg, dst_reg, regs[i]));
}
else
{
for (i = 0; i < reg_count; i++)
emit_insn (gen_move_sw_a (dst_reg,
dst_reg, gen_int_mode (4, SImode), regs[i]));
}
}
/* Generate loop foot, copy the leftover bytes. */
static void
mdx_block_move_loop_foot (rtx dst_reg, HOST_WIDE_INT dst_align,
rtx src_reg, HOST_WIDE_INT src_align,
HOST_WIDE_INT length)
{
bool src_unaligned = (src_align < BITS_PER_WORD);
bool dst_unaligned = (dst_align < BITS_PER_WORD);
HOST_WIDE_INT leftover;
leftover = length % UNITS_PER_WORD;
length -= leftover;
if (length > 0)
mdx_block_move_loop_body (dst_reg, dst_align,
src_reg, src_align, length);
if (dst_unaligned)
emit_insn (gen_move_sce (dst_reg, dst_reg));
if (leftover > 0)
{
HOST_WIDE_INT src_adj = src_unaligned ? -4 : 0;
HOST_WIDE_INT dst_adj = dst_unaligned ? -4 : 0;
rtx temp;
gcc_assert (leftover < UNITS_PER_WORD);
if (leftover >= UNITS_PER_WORD / 2
&& src_align >= BITS_PER_WORD / 2
&& dst_align >= BITS_PER_WORD / 2)
{
temp = gen_reg_rtx (HImode);
emit_insn (gen_move_lhu_b (src_reg, src_reg,
gen_int_mode (src_adj, SImode), temp));
emit_insn (gen_move_sh_b (dst_reg, dst_reg,
gen_int_mode (dst_adj, SImode), temp));
leftover -= UNITS_PER_WORD / 2;
src_adj = UNITS_PER_WORD / 2;
dst_adj = UNITS_PER_WORD / 2;
}
while (leftover > 0)
{
temp = gen_reg_rtx (QImode);
emit_insn (gen_move_lbu_b (src_reg, src_reg,
gen_int_mode (src_adj, SImode), temp));
emit_insn (gen_move_sb_b (dst_reg, dst_reg,
gen_int_mode (dst_adj, SImode), temp));
leftover--;
src_adj = 1;
dst_adj = 1;
}
}
}
#define MIN_MOVE_REGS 3
#define MIN_MOVE_BYTES (MIN_MOVE_REGS * UNITS_PER_WORD)
#define MAX_MOVE_REGS 4
#define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
/* The length is large, generate a loop if necessary.
The loop is consisted by loop head/body/foot. */
static void
mdx_block_move_loop (rtx dst, rtx src, HOST_WIDE_INT length)
{
HOST_WIDE_INT src_align = MEM_ALIGN (src);
HOST_WIDE_INT dst_align = MEM_ALIGN (dst);
HOST_WIDE_INT loop_mov_bytes;
HOST_WIDE_INT iteration = 0;
HOST_WIDE_INT head_length = 0, leftover;
rtx label, src_reg, dst_reg, final_dst;
bool gen_loop_head = (src_align < BITS_PER_WORD
|| dst_align < BITS_PER_WORD);
if (gen_loop_head)
head_length += UNITS_PER_WORD;
for (loop_mov_bytes = MAX_MOVE_BYTES;
loop_mov_bytes >= MIN_MOVE_BYTES;
loop_mov_bytes -= UNITS_PER_WORD)
{
iteration = (length - head_length) / loop_mov_bytes;
if (iteration > 1)
break;
}
if (iteration <= 1)
{
mdx_block_move_straight (dst, src, length);
return;
}
leftover = (length - head_length) % loop_mov_bytes;
length -= leftover;
src_reg = copy_addr_to_reg (XEXP (src, 0));
dst_reg = copy_addr_to_reg (XEXP (dst, 0));
final_dst = expand_simple_binop (Pmode, PLUS, dst_reg, GEN_INT (length),
0, 0, OPTAB_WIDEN);
if (gen_loop_head)
mdx_block_move_loop_head (dst_reg, dst_align,
src_reg, src_align, head_length);
label = gen_label_rtx ();
emit_label (label);
mdx_block_move_loop_body (dst_reg, dst_align,
src_reg, src_align, loop_mov_bytes);
emit_insn (gen_cmpsi (dst_reg, final_dst));
emit_jump_insn (gen_bne (label));
mdx_block_move_loop_foot (dst_reg, dst_align,
src_reg, src_align, leftover);
}
/* Generate block move, for misc.md: "movmemsi". */
bool
mdx_block_move (rtx *ops)
{
rtx dst = ops[0];
rtx src = ops[1];
rtx length = ops[2];
if (TARGET_LITTLE_ENDIAN
&& (MEM_ALIGN (src) < BITS_PER_WORD || MEM_ALIGN (dst) < BITS_PER_WORD)
&& INTVAL (length) >= UNITS_PER_WORD)
return false;
if (GET_CODE (length) == CONST_INT)
{
if (INTVAL (length) <= 2 * MAX_MOVE_BYTES)
{
mdx_block_move_straight (dst, src, INTVAL (length));
return true;
}
else if (optimize &&
!(flag_unroll_loops || flag_unroll_all_loops))
{
mdx_block_move_loop (dst, src, INTVAL (length));
return true;
}
}
return false;
}
/* Generate add insn. */
const char *
mdp_add_imm_ucc (rtx *ops)
mdp_select_add_imm (rtx *ops, bool set_cc)
{
HOST_WIDE_INT v = INTVAL (ops[2]);
gcc_assert (GET_CODE (ops[2]) == CONST_INT);
gcc_assert (REGNO (ops[0]) == REGNO (ops[1]));
if (G16_REG_P (REGNO (ops[0])))
if (set_cc && G16_REG_P (REGNO (ops[0])))
{
if (v > 0 && num_bits1 (v) == 1 && IMM_IN_RANGE (ffs (v) - 1, 4, 0))
if (v > 0 && IMM_IS_POW_OF_2 ((unsigned HOST_WIDE_INT) v, 0, 15))
{
ops[2] = GEN_INT (ffs (v) - 1);
return "addei! %0, %c2";
}
if (v < 0 && num_bits1 (-v) == 1 && IMM_IN_RANGE (ffs (-v) - 1, 4, 0))
if (v < 0 && IMM_IS_POW_OF_2 ((unsigned HOST_WIDE_INT) (-v), 0, 15))
{
ops[2] = GEN_INT (ffs (-v) - 1);
return "subei! %0, %c2";
}
}
if (set_cc)
return "addi.c %0, %c2";
else
return "addi %0, %c2";
}
/* Output arith insn, insn will update condition flag. */
/* Output arith insn. */
const char *
mdp_select (rtx *ops, const char *inst_pre, bool commu, const char *let)
mdp_select (rtx *ops, const char *inst_pre,
bool commu, const char *letter, bool set_cc)
{
gcc_assert (GET_CODE (ops[0]) == REG);
gcc_assert (GET_CODE (ops[1]) == REG);
if (G16_REG_P (REGNO (ops[0]))
if (set_cc && G16_REG_P (REGNO (ops[0]))
&& (GET_CODE (ops[2]) == REG ? G16_REG_P (REGNO (ops[2])) : 1)
&& REGNO (ops[0]) == REGNO (ops[1]))
{
snprintf (ins, INS_BUF_SZ, "%s! %%0, %%%s2", inst_pre, let);
snprintf (ins, INS_BUF_SZ, "%s! %%0, %%%s2", inst_pre, letter);
return ins;
}
if (commu && G16_REG_P (REGNO (ops[0]))
if (commu && set_cc && G16_REG_P (REGNO (ops[0]))
&& G16_REG_P (REGNO (ops[1]))
&& REGNO (ops[0]) == REGNO (ops[2]))
{
gcc_assert (GET_CODE (ops[2]) == REG);
snprintf (ins, INS_BUF_SZ, "%s! %%0, %%%s1", inst_pre, let);
snprintf (ins, INS_BUF_SZ, "%s! %%0, %%%s1", inst_pre, letter);
return ins;
}
snprintf (ins, INS_BUF_SZ, "%s.c %%0, %%1, %%%s2", inst_pre, let);
if (set_cc)
snprintf (ins, INS_BUF_SZ, "%s.c %%0, %%1, %%%s2", inst_pre, letter);
else
snprintf (ins, INS_BUF_SZ, "%s %%0, %%1, %%%s2", inst_pre, letter);
return ins;
}

View File

@ -69,8 +69,6 @@ void mda_gen_cmp (enum machine_mode mode);
int mda_symbolic_constant_p (rtx x, enum score_symbol_type *symbol_type);
bool mda_pindex_mem (rtx addr);
int mda_bp (void);
/* Machine Expand. */
@ -87,8 +85,6 @@ void mdx_call_value (rtx *ops, bool sibcall);
/* Machine Split. */
void mds_movdi (rtx *ops);
void mds_addsi (rtx *ops);
void mds_zero_extract_andi (rtx *ops);
/* Machine Print. */
@ -100,14 +96,21 @@ const char * mdp_linsn (rtx *ops, enum mda_mem_unit unit, bool sign);
const char * mdp_sinsn (rtx *ops, enum mda_mem_unit unit);
const char * mdp_add_imm_ucc (rtx *ops);
const char * mdp_select_add_imm (rtx *ops, bool set_cc);
const char * mdp_select (rtx *ops, const char *inst_pre,
bool comu, const char *let);
bool commu, const char *letter, bool set_cc);
const char * mdp_limm (rtx *ops);
const char * mdp_move (rtx *ops);
/* Machine unaligned memory load/store. */
bool mdx_unaligned_load (rtx* ops);
bool mdx_unaligned_store (rtx* ops);
bool mdx_block_move (rtx* ops);
#endif

View File

@ -21,6 +21,5 @@
/* CC_NZmode should be used if the N (sign) and Z (zero) flag is set correctly.
CC_Nmode should be used if only the N flag is set correctly. */
CC_MODE (CC_NZ);
CC_MODE (CC_N);
CC_MODE (CC_NZ);

View File

@ -36,7 +36,7 @@ enum reg_class score_preferred_reload_class (rtx x, enum reg_class class);
enum reg_class score_secondary_reload_class (enum reg_class class,
enum machine_mode mode, rtx x);
int score_const_ok_for_letter_p (int value, char c);
int score_const_ok_for_letter_p (HOST_WIDE_INT value, char c);
int score_extra_constraint (rtx op, char c);

View File

@ -18,4 +18,4 @@
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#define SCORE_GCC_VERSION "1.1"
#define SCORE_GCC_VERSION "1.2"

View File

@ -67,7 +67,9 @@ 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 *);
static bool score_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
static int score_address_cost (rtx);
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START th_asm_file_start
@ -126,6 +128,9 @@ static bool score_rtx_costs (rtx, int, int, int *);
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS score_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST score_address_cost
#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
@ -154,7 +159,7 @@ score_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
static rtx
score_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
{
if (!CONST_OK_FOR_LETTER_P (offset, 'O'))
if (!IMM_IN_RANGE (offset, 15, 1))
{
reg = expand_simple_binop (GET_MODE (reg), PLUS,
gen_int_mode (offset & 0xffffc000,
@ -499,12 +504,13 @@ enum reg_class score_char_to_class[256];
void
score_override_options (void)
{
flag_pic = false;
if (!flag_pic)
sdata_max = g_switch_set ? g_switch_value : DEFAULT_SDATA_MAX;
else
{
sdata_max = 0;
if (g_switch_set)
if (g_switch_set && (g_switch_value != 0))
warning (0, "-fPIC and -G are incompatible");
}
@ -540,7 +546,7 @@ score_reg_class (int regno)
|| regno == ARG_POINTER_REGNUM)
return ALL_REGS;
for (c = 0 ; c < N_REG_CLASSES ; c++)
for (c = 0; c < N_REG_CLASSES; c++)
if (TEST_HARD_REG_BIT (reg_class_contents[c], regno))
return c;
@ -551,10 +557,10 @@ score_reg_class (int regno)
enum reg_class
score_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
{
if (reg_class_subset_p (G32_REGS, class))
class = G32_REGS;
if (reg_class_subset_p (G16_REGS, class))
class = G16_REGS;
return G16_REGS;
if (reg_class_subset_p (G32_REGS, class))
return G32_REGS;
return class;
}
@ -576,41 +582,34 @@ score_secondary_reload_class (enum reg_class class,
/* Implement CONST_OK_FOR_LETTER_P macro. */
/* imm constraints
I IMM8 (i15-2-form)
J IMM5 (i15_1-form)
K IMM16 (i-form)
L IMM16s (i-form)
M IMM14 (ri-form)
N IMM14s (ri-form)
O IMM15s (ri-form)
P IMM12s (rix-form) / IMM10s(cop-form) << 2 */
I imm16 << 16
J uimm5
K uimm16
L simm16
M uimm14
N simm14 */
int
score_const_ok_for_letter_p (int value, char c)
score_const_ok_for_letter_p (HOST_WIDE_INT value, char c)
{
switch (c)
{
case 'I': return IMM_IN_RANGE (value, 8, 0);
case 'I': return ((value & 0xffff) == 0);
case 'J': return IMM_IN_RANGE (value, 5, 0);
case 'K': return IMM_IN_RANGE (value, 16, 0);
case 'L': return IMM_IN_RANGE (value, 16, 1);
case 'M': return IMM_IN_RANGE (value, 14, 0);
case 'N': return IMM_IN_RANGE (value, 14, 1);
case 'O': return IMM_IN_RANGE (value, 15, 1);
case 'P': return IMM_IN_RANGE (value, 12, 1);
default : return 0;
}
}
/* Implement EXTRA_CONSTRAINT macro. */
/* Q const_hi imm
Z symbol_ref */
/* Z symbol_ref */
int
score_extra_constraint (rtx op, char c)
{
switch (c)
{
case 'Q':
return (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0);
case 'Z':
return GET_CODE (op) == SYMBOL_REF;
default:
@ -917,10 +916,8 @@ score_address_insns (rtx x, enum machine_mode mode)
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))
@ -938,24 +935,53 @@ score_address_insns (rtx x, enum machine_mode mode)
/* Implement TARGET_RTX_COSTS macro. */
static bool
score_rtx_costs (rtx x, int code, int outer_code, int *total)
score_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
int *total)
{
enum machine_mode mode = GET_MODE (x);
switch (code)
{
case CONST_INT:
/* These can be used anywhere. */
*total = 0;
if (outer_code == SET)
{
if (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
|| CONST_OK_FOR_LETTER_P (INTVAL (x), 'L'))
*total = COSTS_N_INSNS (1);
else
*total = COSTS_N_INSNS (2);
}
else if (outer_code == PLUS || outer_code == MINUS)
{
if (CONST_OK_FOR_LETTER_P (INTVAL (x), 'N'))
*total = 0;
else if (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
|| CONST_OK_FOR_LETTER_P (INTVAL (x), 'L'))
*total = 1;
else
*total = COSTS_N_INSNS (2);
}
else if (outer_code == AND || outer_code == IOR)
{
if (CONST_OK_FOR_LETTER_P (INTVAL (x), 'M'))
*total = 0;
else if (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
|| CONST_OK_FOR_LETTER_P (INTVAL (x), 'K'))
*total = 1;
else
*total = COSTS_N_INSNS (2);
}
else
{
*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);
*total = COSTS_N_INSNS (2);
return true;
case MEM:
@ -1011,7 +1037,8 @@ score_rtx_costs (rtx x, int code, int outer_code, int *total)
*total = COSTS_N_INSNS (4);
return true;
}
return false;
*total = COSTS_N_INSNS (1);
return true;
case NEG:
if (mode == DImode)
@ -1022,22 +1049,38 @@ score_rtx_costs (rtx x, int code, int outer_code, int *total)
return false;
case MULT:
*total = COSTS_N_INSNS (12);
*total = optimize_size ? COSTS_N_INSNS (2) : COSTS_N_INSNS (12);
return true;
case DIV:
case MOD:
case UDIV:
case UMOD:
*total = COSTS_N_INSNS (33);
*total = optimize_size ? COSTS_N_INSNS (2) : COSTS_N_INSNS (33);
return true;
case SIGN_EXTEND:
*total = COSTS_N_INSNS (2);
return true;
case ZERO_EXTEND:
*total = COSTS_N_INSNS (1);
switch (GET_MODE (XEXP (x, 0)))
{
case QImode:
case HImode:
if (GET_CODE (XEXP (x, 0)) == MEM)
{
*total = COSTS_N_INSNS (2);
if (!TARGET_LITTLE_ENDIAN &&
side_effects_p (XEXP (XEXP (x, 0), 0)))
*total = 100;
}
else
*total = COSTS_N_INSNS (1);
break;
default:
*total = COSTS_N_INSNS (1);
break;
}
return true;
default:
@ -1045,6 +1088,13 @@ score_rtx_costs (rtx x, int code, int outer_code, int *total)
}
}
/* Implement TARGET_ADDRESS_COST macro. */
int
score_address_cost (rtx addr)
{
return score_address_insns (addr, SImode);
}
/* Implement ASM_OUTPUT_EXTERNAL macro. */
int
score_output_external (FILE *file ATTRIBUTE_UNUSED,
@ -1089,18 +1139,16 @@ score_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
/* Implement PRINT_OPERAND macro. */
/* Score-specific operand codes:
'[' print .set nor1 directive
']' print .set r1 directive
']' print .set r1 directive
'U' print hi part of a CONST_INT rtx
'D' print first part of const double
'S' selectively print '!' if operand is 15bit instruction accessible
'V' print "v!" if operand is 15bit instruction accessible, or
"lfh!"
'E' print log2(v)
'F' print log2(~v)
'D' print SFmode const double
'S' selectively print "!" if operand is 15bit instruction accessible
'V' print "v!" if operand is 15bit instruction accessible, or "lfh!"
'L' low part of DImode reg operand
'H' high part of DImode reg operand
'C' print part of opcode for a branch condition. */
'C' print part of opcode for a branch condition. */
void
score_print_operand (FILE *file, rtx op, int c)
{
@ -1125,9 +1173,11 @@ score_print_operand (FILE *file, rtx op, int c)
else if (c == 'D')
{
if (GET_CODE (op) == CONST_DOUBLE)
fprintf (file, HOST_WIDE_INT_PRINT_HEX,
TARGET_LITTLE_ENDIAN
? CONST_DOUBLE_LOW (op) : CONST_DOUBLE_HIGH (op));
{
rtx temp = gen_lowpart (SImode, op);
gcc_assert (GET_MODE (op) == SFmode);
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (temp));
}
else
output_addr_const (file, op);
}
@ -1142,23 +1192,17 @@ score_print_operand (FILE *file, rtx op, int c)
gcc_assert (code == REG);
fprintf (file, G16_REG_P (REGNO (op)) ? "v!" : "lfh!");
}
else if (code == REG)
{
int regnum = REGNO (op);
if ((c == 'H' && !WORDS_BIG_ENDIAN)
|| (c == 'L' && WORDS_BIG_ENDIAN))
regnum ++;
fprintf (file, "%s", reg_names[regnum]);
}
else if (c == 'C')
{
enum machine_mode mode = GET_MODE (XEXP (op, 0));
switch (code)
{
case EQ: fputs ("eq", file); break;
case NE: fputs ("ne", file); break;
case GT: fputs ("gt", file); break;
case GE: fputs ("ge", file); break;
case LT: fputs ("lt", file); break;
case GE: fputs (mode != CCmode ? "pl" : "ge", file); break;
case LT: fputs (mode != CCmode ? "mi" : "lt", file); break;
case LE: fputs ("le", file); break;
case GTU: fputs ("gtu", file); break;
case GEU: fputs ("cs", file); break;
@ -1168,6 +1212,46 @@ score_print_operand (FILE *file, rtx op, int c)
output_operand_lossage ("invalid operand for code: '%c'", code);
}
}
else if (c == 'E')
{
unsigned HOST_WIDE_INT i;
unsigned HOST_WIDE_INT pow2mask = 1;
unsigned HOST_WIDE_INT val;
val = INTVAL (op);
for (i = 0; i < 32; i++)
{
if (val == pow2mask)
break;
pow2mask <<= 1;
}
gcc_assert (i < 32);
fprintf (file, HOST_WIDE_INT_PRINT_HEX, i);
}
else if (c == 'F')
{
unsigned HOST_WIDE_INT i;
unsigned HOST_WIDE_INT pow2mask = 1;
unsigned HOST_WIDE_INT val;
val = ~INTVAL (op);
for (i = 0; i < 32; i++)
{
if (val == pow2mask)
break;
pow2mask <<= 1;
}
gcc_assert (i < 32);
fprintf (file, HOST_WIDE_INT_PRINT_HEX, i);
}
else if (code == REG)
{
int regnum = REGNO (op);
if ((c == 'H' && !WORDS_BIG_ENDIAN)
|| (c == 'L' && WORDS_BIG_ENDIAN))
regnum ++;
fprintf (file, "%s", reg_names[regnum]);
}
else
{
switch (code)
@ -1233,4 +1317,48 @@ score_print_operand_address (FILE *file, rtx x)
gcc_unreachable ();
}
/* Implement SELECT_CC_MODE macro. */
enum machine_mode
score_select_cc_mode (enum rtx_code op, rtx x, rtx y)
{
if ((op == EQ || op == NE || op == LT || op == GE)
&& y == const0_rtx
&& GET_MODE (x) == SImode)
{
switch (GET_CODE (x))
{
case PLUS:
case MINUS:
case NEG:
case AND:
case IOR:
case XOR:
case NOT:
case ASHIFT:
case LSHIFTRT:
case ASHIFTRT:
return CC_NZmode;
case SIGN_EXTEND:
case ZERO_EXTEND:
case ROTATE:
case ROTATERT:
return (op == LT || op == GE) ? CC_Nmode : CCmode;
default:
return CCmode;
}
}
if ((op == EQ || op == NE)
&& (GET_CODE (y) == NEG)
&& register_operand (XEXP (y, 0), SImode)
&& register_operand (x, SImode))
{
return CC_NZmode;
}
return CCmode;
}
struct gcc_target targetm = TARGET_INITIALIZER;

View File

@ -28,19 +28,20 @@ extern GTY(()) rtx cmp_op0;
extern GTY(()) rtx cmp_op1;
/* Controlling the Compilation Driver. */
#undef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) \
(DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
/* CC1_SPEC is the set of arguments to pass to the compiler proper. */
#undef CC1_SPEC
#define CC1_SPEC "%{!mel:-meb}"
#define CC1_SPEC "%{G*} %{!mel:-meb}"
#undef ASM_SPEC
#define ASM_SPEC \
"%{!mel:-EB} %{mel:-EL} %{mscore5u:-SCORE5U} %{mscore7:-SCORE7} %{G*}"
#undef LINK_SPEC
#define LINK_SPEC "%{!mel:-EB} %{mel:-EL} %{G*}"
#define LINK_SPEC "%{!mel:-EB} %{mel:-EL} %{G*}"
/* Run-time Target Specification. */
#define TARGET_CPU_CPP_BUILTINS() \
@ -96,7 +97,7 @@ extern GTY(()) rtx cmp_op1;
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
#define PARM_BOUNDARY BITS_PER_WORD
#define STACK_BOUNDARY 64
#define STACK_BOUNDARY BITS_PER_WORD
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY BITS_PER_WORD
@ -115,12 +116,41 @@ extern GTY(()) rtx cmp_op1;
data to make it all fit in fewer cache lines. Another is to
cause character arrays to be word-aligned so that `strcpy' calls
that copy constants to character arrays can be done inline. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
((((ALIGN) < BITS_PER_WORD) \
&& (TREE_CODE (TYPE) == ARRAY_TYPE \
|| TREE_CODE (TYPE) == UNION_TYPE \
#define DATA_ALIGNMENT(TYPE, ALIGN) \
((((ALIGN) < BITS_PER_WORD) \
&& (TREE_CODE (TYPE) == ARRAY_TYPE \
|| TREE_CODE (TYPE) == UNION_TYPE \
|| TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
/* If defined, a C expression to compute the alignment given to a
constant that is being placed in memory. EXP is the constant
and ALIGN is the alignment that the object would ordinarily have.
The value of this macro is used instead of that alignment to align
the object.
If this macro is not defined, then ALIGN is used.
The typical use of this macro is to increase alignment for string
constants to be word aligned so that `strcpy' calls that copy
constants can be done inline. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* If defined, a C expression to compute the alignment for a local
variable. TYPE is the data type, and ALIGN is the alignment that
the object would ordinarily have. The value of this macro is used
instead of that alignment to align the object.
If this macro is not defined, then ALIGN is used.
One use of this macro is to increase alignment of medium-size
data to make it all fit in fewer cache lines. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
((TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))
/* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 32
@ -209,7 +239,7 @@ extern GTY(()) rtx cmp_op1;
{ \
/* General Purpose Registers */ \
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, \
/* Control Registers */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
/* CEH/ CEL/ CNT/ LCR/ SCR / ARG_POINTER_REGNUM/ FRAME_POINTER_REGNUM */\
@ -245,8 +275,8 @@ extern GTY(()) rtx cmp_op1;
}
#define REG_ALLOC_ORDER \
{ 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, \
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 2, 3, \
{ 0, 1, 6, 7, 8, 9, 10, 11, 4, 5, 22, 23, 24, 25, 26, 27, \
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 28, 29, 30, 31, 2, 3, \
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, \
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, \
@ -386,18 +416,18 @@ enum reg_class
score_preferred_reload_class (X, CLASS)
/* If we need to load shorts byte-at-a-time, then we need a scratch. */
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
score_secondary_reload_class (CLASS, MODE, X)
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
NO_REGS is returned. */
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
score_secondary_reload_class (CLASS, MODE, X)
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
@ -607,8 +637,8 @@ typedef struct score_args
#define HAVE_PRE_DECREMENT 1
#define HAVE_POST_INCREMENT 1
#define HAVE_POST_DECREMENT 1
#define HAVE_PRE_MODIFY_DISP 0
#define HAVE_POST_MODIFY_DISP 0
#define HAVE_PRE_MODIFY_DISP 1
#define HAVE_POST_MODIFY_DISP 1
#define HAVE_PRE_MODIFY_REG 0
#define HAVE_POST_MODIFY_REG 0
@ -660,6 +690,13 @@ typedef struct score_args
#define LEGITIMATE_CONSTANT_P(X) 1
/* Condition Code Status. */
#define SELECT_CC_MODE(OP, X, Y) score_select_cc_mode (OP, X, Y)
/* Return nonzero if SELECT_CC_MODE will never return MODE for a
floating point inequality comparison. */
#define REVERSIBLE_CC_MODE(MODE) 1
/* Describing Relative Costs of Operations */
/* Compute extra cost of moving data between one register class and another. */
#define REGISTER_MOVE_COST(MODE, FROM, TO) \
@ -753,32 +790,32 @@ typedef struct score_args
sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long) (NUM))
/* Output of Assembler Instructions. */
#define REGISTER_NAMES \
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
\
"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
"cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15", \
\
"ceh", "cel", "sr0", "sr1", "sr2", "_arg", "_frame", "", \
"cr24", "cr25", "cr26", "cr27", "cr28", "cr29", "cr30", "cr31", \
\
"c1r0", "c1r1", "c1r2", "c1r3", "c1r4", "c1r5", "c1r6", "c1r7", \
"c1r8", "c1r9", "c1r10", "c1r11", "c1r12", "c1r13", "c1r14", "c1r15", \
"c1r16", "c1r17", "c1r18", "c1r19", "c1r20", "c1r21", "c1r22", "c1r23",\
"c1r24", "c1r25", "c1r26", "c1r27", "c1r28", "c1r29", "c1r30", "c1r31",\
\
"c2r0", "c2r1", "c2r2", "c2r3", "c2r4", "c2r5", "c2r6", "c2r7", \
"c2r8", "c2r9", "c2r10", "c2r11", "c2r12", "c2r13", "c2r14", "c2r15", \
"c2r16", "c2r17", "c2r18", "c2r19", "c2r20", "c2r21", "c2r22", "c2r23",\
"c2r24", "c2r25", "c2r26", "c2r27", "c2r28", "c2r29", "c2r30", "c2r31",\
\
"c3r0", "c3r1", "c3r2", "c3r3", "c3r4", "c3r5", "c3r6", "c3r7", \
"c3r8", "c3r9", "c3r10", "c3r11", "c3r12", "c3r13", "c3r14", "c3r15", \
"c3r16", "c3r17", "c3r18", "c3r19", "c3r20", "c3r21", "c3r22", "c3r23",\
"c3r24", "c3r25", "c3r26", "c3r27", "c3r28", "c3r29", "c3r30", "c3r31",\
#define REGISTER_NAMES \
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
\
"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
"cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15", \
\
"ceh", "cel", "sr0", "sr1", "sr2", "_arg", "_frame", "", \
"cr24", "cr25", "cr26", "cr27", "cr28", "cr29", "cr30", "cr31", \
\
"c1r0", "c1r1", "c1r2", "c1r3", "c1r4", "c1r5", "c1r6", "c1r7", \
"c1r8", "c1r9", "c1r10", "c1r11", "c1r12", "c1r13", "c1r14", "c1r15", \
"c1r16", "c1r17", "c1r18", "c1r19", "c1r20", "c1r21", "c1r22", "c1r23", \
"c1r24", "c1r25", "c1r26", "c1r27", "c1r28", "c1r29", "c1r30", "c1r31", \
\
"c2r0", "c2r1", "c2r2", "c2r3", "c2r4", "c2r5", "c2r6", "c2r7", \
"c2r8", "c2r9", "c2r10", "c2r11", "c2r12", "c2r13", "c2r14", "c2r15", \
"c2r16", "c2r17", "c2r18", "c2r19", "c2r20", "c2r21", "c2r22", "c2r23", \
"c2r24", "c2r25", "c2r26", "c2r27", "c2r28", "c2r29", "c2r30", "c2r31", \
\
"c3r0", "c3r1", "c3r2", "c3r3", "c3r4", "c3r5", "c3r6", "c3r7", \
"c3r8", "c3r9", "c3r10", "c3r11", "c3r12", "c3r13", "c3r14", "c3r15", \
"c3r16", "c3r17", "c3r18", "c3r19", "c3r20", "c3r21", "c3r22", "c3r23", \
"c3r24", "c3r25", "c3r26", "c3r27", "c3r28", "c3r29", "c3r30", "c3r31", \
}
/* Print operand X (an rtx) in assembler syntax to file FILE. */
@ -907,4 +944,4 @@ struct extern_list GTY ((chain_next ("%h.next")))
int size; /* size in bytes */
};
extern GTY (()) struct extern_list *extern_head ;
extern GTY (()) struct extern_list *extern_head;

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
# without the $gp register.
TARGET_LIBGCC2_CFLAGS = -G 0
MULTILIB_OPTIONS = fPIC mel mscore7
MULTILIB_OPTIONS = mmac mel fPIC
MULTILIB_MATCHES = fPIC=fpic
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
@ -43,4 +43,3 @@ EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib