summaryrefslogtreecommitdiff
path: root/gcc/config/m68k/m68k.md
diff options
context:
space:
mode:
authormkuvyrkov <mkuvyrkov@138bc75d-0d04-0410-961f-82ee72b054a4>2007-09-11 13:56:30 +0000
committermkuvyrkov <mkuvyrkov@138bc75d-0d04-0410-961f-82ee72b054a4>2007-09-11 13:56:30 +0000
commit1d86aeab250b3c69bf826385bd6875cf0b9ea459 (patch)
tree872e1e19c4888e93d9ac7b2a03a6a0bd5dc9f646 /gcc/config/m68k/m68k.md
parent4e1d7ea46e9e60154f976a52a62b115ce5a0803a (diff)
downloadgcc-1d86aeab250b3c69bf826385bd6875cf0b9ea459.tar.gz
* config/m68k/predicates.md (movsi_const0_operand,
non_symbolic_call_operand): New predicates. * config/m68k/constraints.md: (Cs, Ci, C0, Cj, CQ, CW, CZ, CS, Ap, Ac): New constraints. * doc/md.texi (Constraints for Particular Machines: Motorola 680x0): Document constraints N, O, P, R, S, T, Q, U, W, Cs, Ci, C0, Cj, CQ, CW, CZ, CS, Ap and Ac. * config/m68k/m68k.md (UNSPEC_IB): New constant. (constraints.md): New include. (cpu, type, type1, opx, opy, opx_type, opy_type, size, opx_access, opx_mem, opy_mem, op_mem, guess, split): New attributes. (movdf_internal): Name pattern. Fix to use alternatives. Add split. Specify attributes. (pushdi): Add split. (tstsi_internal): Name pattern. Fix to use alternatives. Specify attributes. Split tstsi_internal_68020_cf from it. (tstsi_internal_68020_cf): New pattern. (tsthi_internal, tstqi_internal): Name pattern. Specify attributes. (tst<mode>_cf): Specify attributea. (cmpsi_cf): Name pattern. Specify attributes. (cmp<mode>_68881, cmp<mode>_cf): Specify type attribute. (pushexthisi_const): Fix to use alternatives. Specify attributes. (movsi_const0): Split movsi_const0_68000_10 and movsi_const0_68040_60 from it. Fix to use alternatives. Specify attributes. (movsi_const0_68040_10, movsi_const0_68040_60): New patterns. (movsi_cf, movstrictqi_cf): Fix to use alternatives. Specify attributes. (movsf_cf_soft): Specify attributes. (movdf_cf_soft): Add split. (pushasi, zero_extendhisi2_cf, zero_extendqisi2_cfv4, cfv4_extendhisi2, 68k_extendhisi2, extendqihi2, cfv4_extendqisi2, 68k_extendqisi2, truncdfsf2_cf): Specify attributes. (truncdfsf2_68881): Name pattern. Specify attributes. (floatsi<mode>2_cf, floathi<mode>2_68881, floathi<mode>2_cf, floatqi<mode>2_68881, floatqi<mode>2_cf, ftrunc<mode>2_cf, fix<mode>qi2_cf, fix<mode>hi2_cf, fix<mode>si2_cf, adddi_dishl32): Specify attributes. (addsi3_5200): Fix to use alternatives. Specify attributes. Add splits. (add<mode>3_cf, subdi_dishl32): Specify attributes. (subsi3): Add alternative for subq.l. Specify attributes. (sub<mode>3_cf, mulhi3, mulhisi3): Specify attributes. (mulhisisi3_s, mulsi3_68020, mulsi3_cf): Name pattern. Specify attributes. (umulhisi3): Specify attributes. (mulhisisi3_z): Name pattern. Specify attributes. (fmul<mode>3_cf, div<mode>3_cf, negsi2_internal, negsi2_5200, sqrt<mode>2_68881, clzsi2, one_cmplsi2_5200, subreghi1ashrdi_const32, subregsi1ashrdi_const32, ashrsi3, subreg1lshrdi_const32, lshrsi3, bsetmemqi): Specify attributes. (bsetmemqi_ext): Name pattern. Specify attributes. (bclrmemqi): Specify attributes. (bclrmemqi_ext, scc, sls): Name pattern. Specify attributes. (beq, bne, bgt, bgtu, blt, bltu, bge, bgeu, ble, bleu): Specify attributes. (beq2, bne2, bgt2, bgtu2, blt2, bltu2, bge2, bgeu2, ble2, bleu2): Name pattern. Specify attributes. (jump): Specify attributes. (tablejump_internal): Name pattern. Specify attributes. (call_value): Split into non_symbolic_call_value, symbolic_call_value_jsr, symbolic_call_value_bsr. Fix to use alternatives. Specify attributes. (non_symbolic_call_value, symbolic_call_value_jsr, symbolic_call_value_bsr): New patterns. (nop, return, unlink, indirect_jump): Specify attributes. (trap): Fix condition. Specify attributes. (ib): New pattern. * config/m68k/m68k.c (m68k_symbolic_call_var): New variable. (override_options): Initialize it. Initialize m68k_sched_cpu. (CONST_METHOD): Rename to M68K_CONST_METHOD, move to m68k.h. (const_method): Make global, rename to m68k_const_method. (const_int_cost, output_move_const_into_data_reg): Update. (output_move_double): Parametrize to emit rtl code, rename to handle_move_double. (output_reg_adjust, emit_reg_adjust, output_compadr, output_movsi, emit_movsi): New static functions. (output_move_double): New function with semantics of old output_move_double. (m68k_emit_move_double): New function. (m68k_sched_cpu): New variable. (attr_op_type): New enum. (sched_guess_p): New variable. (sched_address_type, sched_operand_type, sched_attr_op_type): New static functions. (m68k_sched_attr_opx_type, m68k_sched_attr_opy_type, m68k_sched_attr_size, m68k_sched_attr_op_mem): New functions. (sched_branch_type): New static variable. (m68k_sched_branch_type): New function. * config/m68k/m68k.h (M68K_SYMBOLIC_CALL): New enum. (m68k_symbolic_call_var): Declare. (M68K_CONST_METHOD): Rename from CONST_METHOD. Move here from m68k.c. (m68k_const_method, m68k_emit_move_double, m68k_sched_cpu, m68k_sched_attr_opx_type, m68k_sched_attr_opy_type, m68k_sched_attr_size, m68k_sched_attr_op_mem, m68k_sched_branch_type): Declare. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128377 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/m68k/m68k.md')
-rw-r--r--gcc/config/m68k/m68k.md855
1 files changed, 664 insertions, 191 deletions
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 99ee142d6d1..63c0a0edba2 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -114,6 +114,7 @@
[(UNSPEC_SIN 1)
(UNSPEC_COS 2)
(UNSPEC_GOT 3)
+ (UNSPEC_IB 4)
])
;; UNSPEC_VOLATILE usage:
@@ -136,6 +137,205 @@
(include "predicates.md")
(include "constraints.md")
+;; ::::::::::::::::::::
+;; ::
+;; :: Attributes
+;; ::
+;; ::::::::::::::::::::
+
+;; Processor type.
+(define_attr "cpu" "cf_v2, unknown" (const (symbol_ref "m68k_sched_cpu")))
+
+;; Instruction type.
+;; Basically, an asm pattern.
+(define_attr "type"
+ "add_l, addq_l, asr_l, bcc, bclr, bra, bset, bsr,
+ clr_b, clr_w, clr_l, cmp_l,
+ ext_w, extb_l, ext_l,
+ fadd, fcmp, fdiv, ff1, fintrz, fmove, fmul, fsqrt, fsub, ftst, jmp, jsr,
+ ib,
+ lea, lsr_l,
+ move_b, move_w, move_l, moveq_l, mov3q_l, mvs_b, mvs_w, mvz_b, mvz_w,
+ muls_w, muls_l, mulu_w, mulu_l,
+ neg_l, nop, not_l,
+ pea, rts,
+ scc, sub_l, subq_l,
+ trap, tst_b, tst_l, tst_w,
+ unlk, unknown"
+ (const_string "unknown"))
+
+;; Instruction type for use in scheduling description.
+;; _l and _w suffixes indicate size of the operands of instruction.
+;; alu - usual arithmetic or logic instruction.
+;; alu_reg1 - arithmetic or logic instruction with one operand that is
+;; a register.
+;; alu_regx - arithmetic or logic instruction which has a register for its
+;; X operand.
+;; aluq - arithmetic or logic instruction which has a quick immediate (the one
+;; that is encoded in the instruction word) for its Y operand.
+;; <all other values> - corresponding asm instructions.
+(define_attr "type1"
+ "alu_l, alu_reg1, alu_regx, aluq_l, bcc, bra, bsr, clr, cmp_l, jmp, jsr, lea,
+ mov3q_l, move, move_l, moveq_l, mul_l, mul_w, pea, rts, tst, tst_l, unlk,
+ unknown"
+ (cond [(eq_attr "type" "add_l,sub_l") (const_string "alu_l")
+ (eq_attr "type" "ext_w,extb_l,ext_l,neg_l,not_l")
+ (const_string "alu_reg1")
+ (eq_attr "type" "asr_l,lsr_l") (const_string "alu_regx")
+ (eq_attr "type" "addq_l,subq_l") (const_string "aluq_l")
+ (eq_attr "type" "bcc") (const_string "bcc")
+ (eq_attr "type" "bra") (const_string "bra")
+ (eq_attr "type" "bsr") (const_string "bsr")
+ (eq_attr "type" "clr_b,clr_l,clr_w") (const_string "clr")
+ (eq_attr "type" "cmp_l") (const_string "cmp_l")
+ (eq_attr "type" "jmp") (const_string "jmp")
+ (eq_attr "type" "jsr") (const_string "jsr")
+ (eq_attr "type" "lea") (const_string "lea")
+ (eq_attr "type" "mov3q_l") (const_string "mov3q_l")
+ (eq_attr "type" "move_b,move_w") (const_string "move")
+ (eq_attr "type" "move_l") (const_string "move_l")
+ (eq_attr "type" "moveq_l") (const_string "moveq_l")
+ (eq_attr "type" "muls_l,mulu_l") (const_string "mul_l")
+ (eq_attr "type" "muls_w,mulu_w") (const_string "mul_w")
+ (eq_attr "type" "pea") (const_string "pea")
+ (eq_attr "type" "rts") (const_string "rts")
+ (eq_attr "type" "tst_b,tst_w") (const_string "tst")
+ (eq_attr "type" "tst_l") (const_string "tst_l")
+ (eq_attr "type" "unlk") (const_string "unlk")]
+ (const_string "unknown")))
+
+;; Index of the X or Y operand in recog_data.operand[].
+;; Should be used only within opx_type and opy_type.
+(define_attr "opx" "" (const_int 0))
+(define_attr "opy" "" (const_int 1))
+
+;; Type of the X operand.
+;; See m68k.c: enum attr_op_type.
+(define_attr "opx_type"
+ "none, reg, mem1, mem234, mem5, mem6, mem7, imm_q, imm_w, imm_l"
+ (cond [(eq_attr "type1" "rts,unlk") (const_string "none")
+ (eq_attr "type1" "alu_reg1,alu_regx,lea,moveq_l,mul_l,mul_w")
+ (const_string "reg")
+ (eq_attr "type1" "pea") (const_string "mem1")
+ (eq_attr "type1" "bcc") (const_string "imm_q")
+ (eq_attr "type1" "bra,bsr") (const_string "imm_w")
+ (eq_attr "type1" "jmp,jsr")
+ (symbol_ref "m68k_sched_attr_opx_type (insn, 1)")]
+ (symbol_ref "m68k_sched_attr_opx_type (insn, 0)")))
+
+;; Type of the Y operand.
+;; See m68k.c: enum attr_op_type.
+(define_attr "opy_type"
+ "none, reg, mem1, mem234, mem5, mem6, mem7, imm_q, imm_w, imm_l"
+ (cond [(eq_attr "type1" "alu_reg1,bcc,bra,bsr,clr,jmp,jsr,rts,tst,tst_l,
+ unlk") (const_string "none")
+ (eq_attr "type1" "mov3q_l,moveq_l,aluq_l") (const_string "imm_q")
+ (eq_attr "type1" "lea,pea")
+ (symbol_ref "m68k_sched_attr_opy_type (insn, 1)")]
+ (symbol_ref "m68k_sched_attr_opy_type (insn, 0)")))
+
+;; Instruction size in words.
+(define_attr "size" ""
+ (cond [(eq_attr "type1" "alu_reg1,moveq_l,rts,unlk") (const_int 1)]
+ (symbol_ref "m68k_sched_attr_size (insn)")))
+
+;; Access to the X operand: none, read, write, read/write, unknown.
+;; Access to the Y operand is either none (if opy_type is none)
+;; or read otherwise.
+(define_attr "opx_access" "none, r, w, rw, unknown"
+ (cond [(eq_attr "type1" "rts,unlk") (const_string "none")
+ (eq_attr "type1" "bcc,bra,bsr,cmp_l,jmp,jsr,tst,tst_l")
+ (const_string "r")
+ (eq_attr "type1" "clr,lea,mov3q_l,move,move_l,moveq_l,pea")
+ (const_string "w")
+ (eq_attr "type1" "alu_l,alu_reg1,alu_regx,aluq_l")
+ (const_string "rw")]
+ (const_string "unknown")))
+
+;; Memory relation of operands:
+;; r - register or immediate operand
+;; m - non-indexed memory location
+;; i - indexed memory location
+
+(define_attr "opx_mem" "r, m, i, unknown"
+ (cond [(eq_attr "opx_type" "none,reg,imm_q,imm_w,imm_l") (const_string "r")
+ (eq_attr "opx_type" "mem1,mem234,mem5,mem7") (const_string "m")
+ (eq_attr "opx_type" "mem6") (const_string "i")]
+ (const_string "unknown")))
+
+(define_attr "opy_mem" "r, m, i, unknown"
+ (cond [(eq_attr "opy_type" "none,reg,imm_q,imm_w,imm_l") (const_string "r")
+ (eq_attr "opy_type" "mem1,mem234,mem5,mem7") (const_string "m")
+ (eq_attr "opy_type" "mem6") (const_string "i")]
+ (const_string "unknown")))
+
+;; Memory accesses of the insn.
+;; 00 - no memory references
+;; 10 - memory is read
+;; i10 - indexed memory is read
+;; 01 - memory is written
+;; 0i1 - indexed memory is written
+;; 11 - memory is read, memory is written
+;; i11 - indexed memory is read, memory is written
+;; 1i1 - memory is read, indexed memory is written
+;;
+;; unknown - should now occur on normal insn.
+;; ??? This attribute is implemented in C to spare genattrtab from
+;; ??? optimizing it.
+(define_attr "op_mem" "00, 10, i0, 01, 0i, 11, i1, 1i, unknown"
+; (cond [(and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "r"))
+; (const_string "00")
+;
+; (and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "m"))
+; (cond [(eq_attr "opx_access" "r") (const_string "10")
+; (eq_attr "opx_access" "w") (const_string "01")
+; (eq_attr "opx_access" "rw") (const_string "11")]
+; (const_string "unknown"))
+;
+; (and (eq_attr "opy_mem" "r") (eq_attr "opx_mem" "i"))
+; (cond [(eq_attr "opx_access" "r") (const_string "i0")
+; (eq_attr "opx_access" "w") (const_string "0i")
+; (eq_attr "opx_access" "rw") (const_string "i1")]
+; (const_string "unknown"))
+;
+; (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "r"))
+; (const_string "10")
+;
+; (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "m"))
+; (cond [(eq_attr "opx_access" "w") (const_string "11")]
+; (const_string "unknown"))
+;
+; (and (eq_attr "opy_mem" "m") (eq_attr "opx_mem" "i"))
+; (cond [(eq_attr "opx_access" "w") (const_string "1i")]
+; (const_string "unknown"))
+;
+; (and (eq_attr "opy_mem" "i") (eq_attr "opx_mem" "r"))
+; (const_string "i0")
+;
+; (and (eq_attr "opy_mem" "i") (eq_attr "opx_mem" "m"))
+; (cond [(eq_attr "opx_access" "w") (const_string "i1")]
+; (const_string "unknown"))]
+; (const_string "unknown"))
+ (symbol_ref "m68k_sched_attr_op_mem (insn)"))
+
+;; Attribute to support partial automata description.
+;; This attribute has value 'yes' for instructions that are not
+;; fully handled yet.
+(define_attr "guess" "yes, no"
+ (cond [(ior (eq (symbol_ref "reload_completed") (const_int 0))
+ (eq_attr "type1" "unknown"))
+ (const_string "yes")]
+ (const_string "no")))
+
+;; Attribute to support statistics gathering.
+;; Todo means that insn lacks something to get pipeline description.
+;; Done means that insn was transformed to suit pipeline description.
+;; Nothing means that insn was originally good enough for scheduling.
+(define_attr "split" "todo, done, nothing"
+ (if_then_else (eq_attr "type" "unknown")
+ (const_string "todo")
+ (const_string "nothing")))
+
;; Mode macros for floating point operations.
;; Valid floating point modes
(define_mode_iterator FP [SF DF (XF "TARGET_68881")])
@@ -150,22 +350,33 @@
;; Allowable 68881 constant constraints
(define_mode_attr const [(SF "F") (DF "G") (XF "")])
-(define_insn ""
- [(set (match_operand:DF 0 "push_operand" "=m")
- (match_operand:DF 1 "general_operand" "ro<>fE"))]
+
+(define_insn_and_split "*movdf_internal"
+ [(set (match_operand:DF 0 "push_operand" "=m, m")
+ (match_operand:DF 1 "general_operand" "f, ro<>E"))]
""
+ "@
+ fmove%.d %f1,%0
+ #"
+ "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 1)"
+ [(const_int 0)]
{
- if (FP_REG_P (operands[1]))
- return "fmove%.d %f1,%0";
- return output_move_double (operands);
-})
+ m68k_emit_move_double (operands);
+ DONE;
+}
+ [(set_attr "type" "fmove,*")
+ (set_attr "split" "done,*")])
-(define_insn "pushdi"
+(define_insn_and_split "pushdi"
[(set (match_operand:DI 0 "push_operand" "=m")
(match_operand:DI 1 "general_operand" "ro<>Fi"))]
""
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
{
- return output_move_double (operands);
+ m68k_emit_move_double (operands);
+ DONE;
})
;; We don't want to allow a constant operand for test insns because
@@ -194,12 +405,12 @@
xoperands[0] = operands[2];
xoperands[1] = operands[0];
output_move_double (xoperands);
- cc_status.flags |= CC_REVERSED;
+ cc_status.flags |= CC_REVERSED; /*|*/
return "neg%.l %R2\;negx%.l %2";
}
if (find_reg_note (insn, REG_DEAD, operands[0]))
{
- cc_status.flags |= CC_REVERSED;
+ cc_status.flags |= CC_REVERSED; /*|*/
return "neg%.l %R0\;negx%.l %0";
}
else
@@ -217,18 +428,24 @@
""
"m68k_last_compare_had_fp_operands = 0;")
-(define_insn ""
+;; If you think that the 68020 does not support tstl a0,
+;; reread page B-167 of the 68020 manual more carefully.
+(define_insn "*tstsi_internal_68020_cf"
[(set (cc0)
(match_operand:SI 0 "nonimmediate_operand" "rm"))]
- ""
-{
- if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0]))
- return "tst%.l %0";
- /* If you think that the 68020 does not support tstl a0,
- reread page B-167 of the 68020 manual more carefully. */
- /* On an address reg, cmpw may replace cmpl. */
- return "cmp%.w #0,%0";
-})
+ "TARGET_68020 || TARGET_COLDFIRE"
+ "tst%.l %0"
+ [(set_attr "type" "tst_l")])
+
+;; On an address reg, cmpw may replace cmpl.
+(define_insn "*tstsi_internal"
+ [(set (cc0)
+ (match_operand:SI 0 "nonimmediate_operand" "dm,r"))]
+ "!(TARGET_68020 || TARGET_COLDFIRE)"
+ "@
+ tst%.l %0
+ cmp%.w #0,%0"
+ [(set_attr "type" "tst_l,*")])
;; This can't use an address register, because comparisons
;; with address registers as second operand always test the whole word.
@@ -238,11 +455,12 @@
""
"m68k_last_compare_had_fp_operands = 0;")
-(define_insn ""
+(define_insn "*tsthi_internal"
[(set (cc0)
(match_operand:HI 0 "nonimmediate_operand" "dm"))]
""
- "tst%.w %0")
+ "tst%.w %0"
+ [(set_attr "type" "tst_w")])
(define_expand "tstqi"
[(set (cc0)
@@ -250,11 +468,12 @@
""
"m68k_last_compare_had_fp_operands = 0;")
-(define_insn ""
+(define_insn "*tstqi_internal"
[(set (cc0)
(match_operand:QI 0 "nonimmediate_operand" "dm"))]
""
- "tst%.b %0")
+ "tst%.b %0"
+ [(set_attr "type" "tst_b")])
(define_expand "tst<mode>"
[(set (cc0)
@@ -284,7 +503,8 @@
if (FP_REG_P (operands[0]))
return "ftst%.d %0";
return "ftst%.<FP:prec> %0";
-})
+}
+ [(set_attr "type" "ftst")])
;; compare instructions.
@@ -309,7 +529,7 @@
return "sub%.l %R2,%R0\;subx%.l %2,%0";
else
{
- cc_status.flags |= CC_REVERSED;
+ cc_status.flags |= CC_REVERSED; /*|*/
return "sub%.l %R1,%R0\;subx%.l %1,%0";
}
})
@@ -335,7 +555,7 @@
if (REG_P (operands[1])
|| (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
{
- cc_status.flags |= CC_REVERSED;
+ cc_status.flags |= CC_REVERSED; /*|*/
return "cmp%.l %d0,%d1";
}
if (ADDRESS_REG_P (operands[0])
@@ -346,7 +566,7 @@
return "cmp%.l %d1,%d0";
})
-(define_insn ""
+(define_insn "*cmpsi_cf"
[(set (cc0)
(compare (match_operand:SI 0 "nonimmediate_operand" "mrKs,r")
(match_operand:SI 1 "general_operand" "r,mrKs")))]
@@ -355,11 +575,12 @@
if (REG_P (operands[1])
|| (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
{
- cc_status.flags |= CC_REVERSED;
+ cc_status.flags |= CC_REVERSED; /*|*/
return "cmp%.l %d0,%d1";
}
return "cmp%.l %d1,%d0";
-})
+}
+ [(set_attr "type" "cmp_l")])
(define_expand "cmphi"
[(set (cc0)
@@ -403,7 +624,7 @@
if (REG_P (operands[1])
|| (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
{
- cc_status.flags |= CC_REVERSED;
+ cc_status.flags |= CC_REVERSED; /*|*/
return "cmp%.b %d0,%d1";
}
return "cmp%.b %d1,%d0";
@@ -434,9 +655,10 @@
else
return "fcmp%.<FP:prec> %f1,%0";
}
- cc_status.flags |= CC_REVERSED;
+ cc_status.flags |= CC_REVERSED; /*|*/
return "fcmp%.<FP:prec> %f0,%1";
-})
+}
+ [(set_attr "type" "fcmp")])
(define_insn "cmp<mode>_cf"
[(set (cc0)
@@ -452,9 +674,10 @@
else
return "fcmp%.<FP:prec> %f1,%0";
}
- cc_status.flags |= CC_REVERSED;
+ cc_status.flags |= CC_REVERSED; /*|*/
return "fcmp%.<FP:prec> %f0,%1";
-})
+}
+ [(set_attr "type" "fcmp")])
;; Recognizers for btst instructions.
@@ -578,16 +801,15 @@
;; A special case in which it is not desirable
;; to reload the constant into a data register.
(define_insn "pushexthisi_const"
- [(set (match_operand:SI 0 "push_operand" "=m")
- (match_operand:SI 1 "const_int_operand" "J"))]
+ [(set (match_operand:SI 0 "push_operand" "=m,m,m")
+ (match_operand:SI 1 "const_int_operand" "C0,R,J"))]
"INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000"
-{
- if (operands[1] == const0_rtx)
- return "clr%.l %0";
- if (valid_mov3q_const (INTVAL (operands[1])))
- return "mov3q%.l %1,%-";
- return "pea %a1";
-})
+ "@
+ clr%.l %0
+ mov3q%.l %1,%-
+ pea %a1"
+ [(set_attr "type" "clr_l,mov3q_l,pea")
+ (set_attr "split" "done")])
;This is never used.
;(define_insn "swapsi"
@@ -597,30 +819,52 @@
; ""
; "exg %1,%0")
-;; Special case of fullword move when source is zero.
-;; The reason this is special is to avoid loading a zero
-;; into a data reg with moveq in order to store it elsewhere.
-
-(define_insn "movsi_const0"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+;; Special case of fullword move when source is zero for 68000_10.
+;; moveq is faster on the 68000.
+(define_insn "*movsi_const0_68000_10"
+ [(set (match_operand:SI 0 "movsi_const0_operand" "=d,a,g")
+ (const_int 0))]
+ "TUNE_68000_10"
+ "@
+ moveq #0,%0
+ sub%.l %0,%0
+ clr%.l %0"
+ [(set_attr "type" "moveq_l,sub_l,clr_l")
+ (set_attr "opy_type" "imm_q,reg,*")
+ (set_attr "split" "done")])
+
+;; Special case of fullword move when source is zero for 68040_60.
+;; On the '040, 'subl an,an' takes 2 clocks while lea takes only 1
+(define_insn "*movsi_const0_68040_60"
+ [(set (match_operand:SI 0 "movsi_const0_operand" "=a,g")
(const_int 0))]
- ;; clr insns on 68000 read before writing.
- "((TARGET_68010 || TARGET_COLDFIRE)
- || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))"
+ "TUNE_68040_60"
{
- if (ADDRESS_REG_P (operands[0]))
+ if (which_alternative == 0)
+ return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
+ else if (which_alternative == 1)
+ return "clr%.l %0";
+ else
{
- /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
- if (TUNE_68040_60)
- return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
- else
- return "sub%.l %0,%0";
+ gcc_unreachable ();
+ return "";
}
- /* moveq is faster on the 68000. */
- if (DATA_REG_P (operands[0]) && TUNE_68000_10)
- return "moveq #0,%0";
- return "clr%.l %0";
-})
+}
+ [(set_attr "type" "lea,clr_l")
+ (set_attr "opy_type" "imm_w,*")
+ (set_attr "split" "done")])
+
+;; Special case of fullword move when source is zero.
+(define_insn "*movsi_const0"
+ [(set (match_operand:SI 0 "movsi_const0_operand" "=a,g")
+ (const_int 0))]
+ "!(TUNE_68000_10 || TUNE_68040_60)"
+ "@
+ sub%.l %0,%0
+ clr%.l %0"
+ [(set_attr "type" "sub_l,clr_l")
+ (set_attr "opy_type" "reg,*")
+ (set_attr "split" "done")])
;; General case of fullword move.
;;
@@ -688,10 +932,59 @@
;; ColdFire move instructions can have at most one operand of mode >= 6.
(define_insn "*movsi_cf"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U")
- (match_operand:SI 1 "general_operand" "g,Rr<Q>,U"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d, d, d, d, d, a,Ap, a, r<Q>,g, U")
+ (match_operand:SI 1 "general_operand" " R,CQ,CW,CZ,CS,Ci,J,J Cs,Cs, g, Rr<Q>,U"))]
"TARGET_COLDFIRE"
- "* return output_move_simode (operands);")
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "mov3q%.l %1,%0";
+
+ case 1:
+ return "moveq %1,%0";
+
+ case 2:
+ {
+ unsigned u = INTVAL (operands[1]);
+
+ operands[1] = GEN_INT ((u << 16) | (u >> 16)); /*|*/
+ return "moveq %1,%0\n\tswap %0";
+ }
+
+ case 3:
+ return "mvz%.w %1,%0";
+
+ case 4:
+ return "mvs%.w %1,%0";
+
+ case 5:
+ return "move%.l %1,%0";
+
+ case 6:
+ return "move%.w %1,%0";
+
+ case 7:
+ return "pea %a1";
+
+ case 8:
+ return "lea %a1,%0";
+
+ case 9:
+ case 10:
+ case 11:
+ return "move%.l %1,%0";
+
+ default:
+ gcc_unreachable ();
+ return "";
+ }
+}
+ [(set_attr "type" "mov3q_l, moveq_l,*, mvz_w, mvs_w, move_l, move_w, pea, lea, move_l, move_l, move_l")
+ (set (attr "split")
+ (if_then_else (eq_attr "alternative" "2")
+ (const_string "*")
+ (const_string "done")))])
;; Special case of fullword move, where we need to get a non-GOT PIC
;; reference into an address register.
@@ -771,11 +1064,17 @@
"!TARGET_COLDFIRE"
"* return output_move_strictqi (operands);")
-(define_insn ""
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d,m"))
- (match_operand:QI 1 "general_src_operand" "dmn,d"))]
+(define_insn "*movstrictqi_cf"
+ [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d, Ac, d,m"))
+ (match_operand:QI 1 "general_src_operand" "C0,C0, dmn,d"))]
"TARGET_COLDFIRE"
- "* return output_move_strictqi (operands);")
+ "@
+ clr%.b %0
+ clr%.b %0
+ move%.b %1,%0
+ move%.b %1,%0"
+ [(set_attr "type" "clr_b,clr_b,move_b,move_b")
+ (set_attr "split" "done")])
(define_expand "pushqi1"
[(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))
@@ -864,9 +1163,8 @@
[(set (match_operand:SF 0 "nonimmediate_operand" "=r<Q>,g,U")
(match_operand:SF 1 "general_operand" "g,r<Q>,U"))]
"TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
-{
- return "move%.l %1,%0";
-})
+ "move%.l %1,%0"
+ [(set_attr "type" "move_l")])
;; SFmode MEMs are restricted to modes 2-4 if TARGET_COLDFIRE_FPU.
;; The move instructions can handle all combinations.
@@ -1003,12 +1301,16 @@
return output_move_double (operands);
})
-(define_insn "movdf_cf_soft"
+(define_insn_and_split "movdf_cf_soft"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,g")
(match_operand:DF 1 "general_operand" "g,r"))]
"TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
{
- return output_move_double (operands);
+ m68k_emit_move_double (operands);
+ DONE;
})
(define_insn "movdf_cf_hard"
@@ -1230,7 +1532,8 @@
[(set (match_operand:SI 0 "push_operand" "=m")
(match_operand:SI 1 "address_operand" "p"))]
""
- "pea %a1")
+ "pea %a1"
+ [(set_attr "type" "pea")])
;; truncation instructions
(define_insn "truncsiqi2"
@@ -1391,7 +1694,8 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
"ISA_HAS_MVS_MVZ"
- "mvz%.w %1,%0")
+ "mvz%.w %1,%0"
+ [(set_attr "type" "mvz_w")])
(define_insn "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=d")
@@ -1415,7 +1719,8 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
"ISA_HAS_MVS_MVZ"
- "mvz%.b %1,%0")
+ "mvz%.b %1,%0"
+ [(set_attr "type" "mvz_b")])
(define_insn "zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=d")
@@ -1567,24 +1872,25 @@
(sign_extend:SI
(match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
"ISA_HAS_MVS_MVZ"
- "mvs%.w %1,%0")
+ "mvs%.w %1,%0"
+ [(set_attr "type" "mvs_w")])
(define_insn "*68k_extendhisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
(sign_extend:SI
(match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
"!ISA_HAS_MVS_MVZ"
-{
- if (ADDRESS_REG_P (operands[0]))
- return "move%.w %1,%0";
- return "ext%.l %0";
-})
+ "@
+ ext%.l %0
+ move%.w %1,%0"
+ [(set_attr "type" "ext_l,move_w")])
(define_insn "extendqihi2"
[(set (match_operand:HI 0 "nonimmediate_operand" "=d")
(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
""
- "ext%.w %0")
+ "ext%.w %0"
+ [(set_attr "type" "ext_w")])
(define_expand "extendqisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
@@ -1596,13 +1902,15 @@
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))]
"ISA_HAS_MVS_MVZ"
- "mvs%.b %1,%0")
+ "mvs%.b %1,%0"
+ [(set_attr "type" "mvs_b")])
(define_insn "*68k_extendqisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
"TARGET_68020 || (TARGET_COLDFIRE && !ISA_HAS_MVS_MVZ)"
- "extb%.l %0")
+ "extb%.l %0"
+ [(set_attr "type" "extb_l")])
;; Conversions between float and double.
@@ -1691,14 +1999,16 @@
"TARGET_COLDFIRE_FPU"
"@
fsmove%.d %1,%0
- fmove%.s %1,%0")
+ fmove%.s %1,%0"
+ [(set_attr "type" "fmove")])
-(define_insn ""
+(define_insn "*truncdfsf2_68881"
[(set (match_operand:SF 0 "nonimmediate_operand" "=dm")
(float_truncate:SF
(match_operand:DF 1 "general_operand" "f")))]
"TARGET_68881"
- "fmove%.s %f1,%0")
+ "fmove%.s %f1,%0"
+ [(set_attr "type" "fmove")])
;; Conversion between fixed point and floating point.
;; Note that among the fix-to-float insns
@@ -1724,7 +2034,8 @@
[(set (match_operand:FP 0 "nonimmediate_operand" "=f")
(float:FP (match_operand:SI 1 "general_operand" "d<Q>U")))]
"TARGET_COLDFIRE_FPU"
- "f<FP:prec>move%.l %1,%0")
+ "f<FP:prec>move%.l %1,%0"
+ [(set_attr "type" "fmove")])
(define_expand "floathi<mode>2"
@@ -1737,13 +2048,15 @@
[(set (match_operand:FP 0 "nonimmediate_operand" "=f")
(float:FP (match_operand:HI 1 "general_operand" "dmn")))]
"TARGET_68881"
- "fmove%.w %1,%0")
+ "fmove%.w %1,%0"
+ [(set_attr "type" "fmove")])
(define_insn "floathi<mode>2_cf"
[(set (match_operand:FP 0 "nonimmediate_operand" "=f")
(float:FP (match_operand:HI 1 "general_operand" "d<Q>U")))]
"TARGET_COLDFIRE_FPU"
- "fmove%.w %1,%0")
+ "fmove%.w %1,%0"
+ [(set_attr "type" "fmove")])
(define_expand "floatqi<mode>2"
@@ -1756,13 +2069,15 @@
[(set (match_operand:FP 0 "nonimmediate_operand" "=f")
(float:FP (match_operand:QI 1 "general_operand" "dmn")))]
"TARGET_68881"
- "fmove%.b %1,%0")
+ "fmove%.b %1,%0"
+ [(set_attr "type" "fmove")])
(define_insn "floatqi<mode>2_cf"
[(set (match_operand:FP 0 "nonimmediate_operand" "=f")
(float:FP (match_operand:QI 1 "general_operand" "d<Q>U")))]
"TARGET_COLDFIRE_FPU"
- "fmove%.b %1,%0")
+ "fmove%.b %1,%0"
+ [(set_attr "type" "fmove")])
;; New routines to convert floating-point values to integers
@@ -1830,7 +2145,8 @@
if (FP_REG_P (operands[1]))
return "fintrz%.d %f1,%0";
return "fintrz%.<FP:prec> %f1,%0";
-})
+}
+ [(set_attr "type" "fintrz")])
;; Convert a float whose value is an integer
;; to an actual integer. Second stage of converting float to integer type.
@@ -1850,7 +2166,8 @@
[(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>U")
(fix:QI (match_operand:FP 1 "general_operand" "f")))]
"TARGET_COLDFIRE_FPU"
- "fmove%.b %1,%0")
+ "fmove%.b %1,%0"
+ [(set_attr "type" "fmove")])
(define_expand "fix<mode>hi2"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
@@ -1868,7 +2185,8 @@
[(set (match_operand:HI 0 "nonimmediate_operand" "=d<Q>U")
(fix:HI (match_operand:FP 1 "general_operand" "f")))]
"TARGET_COLDFIRE_FPU"
- "fmove%.w %1,%0")
+ "fmove%.w %1,%0"
+ [(set_attr "type" "fmove")])
(define_expand "fix<mode>si2"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
@@ -1886,7 +2204,8 @@
[(set (match_operand:SI 0 "nonimmediate_operand" "=d<Q>U")
(fix:SI (match_operand:FP 1 "general_operand" "f")))]
"TARGET_COLDFIRE_FPU"
- "fmove%.l %1,%0")
+ "fmove%.l %1,%0"
+ [(set_attr "type" "fmove")])
;; add instructions
@@ -1984,7 +2303,8 @@
else
operands[1] = adjust_address (operands[1], SImode, 4);
return "add%.l %1,%0";
-})
+}
+ [(set_attr "type" "add_l")])
(define_insn "adddi3"
[(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d")
@@ -2107,12 +2427,54 @@
"! TARGET_COLDFIRE"
"* return output_addsi3 (operands);")
-(define_insn "*addsi3_5200"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,r")
- (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
- (match_operand:SI 2 "general_src_operand" "dIL,rJK,a,mrIKLi")))]
+(define_insn_and_split "*addsi3_5200"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,m,r, ?a,?a,?a,?a")
+ (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0,0, a, a, r, a")
+ (match_operand:SI 2 "general_src_operand" " I, L, d,mrKi,Cj,r, a, J")))]
"TARGET_COLDFIRE"
- "* return output_addsi3 (operands);")
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "addq%.l %2,%0";
+
+ case 1:
+ operands[2] = GEN_INT (- INTVAL (operands[2]));
+ return "subq%.l %2,%0";
+
+ case 2:
+ case 3:
+ return "add%.l %2,%0";
+
+ case 4:
+ /* move%.l %2,%0\n\tadd%.l %1,%0 */
+ return "#";
+
+ case 5:
+ return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
+
+ case 6:
+ return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0";
+
+ case 7:
+ return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
+
+ default:
+ gcc_unreachable ();
+ return "";
+ }
+}
+ "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 4) && !operands_match_p (operands[0], operands[1])"
+ [(set (match_dup 0)
+ (match_dup 2))
+ (set (match_dup 0)
+ (plus:SI (match_dup 0)
+ (match_dup 1)))]
+ ""
+ [(set_attr "type" "addq_l,subq_l,add_l,add_l,*,lea,lea,lea")
+ (set_attr "opy" "2,2,2,2,*,*,*,*")
+ (set_attr "opy_type" "*,*,*,*,*,mem6,mem6,mem5")
+ (set_attr "split" "done,done,done,done,*,done,done,done")])
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=a")
@@ -2392,7 +2754,8 @@
if (FP_REG_P (operands[2]))
return "f<FP:prec>add%.d %2,%0";
return "f<FP:prec>add%.<FP:prec> %2,%0";
-})
+}
+ [(set_attr "type" "fadd")])
;; subtract instructions
@@ -2426,7 +2789,8 @@
else
operands[1] = adjust_address (operands[1], SImode, 4);
return "sub%.l %1,%0";
-})
+}
+ [(set_attr "type" "sub_l")])
(define_insn "subdi3"
[(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d")
@@ -2508,11 +2872,17 @@
})
(define_insn "subsi3"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d,a")
- (minus:SI (match_operand:SI 1 "general_operand" "0,0,0")
- (match_operand:SI 2 "general_src_operand" "dT,mSrT,mSrs")))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=mda,m,d,a")
+ (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
+ (match_operand:SI 2 "general_src_operand" "I,dT,mSrT,mSrs")))]
""
- "sub%.l %2,%0")
+ "@
+ subq%.l %2, %0
+ sub%.l %2,%0
+ sub%.l %2,%0
+ sub%.l %2,%0"
+ [(set_attr "type" "subq_l,sub_l,sub_l,sub_l")
+ (set_attr "opy" "2")])
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=a")
@@ -2598,7 +2968,8 @@
if (FP_REG_P (operands[2]))
return "f<FP:prec>sub%.d %2,%0";
return "f<FP:prec>sub%.<FP:prec> %2,%0";
-})
+}
+ [(set_attr "type" "fsub")])
;; multiply instructions
@@ -2609,7 +2980,9 @@
""
{
return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
-})
+}
+ [(set_attr "type" "muls_w")
+ (set_attr "opy" "2")])
(define_insn "mulhisi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
@@ -2620,9 +2993,11 @@
""
{
return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
-})
+}
+ [(set_attr "type" "muls_w")
+ (set_attr "opy" "2")])
-(define_insn ""
+(define_insn "*mulhisisi3_s"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(mult:SI (sign_extend:SI
(match_operand:HI 1 "nonimmediate_operand" "%0"))
@@ -2630,7 +3005,9 @@
"INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
{
return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
-})
+}
+ [(set_attr "type" "muls_w")
+ (set_attr "opy" "2")])
(define_expand "mulsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
@@ -2639,20 +3016,24 @@
"TARGET_68020 || TARGET_COLDFIRE"
"")
-(define_insn ""
+(define_insn "*mulsi3_68020"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(mult:SI (match_operand:SI 1 "general_operand" "%0")
(match_operand:SI 2 "general_src_operand" "dmSTK")))]
"TARGET_68020"
- "muls%.l %2,%0")
+ "muls%.l %2,%0"
+ [(set_attr "type" "muls_l")
+ (set_attr "opy" "2")])
-(define_insn ""
+(define_insn "*mulsi3_cf"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(mult:SI (match_operand:SI 1 "general_operand" "%0")
(match_operand:SI 2 "general_operand" "d<Q>")))]
"TARGET_COLDFIRE"
- "muls%.l %2,%0")
+ "muls%.l %2,%0"
+ [(set_attr "type" "muls_l")
+ (set_attr "opy" "2")])
(define_insn "umulhisi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
@@ -2663,9 +3044,11 @@
""
{
return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
-})
+}
+ [(set_attr "type" "mulu_w")
+ (set_attr "opy" "2")])
-(define_insn ""
+(define_insn "*mulhisisi3_z"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(mult:SI (zero_extend:SI
(match_operand:HI 1 "nonimmediate_operand" "%0"))
@@ -2673,7 +3056,9 @@
"INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
{
return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
-})
+}
+ [(set_attr "type" "mulu_w")
+ (set_attr "opy" "2")])
;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
;; proper matching constraint. This is because the matching is between
@@ -2932,7 +3317,8 @@
if (FP_REG_P (operands[2]))
return "f<FP:prec>mul%.d %2,%0";
return "f<FP:prec>mul%.<FP:prec> %2,%0";
-})
+}
+ [(set_attr "type" "fmul")])
;; divide instructions
@@ -3000,7 +3386,8 @@
if (FP_REG_P (operands[2]))
return "f<FP:prec>div%.d %2,%0";
return "f<FP:prec>div%.<FP:prec> %2,%0";
-})
+}
+ [(set_attr "type" "fdiv")])
;; Remainder instructions.
@@ -3692,13 +4079,15 @@
[(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
(neg:SI (match_operand:SI 1 "general_operand" "0")))]
"!TARGET_COLDFIRE"
- "neg%.l %0")
+ "neg%.l %0"
+ [(set_attr "type" "neg_l")])
(define_insn "negsi2_5200"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(neg:SI (match_operand:SI 1 "general_operand" "0")))]
"TARGET_COLDFIRE"
- "neg%.l %0")
+ "neg%.l %0"
+ [(set_attr "type" "neg_l")])
(define_insn "neghi2"
[(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
@@ -3863,7 +4252,8 @@
if (FP_REG_P (operands[1]))
return "f<FP:round>sqrt%.x %1,%0";
return "f<FP:round>sqrt%.<FP:prec> %1,%0";
-})
+}
+ [(set_attr "type" "fsqrt")])
(define_insn "sqrt<mode>2_cf"
[(set (match_operand:FP 0 "nonimmediate_operand" "=f")
@@ -4005,7 +4395,8 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(clz:SI (match_operand:SI 1 "register_operand" "0")))]
"ISA_HAS_FF1"
- "ff1 %0")
+ "ff1 %0"
+ [(set_attr "type" "ff1")])
;; one complement instructions
@@ -4048,7 +4439,8 @@
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(not:SI (match_operand:SI 1 "general_operand" "0")))]
"TARGET_COLDFIRE"
- "not%.l %0")
+ "not%.l %0"
+ [(set_attr "type" "not_l")])
(define_insn "one_cmplhi2"
[(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
@@ -4399,7 +4791,8 @@
if (GET_CODE (operands[1]) != REG)
operands[1] = adjust_address (operands[1], HImode, 2);
return "move%.w %1,%0";
-})
+}
+ [(set_attr "type" "move_w")])
(define_insn "subregsi1ashrdi_const32"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
@@ -4408,7 +4801,8 @@
""
{
return "move%.l %1,%0";
-})
+}
+ [(set_attr "type" "move_l")])
(define_insn "*ashrdi3_const1"
[(set (match_operand:DI 0 "register_operand" "=d")
@@ -4577,7 +4971,9 @@
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "general_operand" "dI")))]
""
- "asr%.l %2,%0")
+ "asr%.l %2,%0"
+ [(set_attr "type" "asr_l")
+ (set_attr "opy" "2")])
(define_insn "ashrhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
@@ -4643,9 +5039,8 @@
(subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32)) 4))]
""
-{
- return "move%.l %1,%0";
-})
+ "move%.l %1,%0"
+ [(set_attr "type" "move_l")])
(define_insn "*lshrdi3_const1"
[(set (match_operand:DI 0 "register_operand" "=d")
@@ -4872,7 +5267,9 @@
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "general_operand" "dI")))]
""
- "lsr%.l %2,%0")
+ "lsr%.l %2,%0"
+ [(set_attr "type" "lsr_l")
+ (set_attr "opy" "2")])
(define_insn "lshrhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
@@ -5029,10 +5426,11 @@
{
CC_STATUS_INIT;
return "bset %1,%0";
-})
+}
+ [(set_attr "type" "bset")])
;; set bit, bit number is (sign/zero)_extended from HImode/QImode
-(define_insn ""
+(define_insn "*bsetmemqi_ext"
[(set (match_operand:QI 0 "memory_operand" "+m")
(ior:QI (subreg:QI (ashift:SI (const_int 1)
(match_operator:SI 2 "extend_operator"
@@ -5042,7 +5440,8 @@
{
CC_STATUS_INIT;
return "bset %1,%0";
-})
+}
+ [(set_attr "type" "bset")])
;; clear bit, bit number is int
(define_insn "bclrmemqi"
@@ -5055,10 +5454,11 @@
{
CC_STATUS_INIT;
return "bclr %1,%0";
-})
+}
+ [(set_attr "type" "bclr")])
;; clear bit, bit number is (sign/zero)_extended from HImode/QImode
-(define_insn ""
+(define_insn "*bclrmemqi_ext"
[(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
(const_int 1)
(minus:SI (const_int 7)
@@ -5069,7 +5469,8 @@
{
CC_STATUS_INIT;
return "bclr %1,%0";
-})
+}
+ [(set_attr "type" "bclr")])
;; Special cases of bit-field insns which we should
;; recognize in preference to the general case.
@@ -5641,14 +6042,15 @@
""
"")
-(define_insn ""
+(define_insn "*scc"
[(set (match_operand:QI 0 "register_operand" "=d")
(geu:QI (cc0) (const_int 0)))]
""
{
cc_status = cc_prev_status;
return "scc %0";
-})
+}
+ [(set_attr "type" "scc")])
(define_expand "sle"
[(set (match_operand:QI 0 "register_operand" "")
@@ -5678,14 +6080,15 @@
""
"")
-(define_insn ""
+(define_insn "*sls"
[(set (match_operand:QI 0 "register_operand" "=d")
(leu:QI (cc0) (const_int 0)))]
""
{
cc_status = cc_prev_status;
return "sls %0";
-})
+}
+ [(set_attr "type" "scc")])
(define_expand "sordered"
[(set (match_operand:QI 0 "register_operand" "")
@@ -6085,7 +6488,9 @@
OUTPUT_JUMP ("jbeq %l0", "fbeq %l0", "jbeq %l0");
else
OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
-})
+}
+ [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))
+ (set_attr "split" "done")])
(define_insn "bne"
[(set (pc)
@@ -6099,7 +6504,9 @@
OUTPUT_JUMP ("jbne %l0", "fbne %l0", "jbne %l0");
else
OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
-})
+}
+ [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))
+ (set_attr "split" "done")])
(define_insn "bgt"
[(set (pc)
@@ -6113,7 +6520,9 @@
OUTPUT_JUMP ("jbgt %l0", "fbgt %l0", 0);
else
OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0);
-})
+}
+ [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))
+ (set_attr "split" "done")])
(define_insn "bgtu"
[(set (pc)
@@ -6124,7 +6533,8 @@
""
{
return MOTOROLA ? "jbhi %l0" : "jhi %l0";
-})
+}
+ [(set_attr "type" "bcc")])
(define_insn "blt"
[(set (pc)
@@ -6138,7 +6548,9 @@
OUTPUT_JUMP ("jblt %l0", "fblt %l0", "jbmi %l0");
else
OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0");
-})
+}
+ [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))
+ (set_attr "split" "done")])
(define_insn "bltu"
[(set (pc)
@@ -6149,7 +6561,8 @@
""
{
return MOTOROLA ? "jbcs %l0" : "jcs %l0";
-})
+}
+ [(set_attr "type" "bcc")])
(define_insn "bge"
[(set (pc)
@@ -6174,7 +6587,8 @@
""
{
return MOTOROLA ? "jbcc %l0" : "jcc %l0";
-})
+}
+ [(set_attr "type" "bcc")])
(define_insn "ble"
[(set (pc)
@@ -6188,7 +6602,8 @@
OUTPUT_JUMP ("jble %l0", "fble %l0", 0);
else
OUTPUT_JUMP ("jle %l0", "fjle %l0", 0);
-})
+}
+ [(set_attr "type" "bcc")])
(define_insn "bleu"
[(set (pc)
@@ -6199,7 +6614,8 @@
""
{
return MOTOROLA ? "jbls %l0" : "jls %l0";
-})
+}
+ [(set_attr "type" "bcc")])
(define_insn "bordered"
[(set (pc)
@@ -6291,7 +6707,7 @@
;; Negated conditional jump instructions.
-(define_insn ""
+(define_insn "*beq2"
[(set (pc)
(if_then_else (eq (cc0)
(const_int 0))
@@ -6303,9 +6719,10 @@
OUTPUT_JUMP ("jbne %l0", "fbne %l0", "jbne %l0");
else
OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*bne2"
[(set (pc)
(if_then_else (ne (cc0)
(const_int 0))
@@ -6317,9 +6734,10 @@
OUTPUT_JUMP ("jbeq %l0", "fbeq %l0", "jbeq %l0");
else
OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*bgt2"
[(set (pc)
(if_then_else (gt (cc0)
(const_int 0))
@@ -6331,9 +6749,10 @@
OUTPUT_JUMP ("jble %l0", "fbngt %l0", 0);
else
OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0);
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*bgtu2"
[(set (pc)
(if_then_else (gtu (cc0)
(const_int 0))
@@ -6342,9 +6761,10 @@
""
{
return MOTOROLA ? "jbls %l0" : "jls %l0";
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*blt2"
[(set (pc)
(if_then_else (lt (cc0)
(const_int 0))
@@ -6356,9 +6776,10 @@
OUTPUT_JUMP ("jbge %l0", "fbnlt %l0", "jbpl %l0");
else
OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0");
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*bltu2"
[(set (pc)
(if_then_else (ltu (cc0)
(const_int 0))
@@ -6367,9 +6788,10 @@
""
{
return MOTOROLA ? "jbcc %l0" : "jcc %l0";
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*bge2"
[(set (pc)
(if_then_else (ge (cc0)
(const_int 0))
@@ -6381,9 +6803,10 @@
OUTPUT_JUMP ("jblt %l0", "fbnge %l0", "jbmi %l0");
else
OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0");
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*bgeu2"
[(set (pc)
(if_then_else (geu (cc0)
(const_int 0))
@@ -6392,9 +6815,10 @@
""
{
return MOTOROLA ? "jbcs %l0" : "jcs %l0";
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*ble2"
[(set (pc)
(if_then_else (le (cc0)
(const_int 0))
@@ -6406,9 +6830,10 @@
OUTPUT_JUMP ("jbgt %l0", "fbnle %l0", 0);
else
OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0);
-})
+}
+ [(set_attr "type" "bcc")])
-(define_insn ""
+(define_insn "*bleu2"
[(set (pc)
(if_then_else (leu (cc0)
(const_int 0))
@@ -6417,7 +6842,8 @@
""
{
return MOTOROLA ? "jbhi %l0" : "jhi %l0";
-})
+}
+ [(set_attr "type" "bcc")])
(define_insn "*bordered_rev"
[(set (pc)
@@ -6514,7 +6940,8 @@
""
{
return MOTOROLA ? "jbra %l0" : "jra %l0";
-})
+}
+ [(set_attr "type" "bra")])
(define_expand "tablejump"
[(parallel [(set (pc) (match_operand 0 "" ""))
@@ -6528,13 +6955,14 @@
})
;; Jump to variable address from dispatch table of absolute addresses.
-(define_insn ""
+(define_insn "*tablejump_internal"
[(set (pc) (match_operand:SI 0 "register_operand" "a"))
(use (label_ref (match_operand 1 "" "")))]
""
{
return MOTOROLA ? "jmp (%0)" : "jmp %0@";
-})
+}
+ [(set_attr "type" "bra")])
;; Jump to variable address from dispatch table of relative addresses.
(define_insn ""
@@ -6746,16 +7174,46 @@
operands[1] = m68k_legitimize_call_address (operands[1]);
})
-(define_insn "*call_value"
+(define_insn "*non_symbolic_call_value"
[(set (match_operand 0 "" "=rf,rf")
- (call (mem:QI (match_operand:SI 1 "call_operand" "a,W"))
+ (call (mem:QI (match_operand:SI 1 "non_symbolic_call_operand" "a,W"))
(match_operand:SI 2 "general_operand" "g,g")))]
;; Operand 2 not really used on the m68000.
"!SIBLING_CALL_P (insn)"
+ "jsr %a1"
+ [(set_attr "type" "jsr")
+ (set_attr "split" "done")
+ (set_attr "opx" "1")])
+
+(define_insn "*symbolic_call_value_jsr"
+ [(set (match_operand 0 "" "=rf,rf")
+ (call (mem:QI (match_operand:SI 1 "symbolic_operand" "a,W"))
+ (match_operand:SI 2 "general_operand" "g,g")))]
+ ;; Operand 2 not really used on the m68000.
+ "!SIBLING_CALL_P (insn) && m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_JSR"
{
operands[0] = operands[1];
- return output_call (operands[0]);
-})
+ return m68k_symbolic_call;
+}
+ [(set_attr "type" "jsr")
+ (set_attr "split" "done")
+ (set_attr "opx" "1")])
+
+(define_insn "*symbolic_call_value_bsr"
+ [(set (match_operand 0 "" "=rf,rf")
+ (call (mem:QI (match_operand:SI 1 "symbolic_operand" "a,W"))
+ (match_operand:SI 2 "general_operand" "g,g")))]
+ ;; Operand 2 not really used on the m68000.
+ "!SIBLING_CALL_P (insn)
+ && (m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_BSR_C
+ || m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_BSR_P)"
+{
+ operands[0] = operands[1];
+ return m68k_symbolic_call;
+}
+ [(set_attr "type" "bsr")
+ (set_attr "split" "done")
+ (set_attr "opx" "1")])
;; Call subroutine returning any type.
@@ -6796,7 +7254,8 @@
(define_insn "nop"
[(const_int 0)]
""
- "nop")
+ "nop"
+ [(set_attr "type" "nop")])
(define_expand "prologue"
[(const_int 0)]
@@ -6849,7 +7308,8 @@
else
return "rts";
}
-})
+}
+ [(set_attr "type" "rts")])
(define_insn "*m68k_store_multiple"
[(match_parallel 0 "" [(match_operand 1 "")])]
@@ -6939,7 +7399,8 @@
(plus:SI (match_dup 0)
(const_int 4)))]
""
- "unlk %0")
+ "unlk %0"
+ [(set_attr "type" "unlk")])
(define_insn "load_got"
[(set (match_operand:SI 0 "register_operand" "=a")
@@ -6971,7 +7432,8 @@
(define_insn "indirect_jump"
[(set (pc) (match_operand:SI 0 "address_operand" "p"))]
""
- "jmp %a0")
+ "jmp %a0"
+ [(set_attr "type" "jmp")])
;; This should not be used unless the add/sub insns can't be.
@@ -7373,10 +7835,12 @@
return "fcos%.<FP:prec> %1,%0";
})
+;; Unconditional traps are assumed to have (const_int 1) for the condition.
(define_insn "trap"
- [(trap_if (const_int -1) (const_int 7))]
+ [(trap_if (const_int 1) (const_int 7))]
""
- "trap #7")
+ "trap #7"
+ [(set_attr "type" "trap")])
(define_insn "conditional_trap"
[(trap_if (match_operator 0 "valid_dbcc_comparison_p"
@@ -7399,3 +7863,12 @@
default: gcc_unreachable ();
}
})
+
+;; Instruction that subscribes one word in ColdFire instruction buffer.
+;; This instruction is used within scheduler only and should not appear
+;; in the instruction stream.
+(define_insn "ib"
+ [(unspec [(const_int 0)] UNSPEC_IB)]
+ ""
+ "#"
+ [(set_attr "type" "ib")])