diff options
Diffstat (limited to 'gcc/config/h8300/h8300.md')
-rw-r--r-- | gcc/config/h8300/h8300.md | 185 |
1 files changed, 148 insertions, 37 deletions
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index f0b906810af..5e9f114d3ec 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -90,7 +90,7 @@ (define_attr "adjust_length" "yes,no" (cond [(eq_attr "type" "branch") (const_string "no")] - (const_string "yes"))) + (const_string "yes"))) ;; Condition code settings. ;; @@ -114,9 +114,9 @@ (define_insn "pushqi1_h8300" [(parallel [(set (reg:HI SP_REG) - (plus:HI (reg:HI SP_REG) (const_int -2))) - (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -1))) - (match_operand:QI 0 "register_operand" "r"))])] + (plus:HI (reg:HI SP_REG) (const_int -2))) + (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -1))) + (match_operand:QI 0 "register_operand" "r"))])] "TARGET_H8300" "mov.w\\t%T0,@-r7" [(set_attr "length" "2") @@ -124,9 +124,9 @@ (define_insn "pushqi1_h8300hs" [(parallel [(set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) (const_int -4))) - (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3))) - (match_operand:QI 0 "register_operand" "r"))])] + (plus:SI (reg:SI SP_REG) (const_int -4))) + (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3))) + (match_operand:QI 0 "register_operand" "r"))])] "TARGET_H8300H || TARGET_H8300S" "mov.l\\t%S0,@-er7" [(set_attr "length" "4") @@ -208,15 +208,15 @@ (define_expand "pushhi1_h8300" [(set (mem:HI (pre_dec:HI (reg:HI SP_REG))) - (match_operand:HI 0 "register_operand" ""))] + (match_operand:HI 0 "register_operand" ""))] "TARGET_H8300" "") (define_insn "pushhi1_h8300hs" [(parallel [(set (reg:SI SP_REG) - (plus:SI (reg:SI SP_REG) (const_int -4))) - (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2))) - (match_operand:HI 0 "register_operand" "r"))])] + (plus:SI (reg:SI SP_REG) (const_int -4))) + (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2))) + (match_operand:HI 0 "register_operand" "r"))])] "TARGET_H8300H || TARGET_H8300S" "mov.l\\t%S0,@-er7" [(set_attr "length" "4") @@ -510,7 +510,7 @@ } /* Look for constants that can be obtained by subs, inc, and - dec to 0. */ + dec to 0. */ switch (val & 0xffffffff) { case 0xffffffff: @@ -599,6 +599,43 @@ [(set_attr "length" "2") (set_attr "cc" "set_zn")]) +(define_insn "" + [(set (cc0) + (and:HI (match_operand:HI 0 "register_operand" "r") + (match_operand:HI 1 "single_one_operand" "n")))] + "" + "* +{ + operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffff); + if (INTVAL (operands[1]) > 128) + { + operands[1] = GEN_INT (INTVAL (operands[1]) >> 8); + return \"btst\\t%V1,%t0\"; + } + return \"btst\\t%V1,%s0\"; +}" + [(set_attr "length" "2") + (set_attr "cc" "set_zn")]) + +(define_insn "" + [(set (cc0) + (and:SI (match_operand:SI 0 "register_operand" "r") + (match_operand:SI 1 "single_one_operand" "n")))] + "(TARGET_H8300H || TARGET_H8300S) + && (INTVAL (operands[1]) & 0xffff) != 0" + "* +{ + operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffff); + if (INTVAL (operands[1]) > 128) + { + operands[1] = GEN_INT (INTVAL (operands[1]) >> 8); + return \"btst\\t%V1,%x0\"; + } + return \"btst\\t%V1,%w0\"; +}" + [(set_attr "length" "2") + (set_attr "cc" "set_zn")]) + (define_insn "tstqi" [(set (cc0) (match_operand:QI 0 "register_operand" "r"))] "" @@ -1058,15 +1095,15 @@ (match_operand:QI 3 "single_one_operand" "n")) (match_operand:QI 1 "register_operand" "0")))] "" - "bld\\t%V3,%X2\;bst\\t%V3,%X0" - [(set_attr "length" "4") + "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0" + [(set_attr "length" "6") (set_attr "cc" "clobber")]) (define_insn "*andorhi3" [(set (match_operand:HI 0 "register_operand" "=r") (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r") (match_operand:HI 3 "single_one_operand" "n")) - (match_operand:HI 1 "register_operand" "0")))] + (match_operand:HI 1 "register_operand" "0")))] "" "* { @@ -1074,11 +1111,30 @@ if (INTVAL (operands[3]) > 128) { operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); - return \"bld\\t%V3,%t2\;bst\\t%V3,%t0\"; + return \"bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0\"; } - return \"bld\\t%V3,%s2\;bst\\t%V3,%s0\"; + return \"bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0\"; }" - [(set_attr "length" "4") + [(set_attr "length" "6") + (set_attr "cc" "clobber")]) + +(define_insn "*andorsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r") + (match_operand:SI 3 "single_one_operand" "n")) + (match_operand:SI 1 "register_operand" "0")))] + "(INTVAL (operands[3]) & 0xffff) != 0" + "* +{ + operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); + if (INTVAL (operands[3]) > 128) + { + operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); + return \"bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0\"; + } + return \"bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0\"; +}" + [(set_attr "length" "6") (set_attr "cc" "clobber")]) (define_expand "andsi3" @@ -1435,9 +1491,9 @@ { if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 && (GET_CODE (operands[1]) == GT - || GET_CODE (operands[1]) == GE - || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == LT)) + || GET_CODE (operands[1]) == GE + || GET_CODE (operands[1]) == LE + || GET_CODE (operands[1]) == LT)) { cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; return 0; @@ -1464,9 +1520,9 @@ { if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 && (GET_CODE (operands[1]) == GT - || GET_CODE (operands[1]) == GE - || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == LT)) + || GET_CODE (operands[1]) == GE + || GET_CODE (operands[1]) == LE + || GET_CODE (operands[1]) == LT)) { cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; return 0; @@ -1524,6 +1580,14 @@ [(set_attr "cc" "none") (set_attr "length" "2")]) +(define_insn "tablejump_normal_mode" + [(set (pc) (match_operand:HI 0 "register_operand" "r")) + (use (label_ref (match_operand 1 "" "")))] + "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE" + "jmp @%S0" + [(set_attr "cc" "none") + (set_attr "length" "2")]) + ;; This is a define expand, because pointers may be either 16 or 32 bits. (define_expand "indirect_jump" @@ -1545,6 +1609,13 @@ [(set_attr "cc" "none") (set_attr "length" "2")]) +(define_insn "indirect_jump_normal_mode" + [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))] + "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE" + "jmp @%S0" + [(set_attr "cc" "none") + (set_attr "length" "2")]) + ;; Call subroutine with no return value. ;; ??? Even though we use HImode here, this works on the H8/300H and H8S. @@ -2082,7 +2153,7 @@ (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") - (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) + (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) (match_operand:HI 2 "register_operand" "0")))] "REG_P (operands[0]) && REG_P (operands[1]) @@ -2093,7 +2164,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) + (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "0")))] "(TARGET_H8300H || TARGET_H8300S) && REG_P (operands[0]) @@ -2105,18 +2176,16 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) + (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "0")))] - "REG_P (operands[0]) - && REG_P (operands[1]) - && REGNO (operands[0]) != REGNO (operands[1])" - "or\\t%X1,%s0" + "" + "or\\t%X1,%w0" [(set_attr "cc" "clobber") (set_attr "length" "2")]) (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") - (xor:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) + (xor:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) (match_operand:HI 2 "register_operand" "0")))] "REG_P (operands[0]) && REG_P (operands[1]) @@ -2127,7 +2196,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") - (xor:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) + (xor:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "0")))] "(TARGET_H8300H || TARGET_H8300S) && REG_P (operands[0]) @@ -2139,18 +2208,18 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") - (xor:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) + (xor:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "0")))] "REG_P (operands[0]) && REG_P (operands[1]) && REGNO (operands[0]) != REGNO (operands[1])" - "xor\\t%X1,%s0" + "xor\\t%X1,%w0" [(set_attr "cc" "clobber") (set_attr "length" "2")]) (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") - (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) + (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0")) (ashift:HI (match_operand:HI 2 "register_operand" "r") (const_int 8))))] "REG_P (operands[0]) @@ -2162,7 +2231,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0")) + (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0")) (ashift:SI (match_operand:SI 2 "register_operand" "r") (const_int 16))))] "(TARGET_H8300H || TARGET_H8300S) @@ -2173,6 +2242,48 @@ [(set_attr "cc" "clobber") (set_attr "length" "2")]) +;; Storing a part of HImode to QImode. + +(define_insn "" + [(set (match_operand:QI 0 "general_operand_dst" "=rm<") + (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r") + (const_int 8)) 1))] + "" + "mov.b\\t%t1,%R0" + [(set_attr "cc" "set_znv") + (set_attr "length" "8")]) + +;; Storing a part of SImode to QImode. + +(define_insn "" + [(set (match_operand:QI 0 "general_operand_dst" "=rm<") + (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") + (const_int 8)) 3))] + "" + "mov.b\\t%x1,%R0" + [(set_attr "cc" "set_znv") + (set_attr "length" "8")]) + +(define_insn "" + [(set (match_operand:QI 0 "general_operand_dst" "=rm<") + (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") + (const_int 16)) 3)) + (clobber (match_scratch:SI 2 "=&r"))] + "TARGET_H8300H || TARGET_H8300S" + "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0" + [(set_attr "cc" "set_znv") + (set_attr "length" "10")]) + +(define_insn "" + [(set (match_operand:QI 0 "general_operand_dst" "=rm<") + (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") + (const_int 24)) 3)) + (clobber (match_scratch:SI 2 "=&r"))] + "TARGET_H8300H || TARGET_H8300S" + "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0" + [(set_attr "cc" "set_znv") + (set_attr "length" "10")]) + (define_insn_and_split "" [(set (pc) (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0) |