;;- Machine description for GNU compiler, Motorola 68000 Version
-;; Copyright (C) 1987, 88, 93, 94, 95, 1996 Free Software Foundation, Inc.
+;; Copyright (C) 1987, 88, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
;; This file is part of GNU CC.
;;- 'K' all integers EXCEPT -128 .. 127
;;- 'L' -8 .. -1
;;- 'M' all integers EXCEPT -256 .. 255
+;;- 'N' 24 .. 31
+;;- 'O' 16
+;;- 'P' 8 .. 15
;;- Assembler specs:
;;- "%." size separator ("." or "") move%.l d0,d1
;; (set (cc0) (const_int foo)) has no mode information. Such insns will
;; be folded while optimizing anyway.
-(define_insn "tstdi"
+(define_expand "tstdi"
+ [(parallel [(set (cc0)
+ (match_operand:DI 0 "nonimmediate_operand" ""))
+ (clobber (match_scratch:SI 1 ""))
+ (clobber (match_scratch:DI 2 ""))])]
+ ""
+ "m68k_last_compare_had_fp_operands = 0;")
+
+(define_insn ""
[(set (cc0)
(match_operand:DI 0 "nonimmediate_operand" "am,d"))
(clobber (match_scratch:SI 1 "=X,d"))
return \"sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0\";
}")
-(define_insn "tstsi"
+(define_expand "tstsi"
+ [(set (cc0)
+ (match_operand:SI 0 "nonimmediate_operand" ""))]
+ ""
+ "m68k_last_compare_had_fp_operands = 0;")
+
+(define_insn ""
[(set (cc0)
(match_operand:SI 0 "nonimmediate_operand" "rm"))]
""
;; This can't use an address register, because comparisons
;; with address registers as second operand always test the whole word.
-(define_insn "tsthi"
+(define_expand "tsthi"
+ [(set (cc0)
+ (match_operand:HI 0 "nonimmediate_operand" ""))]
+ ""
+ "m68k_last_compare_had_fp_operands = 0;")
+
+(define_insn ""
[(set (cc0)
(match_operand:HI 0 "nonimmediate_operand" "dm"))]
""
"tst%.w %0")
-(define_insn "tstqi"
+(define_expand "tstqi"
+ [(set (cc0)
+ (match_operand:QI 0 "nonimmediate_operand" ""))]
+ ""
+ "m68k_last_compare_had_fp_operands = 0;")
+
+(define_insn ""
[(set (cc0)
(match_operand:QI 0 "nonimmediate_operand" "dm"))]
""
"TARGET_68881 || TARGET_FPA"
"
{
+ m68k_last_compare_had_fp_operands = 1;
if (TARGET_FPA)
{
emit_insn (gen_tstsf_fpa (operands[0]));
"TARGET_68881 || TARGET_FPA"
"
{
+ m68k_last_compare_had_fp_operands = 1;
if (TARGET_FPA)
{
emit_insn (gen_tstsf_fpa (operands[0]));
(match_operand:DI 1 "general_operand" "")))
(clobber (match_dup 2))])]
""
- "operands[2] = gen_reg_rtx (DImode);")
+ "m68k_last_compare_had_fp_operands = 0; operands[2] = gen_reg_rtx (DImode);")
(define_insn ""
[(set (cc0)
""
"
{
+ m68k_last_compare_had_fp_operands = 0;
if (flag_pic && symbolic_operand (operands[1], SImode))
{
/* The source is an address which requires PIC relocation.
}
}")
-;; A composite of the cmp, cmpa, & cmpi m68000 op codes.
+;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
(define_insn ""
[(set (cc0)
(compare (match_operand:SI 0 "nonimmediate_operand" "rKs,mr,>")
- (match_operand:SI 1 "general_operand" "mr,Ksr,>")))]
- ""
+ (match_operand:SI 1 "general_operand" "mr,rKs,>")))]
+ "!TARGET_5200"
"*
{
if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
#endif
}")
-(define_insn "cmphi"
+(define_insn ""
+ [(set (cc0)
+ (compare (match_operand:SI 0 "nonimmediate_operand" "mrKs,r")
+ (match_operand:SI 1 "general_operand" "r,mrKs")))]
+ "TARGET_5200"
+ "*
+{
+ if (REG_P (operands[1])
+ || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
+ { cc_status.flags |= CC_REVERSED;
+#ifdef SGS_CMP_ORDER
+ return \"cmp%.l %d1,%d0\";
+#else
+ return \"cmp%.l %d0,%d1\";
+#endif
+ }
+#ifdef SGS_CMP_ORDER
+ return \"cmp%.l %d0,%d1\";
+#else
+ return \"cmp%.l %d1,%d0\";
+#endif
+}")
+
+(define_expand "cmphi"
+ [(set (cc0)
+ (compare (match_operand:HI 0 "nonimmediate_operand" "")
+ (match_operand:HI 1 "general_operand" "")))]
+ "!TARGET_5200"
+ "m68k_last_compare_had_fp_operands = 0;")
+
+(define_insn ""
[(set (cc0)
(compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m,>")
(match_operand:HI 1 "general_operand" "d,rnm,m,n,>")))]
#endif
}")
-(define_insn "cmpqi"
+(define_expand "cmpqi"
+ [(set (cc0)
+ (compare (match_operand:QI 0 "nonimmediate_operand" "")
+ (match_operand:QI 1 "general_operand" "")))]
+ "!TARGET_5200"
+ "m68k_last_compare_had_fp_operands = 0;")
+
+(define_insn ""
[(set (cc0)
(compare (match_operand:QI 0 "nonimmediate_operand" "dn,md,>")
(match_operand:QI 1 "general_operand" "dm,nd,>")))]
"TARGET_68881 || TARGET_FPA"
"
{
+ m68k_last_compare_had_fp_operands = 1;
if (TARGET_FPA)
{
emit_insn (gen_cmpdf_fpa (operands[0], operands[1]));
"TARGET_68881 || TARGET_FPA"
"
{
+ m68k_last_compare_had_fp_operands = 1;
if (TARGET_FPA)
{
emit_insn (gen_cmpsf_fpa (operands[0], operands[1]));
"*
{
if (ADDRESS_REG_P (operands[0]))
- return \"sub%.l %0,%0\";
+ {
+ /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
+ if (!TARGET_68040 && !TARGET_68060)
+ return \"sub%.l %0,%0\";
+ else
+ {
+#ifdef MOTOROLA
+#ifdef SGS
+ /* Many SGS assemblers croak on size specifiers for constants. */
+ return \"lea 0,%0\";
+#else
+ return \"lea 0.w,%0\";
+#endif
+#else
+ return \"lea 0:w,%0\";
+#endif
+ }
+ }
/* moveq is faster on the 68000. */
if (DATA_REG_P (operands[0]) && (!TARGET_68020 && !TARGET_5200))
#if defined(MOTOROLA) && !defined(CRDS)
;; We do allow y and x regs since fixed point is allowed in them.
[(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m")
(match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))]
- ""
+ "!TARGET_5200"
"*
{
if (which_alternative == 3)
return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\";
if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0]))
return \"fpmove%.l %x1,%x0\";
- if (GET_CODE (operands[1]) == CONST_INT)
- return output_move_simode_const (operands);
- else if ((GET_CODE (operands[1]) == SYMBOL_REF
- || GET_CODE (operands[1]) == CONST)
- && push_operand (operands[0], SImode))
- return \"pea %a1\";
- else if ((GET_CODE (operands[1]) == SYMBOL_REF
- || GET_CODE (operands[1]) == CONST)
- && ADDRESS_REG_P (operands[0]))
- return \"lea %a1,%0\";
- return \"move%.l %1,%0\";
+ return output_move_simode (operands);
}")
-(define_insn "movhi"
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=r<>,g")
+ (match_operand:SI 1 "general_operand" "g,r<>"))]
+ "TARGET_5200"
+ "* return output_move_simode (operands);")
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "")
+
+(define_insn ""
[(set (match_operand:HI 0 "general_operand" "=g")
(match_operand:HI 1 "general_operand" "g"))]
- ""
- "*
-{
- if (GET_CODE (operands[1]) == CONST_INT)
- {
- if (operands[1] == const0_rtx
- && (DATA_REG_P (operands[0])
- || GET_CODE (operands[0]) == MEM)
- /* clr insns on 68000 read before writing.
- This isn't so on the 68010, but we have no TARGET_68010. */
- && ((TARGET_68020 || TARGET_5200)
- || !(GET_CODE (operands[0]) == MEM
- && MEM_VOLATILE_P (operands[0]))))
- return \"clr%.w %0\";
- else if (DATA_REG_P (operands[0])
- && INTVAL (operands[1]) < 128
- && INTVAL (operands[1]) >= -128)
- {
-#if defined(MOTOROLA) && !defined(CRDS)
- return \"moveq%.l %1,%0\";
-#else
- return \"moveq %1,%0\";
-#endif
- }
- else if (INTVAL (operands[1]) < 0x8000
- && INTVAL (operands[1]) >= -0x8000)
- return \"move%.w %1,%0\";
- }
- else if (CONSTANT_P (operands[1]))
- return \"move%.l %1,%0\";
-#ifndef SGS_NO_LI
- /* Recognize the insn before a tablejump, one that refers
- to a table of offsets. Such an insn will need to refer
- to a label on the insn. So output one. Use the label-number
- of the table of offsets to generate this label. This code,
- and similar code below, assumes that there will be at most one
- reference to each table. */
- if (GET_CODE (operands[1]) == MEM
- && GET_CODE (XEXP (operands[1], 0)) == PLUS
- && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == LABEL_REF
- && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) != PLUS)
- {
- rtx labelref = XEXP (XEXP (operands[1], 0), 1);
-#if defined (MOTOROLA) && !defined (SGS_SWITCH_TABLES)
-#ifdef SGS
- asm_fprintf (asm_out_file, \"\\tset %LLI%d,.+2\\n\",
- CODE_LABEL_NUMBER (XEXP (labelref, 0)));
-#else /* not SGS */
- asm_fprintf (asm_out_file, \"\\t.set %LLI%d,.+2\\n\",
- CODE_LABEL_NUMBER (XEXP (labelref, 0)));
-#endif /* not SGS */
-#else /* SGS_SWITCH_TABLES or not MOTOROLA */
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LI\",
- CODE_LABEL_NUMBER (XEXP (labelref, 0)));
-#ifdef SGS_SWITCH_TABLES
- /* Set flag saying we need to define the symbol
- LD%n (with value L%n-LI%n) at the end of the switch table. */
- switch_table_difference_label_flag = 1;
-#endif /* SGS_SWITCH_TABLES */
-#endif /* SGS_SWITCH_TABLES or not MOTOROLA */
- }
-#endif /* SGS_NO_LI */
- return \"move%.w %1,%0\";
-}")
+ "!TARGET_5200"
+ "* return output_move_himode (operands);")
+
+ (define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=r<>,g")
+ (match_operand:HI 1 "general_operand" "g,r<>"))]
+ "TARGET_5200"
+ "* return output_move_himode (operands);")
(define_insn "movstricthi"
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
""
"*
{
- if (GET_CODE (operands[1]) == CONST_INT)
- {
- if (operands[1] == const0_rtx
- && (DATA_REG_P (operands[0])
- || GET_CODE (operands[0]) == MEM)
- /* clr insns on 68000 read before writing.
- This isn't so on the 68010, but we have no TARGET_68010. */
- && ((TARGET_68020 || TARGET_5200)
- || !(GET_CODE (operands[0]) == MEM
- && MEM_VOLATILE_P (operands[0]))))
- return \"clr%.w %0\";
- }
+ if (operands[1] == const0_rtx
+ /* clr insns on 68000 read before writing.
+ This isn't so on the 68010, but we have no TARGET_68010. */
+ && ((TARGET_68020 || TARGET_5200)
+ || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
+ return \"clr%.w %0\";
return \"move%.w %1,%0\";
}")
-(define_insn "movqi"
- [(set (match_operand:QI 0 "general_operand" "=d,*a,m")
- (match_operand:QI 1 "general_operand" "dmi*a,di*a,dmi"))]
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
""
- "*
-{
- rtx xoperands[4];
+ "")
- /* This is probably useless, since it loses for pushing a struct
- of several bytes a byte at a time. */
- if (GET_CODE (operands[0]) == MEM
- && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
- && XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx
- && ! ADDRESS_REG_P (operands[1]))
- {
- xoperands[1] = operands[1];
- xoperands[2]
- = gen_rtx (MEM, QImode,
- gen_rtx (PLUS, VOIDmode, stack_pointer_rtx, const1_rtx));
- /* Just pushing a byte puts it in the high byte of the halfword. */
- /* We must put it in the low-order, high-numbered byte. */
- output_asm_insn (\"move%.b %1,%-\;move%.b %@,%2\", xoperands);
- return \"\";
- }
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=d,*a,m")
+ (match_operand:QI 1 "general_operand" "dmi*a,di*a,dmi"))]
+ "!TARGET_5200"
+ "* return output_move_qimode (operands);")
- /* clr and st insns on 68000 read before writing.
- This isn't so on the 68010, but we have no TARGET_68010. */
- if (!ADDRESS_REG_P (operands[0])
- && (TARGET_68020
- || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
- {
- if (operands[1] == const0_rtx)
- return \"clr%.b %0\";
- if (GET_CODE (operands[1]) == CONST_INT
- && INTVAL (operands[1]) == -1)
- {
- CC_STATUS_INIT;
- return \"st %0\";
- }
- }
- if (GET_CODE (operands[1]) == CONST_INT
- && DATA_REG_P (operands[0])
- && INTVAL (operands[1]) < 128
- && INTVAL (operands[1]) >= -128)
- {
-#if defined(MOTOROLA) && !defined(CRDS)
- return \"moveq%.l %1,%0\";
-#else
- return \"moveq %1,%0\";
-#endif
- }
- if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
- return \"move%.l %1,%0\";
- if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
- return \"move%.w %1,%0\";
- return \"move%.b %1,%0\";
-}")
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=d<>,dm")
+ (match_operand:QI 1 "general_operand" "dmi,d<>"))]
+ "TARGET_5200"
+ "* return output_move_qimode (operands);")
(define_insn "movstrictqi"
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
return \"move%.b %1,%0\";
}")
-(define_insn "movsf"
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "general_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "")
+
+(define_insn ""
[(set (match_operand:SF 0 "general_operand" "=rmf,x,y,rm,!x,!rm")
(match_operand:SF 1 "general_operand" "rmfF,xH,rmF,y,rm,x"))]
; [(set (match_operand:SF 0 "general_operand" "=rmf")
; (match_operand:SF 1 "general_operand" "rmfF"))]
- ""
+ "!TARGET_5200"
"*
{
if (which_alternative >= 4)
return \"move%.l %1,%0\";
}")
-(define_insn "movdf"
+(define_insn ""
+ [(set (match_operand:SF 0 "general_operand" "=r,g")
+ (match_operand:SF 1 "general_operand" "g,r"))]
+ "TARGET_5200"
+ "* return \"move%.l %1,%0\";")
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "general_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ "")
+
+(define_insn ""
[(set (match_operand:DF 0 "general_operand" "=rm,rf,rf,&rof<>,y,rm,x,!x,!rm")
(match_operand:DF 1 "general_operand" "rf,m,0,rofE<>,rmE,y,xH,rm,x"))]
; [(set (match_operand:DF 0 "general_operand" "=rm,&rf,&rof<>")
; (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
- ""
+ "!TARGET_5200"
"*
{
if (which_alternative == 7)
return \"fmove%.d %f1,%0\";
}
return output_move_double (operands);
-}
-")
+}")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "general_operand" "=r,g")
+ (match_operand:DF 1 "general_operand" "g,r"))]
+ "TARGET_5200"
+ "* return output_move_double (operands);")
(define_expand "movxf"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
}
")
+(define_expand "movdi"
+ ;; Let's see if it really still needs to handle fp regs, and, if so, why.
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ ""
+ "")
+
;; movdi can apply to fp regs in some cases
-(define_insn "movdi"
+(define_insn ""
;; Let's see if it really still needs to handle fp regs, and, if so, why.
[(set (match_operand:DI 0 "general_operand" "=rm,r,&ro<>,y,rm,!*x,!rm")
(match_operand:DI 1 "general_operand" "rF,m,roi<>F,rmiF,y,rmF,*x"))]
; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfmF,rmi,y,rm,x"))]
; [(set (match_operand:DI 0 "general_operand" "=rm,&rf,&ro<>,!&rm,!&f")
; (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
- ""
+ "!TARGET_5200"
"*
{
if (which_alternative == 8)
return \"fmove%.d %f1,%0\";
}
return output_move_double (operands);
-}
-")
+}")
+
+(define_insn ""
+ [(set (match_operand:DI 0 "general_operand" "=r,g")
+ (match_operand:DI 1 "general_operand" "g,r"))]
+ "TARGET_5200"
+ "* return output_move_double (operands);")
;; Thus goes after the move instructions
;; because the move instructions are better (require no spilling)
#ifndef NO_ADDSUB_Q
if (INTVAL (operands[2]) > 0
&& INTVAL (operands[2]) <= 8)
- return (ADDRESS_REG_P (operands[0]) && !TARGET_5200
- ? \"addq%.w %2,%0\"
- : \"addq%.l %2,%0\");
+ return \"addq%.l %2,%0\";
if (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) >= -8)
{
operands[2] = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (operands[2]));
- return (ADDRESS_REG_P (operands[0]) && !TARGET_5200
- ? \"subq%.w %2,%0\"
- : \"subq%.l %2,%0\");
+ return \"subq%.l %2,%0\";
}
- /* On the 68020 it is faster to use two addqw instructions to
- add a small integer (8 < N <= 16) to an address register.
- Likewise for subqw. */
- if (TARGET_68020 && !TARGET_68040 && !TARGET_68060
- && ADDRESS_REG_P (operands[0]))
+ /* On the CPU32 it is faster to use two addql instructions to
+ add a small integer (8 < N <= 16) to a register.
+ Likewise for subql. */
+ if (TARGET_CPU32 && REG_P (operands[0]))
{
if (INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16)
{
operands[2] = gen_rtx (CONST_INT, VOIDmode,
INTVAL (operands[2]) - 8);
- return \"addq%.w %#8,%0\;addq%.w %2,%0\";
+ return \"addq%.l %#8,%0\;addq%.l %2,%0\";
}
if (INTVAL (operands[2]) < -8
&& INTVAL (operands[2]) >= -16)
{
operands[2] = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (operands[2]) - 8);
- return \"subq%.w %#8,%0\;subq%.w %2,%0\";
+ return \"subq%.l %#8,%0\;subq%.l %2,%0\";
}
}
#endif
if (ADDRESS_REG_P (operands[0])
&& INTVAL (operands[2]) >= -0x8000
- && INTVAL (operands[2]) < 0x8000
- && !TARGET_5200)
- return \"add%.w %2,%0\";
+ && INTVAL (operands[2]) < 0x8000)
+ {
+ if (TARGET_68040)
+ return \"add%.w %2,%0\";
+ else
+#ifdef MOTOROLA
+ return \"lea (%c2,%0),%0\";
+#else
+ return \"lea %0@(%c2),%0\";
+#endif
+ }
}
return \"add%.l %2,%0\";
}")
"!TARGET_5200"
"*
{
-#ifndef NO_ADDSUB_Q
if (GET_CODE (operands[2]) == CONST_INT)
{
+#ifndef NO_ADDSUB_Q
/* If the constant would be a negative number when interpreted as
HImode, make it negative. This is usually, but not always, done
elsewhere in the compiler. First check for constants out of range,
- INTVAL (operands[2]));
return \"subq%.w %2,%0\";
}
- /* On the 68020 it is faster to use two addqw instructions to
- add a small integer (8 < N <= 16) to an address register.
+ /* On the CPU32 it is faster to use two addqw instructions to
+ add a small integer (8 < N <= 16) to a register.
Likewise for subqw. */
- if (TARGET_68020 && !TARGET_68040 && !TARGET_68060
- && ADDRESS_REG_P (operands[0]))
+ if (TARGET_CPU32 && REG_P (operands[0]))
{
if (INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16)
return \"subq%.w %#8,%0\;subq%.w %2,%0\";
}
}
- }
#endif
+ if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
+#ifdef MOTOROLA
+ return \"lea (%c2,%0),%0\";
+#else
+ return \"lea %0@(%c2),%0\";
+#endif
+ }
return \"add%.w %2,%0\";
}")
"!TARGET_5200"
"*
{
-#ifndef NO_ADDSUB_Q
if (GET_CODE (operands[1]) == CONST_INT)
{
+#ifndef NO_ADDSUB_Q
/* If the constant would be a negative number when interpreted as
HImode, make it negative. This is usually, but not always, done
elsewhere in the compiler. First check for constants out of range,
- INTVAL (operands[1]));
return \"subq%.w %1,%0\";
}
- /* On the 68020 it is faster to use two addqw instructions to
- add a small integer (8 < N <= 16) to an address register.
+ /* On the CPU32 it is faster to use two addqw instructions to
+ add a small integer (8 < N <= 16) to a register.
Likewise for subqw. */
- if (TARGET_68020 && !TARGET_68040 && !TARGET_68060
- && ADDRESS_REG_P (operands[0]))
+ if (TARGET_CPU32 && REG_P (operands[0]))
{
if (INTVAL (operands[1]) > 8
&& INTVAL (operands[1]) <= 16)
return \"subq%.w %#8,%0\;subq%.w %1,%0\";
}
}
- }
#endif
+ if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
+#ifdef MOTOROLA
+ return \"lea (%c1,%0),%0\";
+#else
+ return \"lea %0@(%c1),%0\";
+#endif
+ }
return \"add%.w %1,%0\";
}")
"!TARGET_5200"
"*
{
-#ifndef NO_ADDSUB_Q
if (GET_CODE (operands[1]) == CONST_INT)
{
+#ifndef NO_ADDSUB_Q
/* If the constant would be a negative number when interpreted as
HImode, make it negative. This is usually, but not always, done
elsewhere in the compiler. First check for constants out of range,
- INTVAL (operands[1]));
return \"subq%.w %1,%0\";
}
- /* On the 68020 it is faster to use two addqw instructions to
- add a small integer (8 < N <= 16) to an address register.
+ /* On the CPU32 it is faster to use two addqw instructions to
+ add a small integer (8 < N <= 16) to a register.
Likewise for subqw. */
- if (TARGET_68020 && !TARGET_68040 && !TARGET_68060
- && ADDRESS_REG_P (operands[0]))
+ if (TARGET_CPU32 && REG_P (operands[0]))
{
if (INTVAL (operands[1]) > 8
&& INTVAL (operands[1]) <= 16)
return \"subq%.w %#8,%0\;subq%.w %1,%0\";
}
}
- }
#endif
+ if (ADDRESS_REG_P (operands[0]) && !TARGET_68040)
+#ifdef MOTOROLA
+ return \"lea (%c1,%0),%0\";
+#else
+ return \"lea %0@(%c1),%0\";
+#endif
+ }
return \"add%.w %1,%0\";
}")
#endif
}")
-(define_insn "mulsi3"
+(define_expand "mulsi3"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (mult:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_68020 || TARGET_5200"
+ "")
+
+(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=d")
(mult:SI (match_operand:SI 1 "general_operand" "%0")
(match_operand:SI 2 "general_operand" "dmsK")))]
- "TARGET_68020 || TARGET_5200"
+ "TARGET_68020"
+ "muls%.l %2,%0")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (mult:SI (match_operand:SI 1 "general_operand" "%0")
+ (match_operand:SI 2 "general_operand" "d<>")))]
+ "TARGET_5200"
"muls%.l %2,%0")
(define_insn "umulhisi3"
;; Prevent AND from being made with sp. This doesn't exist in the machine
;; and reload will cause inefficient code. Since sp is a FIXED_REG, we
;; can't allocate pseudos into it.
-(define_insn "andsi3"
+
+(define_expand "andsi3"
[(set (match_operand:SI 0 "not_sp_operand" "=m,d")
(and:SI (match_operand:SI 1 "general_operand" "%0,0")
(match_operand:SI 2 "general_operand" "dKs,dmMs")))]
""
+ "")
+
+(define_insn "andsi3_internal"
+ [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
+ (and:SI (match_operand:SI 1 "general_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "dKs,dmMs")))]
+ "!TARGET_5200"
"*
{
int logval;
if (GET_CODE (operands[2]) == CONST_INT
&& (INTVAL (operands[2]) | 0xffff) == 0xffffffff
&& (DATA_REG_P (operands[0])
- || offsettable_memref_p (operands[0]))
- && !TARGET_5200)
+ || offsettable_memref_p (operands[0])))
{
if (GET_CODE (operands[0]) != REG)
operands[0] = adj_offsettable_operand (operands[0], 2);
return \"and%.l %2,%0\";
}")
+(define_insn "andsi3_5200"
+ [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
+ (and:SI (match_operand:SI 1 "general_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,dmsK")))]
+ "TARGET_5200"
+ "and%.l %2,%0")
+
(define_insn "andhi3"
[(set (match_operand:HI 0 "general_operand" "=m,d")
(and:HI (match_operand:HI 1 "general_operand" "%0,0")
\f
;; inclusive-or instructions
-(define_insn "iorsi3"
+(define_expand "iorsi3"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (ior:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ ""
+ "")
+
+(define_insn "iorsi3_internal"
[(set (match_operand:SI 0 "general_operand" "=m,d")
(ior:SI (match_operand:SI 1 "general_operand" "%0,0")
(match_operand:SI 2 "general_operand" "dKs,dmMs")))]
- ""
+ "!TARGET_5200"
"*
{
register int logval;
if (GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) >> 16 == 0
&& (DATA_REG_P (operands[0])
- || offsettable_memref_p (operands[0]))
- && !TARGET_5200)
+ || offsettable_memref_p (operands[0])))
{
if (GET_CODE (operands[0]) != REG)
operands[0] = adj_offsettable_operand (operands[0], 2);
return \"or%.l %2,%0\";
}")
+(define_insn "iorsi3_5200"
+ [(set (match_operand:SI 0 "general_operand" "=m,d")
+ (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,dmsK")))]
+ "TARGET_5200"
+ "or%.l %2,%0")
+
(define_insn "iorhi3"
[(set (match_operand:HI 0 "general_operand" "=m,d")
(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
"!TARGET_5200"
"or%.b %1,%0")
+;; On all 68k models, this makes faster code in a special case.
+;; See also ashlsi_16, ashrsi_16 and lshrsi_16.
+
+(define_insn "iorsi_zexthi_ashl16"
+ [(set (match_operand:SI 0 "general_operand" "=d,d")
+ (ior:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "dmn,dmn"))
+ (ashift:SI (match_operand:SI 2 "general_operand" "o,0")
+ (const_int 16))))]
+ ""
+ "*
+{
+ CC_STATUS_INIT;
+ if (GET_CODE (operands[2]) != REG)
+ {
+ operands[2] = adj_offsettable_operand (operands[2], 2);
+ output_asm_insn (\"move%.w %2,%0\", operands);
+ }
+ return \"swap %0\;mov%.w %1,%0\";
+}")
+
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=o,d")
(ior:SI (zero_extend:SI (match_operand 1 "general_operand" "dn,dmn"))
\f
;; xor instructions
-(define_insn "xorsi3"
+(define_expand "xorsi3"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (xor:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ ""
+ "")
+
+(define_insn "xorsi3_internal"
[(set (match_operand:SI 0 "general_operand" "=do,m")
(xor:SI (match_operand:SI 1 "general_operand" "%0,0")
(match_operand:SI 2 "general_operand" "di,dKs")))]
- ""
+ "!TARGET_5200"
"*
{
if (GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) >> 16 == 0
- && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
- && !TARGET_5200)
+ && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0])))
{
if (! DATA_REG_P (operands[0]))
operands[0] = adj_offsettable_operand (operands[0], 2);
return \"eor%.l %2,%0\";
}")
+(define_insn "xorsi3_5200"
+ [(set (match_operand:SI 0 "general_operand" "=dm,d")
+ (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,Ks")))]
+ "TARGET_5200"
+ "eor%.l %2,%0")
+
(define_insn "xorhi3"
[(set (match_operand:HI 0 "general_operand" "=dm")
(xor:HI (match_operand:HI 1 "general_operand" "%0")
"!TARGET_5200"
"lsl%.b %1,%0")
-;; On all 68k models, this makes faster code in a special case.
+;; On most 68k models, this makes faster code in a special case.
-(define_insn ""
+(define_insn "ashrsi_16"
[(set (match_operand:SI 0 "register_operand" "=d")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
(const_int 16)))]
- ""
+ "!TARGET_68060"
"swap %0\;ext%.l %0")
;; On the 68000, this makes faster code in a special case.
"!TARGET_5200
&& ((INTVAL (operands[2]) == 1 || INTVAL (operands[2]) == 2
|| INTVAL (operands[2]) == 3 || INTVAL (operands[2]) == 8
- || INTVAL (operands[2]) == 16 || INTVAL (operands[2]) == 63))"
+ || INTVAL (operands[2]) == 16 || INTVAL (operands[2]) == 31
+ || INTVAL (operands[2]) == 63))"
"*
{
operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
return \"move%.b %0,%1\;asr%.l %#8,%0\;ror%.l %#8,%1\";
else if (INTVAL (operands[2]) == 16)
return \"move%.w %0,%1\;clr%.w %0\;swap %1\;ext%.l %0\";
+ else if (INTVAL (operands[2]) == 31)
+ return \"add%.l %1,%1\;addx%.l %0,%0\;move%.l %0,%1\;subx%.l %0,%0\";
else if (INTVAL (operands[2]) == 2)
return \"asr%.l %#1,%0\;roxr%.l %#1,%1\;asr%.l %#1,%0\;roxr%.l %#1,%1\";
else/* if (INTVAL (operands[2]) == 3)*/
if (GET_CODE (operands[2]) != CONST_INT
|| (INTVAL (operands[2]) != 1 && INTVAL (operands[2]) != 2
&& INTVAL (operands[2]) != 3 && INTVAL (operands[2]) != 8
- && INTVAL (operands[2]) != 16 && INTVAL (operands[2]) != 32
- && INTVAL (operands[2]) != 63))
+ && INTVAL (operands[2]) != 16 && INTVAL (operands[2]) != 31
+ && INTVAL (operands[2]) != 32 && INTVAL (operands[2]) != 63))
FAIL;
} ")
(define_insn "rotlsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(rotate:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "general_operand" "dI")))]
+ (match_operand:SI 2 "general_operand" "dINO")))]
"!TARGET_5200"
- "rol%.l %2,%0")
+ "*
+{
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)
+ return \"swap %0\";
+ else if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 16)
+ {
+ operands[2] = gen_rtx (CONST_INT, VOIDmode, 32 - INTVAL (operands[2]));
+ return \"ror%.l %2,%0\";
+ }
+ else
+ return \"rol%.l %2,%0\";
+}")
(define_insn "rotlhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
(rotate:HI (match_operand:HI 1 "register_operand" "0")
- (match_operand:HI 2 "general_operand" "dI")))]
+ (match_operand:HI 2 "general_operand" "dIP")))]
"!TARGET_5200"
- "rol%.w %2,%0")
-
+ "*
+{
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
+ {
+ operands[2] = gen_rtx (CONST_INT, VOIDmode, 16 - INTVAL (operands[2]));
+ return \"ror%.w %2,%0\";
+ }
+ else
+ return \"rol%.w %2,%0\";
+}")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
(rotate:HI (match_dup 0)
- (match_operand:HI 1 "general_operand" "dI")))]
+ (match_operand:HI 1 "general_operand" "dIP")))]
"!TARGET_5200"
- "rol%.w %1,%0")
+ "*
+{
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
+ {
+ operands[2] = gen_rtx (CONST_INT, VOIDmode, 16 - INTVAL (operands[2]));
+ return \"ror%.w %2,%0\";
+ }
+ else
+ return \"rol%.w %2,%0\";
+}")
(define_insn "rotlqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
(rotate:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "general_operand" "dI")))]
"!TARGET_5200"
- "rol%.b %2,%0")
+ "*
+{
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
+ {
+ operands[2] = gen_rtx (CONST_INT, VOIDmode, 8 - INTVAL (operands[2]));
+ return \"ror%.b %2,%0\";
+ }
+ else
+ return \"rol%.b %2,%0\";
+}")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
(rotate:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dI")))]
"!TARGET_5200"
- "rol%.b %1,%0")
+ "*
+{
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
+ {
+ operands[2] = gen_rtx (CONST_INT, VOIDmode, 8 - INTVAL (operands[2]));
+ return \"ror%.b %2,%0\";
+ }
+ else
+ return \"rol%.b %2,%0\";
+}")
(define_insn "rotrsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
} ")
-(define_insn "seq"
- [(set (match_operand:QI 0 "general_operand" "=d")
+(define_expand "seq"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (eq:QI (cc0) (const_int 0)))]
+ ""
+ "
+{
+ if (TARGET_68060 && m68k_last_compare_had_fp_operands)
+ {
+ m68k_last_compare_had_fp_operands = 0;
+ FAIL;
+ }
+}")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(eq:QI (cc0) (const_int 0)))]
""
"*
OUTPUT_JUMP (\"seq %0\", \"fseq %0\", \"seq %0\");
")
-(define_insn "sne"
- [(set (match_operand:QI 0 "general_operand" "=d")
+(define_expand "sne"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (ne:QI (cc0) (const_int 0)))]
+ ""
+ "
+{
+ if (TARGET_68060 && m68k_last_compare_had_fp_operands)
+ {
+ m68k_last_compare_had_fp_operands = 0;
+ FAIL;
+ }
+}")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(ne:QI (cc0) (const_int 0)))]
""
"*
OUTPUT_JUMP (\"sne %0\", \"fsne %0\", \"sne %0\");
")
-(define_insn "sgt"
- [(set (match_operand:QI 0 "general_operand" "=d")
+(define_expand "sgt"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (gt:QI (cc0) (const_int 0)))]
+ ""
+ "
+{
+ if (TARGET_68060 && m68k_last_compare_had_fp_operands)
+ {
+ m68k_last_compare_had_fp_operands = 0;
+ FAIL;
+ }
+}")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(gt:QI (cc0) (const_int 0)))]
""
"*
")
(define_insn "sgtu"
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(gtu:QI (cc0) (const_int 0)))]
""
"* cc_status = cc_prev_status;
return \"shi %0\"; ")
-(define_insn "slt"
- [(set (match_operand:QI 0 "general_operand" "=d")
+(define_expand "slt"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (lt:QI (cc0) (const_int 0)))]
+ ""
+ "
+{
+ if (TARGET_68060 && m68k_last_compare_had_fp_operands)
+ {
+ m68k_last_compare_had_fp_operands = 0;
+ FAIL;
+ }
+}")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(lt:QI (cc0) (const_int 0)))]
""
"* cc_status = cc_prev_status;
OUTPUT_JUMP (\"slt %0\", \"fslt %0\", \"smi %0\"); ")
(define_insn "sltu"
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(ltu:QI (cc0) (const_int 0)))]
""
"* cc_status = cc_prev_status;
return \"scs %0\"; ")
-(define_insn "sge"
- [(set (match_operand:QI 0 "general_operand" "=d")
+(define_expand "sge"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (ge:QI (cc0) (const_int 0)))]
+ ""
+ "
+{
+ if (TARGET_68060 && m68k_last_compare_had_fp_operands)
+ {
+ m68k_last_compare_had_fp_operands = 0;
+ FAIL;
+ }
+}")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(ge:QI (cc0) (const_int 0)))]
""
"* cc_status = cc_prev_status;
OUTPUT_JUMP (\"sge %0\", \"fsge %0\", \"spl %0\"); ")
(define_insn "sgeu"
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(geu:QI (cc0) (const_int 0)))]
""
"* cc_status = cc_prev_status;
return \"scc %0\"; ")
-(define_insn "sle"
- [(set (match_operand:QI 0 "general_operand" "=d")
+(define_expand "sle"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (le:QI (cc0) (const_int 0)))]
+ ""
+ "
+{
+ if (TARGET_68060 && m68k_last_compare_had_fp_operands)
+ {
+ m68k_last_compare_had_fp_operands = 0;
+ FAIL;
+ }
+}")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(le:QI (cc0) (const_int 0)))]
""
"*
")
(define_insn "sleu"
- [(set (match_operand:QI 0 "general_operand" "=d")
+ [(set (match_operand:QI 0 "general_operand" "=dm")
(leu:QI (cc0) (const_int 0)))]
""
"* cc_status = cc_prev_status;
return \"move%.l %0,%2\;or%.l %3,%2\;jeq %l1\";
#endif
operands[4] = gen_label_rtx();
+ if (TARGET_68020 || TARGET_5200)
#ifdef MOTOROLA
- output_asm_insn (\"tst%.l %0\;jbne %l4\;tst%.l %3\;jbeq %l1\", operands);
+ output_asm_insn (\"tst%.l %0\;jbne %l4\;tst%.l %3\;jbeq %l1\", operands);
+#else
+ output_asm_insn (\"tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1\", operands);
+#endif
+ else
+#ifdef MOTOROLA
+#ifdef SGS_CMP_ORDER
+ output_asm_insn (\"cmp%.w %0,%#0\;jbne %l4\;cmp%.w %3,%#0\;jbeq %l1\", operands);
#else
- output_asm_insn (\"tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1\", operands);
+ output_asm_insn (\"cmp%.w %#0,%0\;jbne %l4\;cmp%.w %#0,%3\;jbeq %l1\", operands);
+#endif
+#else
+ output_asm_insn (\"cmp%.w %#0,%0\;jne %l4\;cmp%.w %#0,%3\;jeq %l1\", operands);
#endif
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[4]));
operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else
operands[3] = adj_offsettable_operand (operands[0], 4);
- if (ADDRESS_REG_P (operands[0]))
+ if (!ADDRESS_REG_P (operands[0]))
+#ifdef MOTOROLA
+ return \"move%.l %0,%2\;or%.l %3,%2\;jbne %l1\";
+#else
+ return \"move%.l %0,%2\;or%.l %3,%2\;jne %l1\";
+#endif
+ if (TARGET_68020 || TARGET_5200)
#ifdef MOTOROLA
return \"tst%.l %0\;jbne %l1\;tst%.l %3\;jbne %l1\";
#else
#endif
else
#ifdef MOTOROLA
- return \"move%.l %0,%2\;or%.l %3,%2\;jbne %l1\";
+#ifdef SGS_CMP_ORDER
+ return \"cmp%.w %0,%#0\;jbne %l1\;cmp%.w %3,%#0\;jbne %l1\";
#else
- return \"move%.l %0,%2\;or%.l %3,%2\;jne %l1\";
+ return \"cmp%.w %#0,%0\;jbne %l1\;cmp%.w %#0,%3\;jbne %l1\";
+#endif
+#else
+ return \"cmp%.w %#0,%0\;jne %l1\;cmp%.w %#0,%3\;jne %l1\";
#endif
} ")
}
}
CC_STATUS_INIT;
+ if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (operands[0]))
+ output_asm_insn(\"tst%.l %0\", operands);
+ else
+ /* On an address reg, cmpw may replace cmpl. */
+#ifdef SGS_CMP_ORDER
+ output_asm_insn(\"cmp%.w %0,%#0\", operands);
+#else
+ output_asm_insn(\"cmp%.w %#0,%0\", operands);
+#endif
+
#ifdef MOTOROLA
- return \"tst%.l %0\;jbpl %l1\";
+ return \"jbpl %l1\";
#else
- return \"tst%.l %0\;jpl %l1\";
+ return \"jpl %l1\";
#endif
} ")
}
}
CC_STATUS_INIT;
+ if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (operands[0]))
+ output_asm_insn(\"tst%.l %0\", operands);
+ else
+ /* On an address reg, cmpw may replace cmpl. */
+#ifdef SGS_CMP_ORDER
+ output_asm_insn(\"cmp%.w %0,%#0\", operands);
+#else
+ output_asm_insn(\"cmp%.w %#0,%0\", operands);
+#endif
+
#ifdef MOTOROLA
- return \"tst%.l %0\;jbmi %l1\";
+ return \"jbmi %l1\";
#else
- return \"tst%.l %0\;jmi %l1\";
+ return \"jmi %l1\";
#endif
} ")
#else
#ifdef SGS
#ifdef ASM_OUTPUT_CASE_LABEL
- return \"jmp 6(%%pc,%0.w)\";
+ if (TARGET_5200)
+ return \"ext%.l %0\;jmp 6(%%pc,%0.l)\";
+ else
+ return \"jmp 6(%%pc,%0.w)\";
+#else
+ if (TARGET_5200)
+ {
+#ifdef CRDS
+ return \"ext%.l %0\;jmp 2(pc,%0.l)\";
#else
+ return \"extl %0\;jmp 2(%%pc,%0.l)\";
+#endif /* end !CRDS */
+ }
+ else
+ {
#ifdef CRDS
- return \"jmp 2(pc,%0.w)\";
+ return \"jmp 2(pc,%0.w)\";
#else
- return \"jmp 2(%%pc,%0.w)\";
+ return \"jmp 2(%%pc,%0.w)\";
#endif /* end !CRDS */
+ }
#endif
#else /* not SGS */
+ if (TARGET_5200)
+ {
+#ifdef MOTOROLA
+ return \"ext%.l %0\;jmp (2,pc,%0.l)\";
+#else
+ return \"extl %0\;jmp pc@(2,%0:l)\";
+#endif
+ }
+ else
+ {
#ifdef MOTOROLA
- return \"jmp (2,pc,%0.w)\";
+ return \"jmp (2,pc,%0.w)\";
#else
- return \"jmp pc@(2,%0:w)\";
+ return \"jmp pc@(2,%0:w)\";
#endif
+ }
#endif
#endif
")
else
output_asm_insn (\"addq%.l %1,%0\", xoperands);
}
- else if (INTVAL (xoperands[1]) <= 16
- && TARGET_68020 && !TARGET_68040 && !TARGET_68060)
+ else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16)
{
xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
INTVAL (xoperands[1]) - 8);
}
else
#endif
- if (INTVAL (xoperands[1]) <= 0x7FFF && !TARGET_5200)
- output_asm_insn (\"add%.w %1,%0\", xoperands);
+ if (INTVAL (xoperands[1]) <= 0x7FFF)
+ {
+ if (TARGET_68040)
+ output_asm_insn (\"add%.w %1,%0\", xoperands);
+ else
+#ifdef MOTOROLA
+ output_asm_insn (\"lea (%c1,%0),%0\", xoperands);
+#else
+ output_asm_insn (\"lea %0@(%c1),%0\", xoperands);
+#endif
+ }
else
output_asm_insn (\"add%.l %1,%0\", xoperands);
}
else
output_asm_insn (\"addq%.l %1,%0\", xoperands);
}
- else if (INTVAL (xoperands[1]) <= 16
- && TARGET_68020 && !TARGET_68040 && !TARGET_68060)
+ else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16)
{
xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
INTVAL (xoperands[1]) - 8);
}
else
#endif
- if (INTVAL (xoperands[1]) <= 0x7FFF && !TARGET_5200)
- output_asm_insn (\"add%.w %1,%0\", xoperands);
+ if (INTVAL (xoperands[1]) <= 0x7FFF)
+ {
+ if (TARGET_68040)
+ output_asm_insn (\"add%.w %1,%0\", xoperands);
+ else
+#ifdef MOTOROLA
+ output_asm_insn (\"lea (%c1,%0),%0\", xoperands);
+#else
+ output_asm_insn (\"lea %0@(%c1),%0\", xoperands);
+#endif
+ }
else
output_asm_insn (\"add%.l %1,%0\", xoperands);
}
fpsm%.s %x3,%2,%x1,%0
fpsm%.s %x3,%2,%x1,%0")
-(define_insn "tstxf"
+(define_expand "tstxf"
+ [(set (cc0)
+ (match_operand:XF 0 "nonimmediate_operand" ""))]
+ "TARGET_68881"
+ "m68k_last_compare_had_fp_operands = 1;")
+
+(define_insn ""
[(set (cc0)
(match_operand:XF 0 "nonimmediate_operand" "fm"))]
"TARGET_68881"
return \"ftst%.x %0\";
}")
-(define_insn "cmpxf"
+(define_expand "cmpxf"
+ [(set (cc0)
+ (compare (match_operand:XF 0 "nonimmediate_operand" "")
+ (match_operand:XF 1 "nonimmediate_operand" "")))]
+ "TARGET_68881"
+ "m68k_last_compare_had_fp_operands = 1;")
+
+(define_insn ""
[(set (cc0)
(compare (match_operand:XF 0 "nonimmediate_operand" "f,m")
(match_operand:XF 1 "nonimmediate_operand" "fm,f")))]