summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/config/score/crti.asm13
-rw-r--r--gcc/config/score/crtn.asm1
-rw-r--r--gcc/config/score/misc.md315
-rw-r--r--gcc/config/score/mul-div.S10
-rw-r--r--gcc/config/score/predicates.md39
-rw-r--r--gcc/config/score/score-conv.h7
-rw-r--r--gcc/config/score/score-mdaux.c419
-rw-r--r--gcc/config/score/score-mdaux.h15
-rw-r--r--gcc/config/score/score-modes.def3
-rw-r--r--gcc/config/score/score-protos.h2
-rw-r--r--gcc/config/score/score-version.h2
-rw-r--r--gcc/config/score/score.c248
-rw-r--r--gcc/config/score/score.h121
-rw-r--r--gcc/config/score/score.md669
-rw-r--r--gcc/config/score/t-score-elf3
16 files changed, 1493 insertions, 396 deletions
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 <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,
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,11 +154,23 @@
[(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)
{
case 0:
@@ -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
-
OpenPOWER on IntegriCloud