;;- Machine description for GNU compiler, Motorola 68000 Version
-;; Copyright (C) 1987, 1988, 1993, 1994, 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1987, 88, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
;; This file is part of GNU CC.
;; You should have received a copy of the GNU General Public License
;; along with GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;- Information about MCF5200 port.
+
+;;- The MCF5200 "ColdFire" architecture is a reduced version of the
+;;- 68k ISA. Differences include reduced support for byte and word
+;;- operands and the removal of BCD, bitfield, rotate, and integer
+;;- divide instructions. The TARGET_5200 flag turns the use of the
+;;- removed opcodes and addressing modes off.
+;;-
;;- instruction definitions
;;- 'd' one of the data registers can be used.
;;- 'f' one of the m68881 registers can be used
;;- 'r' either a data or an address register can be used.
-;;- 'x' if one of the Sun FPA registers
+;;- 'x' if one of the Sun FPA registers
;;- 'y' if one of the Low Sun FPA registers (fpa0-fpa15).
;;- Immediate Floating point operator constraints
;;- 'J' -32768 .. 32767
;;- '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
;;- into play by defining "%$" and "%&" to expand to "s" and "d" rather
;;- than "".
+;;- Information about 68060 port.
+
+;;- The 68060 executes all 68030 and 68881/2 instructions, but some must
+;;- be emulated in software by the OS. It is faster to avoid these
+;;- instructions and issue a library call rather than trapping into
+;;- the kernel. The affected instructions are: divs.l <ea>,Dr:Dq;
+;;- divu.l <ea>,Dr:Dq; muls.l <ea>,Dr:Dq; mulu.l <ea>,Dr:Dq; and
+;;- fscale. The TARGET_68060 flag turns the use of the opcodes off.
;;- FPA port explanation:
return output_move_double (operands);
}")
-(define_insn ""
+(define_insn "pushdi"
[(set (match_operand:DI 0 "push_operand" "=m")
- (match_operand:DI 1 "general_operand" "ro<>Fy"))]
+ (match_operand:DI 1 "general_operand" "ro<>Fyi"))]
""
"*
{
;; (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" "oa>,d"))
- (clobber (match_scratch:SI 1 "=d,d"))
- (clobber (match_scratch:SI 2 "=d,"))]
+ (match_operand:DI 0 "nonimmediate_operand" "am,d"))
+ (clobber (match_scratch:SI 1 "=X,d"))
+ (clobber (match_scratch:DI 2 "=d,X"))]
""
"*
{
- if (GET_CODE (operands[0]) == REG)
- operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- else if (GET_CODE (operands[0]) == MEM
- && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
- operands[3] = operands[0];
- else
- operands[3] = adj_offsettable_operand (operands[0], 4);
- if (DATA_REG_P (operands[0]))
- operands[2] = operands[0];
+ if (which_alternative == 0)
+ {
+ rtx xoperands[2];
+
+ xoperands[0] = operands[2];
+ xoperands[1] = operands[0];
+ output_move_double (xoperands);
+ 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;
+ return \"neg%.l %R0\;negx%.l %0\";
+ }
else
- output_asm_insn (\"move%.l %0,%2\", operands);
- /*
- ** 'sub' clears %1, and also clears the X cc bit
- ** 'tst' sets the Z cc bit according to the low part of the DImode operand
- ** 'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part
- */
- return \"sub%.l %1,%1\;tst%.l %3\;subx%.l %1,%2\";
+ /*
+ ** 'sub' clears %1, and also clears the X cc bit
+ ** 'tst' sets the Z cc bit according to the low part of the DImode operand
+ ** 'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part
+ */
+ 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"))]
""
/* ISI's assembler fails to handle tstl a0. */
if (! ADDRESS_REG_P (operands[0]))
#else
- if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))
+ if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (operands[0]))
#endif
return \"tst%.l %0\";
/* If you think that the 68020 does not support tstl a0,
;; 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"))]
""
"tst%.b %0")
-
+
(define_expand "tstsf"
[(set (cc0)
(match_operand:SF 0 "general_operand" ""))]
"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)
return \"sub%.l %R2,%R0\;subx%.l %2,%0\";
else
{
- return \"sub%.l %R1,%R0\;subx%.l %1,%0\";
cc_status.flags |= CC_REVERSED;
+ return \"sub%.l %R1,%R0\;subx%.l %1,%0\";
}
}")
""
"
{
- if (flag_pic && symbolic_operand (operands[1], SImode))
+ m68k_last_compare_had_fp_operands = 0;
+ if (flag_pic && symbolic_operand (operands[1], SImode))
{
- /* The source is an address which requires PIC relocation.
+ /* The source is an address which requires PIC relocation.
Call legitimize_pic_address with the source, mode, and a relocation
register (a new pseudo, or the final destination if reload_in_progress
is set). Then fall through normally */
}
}")
-;; 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,>")))]
- ""
+ "!TARGET_5200"
"*
{
if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
#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_5200"
"*
{
if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
"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]));
;; Recognizers for btst instructions.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do")
+ [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
(const_int 1)
(minus:SI (const_int 7)
(match_operand:SI 1 "general_operand" "di"))))]
"* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d")
+ [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
(const_int 1)
(minus:SI (const_int 31)
(match_operand:SI 1 "general_operand" "di"))))]
;; are automatically masked to 3 or 5 bits.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "do")
+ [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
(const_int 1)
(minus:SI (const_int 7)
(and:SI
"* { return output_btst (operands, operands[1], operands[0], insn, 7); }")
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "d")
+ [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
(const_int 1)
(minus:SI (const_int 31)
(and:SI
;; Nonoffsettable mem refs are ok in this one pattern
;; since we don't try to adjust them.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "md")
+ [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
(const_int 1)
(match_operand:SI 1 "const_int_operand" "n")))]
"(unsigned) INTVAL (operands[1]) < 8"
}")
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "do")
+ [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "do")
(const_int 1)
(match_operand:SI 1 "const_int_operand" "n")))]
""
{
operands[0] = adj_offsettable_operand (operands[0],
INTVAL (operands[1]) / 8);
- operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ operands[1] = gen_rtx (CONST_INT, VOIDmode,
7 - INTVAL (operands[1]) % 8);
return output_btst (operands, operands[1], operands[0], insn, 7);
}
;; A special case in which it is not desirable
;; to reload the constant into a data register.
-(define_insn ""
+(define_insn "pushexthisi_const"
[(set (match_operand:SI 0 "push_operand" "=m")
(match_operand:SI 1 "const_int_operand" "J"))]
"INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000"
;; 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 ""
+
+(define_insn "movsi_const0"
[(set (match_operand:SI 0 "general_operand" "=g")
(const_int 0))]
;; clr insns on 68000 read before writing.
- ;; This isn't so on the 68010, but we have no alternative for it.
- "(TARGET_68020
+ ;; 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])))"
"*
{
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)
+ if (DATA_REG_P (operands[0]) && (!TARGET_68020 && !TARGET_5200))
#if defined(MOTOROLA) && !defined(CRDS)
return \"moveq%.l %#0,%0\";
#else
return \"clr%.l %0\";
}")
-;; General case of fullword move.
+;; General case of fullword move.
;;
;; This is the main "hook" for PIC code. When generating
;; PIC, movsi is responsible for determining when the source address
;; to perform the actual relocation.
;;
;; In both the PIC and non-PIC cases the patterns generated will
-;; matched by the next define_insn.
+;; matched by the next define_insn.
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
"
{
- if (flag_pic && symbolic_operand (operands[1], SImode))
+ if (flag_pic && symbolic_operand (operands[1], SImode))
{
- /* The source is an address which requires PIC relocation.
+ /* The source is an address which requires PIC relocation.
Call legitimize_pic_address with the source, mode, and a relocation
register (a new pseudo, or the final destination if reload_in_progress
is set). Then fall through normally */
;; 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\";
+ 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)
- {
- 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 alternative for it. */
- && (TARGET_68020
- || !(GET_CODE (operands[0]) == MEM
- && MEM_VOLATILE_P (operands[0]))))
- return \"clr%.l %0\";
- else if (DATA_REG_P (operands[0]))
- return output_move_const_into_data_reg (operands);
- else if (ADDRESS_REG_P (operands[0])
- && INTVAL (operands[1]) < 0x8000
- && INTVAL (operands[1]) >= -0x8000)
- return \"move%.w %1,%0\";
- else if (push_operand (operands[0], SImode)
- && INTVAL (operands[1]) < 0x8000
- && INTVAL (operands[1]) >= -0x8000)
- return \"pea %a1\";
- }
- 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 alternative for it. */
- && (TARGET_68020
- || !(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 alternative for it. */
- && (TARGET_68020
- || !(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,m,?*a")
- (match_operand:QI 1 "general_operand" "dmi*a,d*a,dmi,?*a,m"))]
+(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 \"\";
- }
-
- /* Moving a byte into an address register is not possible. */
- /* Use d0 as an intermediate, but don't clobber its contents. */
- if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
- {
- /* ??? For 2.5, don't allow this choice and use secondary reloads
- instead.
-
- See if the address register is used in the address. If it
- is, we have to generate a more complex sequence than those below. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], NULL_RTX))
- {
- /* See if the stack pointer is used in the address. If it isn't,
- we can push d0 or d1 (the insn can't use both of them) on
- the stack, perform our move into d0/d1, copy the byte from d0/1,
- and pop d0/1. */
- if (! reg_mentioned_p (stack_pointer_rtx, operands[1]))
- {
- if (! refers_to_regno_p (0, 1, operands[1], NULL_RTX))
- return \"move%.l %/d0,%-\;move%.b %1,%/d0\;move%.l %/d0,%0\;move%.l %+,%/d0\";
- else
- return \"move%.l %/d1,%-\;move%.b %1,%/d1\;move%.l %/d1,%0\;move%.l %+,%/d1\";
- }
- else
- {
- /* Otherwise, we know that d0 cannot be used in the address
- (since sp and one address register is). Assume that sp is
- being used as a base register and replace the address
- register that is our operand[0] with d0. */
- rtx reg_map[FIRST_PSEUDO_REGISTER];
- int i;
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- reg_map[i] = 0;
-
- reg_map[REGNO (operands[0])] = gen_rtx (REG, Pmode, 0);
- operands[1] = copy_rtx (operands[1]);
- replace_regs (operands[1], reg_map, FIRST_PSEUDO_REGISTER, 0);
- return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\";
- }
- }
-
- /* If the address of operand 1 uses d0, choose d1 as intermediate. */
- if (refers_to_regno_p (0, 1, operands[1], NULL_RTX))
- return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\";
- /* Otherwise d0 is usable.
- (An effective address on the 68k can't use two d-regs.) */
- else
- return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\";
- }
-
- /* Likewise for moving from an address reg. */
- if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
- {
- /* ??? For 2.5, don't allow this choice and use secondary reloads
- instead.
-
- See if the address register is used in the address. If it
- is, we have to generate a more complex sequence than those below. */
- if (refers_to_regno_p (REGNO (operands[1]), REGNO (operands[1]) + 1,
- operands[0], NULL_RTX))
- {
- /* See if the stack pointer is used in the address. If it isn't,
- we can push d0 or d1 (the insn can't use both of them) on
- the stack, copy the byte to d0/1, perform our move from d0/d1,
- and pop d0/1. */
- if (! reg_mentioned_p (stack_pointer_rtx, operands[0]))
- {
- if (! refers_to_regno_p (0, 1, operands[0], NULL_RTX))
- return \"move%.l %/d0,%-\;move%.l %1,%/d0\;move%.b %/d0,%0\;move%.l %+,%/d0\";
- else
- return \"move%.l %/d1,%-\;move%.l %1,%/d1\;move%.b %/d1,%0\;move%.l %+,%/d1\";
- }
- else
- {
- /* Otherwise, we know that d0 cannot be used in the address
- (since sp and one address register is). Assume that sp is
- being used as a base register and replace the address
- register that is our operand[1] with d0. */
- rtx reg_map[FIRST_PSEUDO_REGISTER];
- int i;
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- reg_map[i] = 0;
-
- reg_map[REGNO (operands[1])] = gen_rtx (REG, Pmode, 0);
- operands[0] = copy_rtx (operands[0]);
- replace_regs (operands[0], reg_map, FIRST_PSEUDO_REGISTER, 0);
- return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\";
- }
- }
+ "")
- if (refers_to_regno_p (0, 1, operands[0], NULL_RTX))
- return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\";
- else
- return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\";
- }
+(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 alternative for it. */
- if (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 && 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*a<>,d*am")
+ (match_operand:QI 1 "general_operand" "d*ami,d*a<>"))]
+ "TARGET_5200"
+ "* return output_move_qimode (operands);")
(define_insn "movstrictqi"
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
{
if (operands[1] == const0_rtx
/* clr insns on 68000 read before writing.
- This isn't so on the 68010, but we have no alternative for it. */
- && (TARGET_68020
+ 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%.b %0\";
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_insn ""
[(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
(match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))]
- "! TARGET_68881"
+ "! TARGET_68881 && ! TARGET_5200"
"*
{
if (FP_REG_P (operands[0]))
}
")
+(define_insn ""
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g")
+ (match_operand:XF 1 "nonimmediate_operand" "g,r"))]
+ "! TARGET_68881 && TARGET_5200"
+ "* return output_move_double (operands);")
+
+(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)
;; this is the canonical form for (lshiftrt:DI x 32)
(define_insn "zero_extendsidi2"
- [(set (match_operand:DI 0 "general_operand" "ro,<,>")
- (zero_extend:DI (match_operand:SI 1 "general_operand" "rm,rm,rm")))]
+ [(set (match_operand:DI 0 "general_operand" "rm")
+ (zero_extend:DI (match_operand:SI 1 "general_operand" "rm")))]
""
"*
{
CC_STATUS_INIT;
- if (which_alternative == 2)
- return \"clr%.l %0\;move%.l %1,%0\";
- if (which_alternative == 1)
- return \"move%.l %1,%0\;clr%.l %0\";
if (GET_CODE (operands[0]) == REG)
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
+ return \"move%.l %1,%0\;clr%.l %0\";
+ else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
+ return \"clr%.l %0\;move%.l %1,%0\";
else
operands[2] = adj_offsettable_operand (operands[0], 4);
if (ADDRESS_REG_P (operands[0]))
{
CC_STATUS_INIT;
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- if (TARGET_68020)
+ if (TARGET_68020 || TARGET_5200)
return \"move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0\";
else
- return \"move%.b %1,%2\;ext%.w %0\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0\";
+ return \"move%.b %1,%2\;ext%.w %0\;ext%.l %2\;move%.l %2,%0\;smi %0\";
}")
(define_insn "extendhidi2"
{
CC_STATUS_INIT;
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- if (TARGET_68020)
+ if (TARGET_68020 || TARGET_5200)
return \"move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0\";
else
return \"move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0\";
{
CC_STATUS_INIT;
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- if (TARGET_68020)
+ if (TARGET_68020 || TARGET_5200)
return \"move%.l %1,%2\;smi %0\;extb%.l %0\";
else
return \"move%.l %1,%2\;smi %0\;ext%.w %0\;ext%.l %0\";
operands[1] = operands[2];
operands[2] = tmp;
}
- if (TARGET_68020)
- return \"move%.l %2,%3\;add%.l %1,%3\;smi %0\;extb%.l %0\";
+ if (GET_CODE (operands[1]) == REG
+ && REGNO (operands[1]) == REGNO (operands[3]))
+ output_asm_insn (\"add%.l %2,%3\", operands);
+ else
+ output_asm_insn (\"move%.l %2,%3\;add%.l %1,%3\", operands);
+ if (TARGET_68020 || TARGET_5200)
+ return \"smi %0\;extb%.l %0\";
else
- return \"move%.l %2,%3\;add%.l %1,%3\;smi %0\;ext%.w %0\;ext%.l %0\";
+ return \"smi %0\;ext%.w %0\;ext%.l %0\";
}")
(define_insn "extendhisi2"
(define_insn "extendqisi2"
[(set (match_operand:SI 0 "general_operand" "=d")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
- "TARGET_68020"
+ "TARGET_68020 || TARGET_5200"
"extb%.l %0")
\f
;; Conversions between float and double.
\f
;; add instructions
-(define_insn "adddia_sexthishl32"
- [(set (match_operand:DI 0 "register_operand" "+a")
- (plus:DI (ashift:DI (sign_extend:DI
- (match_operand:HI 1 "general_operand" "rm"))
- (const_int 32))
- (match_dup 0)))]
+(define_insn "adddi_lshrdi_63"
+ [(set (match_operand:DI 0 "general_operand" "=d")
+ (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm")
+ (const_int 63))
+ (match_dup 1)))
+ (clobber (match_scratch:SI 2 "=d"))]
""
"*
{
- CC_STATUS_INIT;
- return \"add%.w %1,%0\";
-} ")
-
-(define_insn "adddid_sexthishl32"
- [(set (match_operand:DI 0 "general_operand" "+ro")
- (plus:DI (ashift:DI (sign_extend:DI
- (match_operand:HI 1 "general_operand" "rm"))
+ operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ if (REG_P (operands[1]) && REGNO (operands[1]) == REGNO (operands[0]))
+ return
+ \"move%.l %1,%2\;add%.l %2,%2\;subx%.l %2,%2\;sub%.l %2,%3\;subx%.l %2,%0\";
+ if (GET_CODE (operands[1]) == REG)
+ operands[4] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+ else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
+ || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
+ operands[4] = operands[1];
+ else
+ operands[4] = adj_offsettable_operand (operands[1], 4);
+ if (GET_CODE (operands[1]) == MEM
+ && GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
+ output_asm_insn (\"move%.l %4,%3\", operands);
+ output_asm_insn (\"move%.l %1,%0\;smi %2\", operands);
+ if (TARGET_68020 || TARGET_5200)
+ output_asm_insn (\"extb%.l %2\", operands);
+ else
+ output_asm_insn (\"ext%.w %2\;ext%.l %2\", operands);
+ if (GET_CODE (operands[1]) != MEM
+ || GET_CODE (XEXP (operands[1], 0)) != PRE_DEC)
+ output_asm_insn (\"move%.l %4,%3\", operands);
+ return \"sub%.l %2,%3\;subx%.l %2,%0\";
+}")
+
+(define_insn "adddi_sexthishl32"
+ [(set (match_operand:DI 0 "general_operand" "=o,a,*d,*d")
+ (plus:DI (ashift:DI (sign_extend:DI
+ (match_operand:HI 1 "general_operand" "rm,rm,rm,rm"))
(const_int 32))
- (match_dup 0)))
- (clobber (match_scratch:SI 2 "=a"))]
- ""
+ (match_operand:DI 2 "general_operand" "0,0,0,0")))
+ (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
+ "!TARGET_5200"
"*
{
CC_STATUS_INIT;
- return \"move%.w %1,%2\;add%.l %2,%0\";
+ if (ADDRESS_REG_P (operands[0]))
+ return \"add%.w %1,%0\";
+ else if (ADDRESS_REG_P (operands[3]))
+ return \"move%.w %1,%3\;add%.l %3,%0\";
+ else
+ return \"move%.w %1,%3\;ext%.l %3\;add%.l %3,%0\";
} ")
(define_insn "adddi_dilshr32"
return \"add%.l %1,%0\";
} ")
-(define_insn "adddi_mem"
- [(set (match_operand:DI 0 "general_operand" "=o,<,>")
- (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0")
- (match_operand:DI 2 "general_operand" "d,d,d")))
- (clobber (match_scratch:SI 3 "=d,d,d"))]
+(define_insn "adddi3"
+ [(set (match_operand:DI 0 "general_operand" "=<,o<>,d,d,d")
+ (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0,0")
+ (match_operand:DI 2 "general_operand" "<,d,o>,d,a")))
+ (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
""
"*
{
- CC_STATUS_INIT;
- operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
- if (which_alternative == 2)
+ if (DATA_REG_P (operands[0]))
{
- operands[1] = gen_rtx (MEM, SImode,
- gen_rtx (PLUS, VOIDmode, XEXP(operands[0], 0),
- gen_rtx (CONST_INT, VOIDmode, -8)));
- return \"move%.l %0,%3\;add%.l %4,%0\;addx%.l %2,%3\;move%.l %3,%1\";
+ if (DATA_REG_P (operands[2]))
+ return \"add%.l %R2,%R0\;addx%.l %2,%0\";
+ else if (GET_CODE (operands[2]) == MEM
+ && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
+ {
+ return \"move%.l %2,%3\;add%.l %2,%R0\;addx%.l %3,%0\";
+ }
+ else
+ {
+ /* TODO : this should work also for CONST operands[2] */
+ if (GET_CODE (operands[2]) == REG)
+ operands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+ else
+ operands[1] = adj_offsettable_operand (operands[2], 4);
+ return \"move%.l %2,%3\;add%.l %1,%R0\;addx%.l %3,%0\";
+ }
}
- if (which_alternative == 1)
- {
- operands[1] = XEXP(operands[0], 0);
- return \"add%.l %4,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1\";
- }
- operands[1] = adj_offsettable_operand (operands[0], 4);
- return \"add%.l %4,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\";
-} ")
-
-(define_insn "adddi3"
- [(set (match_operand:DI 0 "general_operand" "=d,d,d,<")
- (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0")
- (match_operand:DI 2 "general_operand" "*ao,>,d,<")))]
- ""
- "*
-{
- if (which_alternative == 3)
- return \"add%.l %2,%0\;addx%.l %2,%0\";
- operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- if (which_alternative == 1)
+ else if (GET_CODE (operands[0]) == MEM)
{
+ if (GET_CODE (operands[2]) == MEM
+ && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
+ return \"add%.l %2,%0\;addx%.l %2,%0\";
CC_STATUS_INIT;
- return \"add%.l %2,%0\;add%.l %2,%1\;negx%.l %0\;neg%.l %0\";
+ if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
+ {
+ operands[1] = gen_rtx (MEM, SImode,
+ gen_rtx (PLUS, VOIDmode, XEXP(operands[0], 0),
+ gen_rtx (CONST_INT, VOIDmode, -8)));
+ return \"move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1\";
+ }
+ else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
+ {
+ operands[1] = XEXP(operands[0], 0);
+ return \"add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1\";
+ }
+ else
+ {
+ operands[1] = adj_offsettable_operand (operands[0], 4);
+ return \"add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0\";
+ }
}
- if (GET_CODE (operands[2]) == REG)
- operands[3] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
- else
- operands[3] = adj_offsettable_operand (operands[2], 4);
- if (which_alternative == 2)
- return \"add%.l %3,%1\;addx%.l %2,%0\";
- CC_STATUS_INIT;
- /* negx + neg simulates (non-existent) addx #0 */
- /* TODO : this should work also for CONST operands[2] */
- return \"add%.l %3,%1\;negx%.l %0\;neg%.l %0\;add%.l %2,%0\";
} ")
(define_insn "addsi_lshrsi_31"
return \"\";
}")
+(define_expand "addsi3"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (plus:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ ""
+ "")
+
;; Note that the middle two alternatives are near-duplicates
;; in order to handle insns generated by reload.
;; This is needed since they are not themselves reloaded,
;; so commutativity won't apply to them.
-(define_insn "addsi3"
+(define_insn "*addsi3_internal"
[(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r")
(plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
(match_operand:SI 2 "general_operand" "dIKLs,rJK,a,mrIKLs")))]
- ""
- "*
-{
- if (! operands_match_p (operands[0], operands[1]))
- {
- if (!ADDRESS_REG_P (operands[1]))
- {
- rtx tmp = operands[1];
-
- operands[1] = operands[2];
- operands[2] = tmp;
- }
+ "! TARGET_5200"
+ "* return output_addsi3 (operands);")
- /* These insns can result from reloads to access
- stack slots over 64k from the frame pointer. */
- if (GET_CODE (operands[2]) == CONST_INT
- && INTVAL (operands[2]) + 0x8000 >= (unsigned) 0x10000)
- return \"move%.l %2,%0\;add%.l %1,%0\";
-#ifdef SGS
- if (GET_CODE (operands[2]) == REG)
- return \"lea 0(%1,%2.l),%0\";
- else
- return \"lea %c2(%1),%0\";
-#else /* not SGS */
-#ifdef MOTOROLA
- if (GET_CODE (operands[2]) == REG)
- return \"lea (%1,%2.l),%0\";
- else
- return \"lea (%c2,%1),%0\";
-#else /* not MOTOROLA (MIT syntax) */
- if (GET_CODE (operands[2]) == REG)
- return \"lea %1@(0,%2:l),%0\";
- else
- return \"lea %1@(%c2),%0\";
-#endif /* not MOTOROLA */
-#endif /* not SGS */
- }
- if (GET_CODE (operands[2]) == CONST_INT)
- {
-#ifndef NO_ADDSUB_Q
- if (INTVAL (operands[2]) > 0
- && INTVAL (operands[2]) <= 8)
- return (ADDRESS_REG_P (operands[0])
- ? \"addq%.w %2,%0\"
- : \"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])
- ? \"subq%.w %2,%0\"
- : \"subq%.l %2,%0\");
- }
- /* On everything except the 68000 it is faster to use two
- addqw instructions to add a small integer (8 < N <= 16)
- to an address register. Likewise for subqw.*/
- if (INTVAL (operands[2]) > 8
- && INTVAL (operands[2]) <= 16
- && ADDRESS_REG_P (operands[0])
- && TARGET_68020)
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
- return \"addq%.w %#8,%0\;addq%.w %2,%0\";
- }
- if (INTVAL (operands[2]) < -8
- && INTVAL (operands[2]) >= -16
- && ADDRESS_REG_P (operands[0])
- && TARGET_68020)
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode,
- - INTVAL (operands[2]) - 8);
- return \"subq%.w %#8,%0\;subq%.w %2,%0\";
- }
-#endif
- if (ADDRESS_REG_P (operands[0])
- && INTVAL (operands[2]) >= -0x8000
- && INTVAL (operands[2]) < 0x8000)
- return \"add%.w %2,%0\";
- }
- return \"add%.l %2,%0\";
-}")
+(define_insn "*addsi3_5200"
+ [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r")
+ (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
+ (match_operand:SI 2 "general_operand" "d,rJK,a,mrIKLs")))]
+ "TARGET_5200"
+ "* return output_addsi3 (operands);")
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=a")
(plus:SI (match_operand:SI 1 "general_operand" "0")
(sign_extend:SI
(match_operand:HI 2 "nonimmediate_operand" "rm"))))]
- ""
+ "!TARGET_5200"
"add%.w %2,%0")
(define_insn "addhi3"
[(set (match_operand:HI 0 "general_operand" "=m,r")
(plus:HI (match_operand:HI 1 "general_operand" "%0,0")
(match_operand:HI 2 "general_operand" "dn,rmn")))]
- ""
+ "!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 everything except the 68000 it is faster to use two
- addqw instructions to add a small integer (8 < N <= 16)
- to an address register. Likewise for subqw. */
- if (INTVAL (operands[2]) > 8
- && INTVAL (operands[2]) <= 16
- && ADDRESS_REG_P (operands[0])
- && TARGET_68020)
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 8);
- return \"addq%.w %#8,%0\;addq%.w %2,%0\";
- }
- if (INTVAL (operands[2]) < -8
- && INTVAL (operands[2]) >= -16
- && ADDRESS_REG_P (operands[0])
- && TARGET_68020)
+ /* 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_CPU32 && REG_P (operands[0]))
{
- operands[2] = gen_rtx (CONST_INT, VOIDmode,
- - INTVAL (operands[2]) - 8);
- return \"subq%.w %#8,%0\;subq%.w %2,%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\";
+ }
+ 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\";
+ }
}
- }
#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\";
}")
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(plus:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dn,rmn")))]
- ""
+ "!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 everything except the 68000 it is faster to use two
- addqw instructions to add a small integer (8 < N <= 16)
- to an address register. Likewise for subqw. */
- if (INTVAL (operands[1]) > 8
- && INTVAL (operands[1]) <= 16
- && ADDRESS_REG_P (operands[0])
- && TARGET_68020)
+ /* 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_CPU32 && REG_P (operands[0]))
{
- operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8);
- return \"addq%.w %#8,%0\;addq%.w %1,%0\";
- }
- if (INTVAL (operands[1]) < -8
- && INTVAL (operands[1]) >= -16
- && ADDRESS_REG_P (operands[0])
- && TARGET_68020)
- {
- operands[1] = gen_rtx (CONST_INT, VOIDmode,
- - INTVAL (operands[1]) - 8);
- return \"subq%.w %#8,%0\;subq%.w %1,%0\";
+ if (INTVAL (operands[1]) > 8
+ && INTVAL (operands[1]) <= 16)
+ {
+ operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ INTVAL (operands[1]) - 8);
+ return \"addq%.w %#8,%0\;addq%.w %1,%0\";
+ }
+ if (INTVAL (operands[1]) < -8
+ && INTVAL (operands[1]) >= -16)
+ {
+ operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ - INTVAL (operands[1]) - 8);
+ 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\";
}")
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(plus:HI (match_operand:HI 1 "general_operand" "dn,rmn")
(match_dup 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 everything except the 68000 it is faster to use two
- addqw instructions to add a small integer (8 < N <= 16)
- to an address register. Likewise for subqw. */
- if (INTVAL (operands[1]) > 8
- && INTVAL (operands[1]) <= 16
- && ADDRESS_REG_P (operands[0])
- && TARGET_68020)
- {
- operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8);
- return \"addq%.w %#8,%0\;addq%.w %1,%0\";
- }
- if (INTVAL (operands[1]) < -8
- && INTVAL (operands[1]) >= -16
- && ADDRESS_REG_P (operands[0])
- && TARGET_68020)
+ /* 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_CPU32 && REG_P (operands[0]))
{
- operands[1] = gen_rtx (CONST_INT, VOIDmode,
- - INTVAL (operands[1]) - 8);
- return \"subq%.w %#8,%0\;subq%.w %1,%0\";
+ if (INTVAL (operands[1]) > 8
+ && INTVAL (operands[1]) <= 16)
+ {
+ operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ INTVAL (operands[1]) - 8);
+ return \"addq%.w %#8,%0\;addq%.w %1,%0\";
+ }
+ if (INTVAL (operands[1]) < -8
+ && INTVAL (operands[1]) >= -16)
+ {
+ operands[1] = gen_rtx (CONST_INT, VOIDmode,
+ - INTVAL (operands[1]) - 8);
+ 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\";
}")
[(set (match_operand:QI 0 "general_operand" "=m,d")
(plus:QI (match_operand:QI 1 "general_operand" "%0,0")
(match_operand:QI 2 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"*
{
#ifndef NO_ADDSUB_Q
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(plus:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"*
{
#ifndef NO_ADDSUB_Q
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(plus:QI (match_operand:QI 1 "general_operand" "dn,dmn")
(match_dup 0)))]
- ""
+ "!TARGET_5200"
"*
{
#ifndef NO_ADDSUB_Q
\f
;; subtract instructions
-(define_insn "subdia_sexthishl32"
- [(set (match_operand:DI 0 "register_operand" "+a")
- (minus:DI (match_dup 0)
- (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
- (const_int 32))))]
- ""
- "*
-{
- CC_STATUS_INIT;
- return \"sub%.w %1,%0\";
-} ")
-
-(define_insn "subdid_sexthishl32"
- [(set (match_operand:DI 0 "general_operand" "+ro")
- (minus:DI (match_dup 0)
- (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
+(define_insn "subdi_sexthishl32"
+ [(set (match_operand:DI 0 "general_operand" "=o,a,*d,*d")
+ (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
+ (ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm"))
(const_int 32))))
- (clobber (match_scratch:SI 2 "=a"))]
- ""
+ (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
+ "!TARGET_5200"
"*
{
CC_STATUS_INIT;
- return \"move%.w %1,%2\;sub%.l %2,%0\";
+ if (ADDRESS_REG_P (operands[0]))
+ return \"sub%.w %2,%0\";
+ else if (ADDRESS_REG_P (operands[3]))
+ return \"move%.w %2,%3\;sub%.l %3,%0\";
+ else
+ return \"move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0\";
} ")
(define_insn "subdi_dishl32"
return \"sub%.l %1,%0\";
} ")
-(define_insn "subdi_mem"
- [(set (match_operand:DI 0 "general_operand" "=o,<,>")
- (minus:DI (match_operand:DI 1 "general_operand" "0,0,0")
- (match_operand:DI 2 "register_operand" "d,d,d")))
- (clobber (match_scratch:SI 3 "=d,d,d"))]
+(define_insn "subdi3"
+ [(set (match_operand:DI 0 "general_operand" "=<,o<>,d,d,d")
+ (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0,0")
+ (match_operand:DI 2 "general_operand" "<,d,o>,d,a")))
+ (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))]
""
"*
{
- CC_STATUS_INIT;
- operands[4] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
- if (which_alternative == 2)
- {
- operands[1] = gen_rtx (MEM, SImode,
- gen_rtx (PLUS, VOIDmode, XEXP(operands[0], 0),
- gen_rtx (CONST_INT, VOIDmode, -8)));
- return \"move%.l %0,%3\;sub%.l %4,%0\;subx%.l %2,%3\;move%.l %3,%1\";
- }
- if (which_alternative == 1)
+ if (DATA_REG_P (operands[0]))
{
- operands[1] = XEXP(operands[0], 0);
- return \"sub%.l %4,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1\";
+ if (DATA_REG_P (operands[2]))
+ return \"sub%.l %R2,%R0\;subx%.l %2,%0\";
+ else if (GET_CODE (operands[2]) == MEM
+ && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
+ {
+ return \"move%.l %2,%3\;sub%.l %2,%R0\;subx%.l %3,%0\";
+ }
+ else
+ {
+ /* TODO : this should work also for CONST operands[2] */
+ if (GET_CODE (operands[2]) == REG)
+ operands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
+ else
+ operands[1] = adj_offsettable_operand (operands[2], 4);
+ return \"move%.l %2,%3\;sub%.l %1,%R0\;subx%.l %3,%0\";
+ }
}
- operands[1] = adj_offsettable_operand (operands[0], 4);
- return \"sub%.l %4,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\";
-} ")
-
-(define_insn "subdi3"
- [(set (match_operand:DI 0 "general_operand" "=d,d,d,<")
- (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
- (match_operand:DI 2 "general_operand" "*ao,>,d,<")))]
- ""
- "*
-{
- if (which_alternative == 3)
- return \"sub%.l %2,%0\;subx%.l %2,%0\";
- operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- if (which_alternative == 1)
+ else if (GET_CODE (operands[0]) == MEM)
{
+ if (GET_CODE (operands[2]) == MEM
+ && GET_CODE (XEXP (operands[2], 0)) == PRE_DEC)
+ return \"sub%.l %2,%0\;subx%.l %2,%0\";
CC_STATUS_INIT;
- return \"neg%.l %0\;add%.l %2,%0\;sub%.l %2,%1\;negx%.l %0\";
+ if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
+ {
+ operands[1] = gen_rtx (MEM, SImode,
+ gen_rtx (PLUS, VOIDmode, XEXP(operands[0], 0),
+ gen_rtx (CONST_INT, VOIDmode, -8)));
+ return \"move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1\";
+ }
+ else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
+ {
+ operands[1] = XEXP(operands[0], 0);
+ return \"sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1\";
+ }
+ else
+ {
+ operands[1] = adj_offsettable_operand (operands[0], 4);
+ return \"sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0\";
+ }
}
- if (GET_CODE (operands[2]) == REG)
- operands[3] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1);
- else
- operands[3] = adj_offsettable_operand (operands[2], 4);
- if (which_alternative == 2)
- return \"sub%.l %3,%1\;subx%.l %2,%0\";
- CC_STATUS_INIT;
- /* neg + negx simulates (non-existent) subx #0 */
- /* TODO : this should work also for CONST operands[2] */
- return \"neg%.l %0\;sub%.l %3,%1\;negx%.l %0\;sub%.l %2,%0\";
} ")
(define_insn "subsi3"
(minus:SI (match_operand:SI 1 "general_operand" "0")
(sign_extend:SI
(match_operand:HI 2 "nonimmediate_operand" "rm"))))]
- ""
+ "!TARGET_5200"
"sub%.w %2,%0")
(define_insn "subhi3"
[(set (match_operand:HI 0 "general_operand" "=m,r")
(minus:HI (match_operand:HI 1 "general_operand" "0,0")
(match_operand:HI 2 "general_operand" "dn,rmn")))]
- ""
+ "!TARGET_5200"
"sub%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(minus:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dn,rmn")))]
- ""
+ "!TARGET_5200"
"sub%.w %1,%0")
(define_insn "subqi3"
[(set (match_operand:QI 0 "general_operand" "=m,d")
(minus:QI (match_operand:QI 1 "general_operand" "0,0")
(match_operand:QI 2 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"sub%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(minus:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"sub%.b %1,%0")
(define_expand "subdf3"
#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"
"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"
[(set (match_operand:SI 0 "general_operand" "=d")
(mult:SI (zero_extend:SI
(truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
(zero_extend:DI (match_dup 2)))
(const_int 32))))])]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"")
(define_insn ""
(truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
(zero_extend:DI (match_dup 2)))
(const_int 32))))]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"mulu%.l %2,%3:%0")
; Match immediate case. For 2.4 only match things < 2^31.
(truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
(match_dup 2))
(const_int 32))))]
- "TARGET_68020
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200
&& (unsigned) INTVAL (operands[2]) <= 0x7fffffff"
"mulu%.l %2,%3:%0")
(truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
(sign_extend:DI (match_dup 2)))
(const_int 32))))])]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"")
(define_insn ""
(truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
(sign_extend:DI (match_dup 2)))
(const_int 32))))]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"muls%.l %2,%3:%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=d")
(mult:SI (match_operand:SI 1 "register_operand" "%0")
- (match_operand:SI 2 "const_int_operand" "n")))
+ (match_operand:SI 2 "const_sint32_operand" "")))
(set (match_operand:SI 3 "register_operand" "=d")
(truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
(match_dup 2))
(const_int 32))))]
- "TARGET_68020
- /* This test is a noop on 32 bit machines,
- but important for a cross-compiler hosted on 64-bit machines. */
- && INTVAL (operands[2]) <= 0x7fffffff
- && INTVAL (operands[2]) >= -0x80000000"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"muls%.l %2,%3:%0")
(define_expand "umulsi3_highpart"
(zero_extend:DI (match_operand:SI 2 "general_operand" "")))
(const_int 32))))
(clobber (match_dup 3))])]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"
{
operands[3] = gen_reg_rtx (SImode);
(zero_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
(const_int 32))))
(clobber (match_operand:SI 1 "register_operand" "=d"))]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"mulu%.l %3,%0:%1")
(define_insn "const_umulsi3_highpart"
(match_operand 3 "const_uint32_operand" ""))
(const_int 32))))
(clobber (match_operand:SI 1 "register_operand" "=d"))]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"mulu%.l %3,%0:%1")
(define_expand "smulsi3_highpart"
(sign_extend:DI (match_operand:SI 2 "general_operand" "")))
(const_int 32))))
(clobber (match_dup 3))])]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"
{
operands[3] = gen_reg_rtx (SImode);
(sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
(const_int 32))))
(clobber (match_operand:SI 1 "register_operand" "=d"))]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"muls%.l %3,%0:%1")
(define_insn "const_smulsi3_highpart"
(match_operand 3 "const_sint32_operand" ""))
(const_int 32))))
(clobber (match_operand:SI 1 "register_operand" "=d"))]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_68060 && !TARGET_5200"
"muls%.l %3,%0:%1")
(define_expand "muldf3"
"*
{
if (GET_CODE (operands[2]) == CONST_DOUBLE
- && floating_exact_log2 (operands[2]) && !TARGET_68040)
+ && floating_exact_log2 (operands[2]) && !TARGET_68040 && !TARGET_68060)
{
int i = floating_exact_log2 (operands[2]);
operands[2] = gen_rtx (CONST_INT, VOIDmode, i);
(match_operand:SI 2 "general_operand" "dmsK")))
(set (match_operand:SI 3 "general_operand" "=d")
(mod:SI (match_dup 1) (match_dup 2)))]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_5200"
"*
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
(match_operand:SI 2 "general_operand" "dmsK")))
(set (match_operand:SI 3 "general_operand" "=d")
(umod:SI (match_dup 1) (match_dup 2)))]
- "TARGET_68020"
+ "TARGET_68020 && !TARGET_5200"
"*
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
(match_operand:HI 2 "general_operand" "dmsK")))
(set (match_operand:HI 3 "general_operand" "=d")
(mod:HI (match_dup 1) (match_dup 2)))]
- ""
+ "!TARGET_5200"
"*
{
#ifdef MOTOROLA
(match_operand:HI 2 "general_operand" "dmsK")))
(set (match_operand:HI 3 "general_operand" "=d")
(umod:HI (match_dup 1) (match_dup 2)))]
- ""
+ "!TARGET_5200"
"*
{
#ifdef MOTOROLA
;; 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,dmKs")))]
+ (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;
&& (INTVAL (operands[2]) | 0xffff) == 0xffffffff
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
- {
+ {
if (GET_CODE (operands[0]) != REG)
operands[0] = adj_offsettable_operand (operands[0], 2);
operands[2] = gen_rtx (CONST_INT, VOIDmode,
&& (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
- {
+ {
if (DATA_REG_P (operands[0]))
{
operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
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")
(match_operand:HI 2 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"and%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(and:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"and%.w %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(and:HI (match_operand:HI 1 "general_operand" "dn,dmn")
(match_dup 0)))]
- ""
+ "!TARGET_5200"
"and%.w %1,%0")
(define_insn "andqi3"
[(set (match_operand:QI 0 "general_operand" "=m,d")
(and:QI (match_operand:QI 1 "general_operand" "%0,0")
(match_operand:QI 2 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"and%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(and:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"and%.b %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(and:QI (match_operand:QI 1 "general_operand" "dn,dmn")
(match_dup 0)))]
- ""
+ "!TARGET_5200"
"and%.b %1,%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,dmKs")))]
- ""
+ (match_operand:SI 2 "general_operand" "dKs,dmMs")))]
+ "!TARGET_5200"
"*
{
register int logval;
&& INTVAL (operands[2]) >> 16 == 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
- {
+ {
if (GET_CODE (operands[0]) != REG)
operands[0] = adj_offsettable_operand (operands[0], 2);
/* Do not delete a following tstl %0 insn; that would be incorrect. */
&& (logval = exact_log2 (INTVAL (operands[2]))) >= 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
- {
+ {
if (DATA_REG_P (operands[0]))
{
operands[1] = gen_rtx (CONST_INT, VOIDmode, logval);
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")
(match_operand:HI 2 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"or%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(ior:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"or%.w %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(ior:HI (match_operand:HI 1 "general_operand" "dn,dmn")
(match_dup 0)))]
- ""
+ "!TARGET_5200"
"or%.w %1,%0")
(define_insn "iorqi3"
[(set (match_operand:QI 0 "general_operand" "=m,d")
(ior:QI (match_operand:QI 1 "general_operand" "%0,0")
(match_operand:QI 2 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"or%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(ior:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dn,dmn")))]
- ""
+ "!TARGET_5200"
"or%.b %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(ior:QI (match_operand:QI 1 "general_operand" "dn,dmn")
(match_dup 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"))
(match_operand:SI 2 "general_operand" "0,0")))]
- ""
+ "!TARGET_5200"
"*
{
int byte_mode;
\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])))
- {
+ {
if (! DATA_REG_P (operands[0]))
operands[0] = adj_offsettable_operand (operands[0], 2);
/* Do not delete a following tstl %0 insn; that would be incorrect. */
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")
(match_operand:HI 2 "general_operand" "dn")))]
- ""
+ "!TARGET_5200"
"eor%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
(xor:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dn")))]
- ""
+ "!TARGET_5200"
"eor%.w %1,%0")
-
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
(xor:HI (match_operand:HI 1 "general_operand" "dn")
(match_dup 0)))]
- ""
+ "!TARGET_5200"
"eor%.w %1,%0")
(define_insn "xorqi3"
[(set (match_operand:QI 0 "general_operand" "=dm")
(xor:QI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "general_operand" "dn")))]
- ""
+ "!TARGET_5200"
"eor%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
(xor:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dn")))]
- ""
+ "!TARGET_5200"
"eor%.b %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
(xor:QI (match_operand:QI 1 "general_operand" "dn")
(match_dup 0)))]
- ""
+ "!TARGET_5200"
"eor%.b %1,%0")
\f
;; negation instructions
-(define_insn "negdi2"
- [(set (match_operand:DI 0 "general_operand" "=d*ao,<")
- (neg:DI (match_operand:DI 1 "general_operand" "0,0")))]
+(define_expand "negdi2"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (neg:DI (match_operand:DI 1 "general_operand" "")))]
""
+ "
+{
+ if (TARGET_5200)
+ emit_insn (gen_negdi2_5200 (operands[0], operands[1]));
+ else
+ emit_insn (gen_negdi2_internal (operands[0], operands[1]));
+ DONE;
+}")
+
+(define_insn "negdi2_internal"
+ [(set (match_operand:DI 0 "general_operand" "=<,do,!*a")
+ (neg:DI (match_operand:DI 1 "general_operand" "0,0,0")))]
+ "!TARGET_5200"
"*
{
- if (which_alternative == 1)
+ if (which_alternative == 0)
return \"neg%.l %0\;negx%.l %0\";
if (GET_CODE (operands[0]) == REG)
operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
return \"neg%.l %1\;negx%.l %0\";
} ")
-(define_insn "negsi2"
+(define_insn "negdi2_5200"
+ [(set (match_operand:DI 0 "general_operand" "=d")
+ (neg:DI (match_operand:DI 1 "general_operand" "0")))]
+ "TARGET_5200"
+ "*
+{
+ operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ return \"neg%.l %1\;negx%.l %0\";
+} ")
+
+(define_expand "negsi2"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (neg:SI (match_operand:SI 1 "general_operand" "")))]
+ ""
+ "
+{
+ if (TARGET_5200)
+ emit_insn (gen_negsi2_5200 (operands[0], operands[1]));
+ else
+ emit_insn (gen_negsi2_internal (operands[0], operands[1]));
+ DONE;
+}")
+
+(define_insn "negsi2_internal"
[(set (match_operand:SI 0 "general_operand" "=dm")
(neg:SI (match_operand:SI 1 "general_operand" "0")))]
- ""
+ "!TARGET_5200"
+ "neg%.l %0")
+
+(define_insn "negsi2_5200"
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (neg:SI (match_operand:SI 1 "general_operand" "0")))]
+ "TARGET_5200"
"neg%.l %0")
(define_insn "neghi2"
[(set (match_operand:HI 0 "general_operand" "=dm")
(neg:HI (match_operand:HI 1 "general_operand" "0")))]
- ""
+ "!TARGET_5200"
"neg%.w %0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
(neg:HI (match_dup 0)))]
- ""
+ "!TARGET_5200"
"neg%.w %0")
(define_insn "negqi2"
[(set (match_operand:QI 0 "general_operand" "=dm")
(neg:QI (match_operand:QI 1 "general_operand" "0")))]
- ""
+ "!TARGET_5200"
"neg%.b %0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
(neg:QI (match_dup 0)))]
- ""
+ "!TARGET_5200"
"neg%.b %0")
;; If using software floating point, just flip the sign bit.
if (result != target)
emit_move_insn (result, target);
-
+
emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
operand_subword_force (operands[1], 1, DFmode));
if (result != target)
emit_move_insn (result, target);
-
+
emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
operand_subword_force (operands[1], 1, DFmode));
(define_insn "one_cmpldi2"
[(set (match_operand:DI 0 "general_operand" "=dm")
(not:DI (match_operand:DI 1 "general_operand" "0")))]
- ""
+ "!TARGET_5200"
"*
{
CC_STATUS_INIT;
if (GET_CODE (operands[0]) == REG)
- operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC
|| GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
operands[1] = operands[0];
return \"not%.l %1\;not%.l %0\";
}")
-(define_insn "one_cmplsi2"
+(define_expand "one_cmplsi2"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (not:SI (match_operand:SI 1 "general_operand" "")))]
+ ""
+ "
+{
+ if (TARGET_5200)
+ emit_insn (gen_one_cmplsi2_5200 (operands[0], operands[1]));
+ else
+ emit_insn (gen_one_cmplsi2_internal (operands[0], operands[1]));
+ DONE;
+}")
+
+(define_insn "one_cmplsi2_internal"
[(set (match_operand:SI 0 "general_operand" "=dm")
(not:SI (match_operand:SI 1 "general_operand" "0")))]
- ""
+ "!TARGET_5200"
+ "not%.l %0")
+
+(define_insn "one_cmplsi2_5200"
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (not:SI (match_operand:SI 1 "general_operand" "0")))]
+ "TARGET_5200"
"not%.l %0")
(define_insn "one_cmplhi2"
[(set (match_operand:HI 0 "general_operand" "=dm")
(not:HI (match_operand:HI 1 "general_operand" "0")))]
- ""
+ "!TARGET_5200"
"not%.w %0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
(not:HI (match_dup 0)))]
- ""
+ "!TARGET_5200"
"not%.w %0")
(define_insn "one_cmplqi2"
[(set (match_operand:QI 0 "general_operand" "=dm")
(not:QI (match_operand:QI 1 "general_operand" "0")))]
- ""
+ "!TARGET_5200"
"not%.b %0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
(not:QI (match_dup 0)))]
- ""
+ "!TARGET_5200"
"not%.b %0")
\f
;; arithmetic shift instructions
} ")
(define_insn "ashldi_sexthi"
- [(set (match_operand:DI 0 "register_operand" "=*da")
- (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm"))
- (const_int 32)))]
+ [(set (match_operand:DI 0 "general_operand" "=m,a*d")
+ (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm,rm"))
+ (const_int 32)))
+ (clobber (match_scratch:SI 2 "=a,X"))]
""
"*
{
CC_STATUS_INIT;
- operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- if (DATA_REG_P (operands[0]))
- return \"move%.w %1,%0\;ext%.l %0\;clr%.l %2\";
+ if (GET_CODE (operands[0]) == MEM)
+ {
+ if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
+ return \"clr%.l %0\;move%.w %1,%2\;move%.l %2,%0\";
+ else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
+ return \"move%.w %1,%2\;move%.l %2,%0\;clr%.l %0\";
+ else
+ {
+ operands[3] = adj_offsettable_operand (operands[0], 4);
+ return \"move%.w %1,%2\;move%.l %2,%0\;clr%.l %3\";
+ }
+ }
+ else if (DATA_REG_P (operands[0]))
+ return \"move%.w %1,%0\;ext%.l %0\;clr%.l %R0\";
else
- return \"move%.w %1,%0\;sub%.l %2,%2\";
+ return \"move%.w %1,%0\;sub%.l %R0,%R0\";
} ")
(define_insn "ashldi_const32"
- [(set (match_operand:DI 0 "general_operand" "=ro,<,>")
- (ashift:DI (match_operand:DI 1 "general_operand" "ro,ro,ro")
+ [(set (match_operand:DI 0 "general_operand" "=rm")
+ (ashift:DI (match_operand:DI 1 "general_operand" "ro")
(const_int 32)))]
""
"*
operands[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
else
operands[3] = adj_offsettable_operand (operands[1], 4);
- if (which_alternative == 1)
- return \"clr%.l %0\;move%.l %3,%0\";
- if (which_alternative == 2)
- return \"move%.l %3,%0\;clr%.l %0\";
if (GET_CODE (operands[0]) == REG)
operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
+ else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
+ return \"clr%.l %0\;move%.l %3,%0\";
+ else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
+ return \"move%.l %3,%0\;clr%.l %0\";
else
operands[2] = adj_offsettable_operand (operands[0], 4);
if (ADDRESS_REG_P (operands[2]))
FAIL;
} ")
-;; 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 "ashlsi_16"
[(set (match_operand:SI 0 "register_operand" "=d")
(ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 16)))]
- ""
+ "!TARGET_68060"
"*
{
CC_STATUS_INIT;
return \"swap %0\;clr%.w %0\";
}")
+;; ashift patterns : use lsl instead of asl, because lsl always clears the
+;; overflow bit, so we must not set CC_NO_OVERFLOW.
+
;; On the 68000, this makes faster code in a special case.
-(define_insn ""
+(define_insn "ashlsi_17_24"
[(set (match_operand:SI 0 "register_operand" "=d")
(ashift:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "n")))]
- "(! TARGET_68020
+ "(! TARGET_68020 && !TARGET_5200
&& INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
"*
{
CC_STATUS_INIT;
operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16);
- return \"asl%.w %2,%0\;swap %0\;clr%.w %0\";
+ return \"lsl%.w %2,%0\;swap %0\;clr%.w %0\";
}")
(define_insn "ashlsi3"
"*
{
if (operands[2] == const1_rtx)
- return \"add%.l %0,%0\";
- return \"asl%.l %2,%0\";
+ {
+ cc_status.flags = CC_NO_OVERFLOW;
+ return \"add%.l %0,%0\";
+ }
+ return \"lsl%.l %2,%0\";
}")
(define_insn "ashlhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
(ashift:HI (match_operand:HI 1 "register_operand" "0")
(match_operand:HI 2 "general_operand" "dI")))]
- ""
- "asl%.w %2,%0")
+ "!TARGET_5200"
+ "lsl%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
(ashift:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dI")))]
- ""
- "asl%.w %1,%0")
+ "!TARGET_5200"
+ "lsl%.w %1,%0")
(define_insn "ashlqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
(ashift:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "general_operand" "dI")))]
- ""
- "asl%.b %2,%0")
+ "!TARGET_5200"
+ "lsl%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
(ashift:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dI")))]
- ""
- "asl%.b %1,%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.
[(set (match_operand:SI 0 "register_operand" "=d")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "n")))]
- "(! TARGET_68020
+ "(! TARGET_68020 && !TARGET_5200
&& INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
"*
{
[(set (match_operand:DI 0 "general_operand" "=d")
(ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
(match_operand 2 "const_int_operand" "n")))]
- "(INTVAL (operands[2]) == 1 || INTVAL (operands[2]) == 2
+ "!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)*/
[(set (match_operand:DI 0 "general_operand" "")
(ashiftrt:DI (match_operand:DI 1 "general_operand" "")
(match_operand 2 "const_int_operand" "")))]
- ""
+ "!TARGET_5200"
"
{
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;
} ")
+;; On all 68k models, this makes faster code in a special case.
+
+(define_insn "ashrsi_31"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (const_int 31)))]
+ ""
+ "*
+{
+ return \"add%.l %0,%0\;subx%.l %0,%0\";
+}")
+
(define_insn "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
[(set (match_operand:HI 0 "register_operand" "=d")
(ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
(match_operand:HI 2 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"asr%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
(ashiftrt:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"asr%.w %1,%0")
(define_insn "ashrqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
(ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"asr%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
(ashiftrt:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"asr%.b %1,%0")
\f
;; logical shift instructions
-(define_insn ""
- [(set (cc0)
- (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
- (const_int 32)) 1))
- (set (match_operand:SI 1 "general_operand" "=dm")
- (subreg:SI (lshiftrt:DI (match_operand:DI 2 "general_operand" "0")
- (const_int 32)) 1))]
- ""
- "*
-{
- return \"move%.l %0,%1\";
-} ")
-
-(define_insn ""
- [(set (cc0)
- (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
- (const_int 32)) 0))
- (set (match_operand:DI 1 "general_operand" "=do")
- (lshiftrt:DI (match_operand:DI 2 "general_operand" "0")
- (const_int 32)))]
- ""
- "*
-{
- if (GET_CODE (operands[1]) == REG)
- operands[2] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
- else
- operands[2] = adj_offsettable_operand (operands[1], 4);
- return \"move%.l %0,%2\;clr%.l %1\";
-} ")
+;; commented out because of reload problems in 950612-1.c
+;;(define_insn ""
+;; [(set (cc0)
+;; (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
+;; (const_int 32)) 1))
+;; (set (match_operand:SI 1 "general_operand" "=dm")
+;; (subreg:SI (lshiftrt:DI (match_dup 0)
+;; (const_int 32)) 1))]
+;; ""
+;; "*
+;;{
+;; return \"move%.l %0,%1\";
+;;} ")
+;;
+;;(define_insn ""
+;; [(set (cc0)
+;; (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
+;; (const_int 32)) 0))
+;; (set (match_operand:DI 1 "general_operand" "=do")
+;; (lshiftrt:DI (match_dup 0)
+;; (const_int 32)))]
+;; ""
+;; "*
+;;{
+;; if (GET_CODE (operands[1]) == REG)
+;; operands[2] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+;; else
+;; operands[2] = adj_offsettable_operand (operands[1], 4);
+;; return \"move%.l %0,%2\;clr%.l %1\";
+;;} ")
(define_insn "subreg1lshrdi_const32"
[(set (match_operand:SI 0 "general_operand" "=rm")
[(set (match_operand:DI 0 "general_operand" "=d")
(lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
(match_operand 2 "const_int_operand" "n")))]
- "(INTVAL (operands[2]) == 1 || INTVAL (operands[2]) == 2
+ "!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]) == 63))"
"*
{
operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
[(set (match_operand:DI 0 "general_operand" "")
(lshiftrt:DI (match_operand:DI 1 "general_operand" "")
(match_operand 2 "const_int_operand" "")))]
- ""
+ "!TARGET_5200"
"
{
if (GET_CODE (operands[2]) != CONST_INT
return \"add%.l %0,%0\;subx%.l %0,%0\;neg%.l %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 "lshrsi_16"
[(set (match_operand:SI 0 "register_operand" "=d")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
(const_int 16)))]
- ""
+ "!TARGET_68060"
"*
{
CC_STATUS_INIT;
[(set (match_operand:SI 0 "register_operand" "=d")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "n")))]
- "(! TARGET_68020
+ "(! TARGET_68020 && !TARGET_5200
&& INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)"
"*
{
[(set (match_operand:HI 0 "register_operand" "=d")
(lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
(match_operand:HI 2 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"lsr%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
(lshiftrt:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"lsr%.w %1,%0")
(define_insn "lshrqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
(lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"lsr%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
(lshiftrt:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"lsr%.b %1,%0")
\f
;; rotate instructions
(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")))]
- ""
- "rol%.l %2,%0")
+ (match_operand:SI 2 "general_operand" "dINO")))]
+ "!TARGET_5200"
+ "*
+{
+ 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")))]
- ""
- "rol%.w %2,%0")
-
+ (match_operand:HI 2 "general_operand" "dIP")))]
+ "!TARGET_5200"
+ "*
+{
+ 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")))]
- ""
- "rol%.w %1,%0")
+ (match_operand:HI 1 "general_operand" "dIP")))]
+ "!TARGET_5200"
+ "*
+{
+ 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")))]
- ""
- "rol%.b %2,%0")
+ "!TARGET_5200"
+ "*
+{
+ 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")))]
- ""
- "rol%.b %1,%0")
+ "!TARGET_5200"
+ "*
+{
+ 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")
(rotatert:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"ror%.l %2,%0")
(define_insn "rotrhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
(rotatert:HI (match_operand:HI 1 "register_operand" "0")
(match_operand:HI 2 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"ror%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
(rotatert:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"ror%.w %1,%0")
(define_insn "rotrqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
(rotatert:QI (match_operand:QI 1 "register_operand" "0")
(match_operand:QI 2 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"ror%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
(rotatert:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "dI")))]
- ""
+ "!TARGET_5200"
"ror%.b %1,%0")
\f
; than an odd byte aligned bit field instruction.
;
(define_insn ""
- [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o")
+ [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
(const_int 32)
(match_operand:SI 2 "const_int_operand" "n"))
(match_operand:SI 3 "general_operand" "rmi"))]
}")
(define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+do")
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+do")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))
(match_operand:SI 3 "register_operand" "d"))]
;
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=rm")
- (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o")
+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "o")
(const_int 32)
(match_operand:SI 3 "const_int_operand" "n")))]
"TARGET_68020 && TARGET_BITFIELD
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=&d")
- (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "do")
(match_operand:SI 2 "const_int_operand" "n")
(match_operand:SI 3 "const_int_operand" "n")))]
"TARGET_68020 && TARGET_BITFIELD
;
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=rm")
- (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o")
+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
(const_int 32)
(match_operand:SI 3 "const_int_operand" "n")))]
"TARGET_68020 && TARGET_BITFIELD
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=d")
- (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do")
+ (sign_extract:SI (match_operand:SI 1 "register_operand" "do")
(match_operand:SI 2 "const_int_operand" "n")
(match_operand:SI 3 "const_int_operand" "n")))]
"TARGET_68020 && TARGET_BITFIELD
;; "o,d" constraint causes a nonoffsettable memref to match the "o"
;; so that its address is reloaded.
-(define_insn "extv"
- [(set (match_operand:SI 0 "general_operand" "=d,d")
- (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
- (match_operand:SI 2 "general_operand" "di,di")
- (match_operand:SI 3 "general_operand" "di,di")))]
+(define_expand "extv"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (sign_extract:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")
+ (match_operand:SI 3 "general_operand" "")))]
+ "TARGET_68020 && TARGET_BITFIELD"
+ "")
+
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=d")
+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
+ (match_operand:SI 2 "general_operand" "di")
+ (match_operand:SI 3 "general_operand" "di")))]
"TARGET_68020 && TARGET_BITFIELD"
"bfexts %1{%b3:%b2},%0")
-(define_insn "extzv"
+(define_expand "extzv"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (zero_extract:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")
+ (match_operand:SI 3 "general_operand" "")))]
+ "TARGET_68020 && TARGET_BITFIELD"
+ "")
+
+(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=d,d")
- (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "o,d")
+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "o,d")
(match_operand:SI 2 "general_operand" "di,di")
(match_operand:SI 3 "general_operand" "di,di")))]
"TARGET_68020 && TARGET_BITFIELD"
}")
(define_insn ""
- [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
- (match_operand:SI 1 "general_operand" "di,di")
- (match_operand:SI 2 "general_operand" "di,di"))
+ [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
+ (match_operand:SI 1 "general_operand" "di")
+ (match_operand:SI 2 "general_operand" "di"))
(xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
- (match_operand 3 "const_int_operand" "n,n")))]
+ (match_operand 3 "const_int_operand" "n")))]
"TARGET_68020 && TARGET_BITFIELD
&& (INTVAL (operands[3]) == -1
|| (GET_CODE (operands[1]) == CONST_INT
}")
(define_insn ""
- [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
- (match_operand:SI 1 "general_operand" "di,di")
- (match_operand:SI 2 "general_operand" "di,di"))
+ [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
+ (match_operand:SI 1 "general_operand" "di")
+ (match_operand:SI 2 "general_operand" "di"))
(const_int 0))]
"TARGET_68020 && TARGET_BITFIELD"
"*
}")
(define_insn ""
- [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
- (match_operand:SI 1 "general_operand" "di,di")
- (match_operand:SI 2 "general_operand" "di,di"))
+ [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
+ (match_operand:SI 1 "general_operand" "di")
+ (match_operand:SI 2 "general_operand" "di"))
(const_int -1))]
"TARGET_68020 && TARGET_BITFIELD"
"*
return \"bfset %0{%b2:%b1}\";
}")
-(define_insn "insv"
- [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+o,d")
- (match_operand:SI 1 "general_operand" "di,di")
- (match_operand:SI 2 "general_operand" "di,di"))
- (match_operand:SI 3 "register_operand" "d,d"))]
+(define_expand "insv"
+ [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" ""))
+ (match_operand:SI 3 "register_operand" ""))]
+ "TARGET_68020 && TARGET_BITFIELD"
+ "")
+
+(define_insn ""
+ [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
+ (match_operand:SI 1 "general_operand" "di")
+ (match_operand:SI 2 "general_operand" "di"))
+ (match_operand:SI 3 "register_operand" "d"))]
"TARGET_68020 && TARGET_BITFIELD"
"bfins %3,%0{%b2:%b1}")
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=d")
- (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
+ (sign_extract:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "general_operand" "di")
(match_operand:SI 3 "general_operand" "di")))]
"TARGET_68020 && TARGET_BITFIELD"
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=d")
- (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "d")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "general_operand" "di")
(match_operand:SI 3 "general_operand" "di")))]
"TARGET_68020 && TARGET_BITFIELD"
}")
(define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
(match_operand:SI 1 "general_operand" "di")
(match_operand:SI 2 "general_operand" "di"))
(const_int 0))]
}")
(define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
(match_operand:SI 1 "general_operand" "di")
(match_operand:SI 2 "general_operand" "di"))
(const_int -1))]
}")
(define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+d")
+ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
(match_operand:SI 1 "general_operand" "di")
(match_operand:SI 2 "general_operand" "di"))
(match_operand:SI 3 "register_operand" "d"))]
{
if (operands[1] == const1_rtx
&& GET_CODE (operands[2]) == CONST_INT)
- {
+ {
int width = GET_CODE (operands[0]) == REG ? 31 : 7;
return output_btst (operands,
gen_rtx (CONST_INT, VOIDmode,
return \"bftst %0{%b2:%b1}\";
}")
-
+
;;; now handle the register cases
(define_insn ""
[(set (cc0)
- (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "d")
+ (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "general_operand" "di")))]
"TARGET_68020 && TARGET_BITFIELD"
{
if (operands[1] == const1_rtx
&& GET_CODE (operands[2]) == CONST_INT)
- {
+ {
int width = GET_CODE (operands[0]) == REG ? 31 : 7;
return output_btst (operands,
gen_rtx (CONST_INT, VOIDmode,
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;
""
"*
{
+ CC_STATUS_INIT;
if (which_alternative == 1)
#ifdef MOTOROLA
return \"move%.l %0,%2\;or%.l %0,%2\;jbeq %l1\";
#else
return \"move%.l %0,%2\;or%.l %0,%2\;jeq %l1\";
#endif
+ if ((cc_prev_status.value1
+ && rtx_equal_p (cc_prev_status.value1, operands[0]))
+ || (cc_prev_status.value2
+ && rtx_equal_p (cc_prev_status.value2, operands[0])))
+ {
+ cc_status = cc_prev_status;
+#ifdef MOTOROLA
+ return \"jbeq %l1\";
+#else
+ return \"jeq %l1\";
+#endif
+ }
if (GET_CODE (operands[0]) == REG)
operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
else
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);
+#else
+ output_asm_insn (\"tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1\", operands);
+#endif
+ else
#ifdef MOTOROLA
- output_asm_insn (\"tst%.l %0\;jbne %l4\;tst%.l %3\;jbeq %l1\", operands);
+#ifdef SGS_CMP_ORDER
+ output_asm_insn (\"cmp%.w %0,%#0\;jbne %l4\;cmp%.w %3,%#0\;jbeq %l1\", operands);
+#else
+ output_asm_insn (\"cmp%.w %#0,%0\;jbne %l4\;cmp%.w %#0,%3\;jbeq %l1\", operands);
+#endif
#else
- output_asm_insn (\"tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1\", operands);
+ 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]));
(const_int 0))
(label_ref (match_operand 1 "" ","))
(pc)))
- (clobber (match_scratch:SI 2 "=d,"))]
+ (clobber (match_scratch:SI 2 "=d,X"))]
""
"*
{
+ if ((cc_prev_status.value1
+ && rtx_equal_p (cc_prev_status.value1, operands[0]))
+ || (cc_prev_status.value2
+ && rtx_equal_p (cc_prev_status.value2, operands[0])))
+ {
+ cc_status = cc_prev_status;
+#ifdef MOTOROLA
+ return \"jbne %l1\";
+#else
+ return \"jne %l1\";
+#endif
+ }
+ CC_STATUS_INIT;
if (GET_CODE (operands[0]) == REG)
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
} ")
""
"*
{
+ if ((cc_prev_status.value1
+ && rtx_equal_p (cc_prev_status.value1, operands[0]))
+ || (cc_prev_status.value2
+ && rtx_equal_p (cc_prev_status.value2, operands[0])))
+ {
+ cc_status = cc_prev_status;
+ if (cc_status.flags & CC_REVERSED)
+ {
+#ifdef MOTOROLA
+ return \"jble %l1\";
+#else
+ return \"jle %l1\";
+#endif
+ }
+ else
+ {
+#ifdef MOTOROLA
+ return \"jbpl %l1\";
+#else
+ 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\;jbge %l1\";
+ return \"jbpl %l1\";
#else
- return \"tst%.l %0\;jge %l1\";
+ return \"jpl %l1\";
#endif
} ")
""
"*
{
+ if ((cc_prev_status.value1
+ && rtx_equal_p (cc_prev_status.value1, operands[0]))
+ || (cc_prev_status.value2
+ && rtx_equal_p (cc_prev_status.value2, operands[0])))
+ {
+ cc_status = cc_prev_status;
+ if (cc_status.flags & CC_REVERSED)
+ {
+#ifdef MOTOROLA
+ return \"jbgt %l1\";
+#else
+ return \"jgt %l1\";
+#endif
+ }
+ else
+ {
+#ifdef MOTOROLA
+ return \"jbmi %l1\";
+#else
+ return \"jmi %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
")
(define_insn ""
[(set (pc)
(if_then_else
- (ne (match_operand:HI 0 "general_operand" "+g")
+ (ne (match_operand:HI 0 "general_operand" "+d*g")
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0)
(plus:HI (match_dup 0)
(const_int -1)))]
- ""
+ "!TARGET_5200"
"*
{
CC_STATUS_INIT;
(define_insn ""
[(set (pc)
(if_then_else
- (ne (match_operand:SI 0 "general_operand" "+g")
+ (ne (match_operand:SI 0 "general_operand" "+d*g")
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))]
- ""
+ "!TARGET_5200"
"*
{
CC_STATUS_INIT;
(set (match_dup 0)
(plus:HI (match_dup 0)
(const_int -1)))]
- "find_reg_note (insn, REG_NONNEG, 0)"
+ "!TARGET_5200 && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
CC_STATUS_INIT;
#endif /* not MOTOROLA */
}")
-(define_insn "decrement_and_branch_until_zero"
+(define_expand "decrement_and_branch_until_zero"
+ [(parallel [(set (pc)
+ (if_then_else
+ (ge (plus:SI (match_operand:SI 0 "general_operand" "")
+ (const_int -1))
+ (const_int 0))
+ (label_ref (match_operand 1 "" ""))
+ (pc)))
+ (set (match_dup 0)
+ (plus:SI (match_dup 0)
+ (const_int -1)))])]
+ ""
+ "")
+
+(define_insn ""
[(set (pc)
(if_then_else
(ge (plus:SI (match_operand:SI 0 "general_operand" "+d*am")
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))]
- "find_reg_note (insn, REG_NONNEG, 0)"
+ "!TARGET_5200 && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
CC_STATUS_INIT;
}")
-;; PIC calls are handled by loading the address of the function into a
+;; For PIC calls, in order to be able to support
+;; dynamic linker LAZY BINDING, all the procedure calls need to go
+;; through the PLT (Procedure Linkage Table) section in PIC mode.
+;;
+;; PIC calls are handled by loading the address of the function into a
;; register (via movsi), then emitting a register indirect call using
;; the "jsr" function call syntax.
;;
-;; It is important to note that the "jsr" syntax is always used for
-;; PIC calls, even on machines in which GCC normally uses the "jbsr"
-;; syntax for non-PIC calls. This keeps at least 1 assembler (Sun)
-;; from emitting incorrect code for a PIC call.
+;; When outputting MIT syntax (e.g. on Suns), we add a bogus extra
+;; operand to the jbsr statement to indicate that this call should
+;; go through the PLT (why? because this is the way that Sun does it).
;;
;; We have different patterns for PIC calls and non-PIC calls. The
-;; different patterns are only used to choose the right syntax
-;; ("jsr" vs "jbsr").
+;; different patterns are only used to choose the right syntax.
;;
-;; On svr4 m68k, PIC stuff is done differently. To be able to support
-;; dynamic linker LAZY BINDING, all the procedure calls need to go
-;; through the PLT (Procedure Linkage Table) section in PIC mode. The
-;; svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it
-;; will create the correct relocation entry (R_68K_PLT32) for `FUNC',
+;; The svr4 m68k assembler recognizes this syntax: `bsr FUNC@PLTPC' and it
+;; will create the correct relocation entry (R_68K_PLT32) for `FUNC',
;; that tells the linker editor to create an entry for `FUNC' in PLT
;; section at link time. However, all global objects reference are still
-;; done by using `OBJ@GOT'. So, the goal here is to output the function
-;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'.
+;; done by using `OBJ@GOT'. So, the goal here is to output the function
+;; call operand as `FUNC@PLTPC', but output object operand as `OBJ@GOT'.
;; We need to have a way to differentiate these two different operands.
;;
-;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate
+;; The strategy I use here is to use SYMBOL_REF_FLAG to differentiate
;; these two different operands. The macro LEGITIMATE_PIC_OPERAND_P needs
-;; to be changed to recognize function calls symbol_ref operand as a valid
-;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will
-;; avoid the compiler to load this symbol_ref operand into a register.
-;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly
+;; to be changed to recognize function calls symbol_ref operand as a valid
+;; PIC operand (by checking whether SYMBOL_REF_FLAG is set). This will
+;; avoid the compiler to load this symbol_ref operand into a register.
+;; Remember, the operand "foo@PLTPC" cannot be called via jsr directly
;; since the value is a PC relative offset, not a real address.
;;
-;; All global objects are treated in the similar way as in SUN3. The only
-;; difference is: on m68k svr4, the reference of such global object needs
+;; All global objects are treated in the similar way as in SUN3. The only
+;; difference is: on m68k svr4, the reference of such global object needs
;; to end with a suffix "@GOT" so the assembler and linker know to create
-;; an entry for it in GOT (Global Offset Table) section. This is done in
+;; an entry for it in GOT (Global Offset Table) section. This is done in
;; m68k.c.
;; Call subroutine with no return value.
"
{
if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
-#ifdef MOTOROLA
SYMBOL_REF_FLAG (XEXP (operands[0], 0)) = 1;
-#else
- operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
- force_reg (Pmode, XEXP (operands[0], 0)));
-#endif
}")
;; This is a normal call sequence.
"! flag_pic"
"*
-#ifdef MOTOROLA
+#if defined (MOTOROLA) && !defined (USE_GAS)
#ifdef MOTOROLA_BSR
- if (GET_CODE (operands[0]) == MEM
+ if (GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
return \"bsr %0\";
#endif
"flag_pic"
"*
-#ifdef MOTOROLA
- if (GET_CODE (operands[0]) == MEM
+ if (GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
+#ifdef MOTOROLA
#ifdef HPUX_ASM
return \"bsr.l %0\";
#else
+#ifdef USE_GAS
+ return \"bsr.l %0@PLTPC\";
+#else
return \"bsr %0@PLTPC\";
#endif
#endif
+#else
+ /* The ',a1' is a dummy argument telling the Sun assembler we want PIC,
+ GAS just plain ignores it. */
+ return \"jbsr %0,a1\";
+#endif
return \"jsr %0\";
")
"
{
if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
-#ifdef MOTOROLA
SYMBOL_REF_FLAG (XEXP (operands[1], 0)) = 1;
-#else
- operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
- force_reg (Pmode, XEXP (operands[1], 0)));
-#endif
}")
;; This is a normal call_value
;; Operand 2 not really used on the m68000.
"! flag_pic"
"*
-#ifdef MOTOROLA
+#if defined (MOTOROLA) && !defined (USE_GAS)
#ifdef MOTOROLA_BSR
- if (GET_CODE (operands[1]) == MEM
+ if (GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
return \"bsr %1\";
#endif
;; Operand 2 not really used on the m68000.
"flag_pic"
"*
-#ifdef MOTOROLA
- if (GET_CODE (operands[1]) == MEM
+ if (GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
+#ifdef MOTOROLA
#ifdef HPUX_ASM
return \"bsr.l %1\";
#else
+#ifdef USE_GAS
+ return \"bsr.l %1@PLTPC\";
+#else
return \"bsr %1@PLTPC\";
#endif
#endif
+#else
+ /* The ',a1' is a dummy argument telling the Sun assembler we want PIC
+ GAS just plain ignores it. */
+ return \"jbsr %1,a1\";
+#endif
return \"jsr %1\";
")
xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4);
#ifndef NO_ADDSUB_Q
if (INTVAL (xoperands[1]) <= 8)
- output_asm_insn (\"addq%.w %1,%0\", xoperands);
- else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
{
- xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
+ if (!TARGET_5200)
+ output_asm_insn (\"addq%.w %1,%0\", xoperands);
+ else
+ output_asm_insn (\"addq%.l %1,%0\", xoperands);
+ }
+ else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16)
+ {
+ xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
INTVAL (xoperands[1]) - 8);
output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
}
else
#endif
if (INTVAL (xoperands[1]) <= 0x7FFF)
- output_asm_insn (\"add%.w %1,%0\", xoperands);
+ {
+ 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);
}
xoperands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[0]) - 4);
#ifndef NO_ADDSUB_Q
if (INTVAL (xoperands[1]) <= 8)
- output_asm_insn (\"addq%.w %1,%0\", xoperands);
- else if (INTVAL (xoperands[1]) <= 16 && TARGET_68020)
{
- xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
+ if (!TARGET_5200)
+ output_asm_insn (\"addq%.w %1,%0\", xoperands);
+ else
+ output_asm_insn (\"addq%.l %1,%0\", xoperands);
+ }
+ else if (TARGET_CPU32 && INTVAL (xoperands[1]) <= 16)
+ {
+ xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
INTVAL (xoperands[1]) - 8);
output_asm_insn (\"addq%.w %#8,%0\;addq%.w %1,%0\", xoperands);
}
else
#endif
if (INTVAL (xoperands[1]) <= 0x7FFF)
- output_asm_insn (\"add%.w %1,%0\", xoperands);
+ {
+ 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);
}
gen_rtx (PLUS, VOIDmode, stack_pointer_rtx,
gen_rtx (CONST_INT, VOIDmode, 3)));
xoperands[3] = stack_pointer_rtx;
- output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands);
+ if (!TARGET_5200)
+ output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands);
+ else
+ output_asm_insn (\"subq%.l %#4,%3\;move%.b %1,%2\", xoperands);
return \"\";
}")
&& (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 alternative for it. */
- && (TARGET_68020
+ 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\";
(set (match_dup 0)
(plus:HI (match_dup 0)
(const_int -1)))])]
- "DATA_REG_P (operands[0])"
+ "!TARGET_5200 && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
"*
{
CC_STATUS_INIT;
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))])]
- "DATA_REG_P (operands[0])"
+ "!TARGET_5200 && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
"*
{
CC_STATUS_INIT;
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_expand "cmpxf"
[(set (cc0)
- (compare (match_operand:XF 0 "general_operand" "f,mG")
- (match_operand:XF 1 "general_operand" "fmG,f")))]
+ (compare (match_operand:XF 0 "nonimmediate_operand" "")
+ (match_operand:XF 1 "nonimmediate_operand" "")))]
"TARGET_68881"
- "
-{
- if (CONSTANT_P (operands[0]))
- operands[0] = force_const_mem (XFmode, operands[0]);
- if (CONSTANT_P (operands[1]))
- operands[1] = force_const_mem (XFmode, operands[1]);
-}")
+ "m68k_last_compare_had_fp_operands = 1;")
(define_insn ""
[(set (cc0)
- (compare (match_operand:XF 0 "nonimmediate_operand" "f,mG")
- (match_operand:XF 1 "nonimmediate_operand" "fmG,f")))]
+ (compare (match_operand:XF 0 "nonimmediate_operand" "f,m")
+ (match_operand:XF 1 "nonimmediate_operand" "fm,f")))]
"TARGET_68881"
"*
{
}
return \"fmove%.d %f1,%0\";
}")
-
+
(define_insn "truncxfsf2"
[(set (match_operand:SF 0 "general_operand" "=dm")
(float_truncate:SF
"TARGET_68881"
"fmove%.l %1,%0")
-(define_expand "addxf3"
- [(set (match_operand:XF 0 "general_operand" "")
- (plus:XF (match_operand:XF 1 "general_operand" "")
- (match_operand:XF 2 "general_operand" "")))]
- "TARGET_68881"
- "
-{
- if (CONSTANT_P (operands[1]))
- operands[1] = force_const_mem (XFmode, operands[1]);
- if (CONSTANT_P (operands[2]))
- operands[2] = force_const_mem (XFmode, operands[2]);
-}")
-
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
(plus:XF (float:XF (match_operand:SI 2 "general_operand" "dmi"))
- (match_operand:XF 1 "general_operand" "0")))]
+ (match_operand:XF 1 "nonimmediate_operand" "0")))]
"TARGET_68881"
"fadd%.l %2,%0")
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
(plus:XF (float:XF (match_operand:HI 2 "general_operand" "dmn"))
- (match_operand:XF 1 "general_operand" "0")))]
+ (match_operand:XF 1 "nonimmediate_operand" "0")))]
"TARGET_68881"
"fadd%.w %2,%0")
"TARGET_68881"
"fadd%.b %2,%0")
-(define_insn ""
+(define_insn "addxf3"
[(set (match_operand:XF 0 "general_operand" "=f")
(plus:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
- (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
+ (match_operand:XF 2 "nonimmediate_operand" "fm")))]
"TARGET_68881"
"*
{
return \"fadd%.x %f2,%0\";
}")
-(define_expand "subxf3"
- [(set (match_operand:XF 0 "general_operand" "")
- (minus:XF (match_operand:XF 1 "general_operand" "")
- (match_operand:XF 2 "general_operand" "")))]
- "TARGET_68881"
- "
-{
- if (CONSTANT_P (operands[1]))
- operands[1] = force_const_mem (XFmode, operands[1]);
- if (CONSTANT_P (operands[2]))
- operands[2] = force_const_mem (XFmode, operands[2]);
-}")
-
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
- (minus:XF (match_operand:XF 1 "general_operand" "0")
+ (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
(float:XF (match_operand:SI 2 "general_operand" "dmi"))))]
"TARGET_68881"
"fsub%.l %2,%0")
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
- (minus:XF (match_operand:XF 1 "general_operand" "0")
+ (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
(float:XF (match_operand:HI 2 "general_operand" "dmn"))))]
"TARGET_68881"
"fsub%.w %2,%0")
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
- (minus:XF (match_operand:XF 1 "general_operand" "0")
+ (minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
(float:XF (match_operand:QI 2 "general_operand" "dmn"))))]
"TARGET_68881"
"fsub%.b %2,%0")
-(define_insn ""
+(define_insn "subxf3"
[(set (match_operand:XF 0 "general_operand" "=f")
(minus:XF (match_operand:XF 1 "nonimmediate_operand" "0")
- (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
+ (match_operand:XF 2 "nonimmediate_operand" "fm")))]
"TARGET_68881"
"*
{
return \"fsub%.x %f2,%0\";
}")
-(define_expand "mulxf3"
- [(set (match_operand:XF 0 "general_operand" "")
- (mult:XF (match_operand:XF 1 "general_operand" "")
- (match_operand:XF 2 "general_operand" "")))]
- "TARGET_68881"
- "
-{
- if (CONSTANT_P (operands[1]))
- operands[1] = force_const_mem (XFmode, operands[1]);
- if (CONSTANT_P (operands[2]))
- operands[2] = force_const_mem (XFmode, operands[2]);
-}")
-
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
(mult:XF (float:XF (match_operand:SI 2 "general_operand" "dmi"))
- (match_operand:XF 1 "general_operand" "0")))]
+ (match_operand:XF 1 "nonimmediate_operand" "0")))]
"TARGET_68881"
"fmul%.l %2,%0")
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
(mult:XF (float:XF (match_operand:HI 2 "general_operand" "dmn"))
- (match_operand:XF 1 "general_operand" "0")))]
+ (match_operand:XF 1 "nonimmediate_operand" "0")))]
"TARGET_68881"
"fmul%.w %2,%0")
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
(mult:XF (float:XF (match_operand:QI 2 "general_operand" "dmn"))
- (match_operand:XF 1 "general_operand" "0")))]
+ (match_operand:XF 1 "nonimmediate_operand" "0")))]
"TARGET_68881"
"fmul%.b %2,%0")
-(define_insn ""
+(define_insn "mulxf3"
[(set (match_operand:XF 0 "general_operand" "=f")
(mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
- (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
+ (match_operand:XF 2 "nonimmediate_operand" "fm")))]
"TARGET_68881"
"*
{
return \"fmul%.x %f2,%0\";
}")
-(define_expand "divxf3"
- [(set (match_operand:XF 0 "general_operand" "")
- (div:XF (match_operand:XF 1 "general_operand" "")
- (match_operand:XF 2 "general_operand" "")))]
- "TARGET_68881"
- "
-{
- if (CONSTANT_P (operands[1]))
- operands[1] = force_const_mem (XFmode, operands[1]);
- if (CONSTANT_P (operands[2]))
- operands[2] = force_const_mem (XFmode, operands[2]);
-}")
-
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
- (div:XF (match_operand:XF 1 "general_operand" "0")
+ (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
(float:XF (match_operand:SI 2 "general_operand" "dmi"))))]
"TARGET_68881"
"fdiv%.l %2,%0")
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
- (div:XF (match_operand:XF 1 "general_operand" "0")
+ (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
(float:XF (match_operand:HI 2 "general_operand" "dmn"))))]
"TARGET_68881"
"fdiv%.w %2,%0")
(define_insn ""
[(set (match_operand:XF 0 "general_operand" "=f")
- (div:XF (match_operand:XF 1 "general_operand" "0")
+ (div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
(float:XF (match_operand:QI 2 "general_operand" "dmn"))))]
"TARGET_68881"
"fdiv%.b %2,%0")
-(define_insn ""
+(define_insn "divxf3"
[(set (match_operand:XF 0 "general_operand" "=f")
(div:XF (match_operand:XF 1 "nonimmediate_operand" "0")
- (match_operand:XF 2 "nonimmediate_operand" "fmG")))]
+ (match_operand:XF 2 "nonimmediate_operand" "fm")))]
"TARGET_68881"
"*
{
(define_expand "negxf2"
[(set (match_operand:XF 0 "general_operand" "")
- (neg:XF (match_operand:XF 1 "general_operand" "")))]
+ (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
""
"
{
/* ??? There isn't an FPA define_insn so we could handle it here too.
For now we don't (paranoia). */
- if (!TARGET_FPA && !TARGET_68881)
+ if (!TARGET_68881)
{
rtx result;
rtx target;
if (result != target)
emit_move_insn (result, target);
-
+
emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
operand_subword_force (operands[1], 1, XFmode));
emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
(define_insn "negxf2_68881"
[(set (match_operand:XF 0 "general_operand" "=f")
- (neg:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))]
+ (neg:XF (match_operand:XF 1 "nonimmediate_operand" "fm")))]
"TARGET_68881"
"*
{
(define_expand "absxf2"
[(set (match_operand:XF 0 "general_operand" "")
- (abs:XF (match_operand:XF 1 "general_operand" "")))]
+ (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
""
"
{
/* ??? There isn't an FPA define_insn so we could handle it here too.
For now we don't (paranoia). */
- if (!TARGET_FPA && !TARGET_68881)
+ if (!TARGET_68881)
{
rtx result;
rtx target;
if (result != target)
emit_move_insn (result, target);
-
+
emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
operand_subword_force (operands[1], 1, XFmode));
emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
(define_insn "absxf2_68881"
[(set (match_operand:XF 0 "general_operand" "=f")
- (abs:XF (match_operand:XF 1 "nonimmediate_operand" "fmF")))]
+ (abs:XF (match_operand:XF 1 "nonimmediate_operand" "fm")))]
"TARGET_68881"
"*
{
[(set (match_operand:XF 0 "general_operand" "=f")
(sqrt:XF (match_operand:XF 1 "nonimmediate_operand" "fm")))]
"TARGET_68881"
- "*
-{
- return \"fsqrt%.x %1,%0\";
-}")
+ "fsqrt%.x %1,%0")
(define_insn "sinsf2"
[(set (match_operand:SF 0 "general_operand" "=f")
[(set (match_operand:XF 0 "general_operand" "=f")
(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 1))]
"TARGET_68881 && flag_fast_math"
- "*
-{
- return \"fsin%.x %1,%0\";
-}")
+ "fsin%.x %1,%0")
(define_insn "cossf2"
[(set (match_operand:SF 0 "general_operand" "=f")
[(set (match_operand:XF 0 "general_operand" "=f")
(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 2))]
"TARGET_68881 && flag_fast_math"
- "*
-{
- return \"fcos%.x %1,%0\";
-}")
+ "fcos%.x %1,%0")