From: Chen Liqin Date: Mon, 8 Jan 2007 04:47:33 +0000 (+0000) Subject: t-score-elf (MULTILIB_OPTIONS): Change. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=99fc25020d47424e0c0b0da370e2e18540b96b73;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cc59fa08486..8e36d9189b2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2007-01-08 Chen Liqin + * 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 * config/arm/arm.c, config/arm/arm.h, config/arm/arm.md, diff --git a/gcc/config/score/crti.asm b/gcc/config/score/crti.asm index 2408596b213..8c6bca0e0cd 100644 --- a/gcc/config/score/crti.asm +++ b/gcc/config/score/crti.asm @@ -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 diff --git a/gcc/config/score/crtn.asm b/gcc/config/score/crtn.asm index 5048a99e435..add988ed5f7 100644 --- a/gcc/config/score/crtn.asm +++ b/gcc/config/score/crtn.asm @@ -59,4 +59,3 @@ br r3 #endif - diff --git a/gcc/config/score/misc.md b/gcc/config/score/misc.md index d19c53538a6..a4f817040f1 100644 --- a/gcc/config/score/misc.md +++ b/gcc/config/score/misc.md @@ -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")]) diff --git a/gcc/config/score/mul-div.S b/gcc/config/score/mul-div.S index 4dabe96f974..138f628d70a 100644 --- a/gcc/config/score/mul-div.S +++ b/gcc/config/score/mul-div.S @@ -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 diff --git a/gcc/config/score/predicates.md b/gcc/config/score/predicates.md index f1633ec4b2e..eefb4971200 100644 --- a/gcc/config/score/predicates.md +++ b/gcc/config/score/predicates.md @@ -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); +}) diff --git a/gcc/config/score/score-conv.h b/gcc/config/score/score-conv.h index 72730d89b83..796255e2533 100644 --- a/gcc/config/score/score-conv.h +++ b/gcc/config/score/score-conv.h @@ -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) diff --git a/gcc/config/score/score-mdaux.c b/gcc/config/score/score-mdaux.c index 09db134ae67..e8d1478ed19 100644 --- a/gcc/config/score/score-mdaux.c +++ b/gcc/config/score/score-mdaux.c @@ -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) { + HOST_WIDE_INT v; + gcc_assert (GET_CODE (ops[0]) == REG); + gcc_assert (GET_CODE (ops[1]) == CONST_INT); - if (G16_REG_P (REGNO (ops[0])) - && CONST_OK_FOR_LETTER_P (INTVAL (ops[1]), 'I')) + 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) +{ + rtx dst = ops[0]; + rtx src = ops[1]; + rtx len = ops[2]; + rtx off = 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 (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; +} + +/* Emit scb/sce insns. */ +bool +mdx_unaligned_store (rtx *ops) { - int i, n = 0; + 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; - for (i = 0; i < BITS_PER_WORD; i++) - n += BITSET_P (v, i) ? 1 : 0; - return n; + 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; } -/* Generate add insn, insn will affect condition flag. Optimize used. */ +/* 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; } diff --git a/gcc/config/score/score-mdaux.h b/gcc/config/score/score-mdaux.h index 965174996b0..ad6d1be014c 100644 --- a/gcc/config/score/score-mdaux.h +++ b/gcc/config/score/score-mdaux.h @@ -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 diff --git a/gcc/config/score/score-modes.def b/gcc/config/score/score-modes.def index 2f076f5b8e6..6cc50cf5eaf 100644 --- a/gcc/config/score/score-modes.def +++ b/gcc/config/score/score-modes.def @@ -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); diff --git a/gcc/config/score/score-protos.h b/gcc/config/score/score-protos.h index bbe444e91d1..c261749d072 100644 --- a/gcc/config/score/score-protos.h +++ b/gcc/config/score/score-protos.h @@ -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); diff --git a/gcc/config/score/score-version.h b/gcc/config/score/score-version.h index 2eeaf2f0d99..b5e85f48494 100644 --- a/gcc/config/score/score-version.h +++ b/gcc/config/score/score-version.h @@ -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" diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c index 7100103a42a..34352a67e4d 100644 --- a/gcc/config/score/score.c +++ b/gcc/config/score/score.c @@ -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; diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h index 2726a04cd51..3ee53cfcb87 100644 --- a/gcc/config/score/score.h +++ b/gcc/config/score/score.h @@ -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; diff --git a/gcc/config/score/score.md b/gcc/config/score/score.md index 856ea1065bd..63934692638 100644 --- a/gcc/config/score/score.md +++ b/gcc/config/score/score.md @@ -59,8 +59,8 @@ (define_constants [(BITTST 0) - (LOAD_ADD 1) - (STORE_ADD 2) + (CPLOAD 1) + (CPRESTORE 2) (SCB 3) (SCW 4) @@ -88,10 +88,22 @@ (include "misc.md") (include "mac.md") -(define_insn "movqi" +(define_expand "movqi" + [(set (match_operand:QI 0 "nonimmediate_operand") + (match_operand:QI 1 "general_operand"))] + "" +{ + if (MEM_P (operands[0]) + && !register_operand (operands[1], QImode)) + { + operands[1] = force_reg (QImode, operands[1]); + } +}) + +(define_insn "*movqi_insns" [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,d,*x,d,*a") (match_operand:QI 1 "general_operand" "i,d,m,d,*x,d,*a,d"))] - "" + "!MEM_P (operands[0]) || register_operand (operands[1], QImode)" { switch (which_alternative) { @@ -109,10 +121,22 @@ [(set_attr "type" "arith,move,load,store,fce,tce,fsr,tsr") (set_attr "mode" "QI")]) -(define_insn "movhi" +(define_expand "movhi" + [(set (match_operand:HI 0 "nonimmediate_operand") + (match_operand:HI 1 "general_operand"))] + "" +{ + if (MEM_P (operands[0]) + && !register_operand (operands[1], HImode)) + { + operands[1] = force_reg (HImode, operands[1]); + } +}) + +(define_insn "*movhi_insns" [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,d,*x,d,*a") (match_operand:HI 1 "general_operand" "i,d,m,d,*x,d,*a,d"))] - "" + "!MEM_P (operands[0]) || register_operand (operands[1], HImode)" { switch (which_alternative) { @@ -130,10 +154,22 @@ [(set_attr "type" "arith,move,load,store,fce,tce,fsr,tsr") (set_attr "mode" "HI")]) -(define_insn "movsi" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,m,d,*x,d,*a,d,c") - (match_operand:SI 1 "general_operand" "i,d,m,d,*x,d,*a,d,c,d"))] +(define_expand "movsi" + [(set (match_operand:SI 0 "nonimmediate_operand") + (match_operand:SI 1 "general_operand"))] "" +{ + if (MEM_P (operands[0]) + && !register_operand (operands[1], SImode)) + { + operands[1] = force_reg (SImode, operands[1]); + } +}) + +(define_insn "*movsi_insns" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,m,d,*x,d,*a,d,*c") + (match_operand:SI 1 "general_operand" "i,d,m,d,*x,d,*a,d,*c,d"))] + "!MEM_P (operands[0]) || register_operand (operands[1], SImode)" { switch (which_alternative) { @@ -169,46 +205,103 @@ DONE; }) +(define_expand "movsf" + [(set (match_operand:SF 0 "nonimmediate_operand") + (match_operand:SF 1 "general_operand"))] + "" +{ + if (MEM_P (operands[0]) + && !register_operand (operands[1], SFmode)) + { + operands[1] = force_reg (SFmode, operands[1]); + } +}) + +(define_insn "*movsf_insns" + [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,m") + (match_operand:SF 1 "general_operand" "i,d,m,d"))] + "!MEM_P (operands[0]) || register_operand (operands[1], SFmode)" +{ + switch (which_alternative) + { + case 0: return \"li %0, %D1\";; + case 1: return mdp_move (operands); + case 2: return mdp_linsn (operands, MDA_WORD, false); + case 3: return mdp_sinsn (operands, MDA_WORD); + default: gcc_unreachable (); + } +} + [(set_attr "type" "arith,move,load,store") + (set_attr "mode" "SI")]) + +(define_insn_and_split "movdf" + [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,m") + (match_operand:DF 1 "general_operand" "i,d,m,d"))] + "" + "#" + "reload_completed" + [(const_int 0)] +{ + mds_movdi (operands); + DONE; +}) + (define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (plus:SI (match_operand:SI 1 "register_operand" "0,d,%d") - (match_operand:SI 2 "arith_operand" "L,N,d")))] + [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") + (plus:SI (match_operand:SI 1 "register_operand" "0,0,d,d") + (match_operand:SI 2 "arith_operand" "I,L,N,d")))] "" - "@ - addi %0, %c2 - addri %0, %1, %c2 - add %0, %1, %2" +{ + switch (which_alternative) + { + case 0: return \"addis %0, %U2\"; + case 1: return mdp_select_add_imm (operands, false); + case 2: return \"addri %0, %1, %c2\"; + case 3: return mdp_select (operands, "add", true, "", false); + default: gcc_unreachable (); + } +} [(set_attr "type" "arith") (set_attr "mode" "SI")]) (define_insn "*addsi3_cmp" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (plus:SI (match_operand:SI 0 "register_operand" "d,d,d") - (match_operand:SI 1 "arith_operand" "N,L,d")) - (const_int 0)))] + (compare:CC_NZ (plus:SI + (match_operand:SI 1 "register_operand" "0,0,d,d") + (match_operand:SI 2 "arith_operand" "I,L,N,d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d,d,d,d"))] "" - "@ - %[ addri.c r1, %0, %c1 %] - %[ m%V0 r1, %0\;addi.c r1, %2 %] - %[ add.c r1, %0, %1 %]" +{ + switch (which_alternative) + { + case 0: return \"addis.c %0, %U2\"; + case 1: return mdp_select_add_imm (operands, true); + case 2: return \"addri.c %0, %1, %c2\"; + case 3: return mdp_select (operands, "add", true, "", true); + default: gcc_unreachable (); + } +} [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) -(define_insn "addsi3_ucc" +(define_insn "*addsi3_ucc" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (plus:SI (match_operand:SI 1 "register_operand" "0,d,d") - (match_operand:SI 2 "arith_operand" "L,N,d")) + (compare:CC_NZ (plus:SI + (match_operand:SI 1 "register_operand" "0,0,d,d") + (match_operand:SI 2 "arith_operand" "I,L,N,d")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (plus:SI (match_dup 1) (match_dup 2)))] "" { switch (which_alternative) { - case 0: return mdp_add_imm_ucc (operands); - case 1: return \"addri.c %0, %1, %c2\"; - case 2: return mdp_select (operands, "add", true, ""); + case 0: return \"addis.c %0, %U2\"; + case 1: return mdp_select_add_imm (operands, true); + case 2: return \"addri.c %0, %1, %c2\"; + case 3: return mdp_select (operands, "add", true, "", true); default: gcc_unreachable (); } } @@ -217,9 +310,9 @@ (set_attr "mode" "SI")]) (define_insn "adddi3" - [(set (match_operand:DI 0 "register_operand" "=*e,d") - (plus:DI (match_operand:DI 1 "register_operand" "*0,d") - (match_operand:DI 2 "register_operand" "*e,d"))) + [(set (match_operand:DI 0 "register_operand" "=e,d") + (plus:DI (match_operand:DI 1 "register_operand" "0,d") + (match_operand:DI 2 "register_operand" "e,d"))) (clobber (reg:CC CC_REGNUM))] "" "@ @@ -233,17 +326,22 @@ (minus:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d")))] "" - "sub %0, %1, %2" +{ + return mdp_select (operands, "sub", false, "", false); +} [(set_attr "type" "arith") (set_attr "mode" "SI")]) (define_insn "*subsi3_cmp" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (minus:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "register_operand" "d")) - (const_int 0)))] + (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d"))] "" - "%[ sub.c r1, %0, %1 %]" +{ + return mdp_select (operands, "sub", false, "", true); +} [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) @@ -255,11 +353,10 @@ (set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (match_dup 2)))] "" - [(parallel - [(set (reg:CC CC_REGNUM) - (compare:CC (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (minus:SI (match_dup 1) (match_dup 2)))])]) + [(set (reg:CC CC_REGNUM) + (compare:CC (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (minus:SI (match_dup 1) (match_dup 2)))]) (define_insn "subsi3_ucc_pcmp" [(parallel @@ -270,7 +367,7 @@ (minus:SI (match_dup 1) (match_dup 2)))])] "" { - return mdp_select (operands, "sub", false, ""); + return mdp_select (operands, "sub", false, "", true); } [(set_attr "type" "arith") (set_attr "up_c" "yes") @@ -285,16 +382,16 @@ (minus:SI (match_dup 1) (match_dup 2)))] "" { - return mdp_select (operands, "sub", false, ""); + return mdp_select (operands, "sub", false, "", true); } [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) (define_insn "subdi3" - [(set (match_operand:DI 0 "register_operand" "=*e,d") - (minus:DI (match_operand:DI 1 "register_operand" "*0,d") - (match_operand:DI 2 "register_operand" "*e,d"))) + [(set (match_operand:DI 0 "register_operand" "=e,d") + (minus:DI (match_operand:DI 1 "register_operand" "0,d") + (match_operand:DI 2 "register_operand" "e,d"))) (clobber (reg:CC CC_REGNUM))] "" "@ @@ -306,36 +403,47 @@ (define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") (and:SI (match_operand:SI 1 "register_operand" "0,0,d,d") - (match_operand:SI 2 "arith_operand" "K,Q,M,d")))] + (match_operand:SI 2 "arith_operand" "I,K,M,d")))] "" - "@ - andi %0, %c2 - andis %0, %U2 - andri %0, %1, %c2 - and %0, %1, %2" +{ + switch (which_alternative) + { + case 0: return \"andis %0, %U2\"; + case 1: return \"andi %0, %c2"; + case 2: return \"andri %0, %1, %c2\"; + case 3: return mdp_select (operands, "and", true, "", false); + default: gcc_unreachable (); + } +} [(set_attr "type" "arith") (set_attr "mode" "SI")]) (define_insn "andsi3_cmp" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (and:SI (match_operand:SI 0 "register_operand" "d,d,d,d") - (match_operand:SI 1 "arith_operand" "M,K,Q,d")) - (const_int 0)))] + (compare:CC_NZ (and:SI (match_operand:SI 1 "register_operand" "0,0,0,d") + (match_operand:SI 2 "arith_operand" "I,K,M,d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d,d,d,d"))] "" - "@ - %[ andri.c r1, %0, %c1 %] - %[ m%V0 r1, %0\;andi.c r1, %c1 %] - %[ m%V0 r1, %0\;andis.c r1, %U1 %] - %[ and.c r1, %0, %1 %]" +{ + switch (which_alternative) + { + case 0: return \"andis.c %0, %U2\"; + case 1: return \"andi.c %0, %c2"; + case 2: return \"andri.c %0, %1, %c2\"; + case 3: return mdp_select (operands, "and", true, "", true); + default: gcc_unreachable (); + } +} [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) -(define_insn "andsi3_ucc" +(define_insn "*andsi3_ucc" [(set (reg:CC_NZ CC_REGNUM) (compare:CC_NZ (and:SI (match_operand:SI 1 "register_operand" "0,0,d,d") - (match_operand:SI 2 "arith_operand" "K,Q,M,d")) + (match_operand:SI 2 "arith_operand" "I,K,M,d")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (and:SI (match_dup 1) (match_dup 2)))] @@ -343,10 +451,10 @@ { switch (which_alternative) { - case 0: return \"andi.c %0, %c2\"; - case 1: return \"andis.c %0, %U2\"; - case 2: return \"andri.c %0, %1, %c2\"; - case 3: return mdp_select (operands, "and", true, ""); + case 0: return \"andis.c %0, %U2\"; + case 1: return \"andi.c %0, %c2"; + case 2: return \"andri.c %0, %1, %c2\"; + case 3: return mdp_select (operands, "and", true, "", true); default: gcc_unreachable (); } } @@ -355,12 +463,12 @@ (set_attr "mode" "SI")]) (define_insn_and_split "*zero_extract_andi" - [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (zero_extract:SI - (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "const_bi_operand" "") - (match_operand:SI 2 "const_bi_operand" "")) - (const_int 0)))] + [(set (reg:CC CC_REGNUM) + (compare:CC (zero_extract:SI + (match_operand:SI 0 "register_operand" "d") + (match_operand:SI 1 "const_uimm5" "") + (match_operand:SI 2 "const_uimm5" "")) + (const_int 0)))] "" "#" "" @@ -373,26 +481,39 @@ (define_insn "iorsi3" [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") (ior:SI (match_operand:SI 1 "register_operand" "0,0,d,d") - (match_operand:SI 2 "arith_operand" "K,Q,M,d")))] + (match_operand:SI 2 "arith_operand" "I,K,M,d")))] "" - "@ - ori %0, %c2 - oris %0, %U2 - orri %0, %1, %c2 - or %0, %1, %2" +{ + switch (which_alternative) + { + case 0: return \"oris %0, %U2\"; + case 1: return \"ori %0, %c2\"; + case 2: return \"orri %0, %1, %c2\"; + case 3: return mdp_select (operands, "or", true, "", false); + default: gcc_unreachable (); + } +} [(set_attr "type" "arith") (set_attr "mode" "SI")]) (define_insn "iorsi3_ucc" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (ior:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "register_operand" "d")) + (compare:CC_NZ (ior:SI + (match_operand:SI 1 "register_operand" "0,0,d,d") + (match_operand:SI 2 "arith_operand" "I,K,M,d")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (ior:SI (match_dup 1) (match_dup 2)))] "" { - return mdp_select (operands, "or", true, ""); + switch (which_alternative) + { + case 0: return \"oris.c %0, %U2\"; + case 1: return \"ori.c %0, %c2\"; + case 2: return \"orri.c %0, %1, %c2\"; + case 3: return mdp_select (operands, "or", true, "", true); + default: gcc_unreachable (); + } } [(set_attr "type" "arith") (set_attr "up_c" "yes") @@ -400,11 +521,22 @@ (define_insn "iorsi3_cmp" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (ior:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "register_operand" "d")) - (const_int 0)))] + (compare:CC_NZ (ior:SI + (match_operand:SI 1 "register_operand" "0,0,d,d") + (match_operand:SI 2 "arith_operand" "I,K,M,d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d,d,d,d"))] "" - "%[ or.c r1, %0, %1 %]" +{ + switch (which_alternative) + { + case 0: return \"oris.c %0, %U2\"; + case 1: return \"ori.c %0, %c2\"; + case 2: return \"orri.c %0, %1, %c2\"; + case 3: return mdp_select (operands, "or", true, "", true); + default: gcc_unreachable (); + } +} [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) @@ -414,7 +546,9 @@ (xor:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d")))] "" - "xor %0, %1, %2" +{ + return mdp_select (operands, "xor", true, "", false); +} [(set_attr "type" "arith") (set_attr "mode" "SI")]) @@ -427,7 +561,7 @@ (xor:SI (match_dup 1) (match_dup 2)))] "" { - return mdp_select (operands, "xor", true, ""); + return mdp_select (operands, "xor", true, "", true); } [(set_attr "type" "arith") (set_attr "up_c" "yes") @@ -435,11 +569,14 @@ (define_insn "xorsi3_cmp" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (xor:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "register_operand" "d")) - (const_int 0)))] + (compare:CC_NZ (xor:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d"))] "" - "%[ xor.c r1, %0, %1 %]" +{ + return mdp_select (operands, "xor", true, "", true); +} [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) @@ -459,49 +596,35 @@ [(set_attr "type" "arith,load") (set_attr "mode" "SI")]) -(define_insn "extendqisi2_cmp" +(define_insn "*extendqisi2_ucc" [(set (reg:CC_N CC_REGNUM) (compare:CC_N (ashiftrt:SI - (ashift:SI (match_operand:SI 0 "register_operand" "d") + (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 24)) (const_int 24)) - (const_int 0)))] + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=d") + (sign_extend:SI (match_operand:QI 2 "register_operand" "0")))] "" - "%[ extsb.c r1, %0 %]" + "extsb.c %0, %1" [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) -(define_insn "extendqisi2_ucc" +(define_insn "*extendqisi2_cmp" [(set (reg:CC_N CC_REGNUM) (compare:CC_N (ashiftrt:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 24)) (const_int 24)) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d") - (sign_extend:SI (match_operand:QI 2 "register_operand" "0")))] + (clobber (match_scratch:SI 0 "=d"))] "" "extsb.c %0, %1" [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand""=d,d") - (zero_extend:SI (match_operand:QI 1 "register_operand" "d,m")))] - "" -{ - switch (which_alternative) - { - case 0: return \"extzb %0, %1\"; - case 1: return mdp_linsn (operands, MDA_BYTE, false); - default: gcc_unreachable (); - } -} - [(set_attr "type" "arith, load") - (set_attr "mode" "SI")]) - (define_insn "extendhisi2" [(set (match_operand:SI 0 "register_operand" "=d,d") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] @@ -517,34 +640,79 @@ [(set_attr "type" "arith, load") (set_attr "mode" "SI")]) -(define_insn "extendhisi2_cmp" +(define_insn "*extendhisi2_ucc" [(set (reg:CC_N CC_REGNUM) (compare:CC_N (ashiftrt:SI - (ashift:SI (match_operand:SI 0 "register_operand" "d") + (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 16)) (const_int 16)) - (const_int 0)))] + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=d") + (sign_extend:SI (match_operand:HI 2 "register_operand" "0")))] "" - "%[ extsh.c r1, %0 %]" + "extsh.c %0, %1" [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) -(define_insn "extendhisi2_ucc" +(define_insn "*extendhisi2_cmp" [(set (reg:CC_N CC_REGNUM) (compare:CC_N (ashiftrt:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 16)) (const_int 16)) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d") - (sign_extend:SI (match_operand:HI 2 "register_operand" "0")))] + (clobber (match_scratch:SI 0 "=d"))] "" "extsh.c %0, %1" [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) +(define_insn "zero_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] + "" +{ + switch (which_alternative) + { + case 0: return \"extzb %0, %1\"; + case 1: return mdp_linsn (operands, MDA_BYTE, false); + default: gcc_unreachable (); + } + } + [(set_attr "type" "arith, load") + (set_attr "mode" "SI")]) + +(define_insn "*zero_extendqisi2_ucc" + [(set (reg:CC_N CC_REGNUM) + (compare:CC_N (lshiftrt:SI + (ashift:SI (match_operand:SI 1 "register_operand" "d") + (const_int 24)) + (const_int 24)) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:QI 2 "register_operand" "0")))] + "" + "extzb.c %0, %1" + [(set_attr "type" "arith") + (set_attr "up_c" "yes") + (set_attr "mode" "SI")]) + +(define_insn "*zero_extendqisi2_cmp" + [(set (reg:CC_N CC_REGNUM) + (compare:CC_N (lshiftrt:SI + (ashift:SI (match_operand:SI 1 "register_operand" "d") + (const_int 24)) + (const_int 24)) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d"))] + "" + "extzb.c %0, %1" + [(set_attr "type" "arith") + (set_attr "up_c" "yes") + (set_attr "mode" "SI")]) + (define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "=d,d") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] @@ -560,6 +728,35 @@ [(set_attr "type" "arith, load") (set_attr "mode" "SI")]) +(define_insn "*zero_extendhisi2_ucc" + [(set (reg:CC_N CC_REGNUM) + (compare:CC_N (lshiftrt:SI + (ashift:SI (match_operand:SI 1 "register_operand" "d") + (const_int 16)) + (const_int 16)) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:HI 2 "register_operand" "0")))] + "" + "extzh.c %0, %1" + [(set_attr "type" "arith") + (set_attr "up_c" "yes") + (set_attr "mode" "SI")]) + +(define_insn "*zero_extendhisi2_cmp" + [(set (reg:CC_N CC_REGNUM) + (compare:CC_N (lshiftrt:SI + (ashift:SI (match_operand:SI 1 "register_operand" "d") + (const_int 16)) + (const_int 16)) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d"))] + "" + "extzh.c %0, %1" + [(set_attr "type" "arith") + (set_attr "up_c" "yes") + (set_attr "mode" "SI")]) + (define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=l") (mult:SI (match_operand:SI 1 "register_operand" "d") @@ -572,7 +769,8 @@ (define_insn "mulsidi3" [(set (match_operand:DI 0 "register_operand" "=x") - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (mult:DI (sign_extend:DI + (match_operand:SI 1 "register_operand" "d")) (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))] "!TARGET_SCORE5U" @@ -582,7 +780,8 @@ (define_insn "umulsidi3" [(set (match_operand:DI 0 "register_operand" "=x") - (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) + (mult:DI (zero_extend:DI + (match_operand:SI 1 "register_operand" "d")) (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))] "!TARGET_SCORE5U" @@ -635,8 +834,8 @@ { switch (which_alternative) { - case 0: return mdp_select (operands, "slli", false, "c"); - case 1: return mdp_select (operands, "sll", false, ""); + case 0: return mdp_select (operands, "slli", false, "c", true); + case 1: return mdp_select (operands, "sll", false, "", true); default: gcc_unreachable (); } } @@ -647,13 +846,19 @@ (define_insn "ashlsi3_cmp" [(set (reg:CC_NZ CC_REGNUM) (compare:CC_NZ (ashift:SI - (match_operand:SI 0 "register_operand" "d,d") - (match_operand:SI 1 "arith_operand" "J,d")) - (const_int 0)))] + (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "arith_operand" "J,d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d,d"))] "" - "@ - %[ slli.c r1, %0, %c1 %] - %[ sll.c r1, %0, %1 %]" +{ + switch (which_alternative) + { + case 0: return mdp_select (operands, "slli", false, "c", true); + case 1: return mdp_select (operands, "sll", false, "", true); + default: gcc_unreachable (); + } +} [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) @@ -682,7 +887,7 @@ switch (which_alternative) { case 0: return \"srai.c %0, %1, %c2\"; - case 1: return mdp_select (operands, "sra", false, ""); + case 1: return mdp_select (operands, "sra", false, "", true); default: gcc_unreachable (); } } @@ -693,31 +898,16 @@ (define_insn "ashrsi3_cmp" [(set (reg:CC_NZ CC_REGNUM) (compare:CC_NZ (ashiftrt:SI - (match_operand:SI 0 "register_operand" "d,d") - (match_operand:SI 1 "arith_operand" "J,d")) - (const_int 0)))] - "" - "@ - %[ srai.c r1, %0, %c1 %] - %[ sra.c r1, %0, %1 %]" - [(set_attr "type" "arith") - (set_attr "up_c" "yes") - (set_attr "mode" "SI")]) - -(define_insn "ashrsi3_ucc_n" - [(set (reg:CC_N CC_REGNUM) - (compare:CC_N (ashiftrt:SI - (match_operand:SI 1 "register_operand" "d,d") - (match_operand:SI 2 "arith_operand" "J,d")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d") - (ashiftrt:SI (match_dup 1) (match_dup 2)))] + (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "arith_operand" "J,d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d,d"))] "" { switch (which_alternative) { case 0: return \"srai.c %0, %1, %c2\"; - case 1: return mdp_select (operands, "sra", false, ""); + case 1: return mdp_select (operands, "sra", false, "", true); default: gcc_unreachable (); } } @@ -725,20 +915,6 @@ (set_attr "up_c" "yes") (set_attr "mode" "SI")]) -(define_insn "ashrsi3_cmp_n" - [(set (reg:CC_N CC_REGNUM) - (compare:CC_N (ashiftrt:SI - (match_operand:SI 0 "register_operand" "d,d") - (match_operand:SI 1 "arith_operand" "J,d")) - (const_int 0)))] - "" - "@ - %[ srai.c r1, %0, %c1 %] - %[ sra.c r1, %0, %1 %]" - [(set_attr "type" "arith") - (set_attr "up_c" "yes") - (set_attr "mode" "SI")]) - (define_insn "lshrsi3" [(set (match_operand:SI 0 "register_operand" "=d,d") (lshiftrt:SI (match_operand:SI 1 "register_operand" "d,d") @@ -762,8 +938,8 @@ { switch (which_alternative) { - case 0: return mdp_select (operands, "srli", false, "c"); - case 1: return mdp_select (operands, "srl", false, ""); + case 0: return mdp_select (operands, "srli", false, "c", true); + case 1: return mdp_select (operands, "srl", false, "", true); default: gcc_unreachable (); } } @@ -774,13 +950,19 @@ (define_insn "lshrsi3_cmp" [(set (reg:CC_NZ CC_REGNUM) (compare:CC_NZ (lshiftrt:SI - (match_operand:SI 0 "register_operand" "d,d") - (match_operand:SI 1 "arith_operand" "J,d")) - (const_int 0)))] + (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "arith_operand" "J,d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=d,d"))] "" - "@ - %[ srli.c r1, %0, %c1 %] - %[ srl.c r1, %0, %1 %]" +{ + switch (which_alternative) + { + case 0: return mdp_select (operands, "srli", false, "c", true); + case 1: return mdp_select (operands, "srl", false, "", true); + default: gcc_unreachable (); + } +} [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) @@ -793,11 +975,24 @@ [(set_attr "type" "arith") (set_attr "mode" "SI")]) +(define_insn "*negsi2_cmp" + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "e,d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=e,d"))] + "" + "@ + neg! %0, %1 + neg.c %0, %1" + [(set_attr "type" "arith") + (set_attr "up_c" "yes") + (set_attr "mode" "SI")]) + (define_insn "negsi2_ucc" - [(set (reg:CC CC_REGNUM) - (compare:CC (neg:SI (match_operand:SI 1 "register_operand" "*e,d")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=*e,d") + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "e,d")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=e,d") (neg:SI (match_dup 1)))] "" "@ @@ -817,9 +1012,9 @@ (define_insn "one_cmplsi2_ucc" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (not:SI (match_operand:SI 1 "register_operand" "*e,d")) + (compare:CC_NZ (not:SI (match_operand:SI 1 "register_operand" "e,d")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=*e,d") + (set (match_operand:SI 0 "register_operand" "=e,d") (not:SI (match_dup 1)))] "" "@ @@ -831,12 +1026,13 @@ (define_insn "one_cmplsi2_cmp" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (not:SI (match_operand:SI 0 "register_operand" "*e,d")) - (const_int 0)))] + (compare:CC_NZ (not:SI (match_operand:SI 1 "register_operand" "e,d")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=e,d"))] "" "@ - %[ not! r1, %0 %] - %[ not.c r1, %0 %]" + not! %0, %1 + not.c %0, %1" [(set_attr "type" "arith") (set_attr "up_c" "yes") (set_attr "mode" "SI")]) @@ -877,8 +1073,8 @@ (define_insn "cmpsi_nz" [(set (reg:CC_NZ CC_REGNUM) - (compare:CC_NZ (match_operand:SI 0 "register_operand" "d,*e,d") - (match_operand:SI 1 "arith_operand" "L,*e,d")))] + (compare:CC_NZ (match_operand:SI 0 "register_operand" "d,e,d") + (match_operand:SI 1 "arith_operand" "L,e,d")))] "" "@ cmpi.c %0, %c1 @@ -890,8 +1086,8 @@ (define_insn "cmpsi_n" [(set (reg:CC_N CC_REGNUM) - (compare:CC_N (match_operand:SI 0 "register_operand" "d,*e,d") - (match_operand:SI 1 "arith_operand" "L,*e,d")))] + (compare:CC_N (match_operand:SI 0 "register_operand" "d,e,d") + (match_operand:SI 1 "arith_operand" "L,e,d")))] "" "@ cmpi.c %0, %c1 @@ -901,10 +1097,23 @@ (set_attr "up_c" "yes") (set_attr "mode" "SI")]) +(define_insn "*cmpsi_to_addsi" + [(set (reg:CC_NZ CC_REGNUM) + (compare:CC_NZ (match_operand:SI 1 "register_operand" "0,d") + (neg:SI (match_operand:SI 2 "register_operand" "e,d")))) + (clobber (match_scratch:SI 0 "=e,d"))] + "" + "@ + add! %0, %2 + add.c %0, %1, %2" + [(set_attr "type" "cmp") + (set_attr "up_c" "yes") + (set_attr "mode" "SI")]) + (define_insn "cmpsi_cc" [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:SI 0 "register_operand" "d,*e,d") - (match_operand:SI 1 "arith_operand" "L,*e,d")))] + (compare:CC (match_operand:SI 0 "register_operand" "d,e,d") + (match_operand:SI 1 "arith_operand" "L,e,d")))] "" "@ cmpi.c %0, %c1 @@ -1078,17 +1287,17 @@ (clobber (reg:SI RT_REGNUM))] "SIBLING_CALL_P (insn)" { - if (!flag_pic) - switch (which_alternative) + if (!flag_pic) + switch (which_alternative) { case 0: return \"br%S0 %0\"; case 1: return \"j %0\"; default: gcc_unreachable (); } else - switch (which_alternative) + switch (which_alternative) { - case 0: return \"mv r29, %0\;.cpadd r29\;br r29\"; + case 0: return \"mv r29, %0\;br r29\"; case 1: return \"la r29, %0\;br r29\"; default: gcc_unreachable (); } @@ -1112,17 +1321,17 @@ (clobber (reg:SI RT_REGNUM))] "SIBLING_CALL_P (insn)" { - if (!flag_pic) - switch (which_alternative) + if (!flag_pic) + switch (which_alternative) { case 0: return \"br%S1 %1\"; case 1: return \"j %1\"; default: gcc_unreachable (); } else - switch (which_alternative) + switch (which_alternative) { - case 0: return \"mv r29, %1\;.cpadd r29\;br r29\"; + case 0: return \"mv r29, %1\;br r29\"; case 1: return \"la r29, %1\;br r29\"; default: gcc_unreachable (); } @@ -1154,7 +1363,7 @@ else switch (which_alternative) { - case 0: return \"mv r29, %0\;.cpadd r29\;brl r29\"; + case 0: return \"mv r29, %0\;brl r29\"; case 1: return \"la r29, %0\;brl r29\"; default: gcc_unreachable (); } @@ -1163,7 +1372,7 @@ (define_expand "call_value" [(parallel [(set (match_operand 0 "" "") - (call (match_operand 1 "" "") (match_operand 2 "" ""))) + (call (match_operand 1 "" "") (match_operand 2 "" ""))) (use (match_operand 3 "" ""))])] "" { @@ -1188,7 +1397,7 @@ else switch (which_alternative) { - case 0: return \"mv r29, %1\;.cpadd r29\;brl r29\"; + case 0: return \"mv r29, %1\;brl r29\"; case 1: return \"la r29, %1\;brl r29\"; default: gcc_unreachable (); } @@ -1277,13 +1486,59 @@ ) (define_insn "cpload" - [(unspec:SI [(const_int 1)] 1)] + [(unspec_volatile:SI [(const_int 1)] CPLOAD)] "flag_pic" ".cpload r29" ) -(define_insn "cprestore" - [(unspec:SI [(match_operand:SI 0 "" "")] 2)] +(define_insn "cprestore_use_fp" + [(unspec_volatile:SI [(match_operand:SI 0 "" "")] CPRESTORE) + (use (reg:SI FP_REGNUM))] "flag_pic" - ".cprestore %0" + ".cprestore r2, %0" ) + +(define_insn "cprestore_use_sp" + [(unspec_volatile:SI [(match_operand:SI 0 "" "")] CPRESTORE) + (use (reg:SI SP_REGNUM))] + "flag_pic" + ".cprestore r0, %0" +) + +(define_expand "doloop_end" + [(use (match_operand 0 "" "")) ; loop pseudo + (use (match_operand 1 "" "")) ; iterations; zero if unknown + (use (match_operand 2 "" "")) ; max iterations + (use (match_operand 3 "" "")) ; loop level + (use (match_operand 4 "" ""))] ; label + "" + { + if (INTVAL (operands[3]) > 1) + FAIL; + + if (GET_MODE (operands[0]) == SImode) + { + rtx sr0 = gen_rtx_REG (SImode, CN_REGNUM); + emit_jump_insn (gen_doloop_end_si (sr0, operands[4])); + } + else + FAIL; + + DONE; + }) + +(define_insn "doloop_end_si" + [(set (pc) + (if_then_else + (ne (match_operand:SI 0 "sr0_operand" "") + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC CC_REGNUM)) +] + "" + "bcnz %1" + [(set_attr "type" "branch")]) diff --git a/gcc/config/score/t-score-elf b/gcc/config/score/t-score-elf index 535c4c6220f..d8bc89fe95c 100644 --- a/gcc/config/score/t-score-elf +++ b/gcc/config/score/t-score-elf @@ -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 -