OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc2/] [gcc/] [config/] [m68k/] [m68k.md] - Blame information for rev 435

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
;;- Machine description for GNU compiler, Motorola 68000 Version
2
;;  Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001,
3
;;  2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4
;;  Free Software Foundation, Inc.
5
 
6
;; This file is part of GCC.
7
 
8
;; GCC is free software; you can redistribute it and/or modify
9
;; it under the terms of the GNU General Public License as published by
10
;; the Free Software Foundation; either version 3, or (at your option)
11
;; any later version.
12
 
13
;; GCC is distributed in the hope that it will be useful,
14
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
;; GNU General Public License for more details.
17
 
18
;; You should have received a copy of the GNU General Public License
19
;; along with GCC; see the file COPYING3.  If not see
20
;; .
21
 
22
;;- Information about MCF5200 port.
23
 
24
;;- The MCF5200 "ColdFire" architecture is a reduced version of the
25
;;- 68k ISA.  Differences include reduced support for byte and word
26
;;- operands and the removal of BCD, bitfield, rotate, and integer
27
;;- divide instructions.  The TARGET_COLDFIRE flag turns the use of the
28
;;- removed opcodes and addressing modes off.
29
;;-
30
 
31
 
32
;;- instruction definitions
33
 
34
;;- @@The original PO technology requires these to be ordered by speed,
35
;;- @@    so that assigner will pick the fastest.
36
 
37
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
38
 
39
;;- When naming insn's (operand 0 of define_insn) be careful about using
40
;;- names from other targets machine descriptions.
41
 
42
;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
43
;;- updates for most instructions.
44
 
45
;;- Operand classes for the register allocator:
46
;;- 'a' one of the address registers can be used.
47
;;- 'd' one of the data registers can be used.
48
;;- 'f' one of the m68881/fpu registers can be used
49
;;- 'r' either a data or an address register can be used.
50
 
51
;;- Immediate Floating point operator constraints
52
;;- 'G' a floating point constant that is *NOT* one of the standard
53
;;   68881 constant values (to force calling output_move_const_double
54
;;   to get it from rom if it is a 68881 constant).
55
;;
56
;;   See the functions standard_XXX_constant_p in output-m68k.c for more
57
;; info.
58
 
59
;;- Immediate integer operand constraints:
60
;;- 'I'  1 .. 8
61
;;- 'J'  -32768 .. 32767
62
;;- 'K'  all integers EXCEPT -128 .. 127
63
;;- 'L'  -8 .. -1
64
;;- 'M'  all integers EXCEPT -256 .. 255
65
;;- 'N'  24 .. 31
66
;;- 'O'  16
67
;;- 'P'  8 .. 15
68
 
69
;;- Assembler specs:
70
;;- "%."    size separator ("." or "")                  move%.l d0,d1
71
;;- "%-"    push operand "sp@-"                         move%.l d0,%-
72
;;- "%+"    pop operand "sp@+"                          move%.l d0,%+
73
;;- "%@"    top of stack "sp@"                          move%.l d0,%@
74
;;- "%!"    fpcr register
75
;;- "%$"    single-precision fp specifier ("s" or "")   f%$add.x fp0,fp1
76
;;- "%&"    double-precision fp specifier ("d" or "")   f%&add.x fp0,fp1
77
 
78
;;- Information about 68040 port.
79
 
80
;;- The 68040 executes all 68030 and 68881/2 instructions, but some must
81
;;- be emulated in software by the OS.  It is faster to avoid these
82
;;- instructions and issue a library call rather than trapping into
83
;;- the kernel.  The affected instructions are fintrz and fscale.  The
84
;;- TUNE_68040 flag turns the use of the opcodes off.
85
 
86
;;- The '040 also implements a set of new floating-point instructions
87
;;- which specify the rounding precision in the opcode.  This finally
88
;;- permit the 68k series to be truly IEEE compliant, and solves all
89
;;- issues of excess precision accumulating in the extended registers.
90
;;- By default, GCC does not use these instructions, since such code will
91
;;- not run on an '030.  To use these instructions, use the -m68040-only
92
;;- switch.
93
 
94
;;- These new instructions aren't directly in the md.  They are brought
95
;;- into play by defining "%$" and "%&" to expand to "s" and "d" rather
96
;;- than "".
97
 
98
;;- Information about 68060 port.
99
 
100
;;- The 68060 executes all 68030 and 68881/2 instructions, but some must
101
;;- be emulated in software by the OS.  It is faster to avoid these
102
;;- instructions and issue a library call rather than trapping into
103
;;- the kernel.  The affected instructions are: divs.l ,Dr:Dq;
104
;;- divu.l ,Dr:Dq; muls.l ,Dr:Dq; mulu.l ,Dr:Dq; and
105
;;- fscale.  The TUNE_68060 flag turns the use of the opcodes off.
106
 
107
;;- Some of these insn's are composites of several m68000 op codes.
108
;;- The assembler (or final @@??) insures that the appropriate one is
109
;;- selected.
110
 
111
;; UNSPEC usage:
112
 
113
(define_constants
114
  [(UNSPEC_SIN 1)
115
   (UNSPEC_COS 2)
116
   (UNSPEC_GOT 3)
117
   (UNSPEC_IB 4)
118
   (UNSPEC_TIE 5)
119
   (UNSPEC_RELOC16 6)
120
   (UNSPEC_RELOC32 7)
121
  ])
122
 
123
;; UNSPEC_VOLATILE usage:
124
 
125
(define_constants
126
  [(UNSPECV_BLOCKAGE    0)
127
  ])
128
 
129
;; Registers by name.
130
(define_constants
131
  [(D0_REG              0)
132
   (A0_REG              8)
133
   (A1_REG              9)
134
   (PIC_REG             13)
135
   (A6_REG              14)
136
   (SP_REG              15)
137
   (FP0_REG             16)
138
  ])
139
 
140
(include "predicates.md")
141
(include "constraints.md")
142
 
143
;; ::::::::::::::::::::
144
;; ::
145
;; :: Attributes
146
;; ::
147
;; ::::::::::::::::::::
148
 
149
;; Processor type.
150
(define_attr "cpu" "cfv1, cfv2, cfv3, cfv4, unknown"
151
  (const (symbol_ref "m68k_sched_cpu")))
152
 
153
;; MAC type.
154
(define_attr "mac" "no, cf_mac, cf_emac"
155
  (const (symbol_ref "m68k_sched_mac")))
156
 
157
;; Instruction type for use in scheduling description.
158
;; _l and _w suffixes indicate size of the operands of instruction.
159
;; alu - usual arithmetic or logic instruction.
160
;; aluq - arithmetic or logic instruction which has a quick immediate (the one
161
;;        that is encoded in the instruction word) for its Y operand.
162
;; alux - Arithmetic instruction that uses carry bit (e.g., addx and subx).
163
;; bcc - conditional branch.
164
;; bitr - bit operation that only updates flags.
165
;; bitrw - bit operation that updates flags and output operand.
166
;; bra, bsr, clr, cmp, div, ext - corresponding instruction.
167
;; falu, fbcc, fcmp, fdiv, fmove, fmul, fneg, fsqrt, ftst - corresponding
168
;;                                                          instruction.
169
;; ib - fake instruction to subscribe slots in ColdFire V1,V2,V3 instruction
170
;;      buffer.
171
;; ignore - fake instruction.
172
;; jmp, jsr, lea, link, mov3q, move, moveq, mul - corresponding instruction.
173
;; mvsz - mvs or mvz instruction.
174
;; neg, nop, pea, rts, scc - corresponding instruction.
175
;; shift - arithmetic or logical shift instruction.
176
;; trap, tst, unlk - corresponding instruction.
177
(define_attr "type"
178
  "alu_l,aluq_l,alux_l,bcc,bitr,bitrw,bra,bsr,clr,clr_l,cmp,cmp_l,
179
   div_w,div_l,ext,
180
   falu,fbcc,fcmp,fdiv,fmove,fmul,fneg,fsqrt,ftst,
181
   ib,ignore,
182
   jmp,jsr,lea,link,mov3q_l,move,move_l,moveq_l,mul_w,mul_l,mvsz,neg_l,nop,
183
   pea,rts,scc,shift,
184
   trap,tst,tst_l,unlk,
185
   unknown"
186
  (const_string "unknown"))
187
 
188
;; Index of the X or Y operand in recog_data.operand[].
189
;; Should be used only within opx_type and opy_type.
190
(define_attr "opx" "" (const_int 0))
191
(define_attr "opy" "" (const_int 1))
192
 
193
;; Type of the Y operand.
194
;; See m68k.c: enum attr_op_type.
195
(define_attr "opy_type"
196
  "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l"
197
  (cond [(eq_attr "type" "ext,fbcc,ftst,neg_l,bcc,bra,bsr,clr,clr_l,ib,ignore,
198
                          jmp,jsr,nop,rts,scc,trap,tst,tst_l,
199
                          unlk,unknown") (const_string "none")
200
         (eq_attr "type" "lea,pea")
201
         (symbol_ref "m68k_sched_attr_opy_type (insn, 1)")]
202
        (symbol_ref "m68k_sched_attr_opy_type (insn, 0)")))
203
 
204
;; Type of the X operand.
205
;; See m68k.c: enum attr_op_type.
206
(define_attr "opx_type"
207
  "none,Rn,FPn,mem1,mem234,mem5,mem6,mem7,imm_q,imm_w,imm_l"
208
  (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk,
209
                          unknown") (const_string "none")
210
         (eq_attr "type" "pea") (const_string "mem1")
211
         (eq_attr "type" "jmp,jsr")
212
         (symbol_ref "m68k_sched_attr_opx_type (insn, 1)")]
213
        (symbol_ref "m68k_sched_attr_opx_type (insn, 0)")))
214
 
215
;; Access to the X operand: none, read, write, read/write, unknown.
216
;; Access to the Y operand is either none (if opy_type is none)
217
;; or read otherwise.
218
(define_attr "opx_access" "none, r, w, rw"
219
  (cond [(eq_attr "type" "ib,ignore,nop,rts,trap,unlk,
220
                          unknown") (const_string "none")
221
         (eq_attr "type" "bcc,bra,bsr,bitr,cmp,cmp_l,fbcc,fcmp,ftst,
222
                          jmp,jsr,tst,tst_l") (const_string "r")
223
         (eq_attr "type" "clr,clr_l,fneg,fmove,lea,
224
                          mov3q_l,move,move_l,moveq_l,mvsz,
225
                          pea,scc") (const_string "w")
226
         (eq_attr "type" "alu_l,aluq_l,alux_l,bitrw,div_w,div_l,ext,
227
                          falu,fdiv,fmul,fsqrt,link,mul_w,mul_l,
228
                          neg_l,shift") (const_string "rw")]
229
        ;; Should never be used.
230
        (symbol_ref "(gcc_unreachable (), OPX_ACCESS_NONE)")))
231
 
232
;; Memory accesses of the insn.
233
;; 00 - no memory references
234
;; 10 - memory is read
235
;; i0 - indexed memory is read
236
;; 01 - memory is written
237
;; 0i - indexed memory is written
238
;; 11 - memory is read, memory is written
239
;; i1 - indexed memory is read, memory is written
240
;; 1i - memory is read, indexed memory is written
241
(define_attr "op_mem" "00, 10, i0, 01, 0i, 11, i1, 1i"
242
  (symbol_ref "m68k_sched_attr_op_mem (insn)"))
243
 
244
;; Instruction size in words.
245
(define_attr "size" "1,2,3"
246
  (symbol_ref "m68k_sched_attr_size (insn)"))
247
 
248
;; Alternative is OK for ColdFire.
249
(define_attr "ok_for_coldfire" "yes,no" (const_string "yes"))
250
 
251
;; Define 'enabled' attribute.
252
(define_attr "enabled" ""
253
  (cond [(and (ne (symbol_ref "TARGET_COLDFIRE") (const_int 0))
254
              (eq_attr "ok_for_coldfire" "no"))
255
         (const_int 0)]
256
        (const_int 1)))
257
 
258
;; Mode macros for floating point operations.
259
;; Valid floating point modes
260
(define_mode_iterator FP [SF DF (XF "TARGET_68881")])
261
;; Mnemonic infix to round result
262
(define_mode_attr round [(SF "%$") (DF "%&") (XF "")])
263
;; Mnemonic infix to round result for mul or div instruction
264
(define_mode_attr round_mul [(SF "sgl") (DF "%&") (XF "")])
265
;; Suffix specifying source operand format
266
(define_mode_attr prec [(SF "s") (DF "d") (XF "x")])
267
;; Allowable D registers
268
(define_mode_attr dreg [(SF "d") (DF "") (XF "")])
269
;; Allowable 68881 constant constraints
270
(define_mode_attr const [(SF "F") (DF "G") (XF "")])
271
 
272
 
273
(define_insn_and_split "*movdf_internal"
274
  [(set (match_operand:DF 0 "push_operand"   "=m, m")
275
        (match_operand:DF 1 "general_operand" "f, ro<>E"))]
276
  ""
277
  "@
278
   fmove%.d %f1,%0
279
   #"
280
  "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 1)"
281
  [(const_int 0)]
282
{
283
  m68k_emit_move_double (operands);
284
  DONE;
285
}
286
  [(set_attr "type" "fmove,*")])
287
 
288
(define_insn_and_split "pushdi"
289
  [(set (match_operand:DI 0 "push_operand" "=m")
290
        (match_operand:DI 1 "general_operand" "ro<>Fi"))]
291
  ""
292
  "#"
293
  "&& reload_completed"
294
  [(const_int 0)]
295
{
296
  m68k_emit_move_double (operands);
297
  DONE;
298
})
299
 
300
;; We don't want to allow a constant operand for test insns because
301
;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
302
;; be folded while optimizing anyway.
303
 
304
(define_insn "tstdi"
305
  [(set (cc0)
306
        (compare (match_operand:DI 0 "nonimmediate_operand" "am,d")
307
                 (const_int 0)))
308
   (clobber (match_scratch:SI 1 "=X,d"))
309
   (clobber (match_scratch:DI 2 "=d,X"))]
310
  ""
311
{
312
  if (which_alternative == 0)
313
    {
314
      rtx xoperands[2];
315
 
316
      xoperands[0] = operands[2];
317
      xoperands[1] = operands[0];
318
      output_move_double (xoperands);
319
      cc_status.flags |= CC_REVERSED; /*|*/
320
      return "neg%.l %R2\;negx%.l %2";
321
    }
322
  if (find_reg_note (insn, REG_DEAD, operands[0]))
323
    {
324
      cc_status.flags |= CC_REVERSED; /*|*/
325
      return "neg%.l %R0\;negx%.l %0";
326
    }
327
  else
328
    /*
329
       'sub' clears %1, and also clears the X cc bit
330
       'tst' sets the Z cc bit according to the low part of the DImode operand
331
       'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part.
332
    */
333
    return "sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0";
334
})
335
 
336
;; If you think that the 68020 does not support tstl a0,
337
;; reread page B-167 of the 68020 manual more carefully.
338
(define_insn "*tstsi_internal_68020_cf"
339
  [(set (cc0)
340
        (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
341
                 (const_int 0)))]
342
  "TARGET_68020 || TARGET_COLDFIRE"
343
  "tst%.l %0"
344
  [(set_attr "type" "tst_l")])
345
 
346
;; On an address reg, cmpw may replace cmpl.
347
(define_insn "*tstsi_internal"
348
  [(set (cc0)
349
        (compare (match_operand:SI 0 "nonimmediate_operand" "dm,r")
350
                 (const_int 0)))]
351
  "!(TARGET_68020 || TARGET_COLDFIRE)"
352
  "@
353
   tst%.l %0
354
   cmp%.w #0,%0"
355
  [(set_attr "type" "tst_l,cmp")])
356
 
357
;; This can't use an address register, because comparisons
358
;; with address registers as second operand always test the whole word.
359
(define_insn "*tsthi_internal"
360
  [(set (cc0)
361
        (compare (match_operand:HI 0 "nonimmediate_operand" "dm")
362
                 (const_int 0)))]
363
  ""
364
  "tst%.w %0"
365
  [(set_attr "type" "tst")])
366
 
367
(define_insn "*tstqi_internal"
368
  [(set (cc0)
369
        (compare (match_operand:QI 0 "nonimmediate_operand" "dm")
370
                 (const_int 0)))]
371
  ""
372
  "tst%.b %0"
373
  [(set_attr "type" "tst")])
374
 
375
(define_insn "tst_68881"
376
  [(set (cc0)
377
        (compare (match_operand:FP 0 "general_operand" "fm")
378
                 (match_operand:FP 1 "const0_operand" "H")))]
379
  "TARGET_68881"
380
{
381
  cc_status.flags = CC_IN_68881;
382
  if (FP_REG_P (operands[0]))
383
    return "ftst%.x %0";
384
  return "ftst%. %0";
385
}
386
  [(set_attr "type" "ftst")])
387
 
388
(define_insn "tst_cf"
389
  [(set (cc0)
390
        (compare (match_operand:FP 0 "general_operand" "fU")
391
                 (match_operand:FP 1 "const0_operand" "H")))]
392
  "TARGET_COLDFIRE_FPU"
393
{
394
  cc_status.flags = CC_IN_68881;
395
  if (FP_REG_P (operands[0]))
396
    return "ftst%.d %0";
397
  return "ftst%. %0";
398
}
399
  [(set_attr "type" "ftst")])
400
 
401
 
402
;; compare instructions.
403
 
404
(define_insn "*cmpdi_internal"
405
 [(set (cc0)
406
       (compare (match_operand:DI 1 "nonimmediate_operand" "0,d")
407
                (match_operand:DI 2 "general_operand" "d,0")))
408
  (clobber (match_scratch:DI 0 "=d,d"))]
409
  ""
410
{
411
  if (rtx_equal_p (operands[0], operands[1]))
412
    return "sub%.l %R2,%R0\;subx%.l %2,%0";
413
  else
414
    {
415
      cc_status.flags |= CC_REVERSED; /*|*/
416
      return "sub%.l %R1,%R0\;subx%.l %1,%0";
417
    }
418
})
419
 
420
(define_insn "cmpdi"
421
 [(set (cc0)
422
       (compare (match_operand:DI 0 "nonimmediate_operand")
423
                (match_operand:DI 1 "general_operand")))
424
  (clobber (match_scratch:DI 2))]
425
  ""
426
  "")
427
 
428
 
429
(define_expand "cbranchdi4"
430
  [(set (pc)
431
        (if_then_else (match_operator 0 "ordered_comparison_operator"
432
                       [(match_operand:DI 1 "nonimmediate_operand")
433
                        (match_operand:DI 2 "general_operand")])
434
                      (label_ref (match_operand 3 ""))
435
                      (pc)))]
436
  ""
437
{
438
  if (operands[2] == const0_rtx)
439
    emit_insn (gen_tstdi (operands[1]));
440
  else
441
    emit_insn (gen_cmpdi (operands[1], operands[2]));
442
  operands[1] = cc0_rtx;
443
  operands[2] = const0_rtx;
444
})
445
 
446
(define_expand "cstoredi4"
447
  [(set (match_operand:QI 0 "register_operand")
448
        (match_operator:QI 1 "ordered_comparison_operator"
449
         [(match_operand:DI 2 "nonimmediate_operand")
450
          (match_operand:DI 3 "general_operand")]))]
451
  ""
452
{
453
  if (operands[3] == const0_rtx)
454
    emit_insn (gen_tstdi (operands[2]));
455
  else
456
    emit_insn (gen_cmpdi (operands[2], operands[3]));
457
  operands[2] = cc0_rtx;
458
  operands[3] = const0_rtx;
459
})
460
 
461
 
462
(define_expand "cbranchsi4"
463
  [(set (cc0)
464
        (compare (match_operand:SI 1 "nonimmediate_operand" "")
465
                 (match_operand:SI 2 "general_operand" "")))
466
   (set (pc)
467
        (if_then_else (match_operator 0 "ordered_comparison_operator"
468
                       [(cc0) (const_int 0)])
469
                      (label_ref (match_operand 3 ""))
470
                      (pc)))]
471
  ""
472
  "")
473
 
474
(define_expand "cstoresi4"
475
  [(set (cc0)
476
        (compare (match_operand:SI 2 "nonimmediate_operand" "")
477
                 (match_operand:SI 3 "general_operand" "")))
478
   (set (match_operand:QI 0 "register_operand")
479
        (match_operator:QI 1 "ordered_comparison_operator"
480
         [(cc0) (const_int 0)]))]
481
  ""
482
  "")
483
 
484
 
485
;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
486
(define_insn ""
487
  [(set (cc0)
488
        (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mSr,mSa,>")
489
                 (match_operand:SI 1 "general_src_operand" "mSr,mSa,KTr,Ksr,>")))]
490
  "!TARGET_COLDFIRE"
491
{
492
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
493
    return "cmpm%.l %1,%0";
494
  if (REG_P (operands[1])
495
      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
496
    {
497
      cc_status.flags |= CC_REVERSED; /*|*/
498
      return "cmp%.l %d0,%d1";
499
    }
500
  if (ADDRESS_REG_P (operands[0])
501
      && GET_CODE (operands[1]) == CONST_INT
502
      && INTVAL (operands[1]) < 0x8000
503
      && INTVAL (operands[1]) >= -0x8000)
504
    return "cmp%.w %1,%0";
505
  return "cmp%.l %d1,%d0";
506
})
507
 
508
(define_insn "*cmpsi_cf"
509
  [(set (cc0)
510
        (compare (match_operand:SI 0 "nonimmediate_operand" "mrKs,r")
511
                 (match_operand:SI 1 "general_operand" "r,mrKs")))]
512
  "TARGET_COLDFIRE"
513
{
514
  if (REG_P (operands[1])
515
      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
516
    {
517
      cc_status.flags |= CC_REVERSED; /*|*/
518
      return "cmp%.l %d0,%d1";
519
    }
520
  return "cmp%.l %d1,%d0";
521
}
522
  [(set_attr "type" "cmp_l")])
523
 
524
(define_expand "cbranchhi4"
525
  [(set (cc0)
526
        (compare (match_operand:HI 1 "nonimmediate_src_operand" "")
527
                 (match_operand:HI 2 "m68k_subword_comparison_operand" "")))
528
   (set (pc)
529
        (if_then_else (match_operator 0 "ordered_comparison_operator"
530
                       [(cc0) (const_int 0)])
531
                      (label_ref (match_operand 3 ""))
532
                      (pc)))]
533
  ""
534
  "")
535
 
536
(define_expand "cstorehi4"
537
  [(set (cc0)
538
        (compare (match_operand:HI 2 "nonimmediate_operand" "")
539
                 (match_operand:HI 3 "m68k_subword_comparison_operand" "")))
540
   (set (match_operand:QI 0 "register_operand")
541
        (match_operator:QI 1 "ordered_comparison_operator"
542
         [(cc0) (const_int 0)]))]
543
  ""
544
  "")
545
 
546
(define_insn ""
547
  [(set (cc0)
548
        (compare (match_operand:HI 0 "nonimmediate_src_operand" "rnmS,d,n,mS,>")
549
                 (match_operand:HI 1 "general_src_operand" "d,rnmS,mS,n,>")))]
550
  "!TARGET_COLDFIRE"
551
{
552
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
553
    return "cmpm%.w %1,%0";
554
  if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
555
      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
556
    {
557
      cc_status.flags |= CC_REVERSED; /*|*/
558
      return "cmp%.w %d0,%d1";
559
    }
560
  return "cmp%.w %d1,%d0";
561
})
562
 
563
(define_expand "cbranchqi4"
564
  [(set (cc0)
565
        (compare (match_operand:QI 1 "nonimmediate_src_operand" "")
566
                 (match_operand:QI 2 "m68k_subword_comparison_operand" "")))
567
   (set (pc)
568
        (if_then_else (match_operator 0 "ordered_comparison_operator"
569
                       [(cc0) (const_int 0)])
570
                      (label_ref (match_operand 3 ""))
571
                      (pc)))]
572
  ""
573
  "")
574
 
575
(define_expand "cstoreqi4"
576
  [(set (cc0)
577
        (compare (match_operand:QI 2 "nonimmediate_src_operand" "")
578
                 (match_operand:QI 3 "m68k_subword_comparison_operand" "")))
579
   (set (match_operand:QI 0 "register_operand")
580
        (match_operator:QI 1 "ordered_comparison_operator"
581
         [(cc0) (const_int 0)]))]
582
  ""
583
  "")
584
 
585
(define_insn ""
586
  [(set (cc0)
587
        (compare (match_operand:QI 0 "nonimmediate_src_operand" "dn,dmS,>")
588
                 (match_operand:QI 1 "general_src_operand" "dmS,nd,>")))]
589
  "!TARGET_COLDFIRE"
590
{
591
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
592
    return "cmpm%.b %1,%0";
593
  if (REG_P (operands[1])
594
      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
595
    {
596
      cc_status.flags |= CC_REVERSED; /*|*/
597
      return "cmp%.b %d0,%d1";
598
    }
599
  return "cmp%.b %d1,%d0";
600
})
601
 
602
(define_expand "cbranch4"
603
  [(set (cc0)
604
        (compare (match_operand:FP 1 "register_operand" "")
605
                 (match_operand:FP 2 "fp_src_operand" "")))
606
   (set (pc)
607
        (if_then_else (match_operator 0 "comparison_operator"
608
                       [(cc0) (const_int 0)])
609
                      (label_ref (match_operand 3 ""))
610
                      (pc)))]
611
  "TARGET_HARD_FLOAT"
612
  "")
613
 
614
(define_expand "cstore4"
615
  [(set (cc0)
616
        (compare (match_operand:FP 2 "register_operand" "")
617
                 (match_operand:FP 3 "fp_src_operand" "")))
618
   (set (match_operand:QI 0 "register_operand")
619
        (match_operator:QI 1 "m68k_cstore_comparison_operator"
620
         [(cc0) (const_int 0)]))]
621
  "TARGET_HARD_FLOAT && !(TUNE_68060 || TARGET_COLDFIRE_FPU)"
622
  "if (TARGET_COLDFIRE && operands[2] != const0_rtx)
623
     FAIL;")
624
 
625
(define_insn "*cmp_68881"
626
  [(set (cc0)
627
        (compare (match_operand:FP 0 "fp_src_operand" "f,f,mF")
628
                 (match_operand:FP 1 "fp_src_operand" "f,mF,f")))]
629
  "TARGET_68881
630
   && (register_operand (operands[0], mode)
631
       || register_operand (operands[1], mode))"
632
  "@
633
   fcmp%.x %1,%0
634
   fcmp%. %f1,%0
635
   fcmp%. %0,%f1"
636
  [(set_attr "type" "fcmp")])
637
 
638
(define_insn "*cmp_cf"
639
  [(set (cc0)
640
        (compare (match_operand:FP 0 "fp_src_operand" "f,f,U")
641
                 (match_operand:FP 1 "fp_src_operand" "f,U,f")))]
642
  "TARGET_COLDFIRE_FPU
643
   && (register_operand (operands[0], mode)
644
       || register_operand (operands[1], mode))"
645
  "@
646
   fcmp%.d %1,%0
647
   fcmp%. %f1,%0
648
   fcmp%. %0,%f1"
649
  [(set_attr "type" "fcmp")])
650
 
651
;; Recognizers for btst instructions.
652
 
653
;; ColdFire/5200 only allows "" type addresses when the bit position is
654
;; specified as a constant, so we must disable all patterns that may extract
655
;; from a MEM at a constant bit position if we can't use this as a constraint.
656
 
657
(define_insn ""
658
  [(set
659
    (cc0)
660
    (compare (zero_extract:SI (match_operand:QI 0 "memory_src_operand" "oS")
661
                               (const_int 1)
662
                               (minus:SI (const_int 7)
663
                                         (match_operand:SI 1 "general_operand" "di")))
664
             (const_int 0)))]
665
  "!TARGET_COLDFIRE"
666
{
667
  return output_btst (operands, operands[1], operands[0], insn, 7);
668
})
669
 
670
;; This is the same as the above pattern except for the constraints.  The 'i'
671
;; has been deleted.
672
 
673
(define_insn ""
674
  [(set
675
    (cc0)
676
    (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
677
                               (const_int 1)
678
                               (minus:SI (const_int 7)
679
                                         (match_operand:SI 1 "general_operand" "d")))
680
             (const_int 0)))]
681
  "TARGET_COLDFIRE"
682
{
683
  return output_btst (operands, operands[1], operands[0], insn, 7);
684
})
685
 
686
(define_insn ""
687
  [(set
688
    (cc0)
689
    (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
690
                               (const_int 1)
691
                               (minus:SI (const_int 31)
692
                                         (match_operand:SI 1 "general_operand" "di")))
693
             (const_int 0)))]
694
  ""
695
{
696
  return output_btst (operands, operands[1], operands[0], insn, 31);
697
})
698
 
699
;; The following two patterns are like the previous two
700
;; except that they use the fact that bit-number operands
701
;; are automatically masked to 3 or 5 bits.
702
 
703
(define_insn ""
704
  [(set
705
    (cc0)
706
    (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
707
                               (const_int 1)
708
                               (minus:SI (const_int 7)
709
                                         (and:SI
710
                                          (match_operand:SI 1 "register_operand" "d")
711
                                          (const_int 7))))
712
             (const_int 0)))]
713
  ""
714
{
715
  return output_btst (operands, operands[1], operands[0], insn, 7);
716
})
717
 
718
(define_insn ""
719
  [(set
720
    (cc0)
721
    (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
722
                               (const_int 1)
723
                               (minus:SI (const_int 31)
724
                                         (and:SI
725
                                          (match_operand:SI 1 "register_operand" "d")
726
                                          (const_int 31))))
727
             (const_int 0)))]
728
  ""
729
{
730
  return output_btst (operands, operands[1], operands[0], insn, 31);
731
})
732
 
733
;; Nonoffsettable mem refs are ok in this one pattern
734
;; since we don't try to adjust them.
735
(define_insn ""
736
  [(set
737
    (cc0)
738
    (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
739
                              (const_int 1)
740
                              (match_operand:SI 1 "const_int_operand" "n"))
741
             (const_int 0)))]
742
  "(unsigned) INTVAL (operands[1]) < 8 && !TARGET_COLDFIRE"
743
{
744
  operands[1] = GEN_INT (7 - INTVAL (operands[1]));
745
  return output_btst (operands, operands[1], operands[0], insn, 7);
746
})
747
 
748
(define_insn ""
749
  [(set
750
    (cc0)
751
    (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "do")
752
                              (const_int 1)
753
                            (match_operand:SI 1 "const_int_operand" "n"))
754
             (const_int 0)))]
755
  "!TARGET_COLDFIRE"
756
{
757
  if (GET_CODE (operands[0]) == MEM)
758
    {
759
      operands[0] = adjust_address (operands[0], QImode,
760
                                    INTVAL (operands[1]) / 8);
761
      operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
762
      return output_btst (operands, operands[1], operands[0], insn, 7);
763
    }
764
  operands[1] = GEN_INT (31 - INTVAL (operands[1]));
765
  return output_btst (operands, operands[1], operands[0], insn, 31);
766
})
767
 
768
;; This is the same as the above pattern except for the constraints.
769
;; The 'o' has been replaced with 'Q'.
770
 
771
(define_insn ""
772
  [(set
773
    (cc0)
774
    (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "dQ")
775
                              (const_int 1)
776
                              (match_operand:SI 1 "const_int_operand" "n"))
777
             (const_int 0)))]
778
  "TARGET_COLDFIRE"
779
{
780
  if (GET_CODE (operands[0]) == MEM)
781
    {
782
      operands[0] = adjust_address (operands[0], QImode,
783
                                    INTVAL (operands[1]) / 8);
784
      operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
785
      return output_btst (operands, operands[1], operands[0], insn, 7);
786
    }
787
  operands[1] = GEN_INT (31 - INTVAL (operands[1]));
788
  return output_btst (operands, operands[1], operands[0], insn, 31);
789
})
790
 
791
 
792
;; move instructions
793
 
794
;; A special case in which it is not desirable
795
;; to reload the constant into a data register.
796
(define_insn "pushexthisi_const"
797
  [(set (match_operand:SI 0 "push_operand" "=m,m,m")
798
        (match_operand:SI 1 "const_int_operand" "C0,R,J"))]
799
  "INTVAL (operands[1]) >= -0x8000 && INTVAL (operands[1]) < 0x8000"
800
  "@
801
   clr%.l %0
802
   mov3q%.l %1,%-
803
   pea %a1"
804
  [(set_attr "type" "clr_l,mov3q_l,pea")])
805
 
806
;This is never used.
807
;(define_insn "swapsi"
808
;  [(set (match_operand:SI 0 "nonimmediate_operand" "+r")
809
;       (match_operand:SI 1 "general_operand" "+r"))
810
;   (set (match_dup 1) (match_dup 0))]
811
;  ""
812
;  "exg %1,%0")
813
 
814
;; Special case of fullword move when source is zero for 68000_10.
815
;; moveq is faster on the 68000.
816
(define_insn "*movsi_const0_68000_10"
817
  [(set (match_operand:SI 0 "movsi_const0_operand" "=d,a,g")
818
        (const_int 0))]
819
  "TUNE_68000_10"
820
  "@
821
   moveq #0,%0
822
   sub%.l %0,%0
823
   clr%.l %0"
824
  [(set_attr "type" "moveq_l,alu_l,clr_l")
825
   (set_attr "opy" "*,0,*")])
826
 
827
;; Special case of fullword move when source is zero for 68040_60.
828
;; On the '040, 'subl an,an' takes 2 clocks while lea takes only 1
829
(define_insn "*movsi_const0_68040_60"
830
  [(set (match_operand:SI 0 "movsi_const0_operand" "=a,g")
831
        (const_int 0))]
832
  "TUNE_68040_60"
833
{
834
  if (which_alternative == 0)
835
    return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
836
  else if (which_alternative == 1)
837
    return "clr%.l %0";
838
  else
839
    {
840
      gcc_unreachable ();
841
      return "";
842
    }
843
}
844
  [(set_attr "type" "lea,clr_l")])
845
 
846
;; Special case of fullword move when source is zero.
847
(define_insn "*movsi_const0"
848
  [(set (match_operand:SI 0 "movsi_const0_operand" "=a,g")
849
        (const_int 0))]
850
  "!(TUNE_68000_10 || TUNE_68040_60)"
851
  "@
852
   sub%.l %0,%0
853
   clr%.l %0"
854
  [(set_attr "type" "alu_l,clr_l")
855
   (set_attr "opy" "0,*")])
856
 
857
;; General case of fullword move.
858
;;
859
;; This is the main "hook" for PIC code.  When generating
860
;; PIC, movsi is responsible for determining when the source address
861
;; needs PIC relocation and appropriately calling legitimize_pic_address
862
;; to perform the actual relocation.
863
;;
864
;; In both the PIC and non-PIC cases the patterns generated will
865
;; matched by the next define_insn.
866
(define_expand "movsi"
867
  [(set (match_operand:SI 0 "" "")
868
        (match_operand:SI 1 "" ""))]
869
  ""
870
{
871
  rtx tmp, base, offset;
872
 
873
  /* Recognize the case where operand[1] is a reference to thread-local
874
     data and load its address to a register.  */
875
  if (!TARGET_PCREL && m68k_tls_reference_p (operands[1], false))
876
    {
877
      rtx tmp = operands[1];
878
      rtx addend = NULL;
879
 
880
      if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
881
        {
882
          addend = XEXP (XEXP (tmp, 0), 1);
883
          tmp = XEXP (XEXP (tmp, 0), 0);
884
        }
885
 
886
      gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
887
      gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
888
 
889
      tmp = m68k_legitimize_tls_address (tmp);
890
 
891
      if (addend)
892
        {
893
          if (!REG_P (tmp))
894
            {
895
              rtx reg;
896
 
897
              reg = gen_reg_rtx (Pmode);
898
              emit_move_insn (reg, tmp);
899
              tmp = reg;
900
            }
901
 
902
          tmp = gen_rtx_PLUS (SImode, tmp, addend);
903
        }
904
 
905
      operands[1] = tmp;
906
    }
907
  else if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
908
    {
909
      /* The source is an address which requires PIC relocation.
910
         Call legitimize_pic_address with the source, mode, and a relocation
911
         register (a new pseudo, or the final destination if reload_in_progress
912
         is set).   Then fall through normally */
913
      rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
914
      operands[1] = legitimize_pic_address (operands[1], SImode, temp);
915
    }
916
  else if (flag_pic && TARGET_PCREL && ! reload_in_progress)
917
    {
918
      /* Don't allow writes to memory except via a register;
919
         the m68k doesn't consider PC-relative addresses to be writable.  */
920
      if (symbolic_operand (operands[0], SImode))
921
        operands[0] = force_reg (SImode, XEXP (operands[0], 0));
922
      else if (GET_CODE (operands[0]) == MEM
923
               && symbolic_operand (XEXP (operands[0], 0), SImode))
924
        operands[0] = gen_rtx_MEM (SImode,
925
                               force_reg (SImode, XEXP (operands[0], 0)));
926
    }
927
  if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
928
    {
929
      split_const (operands[1], &base, &offset);
930
      if (GET_CODE (base) == SYMBOL_REF
931
          && !offset_within_block_p (base, INTVAL (offset)))
932
        {
933
          tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
934
          emit_move_insn (tmp, base);
935
          emit_insn (gen_addsi3 (operands[0], tmp, offset));
936
          DONE;
937
        }
938
    }
939
})
940
 
941
;; General case of fullword move.
942
(define_insn "*movsi_m68k"
943
  ;; Notes: make sure no alternative allows g vs g.
944
  ;; We don't allow f-regs since fixed point cannot go in them.
945
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
946
        (match_operand:SI 1 "general_src_operand" "damSnT,n,i"))]
947
  "!TARGET_COLDFIRE && reload_completed"
948
{
949
  return output_move_simode (operands);
950
})
951
 
952
;; Before reload is completed the register constraints
953
;; force integer constants in range for a moveq to be reloaded
954
;; if they are headed for memory.
955
(define_insn "*movsi_m68k2"
956
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<")
957
        (match_operand:SI 1 "general_src_operand" "damSKT,n,i"))]
958
 
959
  "!TARGET_COLDFIRE"
960
{
961
  return output_move_simode (operands);
962
})
963
 
964
;; ColdFire move instructions can have at most one operand of mode >= 6.
965
(define_insn "*movsi_cf"
966
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d, d, d, d, d, a,Ap,  a,  r,g,    U")
967
        (match_operand:SI 1 "general_operand"      " R,CQ,CW,CZ,CS,Ci,J,J Cs,Cs, g,   Rr,U"))]
968
  "TARGET_COLDFIRE"
969
{
970
  switch (which_alternative)
971
    {
972
    case 0:
973
      return "mov3q%.l %1,%0";
974
 
975
    case 1:
976
      return "moveq %1,%0";
977
 
978
    case 2:
979
      {
980
        unsigned u = INTVAL (operands[1]);
981
 
982
        operands[1] = GEN_INT ((u << 16) | (u >> 16));  /*|*/
983
        return "moveq %1,%0\n\tswap %0";
984
      }
985
 
986
    case 3:
987
      return "mvz%.w %1,%0";
988
 
989
    case 4:
990
      return "mvs%.w %1,%0";
991
 
992
    case 5:
993
      return "move%.l %1,%0";
994
 
995
    case 6:
996
      return "move%.w %1,%0";
997
 
998
    case 7:
999
      return "pea %a1";
1000
 
1001
    case 8:
1002
      return "lea %a1,%0";
1003
 
1004
    case 9:
1005
    case 10:
1006
    case 11:
1007
      return "move%.l %1,%0";
1008
 
1009
    default:
1010
      gcc_unreachable ();
1011
      return "";
1012
    }
1013
}
1014
  [(set_attr "type" "mov3q_l,moveq_l,*,mvsz,mvsz,move_l,move,pea,lea,move_l,move_l,move_l")])
1015
 
1016
;; Special case of fullword move, where we need to get a non-GOT PIC
1017
;; reference into an address register.
1018
(define_insn ""
1019
  [(set (match_operand:SI 0 "nonimmediate_operand" "=a<")
1020
        (match_operand:SI 1 "pcrel_address" ""))]
1021
  "TARGET_PCREL"
1022
{
1023
  if (push_operand (operands[0], SImode))
1024
    return "pea %a1";
1025
  return "lea %a1,%0";
1026
})
1027
 
1028
(define_expand "movhi"
1029
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1030
        (match_operand:HI 1 "general_operand" ""))]
1031
  ""
1032
  "")
1033
 
1034
(define_insn ""
1035
  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
1036
        (match_operand:HI 1 "general_src_operand" "gS"))]
1037
  "!TARGET_COLDFIRE"
1038
  "* return output_move_himode (operands);")
1039
 
1040
(define_insn ""
1041
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,g,U")
1042
        (match_operand:HI 1 "general_operand" "g,r,U"))]
1043
  "TARGET_COLDFIRE"
1044
  "* return output_move_himode (operands);")
1045
 
1046
(define_expand "movstricthi"
1047
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1048
        (match_operand:HI 1 "general_src_operand" ""))]
1049
  ""
1050
  "")
1051
 
1052
(define_insn ""
1053
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
1054
        (match_operand:HI 1 "general_src_operand" "rmSn"))]
1055
  "!TARGET_COLDFIRE"
1056
  "* return output_move_stricthi (operands);")
1057
 
1058
(define_insn ""
1059
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+d,m"))
1060
        (match_operand:HI 1 "general_src_operand" "rmn,r"))]
1061
  "TARGET_COLDFIRE"
1062
  "* return output_move_stricthi (operands);")
1063
 
1064
(define_expand "movqi"
1065
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1066
        (match_operand:QI 1 "general_src_operand" ""))]
1067
  ""
1068
  "")
1069
 
1070
(define_insn ""
1071
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,*a,m")
1072
        (match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))]
1073
  "!TARGET_COLDFIRE"
1074
  "* return output_move_qimode (operands);")
1075
 
1076
(define_insn ""
1077
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,dm,U,d*a")
1078
        (match_operand:QI 1 "general_src_operand" "dmi,d,U,di*a"))]
1079
  "TARGET_COLDFIRE"
1080
  "* return output_move_qimode (operands);")
1081
 
1082
(define_expand "movstrictqi"
1083
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1084
        (match_operand:QI 1 "general_src_operand" ""))]
1085
  ""
1086
  "")
1087
 
1088
(define_insn ""
1089
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
1090
        (match_operand:QI 1 "general_src_operand" "dmSn"))]
1091
  "!TARGET_COLDFIRE"
1092
  "* return output_move_strictqi (operands);")
1093
 
1094
(define_insn "*movstrictqi_cf"
1095
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d, Ac, d,m"))
1096
        (match_operand:QI 1 "general_src_operand"                    "C0,C0, dmn,d"))]
1097
  "TARGET_COLDFIRE"
1098
  "@
1099
   clr%.b %0
1100
   clr%.b %0
1101
   move%.b %1,%0
1102
   move%.b %1,%0"
1103
  [(set_attr "type" "clr,clr,move,move")])
1104
 
1105
(define_expand "pushqi1"
1106
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))
1107
   (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int 1)))
1108
        (match_operand:QI 0 "general_operand" ""))]
1109
  "!TARGET_COLDFIRE"
1110
  "")
1111
 
1112
(define_expand "reload_insf"
1113
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
1114
        (match_operand:SF 1 "general_operand" "mf"))
1115
   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
1116
  "TARGET_COLDFIRE_FPU"
1117
{
1118
  if (emit_move_sequence (operands, SFmode, operands[2]))
1119
    DONE;
1120
 
1121
  /* We don't want the clobber emitted, so handle this ourselves. */
1122
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1123
  DONE;
1124
})
1125
 
1126
(define_expand "reload_outsf"
1127
  [(set (match_operand:SF 0 "general_operand" "")
1128
        (match_operand:SF 1 "register_operand" "f"))
1129
   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
1130
  "TARGET_COLDFIRE_FPU"
1131
{
1132
  if (emit_move_sequence (operands, SFmode, operands[2]))
1133
    DONE;
1134
 
1135
  /* We don't want the clobber emitted, so handle this ourselves. */
1136
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1137
  DONE;
1138
})
1139
 
1140
(define_expand "movsf"
1141
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
1142
        (match_operand:SF 1 "general_operand" ""))]
1143
  ""
1144
  "")
1145
 
1146
(define_insn ""
1147
  [(set (match_operand:SF 0 "nonimmediate_operand" "=rmf")
1148
        (match_operand:SF 1 "general_operand" "rmfF"))]
1149
  "!TARGET_COLDFIRE"
1150
{
1151
  if (FP_REG_P (operands[0]))
1152
    {
1153
      if (FP_REG_P (operands[1]))
1154
        return "f%$move%.x %1,%0";
1155
      else if (ADDRESS_REG_P (operands[1]))
1156
        return "move%.l %1,%-\;f%$move%.s %+,%0";
1157
      else if (GET_CODE (operands[1]) == CONST_DOUBLE)
1158
        return output_move_const_single (operands);
1159
      return "f%$move%.s %f1,%0";
1160
    }
1161
  if (FP_REG_P (operands[1]))
1162
    {
1163
      if (ADDRESS_REG_P (operands[0]))
1164
        return "fmove%.s %1,%-\;move%.l %+,%0";
1165
      return "fmove%.s %f1,%0";
1166
    }
1167
  if (operands[1] == CONST0_RTX (SFmode)
1168
      /* clr insns on 68000 read before writing.  */
1169
      && ((TARGET_68010 || TARGET_COLDFIRE)
1170
          || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))))
1171
    {
1172
      if (ADDRESS_REG_P (operands[0]))
1173
        {
1174
          /* On the '040, 'subl an,an' takes 2 clocks while lea takes only 1 */
1175
          if (TUNE_68040_60)
1176
            return MOTOROLA ? "lea 0.w,%0" : "lea 0:w,%0";
1177
          else
1178
            return "sub%.l %0,%0";
1179
        }
1180
      /* moveq is faster on the 68000.  */
1181
      if (DATA_REG_P (operands[0]) && TUNE_68000_10)
1182
        return "moveq #0,%0";
1183
      return "clr%.l %0";
1184
    }
1185
  return "move%.l %1,%0";
1186
})
1187
 
1188
(define_insn "movsf_cf_soft"
1189
  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,g,U")
1190
        (match_operand:SF 1 "general_operand" "g,r,U"))]
1191
  "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
1192
  "move%.l %1,%0"
1193
  [(set_attr "type" "move_l")])
1194
 
1195
;; SFmode MEMs are restricted to modes 2-4 if TARGET_COLDFIRE_FPU.
1196
;; The move instructions can handle all combinations.
1197
(define_insn "movsf_cf_hard"
1198
  [(set (match_operand:SF 0 "nonimmediate_operand" "=rU, f,    f,mr,f,r,f
1199
,m")
1200
        (match_operand:SF 1 "general_operand"      " f,     rU,f,rm,F,F,   m
1201
,f"))]
1202
  "TARGET_COLDFIRE_FPU"
1203
{
1204
  if (which_alternative == 4 || which_alternative == 5) {
1205
    rtx xoperands[2];
1206
    REAL_VALUE_TYPE r;
1207
    long l;
1208
    REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1209
    REAL_VALUE_TO_TARGET_SINGLE (r, l);
1210
    xoperands[0] = operands[0];
1211
    xoperands[1] = GEN_INT (l);
1212
    if (which_alternative == 5) {
1213
      if (l == 0) {
1214
        if (ADDRESS_REG_P (xoperands[0]))
1215
          output_asm_insn ("sub%.l %0,%0", xoperands);
1216
        else
1217
          output_asm_insn ("clr%.l %0", xoperands);
1218
      } else
1219
        if (GET_CODE (operands[0]) == MEM
1220
            && symbolic_operand (XEXP (operands[0], 0), SImode))
1221
          output_asm_insn ("move%.l %1,%-;move%.l %+,%0", xoperands);
1222
        else
1223
          output_asm_insn ("move%.l %1,%0", xoperands);
1224
      return "";
1225
    }
1226
    if (l != 0)
1227
      output_asm_insn ("move%.l %1,%-;fsmove%.s %+,%0", xoperands);
1228
    else
1229
      output_asm_insn ("clr%.l %-;fsmove%.s %+,%0", xoperands);
1230
    return "";
1231
  }
1232
  if (FP_REG_P (operands[0]))
1233
    {
1234
      if (ADDRESS_REG_P (operands[1]))
1235
        return "move%.l %1,%-;fsmove%.s %+,%0";
1236
      if (FP_REG_P (operands[1]))
1237
        return "fsmove%.d %1,%0";
1238
      return "fsmove%.s %f1,%0";
1239
    }
1240
  if (FP_REG_P (operands[1]))
1241
    {
1242
      if (ADDRESS_REG_P (operands[0]))
1243
        return "fmove%.s %1,%-;move%.l %+,%0";
1244
      return "fmove%.s %f1,%0";
1245
    }
1246
  if (operands[1] == CONST0_RTX (SFmode))
1247
    {
1248
      if (ADDRESS_REG_P (operands[0]))
1249
        return "sub%.l %0,%0";
1250
      return "clr%.l %0";
1251
    }
1252
  return "move%.l %1,%0";
1253
})
1254
 
1255
(define_expand "reload_indf"
1256
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
1257
        (match_operand:DF 1 "general_operand" "mf"))
1258
   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
1259
  "TARGET_COLDFIRE_FPU"
1260
{
1261
  if (emit_move_sequence (operands, DFmode, operands[2]))
1262
    DONE;
1263
 
1264
  /* We don't want the clobber emitted, so handle this ourselves. */
1265
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1266
  DONE;
1267
})
1268
 
1269
(define_expand "reload_outdf"
1270
  [(set (match_operand:DF 0 "general_operand" "")
1271
        (match_operand:DF 1 "register_operand" "f"))
1272
   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
1273
  "TARGET_COLDFIRE_FPU"
1274
{
1275
  if (emit_move_sequence (operands, DFmode, operands[2]))
1276
    DONE;
1277
 
1278
  /* We don't want the clobber emitted, so handle this ourselves. */
1279
  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1280
  DONE;
1281
})
1282
 
1283
(define_expand "movdf"
1284
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1285
        (match_operand:DF 1 "general_operand" ""))]
1286
  ""
1287
{
1288
  if (TARGET_COLDFIRE_FPU)
1289
    if (emit_move_sequence (operands, DFmode, 0))
1290
      DONE;
1291
})
1292
 
1293
(define_insn ""
1294
  [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,rf,rf,&rof<>")
1295
        (match_operand:DF 1 "general_operand" "*rf,m,0,*rofE<>"))]
1296
;  [(set (match_operand:DF 0 "nonimmediate_operand" "=rm,&rf,&rof<>")
1297
;       (match_operand:DF 1 "general_operand" "rf,m,rofF<>"))]
1298
  "!TARGET_COLDFIRE"
1299
{
1300
  if (FP_REG_P (operands[0]))
1301
    {
1302
      if (FP_REG_P (operands[1]))
1303
        return "f%&move%.x %1,%0";
1304
      if (REG_P (operands[1]))
1305
        {
1306
          rtx xoperands[2];
1307
          xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1308
          output_asm_insn ("move%.l %1,%-", xoperands);
1309
          output_asm_insn ("move%.l %1,%-", operands);
1310
          return "f%&move%.d %+,%0";
1311
        }
1312
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
1313
        return output_move_const_double (operands);
1314
      return "f%&move%.d %f1,%0";
1315
    }
1316
  else if (FP_REG_P (operands[1]))
1317
    {
1318
      if (REG_P (operands[0]))
1319
        {
1320
          output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1321
          operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1322
          return "move%.l %+,%0";
1323
        }
1324
      else
1325
        return "fmove%.d %f1,%0";
1326
    }
1327
  return output_move_double (operands);
1328
})
1329
 
1330
(define_insn_and_split "movdf_cf_soft"
1331
  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,g")
1332
        (match_operand:DF 1 "general_operand" "g,r"))]
1333
  "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
1334
  "#"
1335
  "&& reload_completed"
1336
  [(const_int 0)]
1337
{
1338
  m68k_emit_move_double (operands);
1339
  DONE;
1340
})
1341
 
1342
(define_insn "movdf_cf_hard"
1343
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,    U,r,f,r,r,m,f")
1344
        (match_operand:DF 1 "general_operand"      " fU,f,   f,r,r,m,r,E"))]
1345
  "TARGET_COLDFIRE_FPU"
1346
{
1347
  rtx xoperands[3];
1348
  REAL_VALUE_TYPE r;
1349
  long l[2];
1350
 
1351
  switch (which_alternative)
1352
    {
1353
    default:
1354
      return "fdmove%.d %1,%0";
1355
    case 1:
1356
      return "fmove%.d %1,%0";
1357
    case 2:
1358
      return "fmove%.d %1,%-;move%.l %+,%0;move%.l %+,%R0";
1359
    case 3:
1360
      return "move%.l %R1,%-;move%.l %1,%-;fdmove%.d %+,%0";
1361
    case 4: case 5: case 6:
1362
      return output_move_double (operands);
1363
    case 7:
1364
      REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1365
      REAL_VALUE_TO_TARGET_DOUBLE (r, l);
1366
      xoperands[0] = operands[0];
1367
      xoperands[1] = GEN_INT (l[0]);
1368
      xoperands[2] = GEN_INT (l[1]);
1369
      if (operands[1] == CONST0_RTX (DFmode))
1370
        output_asm_insn ("clr%.l %-;clr%.l %-;fdmove%.d %+,%0",
1371
                        xoperands);
1372
      else
1373
        if (l[1] == 0)
1374
          output_asm_insn ("clr%.l %-;move%.l %1,%-;fdmove%.d %+,%0",
1375
                          xoperands);
1376
        else
1377
          output_asm_insn ("move%.l %2,%-;move%.l %1,%-;fdmove%.d %+,%0",
1378
                          xoperands);
1379
      return "";
1380
    }
1381
})
1382
 
1383
;; ??? The XFmode patterns are schizophrenic about whether constants are
1384
;; allowed.  Most but not all have predicates and constraint that disallow
1385
;; constants.  Most but not all have output templates that handle constants.
1386
;; See also LEGITIMATE_CONSTANT_P.
1387
 
1388
(define_expand "movxf"
1389
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
1390
        (match_operand:XF 1 "general_operand" ""))]
1391
  ""
1392
{
1393
  /* We can't rewrite operands during reload.  */
1394
  if (! reload_in_progress)
1395
    {
1396
      if (CONSTANT_P (operands[1]))
1397
        {
1398
          operands[1] = force_const_mem (XFmode, operands[1]);
1399
          if (! memory_address_p (XFmode, XEXP (operands[1], 0)))
1400
            operands[1] = adjust_address (operands[1], XFmode, 0);
1401
        }
1402
      if (flag_pic && TARGET_PCREL)
1403
        {
1404
          /* Don't allow writes to memory except via a register; the
1405
             m68k doesn't consider PC-relative addresses to be writable.  */
1406
          if (GET_CODE (operands[0]) == MEM
1407
              && symbolic_operand (XEXP (operands[0], 0), SImode))
1408
            operands[0] = gen_rtx_MEM (XFmode,
1409
                                   force_reg (SImode, XEXP (operands[0], 0)));
1410
        }
1411
    }
1412
})
1413
 
1414
(define_insn ""
1415
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,!r,!f,!r,m,!r")
1416
        (match_operand:XF 1 "nonimmediate_operand" "m,f,f,f,r,!r,!r,m"))]
1417
  "TARGET_68881"
1418
{
1419
  if (FP_REG_P (operands[0]))
1420
    {
1421
      if (FP_REG_P (operands[1]))
1422
        return "fmove%.x %1,%0";
1423
      if (REG_P (operands[1]))
1424
        {
1425
          rtx xoperands[2];
1426
          xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1427
          output_asm_insn ("move%.l %1,%-", xoperands);
1428
          xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1429
          output_asm_insn ("move%.l %1,%-", xoperands);
1430
          output_asm_insn ("move%.l %1,%-", operands);
1431
          return "fmove%.x %+,%0";
1432
        }
1433
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
1434
        return "fmove%.x %1,%0";
1435
      return "fmove%.x %f1,%0";
1436
    }
1437
  if (FP_REG_P (operands[1]))
1438
    {
1439
      if (REG_P (operands[0]))
1440
        {
1441
          output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands);
1442
          operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1443
          output_asm_insn ("move%.l %+,%0", operands);
1444
          operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1445
          return "move%.l %+,%0";
1446
        }
1447
      /* Must be memory destination.  */
1448
      return "fmove%.x %f1,%0";
1449
    }
1450
  return output_move_double (operands);
1451
})
1452
 
1453
(define_insn ""
1454
  [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
1455
        (match_operand:XF 1 "nonimmediate_operand" "rf,m,rof<>"))]
1456
  "! TARGET_68881 && ! TARGET_COLDFIRE"
1457
{
1458
  if (FP_REG_P (operands[0]))
1459
    {
1460
      if (FP_REG_P (operands[1]))
1461
        return "fmove%.x %1,%0";
1462
      if (REG_P (operands[1]))
1463
        {
1464
          rtx xoperands[2];
1465
          xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
1466
          output_asm_insn ("move%.l %1,%-", xoperands);
1467
          xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1468
          output_asm_insn ("move%.l %1,%-", xoperands);
1469
          output_asm_insn ("move%.l %1,%-", operands);
1470
          return "fmove%.x %+,%0";
1471
        }
1472
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
1473
        return "fmove%.x %1,%0";
1474
      return "fmove%.x %f1,%0";
1475
    }
1476
  if (FP_REG_P (operands[1]))
1477
    {
1478
      if (REG_P (operands[0]))
1479
        {
1480
          output_asm_insn ("fmove%.x %f1,%-\;move%.l %+,%0", operands);
1481
          operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1482
          output_asm_insn ("move%.l %+,%0", operands);
1483
          operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1484
          return "move%.l %+,%0";
1485
        }
1486
      else
1487
        return "fmove%.x %f1,%0";
1488
    }
1489
  return output_move_double (operands);
1490
})
1491
 
1492
(define_insn ""
1493
  [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g")
1494
        (match_operand:XF 1 "nonimmediate_operand" "g,r"))]
1495
  "! TARGET_68881 && TARGET_COLDFIRE"
1496
  "* return output_move_double (operands);")
1497
 
1498
(define_expand "movdi"
1499
  ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1500
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1501
        (match_operand:DI 1 "general_operand" ""))]
1502
  ""
1503
  "")
1504
 
1505
;; movdi can apply to fp regs in some cases
1506
(define_insn ""
1507
  ;; Let's see if it really still needs to handle fp regs, and, if so, why.
1508
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r,&ro<>")
1509
        (match_operand:DI 1 "general_operand" "rF,m,roi<>F"))]
1510
;  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&r,&ro<>,!&rm,!&f")
1511
;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF"))]
1512
;  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,&rf,&ro<>,!&rm,!&f")
1513
;       (match_operand:DI 1 "general_operand" "r,m,roi<>,fF,rfF"))]
1514
  "!TARGET_COLDFIRE"
1515
{
1516
  if (FP_REG_P (operands[0]))
1517
    {
1518
      if (FP_REG_P (operands[1]))
1519
        return "fmove%.x %1,%0";
1520
      if (REG_P (operands[1]))
1521
        {
1522
          rtx xoperands[2];
1523
          xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1524
          output_asm_insn ("move%.l %1,%-", xoperands);
1525
          output_asm_insn ("move%.l %1,%-", operands);
1526
          return "fmove%.d %+,%0";
1527
        }
1528
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
1529
        return output_move_const_double (operands);
1530
      return "fmove%.d %f1,%0";
1531
    }
1532
  else if (FP_REG_P (operands[1]))
1533
    {
1534
      if (REG_P (operands[0]))
1535
        {
1536
          output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1537
          operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1538
          return "move%.l %+,%0";
1539
        }
1540
      else
1541
        return "fmove%.d %f1,%0";
1542
    }
1543
  return output_move_double (operands);
1544
})
1545
 
1546
(define_insn ""
1547
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,g")
1548
        (match_operand:DI 1 "general_operand" "g,r"))]
1549
  "TARGET_COLDFIRE"
1550
  "* return output_move_double (operands);")
1551
 
1552
;; Thus goes after the move instructions
1553
;; because the move instructions are better (require no spilling)
1554
;; when they can apply.  It goes before the add/sub insns
1555
;; so we will prefer it to them.
1556
 
1557
(define_insn "pushasi"
1558
  [(set (match_operand:SI 0 "push_operand" "=m")
1559
        (match_operand:SI 1 "address_operand" "p"))]
1560
  ""
1561
  "pea %a1"
1562
  [(set_attr "type" "pea")])
1563
 
1564
;; truncation instructions
1565
(define_insn "truncsiqi2"
1566
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
1567
        (truncate:QI
1568
         (match_operand:SI 1 "general_src_operand" "doJS,i")))]
1569
  ""
1570
{
1571
  if (GET_CODE (operands[0]) == REG)
1572
    {
1573
      /* Must clear condition codes, since the move.l bases them on
1574
         the entire 32 bits, not just the desired 8 bits.  */
1575
      CC_STATUS_INIT;
1576
      return "move%.l %1,%0";
1577
    }
1578
  if (GET_CODE (operands[1]) == MEM)
1579
    operands[1] = adjust_address (operands[1], QImode, 3);
1580
  return "move%.b %1,%0";
1581
})
1582
 
1583
(define_insn "trunchiqi2"
1584
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
1585
        (truncate:QI
1586
         (match_operand:HI 1 "general_src_operand" "doJS,i")))]
1587
  ""
1588
{
1589
  if (GET_CODE (operands[0]) == REG
1590
      && (GET_CODE (operands[1]) == MEM
1591
          || GET_CODE (operands[1]) == CONST_INT))
1592
    {
1593
      /* Must clear condition codes, since the move.w bases them on
1594
         the entire 16 bits, not just the desired 8 bits.  */
1595
      CC_STATUS_INIT;
1596
      return "move%.w %1,%0";
1597
    }
1598
  if (GET_CODE (operands[0]) == REG)
1599
    {
1600
      /* Must clear condition codes, since the move.l bases them on
1601
         the entire 32 bits, not just the desired 8 bits.  */
1602
      CC_STATUS_INIT;
1603
      return "move%.l %1,%0";
1604
    }
1605
  if (GET_CODE (operands[1]) == MEM)
1606
    operands[1] = adjust_address (operands[1], QImode, 1);
1607
  return "move%.b %1,%0";
1608
})
1609
 
1610
(define_insn "truncsihi2"
1611
  [(set (match_operand:HI 0 "nonimmediate_operand" "=dm,d")
1612
        (truncate:HI
1613
         (match_operand:SI 1 "general_src_operand" "roJS,i")))]
1614
  ""
1615
{
1616
  if (GET_CODE (operands[0]) == REG)
1617
    {
1618
      /* Must clear condition codes, since the move.l bases them on
1619
         the entire 32 bits, not just the desired 8 bits.  */
1620
      CC_STATUS_INIT;
1621
      return "move%.l %1,%0";
1622
    }
1623
  if (GET_CODE (operands[1]) == MEM)
1624
    operands[1] = adjust_address (operands[1], QImode, 2);
1625
  return "move%.w %1,%0";
1626
})
1627
 
1628
;; zero extension instructions
1629
 
1630
;; two special patterns to match various post_inc/pre_dec patterns
1631
(define_insn_and_split "*zero_extend_inc"
1632
  [(set (match_operand 0 "post_inc_operand" "")
1633
        (zero_extend (match_operand 1 "register_operand" "")))]
1634
  "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT &&
1635
   GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT &&
1636
   GET_MODE_SIZE (GET_MODE (operands[0])) == GET_MODE_SIZE (GET_MODE (operands[1])) * 2"
1637
  "#"
1638
  ""
1639
  [(set (match_dup 0)
1640
        (const_int 0))
1641
   (set (match_dup 0)
1642
        (match_dup 1))]
1643
{
1644
  operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0);
1645
})
1646
 
1647
(define_insn_and_split "*zero_extend_dec"
1648
  [(set (match_operand 0 "pre_dec_operand" "")
1649
        (zero_extend (match_operand 1 "register_operand" "")))]
1650
  "(GET_MODE (operands[0]) != HImode || XEXP (XEXP (operands[0], 0), 0) != stack_pointer_rtx) &&
1651
   GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT &&
1652
   GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT &&
1653
   GET_MODE_SIZE (GET_MODE (operands[0])) == GET_MODE_SIZE (GET_MODE (operands[1])) * 2"
1654
  "#"
1655
  ""
1656
  [(set (match_dup 0)
1657
        (match_dup 1))
1658
   (set (match_dup 0)
1659
        (const_int 0))]
1660
{
1661
  operands[0] = adjust_address (operands[0], GET_MODE (operands[1]), 0);
1662
})
1663
 
1664
(define_insn_and_split "zero_extendqidi2"
1665
  [(set (match_operand:DI 0 "register_operand" "")
1666
        (zero_extend:DI (match_operand:QI 1 "nonimmediate_src_operand" "")))]
1667
  ""
1668
  "#"
1669
  ""
1670
  [(set (match_dup 2)
1671
        (zero_extend:SI (match_dup 1)))
1672
   (set (match_dup 3)
1673
        (const_int 0))]
1674
{
1675
  operands[2] = gen_lowpart (SImode, operands[0]);
1676
  operands[3] = gen_highpart (SImode, operands[0]);
1677
})
1678
 
1679
(define_insn_and_split "zero_extendhidi2"
1680
  [(set (match_operand:DI 0 "register_operand" "")
1681
        (zero_extend:DI (match_operand:HI 1 "nonimmediate_src_operand" "")))]
1682
  ""
1683
  "#"
1684
  ""
1685
  [(set (match_dup 2)
1686
        (zero_extend:SI (match_dup 1)))
1687
   (set (match_dup 3)
1688
        (const_int 0))]
1689
{
1690
  operands[2] = gen_lowpart (SImode, operands[0]);
1691
  operands[3] = gen_highpart (SImode, operands[0]);
1692
})
1693
 
1694
(define_expand "zero_extendsidi2"
1695
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1696
        (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))]
1697
  ""
1698
{
1699
  if (GET_CODE (operands[0]) == MEM
1700
      && GET_CODE (operands[1]) == MEM)
1701
    operands[1] = force_reg (SImode, operands[1]);
1702
})
1703
 
1704
(define_insn_and_split "*zero_extendsidi2"
1705
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1706
        (zero_extend:DI (match_operand:SI 1 "nonimmediate_src_operand" "")))]
1707
  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1708
  "#"
1709
  ""
1710
  [(set (match_dup 2)
1711
        (match_dup 1))
1712
   (set (match_dup 3)
1713
        (const_int 0))]
1714
{
1715
  operands[2] = gen_lowpart (SImode, operands[0]);
1716
  operands[3] = gen_highpart (SImode, operands[0]);
1717
})
1718
 
1719
(define_insn "*zero_extendhisi2_cf"
1720
  [(set (match_operand:SI 0 "register_operand" "=d")
1721
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
1722
  "ISA_HAS_MVS_MVZ"
1723
  "mvz%.w %1,%0"
1724
  [(set_attr "type" "mvsz")])
1725
 
1726
(define_insn "zero_extendhisi2"
1727
  [(set (match_operand:SI 0 "register_operand" "=d")
1728
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
1729
  ""
1730
  "#")
1731
 
1732
(define_expand "zero_extendqihi2"
1733
  [(set (match_operand:HI 0 "register_operand" "")
1734
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "")))]
1735
  "!TARGET_COLDFIRE"
1736
  "")
1737
 
1738
(define_insn "*zero_extendqihi2"
1739
  [(set (match_operand:HI 0 "register_operand" "=d")
1740
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
1741
  "!TARGET_COLDFIRE"
1742
  "#")
1743
 
1744
(define_insn "*zero_extendqisi2_cfv4"
1745
  [(set (match_operand:SI 0 "register_operand" "=d")
1746
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
1747
  "ISA_HAS_MVS_MVZ"
1748
  "mvz%.b %1,%0"
1749
  [(set_attr "type" "mvsz")])
1750
 
1751
(define_insn "zero_extendqisi2"
1752
  [(set (match_operand:SI 0 "register_operand" "=d")
1753
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "dmS")))]
1754
  ""
1755
  "#")
1756
 
1757
;; these two pattern split everything else which isn't matched by
1758
;; something else above
1759
(define_split
1760
  [(set (match_operand 0 "register_operand" "")
1761
        (zero_extend (match_operand 1 "nonimmediate_src_operand" "")))]
1762
  "!ISA_HAS_MVS_MVZ
1763
   && reload_completed
1764
   && reg_mentioned_p (operands[0], operands[1])"
1765
  [(set (strict_low_part (match_dup 2))
1766
        (match_dup 1))
1767
   (set (match_dup 0)
1768
        (match_op_dup 4 [(match_dup 0) (match_dup 3)]))]
1769
{
1770
  operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]);
1771
  operands[3] = GEN_INT (GET_MODE_MASK (GET_MODE (operands[1])));
1772
  operands[4] = gen_rtx_AND (GET_MODE (operands[0]), operands[0], operands[3]);
1773
})
1774
 
1775
(define_split
1776
  [(set (match_operand 0 "register_operand" "")
1777
        (zero_extend (match_operand 1 "nonimmediate_src_operand" "")))]
1778
  "!ISA_HAS_MVS_MVZ && reload_completed"
1779
  [(set (match_dup 0)
1780
        (const_int 0))
1781
   (set (strict_low_part (match_dup 2))
1782
        (match_dup 1))]
1783
{
1784
  operands[2] = gen_lowpart (GET_MODE (operands[1]), operands[0]);
1785
})
1786
 
1787
;; sign extension instructions
1788
 
1789
(define_insn "extendqidi2"
1790
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1791
        (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))]
1792
  ""
1793
{
1794
  CC_STATUS_INIT;
1795
  operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1796
  if (ISA_HAS_MVS_MVZ)
1797
    return "mvs%.b %1,%2\;smi %0\;extb%.l %0";
1798
  if (TARGET_68020 || TARGET_COLDFIRE)
1799
    {
1800
      if (ADDRESS_REG_P (operands[1]))
1801
        return "move%.w %1,%2\;extb%.l %2\;smi %0\;extb%.l %0";
1802
      else
1803
        return "move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0";
1804
    }
1805
  else
1806
    {
1807
      if (ADDRESS_REG_P (operands[1]))
1808
        return "move%.w %1,%2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\;smi %0";
1809
      else
1810
        return "move%.b %1,%2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0\;smi %0";
1811
    }
1812
})
1813
 
1814
(define_insn "extendhidi2"
1815
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
1816
        (sign_extend:DI
1817
         (match_operand:HI 1 "general_src_operand" "rmS")))]
1818
  ""
1819
{
1820
  CC_STATUS_INIT;
1821
  operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1822
  if (ISA_HAS_MVS_MVZ)
1823
    return "mvs%.w %1,%2\;smi %0\;extb%.l %0";
1824
  if (TARGET_68020 || TARGET_COLDFIRE)
1825
    return "move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0";
1826
  else
1827
    return "move%.w %1,%2\;ext%.l %2\;smi %0\;ext%.w %0\;ext%.l %0";
1828
})
1829
 
1830
(define_insn "extendsidi2"
1831
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o,o,<")
1832
        (sign_extend:DI
1833
         (match_operand:SI 1 "nonimmediate_src_operand" "rm,rm,r,rm")))
1834
   (clobber (match_scratch:SI 2 "=X,d,d,d"))]
1835
  ""
1836
{
1837
  CC_STATUS_INIT;
1838
 
1839
  if (which_alternative == 0)
1840
    /* Handle alternative 0.  */
1841
    {
1842
      if (TARGET_68020 || TARGET_COLDFIRE)
1843
        return "move%.l %1,%R0\;smi %0\;extb%.l %0";
1844
      else
1845
        return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0";
1846
    }
1847
 
1848
  /* Handle alternatives 1, 2 and 3.  We don't need to adjust address by 4
1849
     in alternative 3 because autodecrement will do that for us.  */
1850
  operands[3] = adjust_address (operands[0], SImode,
1851
                                which_alternative == 3 ? 0 : 4);
1852
  operands[0] = adjust_address (operands[0], SImode, 0);
1853
 
1854
  if (TARGET_68020 || TARGET_COLDFIRE)
1855
    return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
1856
  else
1857
    return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
1858
}
1859
  [(set_attr "ok_for_coldfire" "yes,no,yes,yes")])
1860
 
1861
;; Special case when one can avoid register clobbering, copy and test
1862
;; Maybe there is a way to make that the general case, by forcing the
1863
;; result of the SI tree to be in the lower register of the DI target
1864
 
1865
(define_insn "extendplussidi"
1866
  [(set (match_operand:DI 0 "register_operand" "=d")
1867
    (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
1868
            (match_operand:SI 2 "general_operand" "rmn"))))]
1869
  ""
1870
{
1871
  CC_STATUS_INIT;
1872
  operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1873
  if (GET_CODE (operands[1]) == CONST_INT
1874
  && (unsigned) INTVAL (operands[1]) > 8)
1875
    {
1876
      rtx tmp = operands[1];
1877
 
1878
      operands[1] = operands[2];
1879
      operands[2] = tmp;
1880
    }
1881
  if (GET_CODE (operands[1]) == REG
1882
      && REGNO (operands[1]) == REGNO (operands[3]))
1883
    output_asm_insn ("add%.l %2,%3", operands);
1884
  else
1885
    output_asm_insn ("move%.l %2,%3\;add%.l %1,%3", operands);
1886
  if (TARGET_68020 || TARGET_COLDFIRE)
1887
    return "smi %0\;extb%.l %0";
1888
  else
1889
    return "smi %0\;ext%.w %0\;ext%.l %0";
1890
})
1891
 
1892
(define_expand "extendhisi2"
1893
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1894
        (sign_extend:SI
1895
         (match_operand:HI 1 "nonimmediate_src_operand" "")))]
1896
  ""
1897
  "")
1898
 
1899
(define_insn "*cfv4_extendhisi2"
1900
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
1901
        (sign_extend:SI
1902
         (match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
1903
  "ISA_HAS_MVS_MVZ"
1904
  "mvs%.w %1,%0"
1905
  [(set_attr "type" "mvsz")])
1906
 
1907
(define_insn "*68k_extendhisi2"
1908
  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
1909
        (sign_extend:SI
1910
         (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
1911
  "!ISA_HAS_MVS_MVZ"
1912
  "@
1913
   ext%.l %0
1914
   move%.w %1,%0"
1915
  [(set_attr "type" "ext,move")])
1916
 
1917
(define_insn "extendqihi2"
1918
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
1919
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1920
  ""
1921
  "ext%.w %0"
1922
  [(set_attr "type" "ext")])
1923
 
1924
(define_expand "extendqisi2"
1925
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1926
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1927
  "TARGET_68020 || TARGET_COLDFIRE"
1928
  "")
1929
 
1930
(define_insn "*cfv4_extendqisi2"
1931
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
1932
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))]
1933
  "ISA_HAS_MVS_MVZ"
1934
  "mvs%.b %1,%0"
1935
  [(set_attr "type" "mvsz")])
1936
 
1937
(define_insn "*68k_extendqisi2"
1938
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
1939
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
1940
  "TARGET_68020 || (TARGET_COLDFIRE && !ISA_HAS_MVS_MVZ)"
1941
  "extb%.l %0"
1942
  [(set_attr "type" "ext")])
1943
 
1944
;; Conversions between float and double.
1945
 
1946
(define_expand "extendsfdf2"
1947
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1948
        (float_extend:DF
1949
         (match_operand:SF 1 "general_operand" "")))]
1950
  "TARGET_HARD_FLOAT"
1951
  "")
1952
 
1953
(define_insn ""
1954
  [(set (match_operand:DF 0 "nonimmediate_operand" "=*fdm,f")
1955
        (float_extend:DF
1956
          (match_operand:SF 1 "general_operand" "f,dmF")))]
1957
  "TARGET_68881"
1958
{
1959
  if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1960
    {
1961
      if (REGNO (operands[0]) == REGNO (operands[1]))
1962
        {
1963
          /* Extending float to double in an fp-reg is a no-op.
1964
             NOTICE_UPDATE_CC has already assumed that the
1965
             cc will be set.  So cancel what it did.  */
1966
          cc_status = cc_prev_status;
1967
          return "";
1968
        }
1969
      return "f%&move%.x %1,%0";
1970
    }
1971
  if (FP_REG_P (operands[0]))
1972
    return "f%&move%.s %f1,%0";
1973
  if (DATA_REG_P (operands[0]) && FP_REG_P (operands[1]))
1974
    {
1975
      output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
1976
      operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1977
      return "move%.l %+,%0";
1978
    }
1979
  return "fmove%.d %f1,%0";
1980
})
1981
 
1982
(define_insn "extendsfdf2_cf"
1983
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f")
1984
        (float_extend:DF
1985
         (match_operand:SF 1 "general_operand" "f,U")))]
1986
  "TARGET_COLDFIRE_FPU"
1987
{
1988
  if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
1989
    {
1990
      if (REGNO (operands[0]) == REGNO (operands[1]))
1991
        {
1992
          /* Extending float to double in an fp-reg is a no-op.
1993
             NOTICE_UPDATE_CC has already assumed that the
1994
             cc will be set.  So cancel what it did.  */
1995
          cc_status = cc_prev_status;
1996
          return "";
1997
        }
1998
      return "fdmove%.d %1,%0";
1999
    }
2000
  return "fdmove%.s %f1,%0";
2001
})
2002
 
2003
;; This cannot output into an f-reg because there is no way to be
2004
;; sure of truncating in that case.
2005
(define_expand "truncdfsf2"
2006
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2007
        (float_truncate:SF
2008
          (match_operand:DF 1 "general_operand" "")))]
2009
  "TARGET_HARD_FLOAT"
2010
  "")
2011
 
2012
;; On the '040 we can truncate in a register accurately and easily.
2013
(define_insn ""
2014
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
2015
        (float_truncate:SF
2016
          (match_operand:DF 1 "general_operand" "fmG")))]
2017
  "TARGET_68881 && TARGET_68040"
2018
{
2019
  if (FP_REG_P (operands[1]))
2020
    return "f%$move%.x %1,%0";
2021
  return "f%$move%.d %f1,%0";
2022
})
2023
 
2024
(define_insn "truncdfsf2_cf"
2025
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dU")
2026
        (float_truncate:SF
2027
          (match_operand:DF 1 "general_operand" "U,f")))]
2028
  "TARGET_COLDFIRE_FPU"
2029
  "@
2030
  fsmove%.d %1,%0
2031
  fmove%.s %1,%0"
2032
  [(set_attr "type" "fmove")])
2033
 
2034
(define_insn "*truncdfsf2_68881"
2035
  [(set (match_operand:SF 0 "nonimmediate_operand" "=dm")
2036
        (float_truncate:SF
2037
          (match_operand:DF 1 "general_operand" "f")))]
2038
  "TARGET_68881"
2039
  "fmove%.s %f1,%0"
2040
  [(set_attr "type" "fmove")])
2041
 
2042
;; Conversion between fixed point and floating point.
2043
;; Note that among the fix-to-float insns
2044
;; the ones that start with SImode come first.
2045
;; That is so that an operand that is a CONST_INT
2046
;; (and therefore lacks a specific machine mode).
2047
;; will be recognized as SImode (which is always valid)
2048
;; rather than as QImode or HImode.
2049
 
2050
(define_expand "floatsi2"
2051
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
2052
        (float:FP (match_operand:SI 1 "general_operand" "")))]
2053
  "TARGET_HARD_FLOAT"
2054
  "")
2055
 
2056
(define_insn "floatsi2_68881"
2057
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2058
        (float:FP (match_operand:SI 1 "general_operand" "dmi")))]
2059
  "TARGET_68881"
2060
  "fmove%.l %1,%0"
2061
  [(set_attr "type" "fmove")])
2062
 
2063
(define_insn "floatsi2_cf"
2064
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2065
        (float:FP (match_operand:SI 1 "general_operand" "dU")))]
2066
  "TARGET_COLDFIRE_FPU"
2067
  "fmove%.l %1,%0"
2068
  [(set_attr "type" "fmove")])
2069
 
2070
 
2071
(define_expand "floathi2"
2072
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
2073
        (float:FP (match_operand:HI 1 "general_operand" "")))]
2074
  "TARGET_HARD_FLOAT"
2075
  "")
2076
 
2077
(define_insn "floathi2_68881"
2078
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2079
        (float:FP (match_operand:HI 1 "general_operand" "dmn")))]
2080
  "TARGET_68881"
2081
  "fmove%.w %1,%0"
2082
  [(set_attr "type" "fmove")])
2083
 
2084
(define_insn "floathi2_cf"
2085
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2086
        (float:FP (match_operand:HI 1 "general_operand" "dU")))]
2087
  "TARGET_COLDFIRE_FPU"
2088
  "fmove%.w %1,%0"
2089
  [(set_attr "type" "fmove")])
2090
 
2091
 
2092
(define_expand "floatqi2"
2093
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
2094
        (float:FP (match_operand:QI 1 "general_operand" "")))]
2095
  "TARGET_HARD_FLOAT"
2096
  "")
2097
 
2098
(define_insn "floatqi2_68881"
2099
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2100
        (float:FP (match_operand:QI 1 "general_operand" "dmn")))]
2101
  "TARGET_68881"
2102
  "fmove%.b %1,%0"
2103
  [(set_attr "type" "fmove")])
2104
 
2105
(define_insn "floatqi2_cf"
2106
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2107
        (float:FP (match_operand:QI 1 "general_operand" "dU")))]
2108
  "TARGET_COLDFIRE_FPU"
2109
  "fmove%.b %1,%0"
2110
  [(set_attr "type" "fmove")])
2111
 
2112
 
2113
;; New routines to convert floating-point values to integers
2114
;; to be used on the '040.  These should be faster than trapping
2115
;; into the kernel to emulate fintrz.  They should also be faster
2116
;; than calling the subroutines fixsfsi or fixdfsi.
2117
 
2118
(define_insn "fix_truncdfsi2"
2119
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
2120
        (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2121
   (clobber (match_scratch:SI 2 "=d"))
2122
   (clobber (match_scratch:SI 3 "=d"))]
2123
  "TARGET_68881 && TUNE_68040"
2124
{
2125
  CC_STATUS_INIT;
2126
  return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.l %1,%0\;fmovem%.l %2,%!";
2127
})
2128
 
2129
(define_insn "fix_truncdfhi2"
2130
  [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
2131
        (fix:HI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2132
   (clobber (match_scratch:SI 2 "=d"))
2133
   (clobber (match_scratch:SI 3 "=d"))]
2134
  "TARGET_68881 && TUNE_68040"
2135
{
2136
  CC_STATUS_INIT;
2137
  return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.w %1,%0\;fmovem%.l %2,%!";
2138
})
2139
 
2140
(define_insn "fix_truncdfqi2"
2141
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
2142
        (fix:QI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
2143
   (clobber (match_scratch:SI 2 "=d"))
2144
   (clobber (match_scratch:SI 3 "=d"))]
2145
  "TARGET_68881 && TUNE_68040"
2146
{
2147
  CC_STATUS_INIT;
2148
  return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.b %1,%0\;fmovem%.l %2,%!";
2149
})
2150
 
2151
;; Convert a float to a float whose value is an integer.
2152
;; This is the first stage of converting it to an integer type.
2153
 
2154
(define_expand "ftrunc2"
2155
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
2156
        (fix:FP (match_operand:FP 1 "general_operand" "")))]
2157
  "TARGET_HARD_FLOAT && !TUNE_68040"
2158
  "")
2159
 
2160
(define_insn "ftrunc2_68881"
2161
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2162
        (fix:FP (match_operand:FP 1 "general_operand" "fm")))]
2163
  "TARGET_68881 && !TUNE_68040"
2164
{
2165
  if (FP_REG_P (operands[1]))
2166
    return "fintrz%.x %f1,%0";
2167
  return "fintrz%. %f1,%0";
2168
}
2169
  [(set_attr "type" "falu")])
2170
 
2171
(define_insn "ftrunc2_cf"
2172
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2173
        (fix:FP (match_operand:FP 1 "general_operand" "fU")))]
2174
  "TARGET_COLDFIRE_FPU"
2175
{
2176
  if (FP_REG_P (operands[1]))
2177
    return "fintrz%.d %f1,%0";
2178
  return "fintrz%. %f1,%0";
2179
}
2180
  [(set_attr "type" "falu")])
2181
 
2182
;; Convert a float whose value is an integer
2183
;; to an actual integer.  Second stage of converting float to integer type.
2184
(define_expand "fixqi2"
2185
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
2186
        (fix:QI (match_operand:FP 1 "general_operand" "")))]
2187
  "TARGET_HARD_FLOAT"
2188
  "")
2189
 
2190
(define_insn "fixqi2_68881"
2191
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
2192
        (fix:QI (match_operand:FP 1 "general_operand" "f")))]
2193
  "TARGET_68881"
2194
  "fmove%.b %1,%0"
2195
  [(set_attr "type" "fmove")])
2196
 
2197
(define_insn "fixqi2_cf"
2198
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dU")
2199
        (fix:QI (match_operand:FP 1 "general_operand" "f")))]
2200
  "TARGET_COLDFIRE_FPU"
2201
  "fmove%.b %1,%0"
2202
  [(set_attr "type" "fmove")])
2203
 
2204
(define_expand "fixhi2"
2205
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
2206
        (fix:HI (match_operand:FP 1 "general_operand" "")))]
2207
  "TARGET_HARD_FLOAT"
2208
  "")
2209
 
2210
(define_insn "fixhi2_68881"
2211
  [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
2212
        (fix:HI (match_operand:FP 1 "general_operand" "f")))]
2213
  "TARGET_68881"
2214
  "fmove%.w %1,%0"
2215
  [(set_attr "type" "fmove")])
2216
 
2217
(define_insn "fixhi2_cf"
2218
  [(set (match_operand:HI 0 "nonimmediate_operand" "=dU")
2219
        (fix:HI (match_operand:FP 1 "general_operand" "f")))]
2220
  "TARGET_COLDFIRE_FPU"
2221
  "fmove%.w %1,%0"
2222
  [(set_attr "type" "fmove")])
2223
 
2224
(define_expand "fixsi2"
2225
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
2226
        (fix:SI (match_operand:FP 1 "general_operand" "")))]
2227
  "TARGET_HARD_FLOAT"
2228
  "")
2229
 
2230
(define_insn "fixsi2_68881"
2231
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
2232
        (fix:SI (match_operand:FP 1 "general_operand" "f")))]
2233
  "TARGET_68881"
2234
  "fmove%.l %1,%0"
2235
  [(set_attr "type" "fmove")])
2236
 
2237
(define_insn "fixsi2_cf"
2238
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dU")
2239
        (fix:SI (match_operand:FP 1 "general_operand" "f")))]
2240
  "TARGET_COLDFIRE_FPU"
2241
  "fmove%.l %1,%0"
2242
  [(set_attr "type" "fmove")])
2243
 
2244
 
2245
;; add instructions
2246
 
2247
(define_insn "adddi_lshrdi_63"
2248
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
2249
    (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "rm")
2250
            (const_int 63))
2251
        (match_dup 1)))
2252
   (clobber (match_scratch:SI 2 "=d"))]
2253
  ""
2254
{
2255
  operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2256
  if (REG_P (operands[1]) && REGNO (operands[1]) == REGNO (operands[0]))
2257
    return
2258
    "move%.l %1,%2\;add%.l %2,%2\;subx%.l %2,%2\;sub%.l %2,%3\;subx%.l %2,%0";
2259
  if (GET_CODE (operands[1]) == REG)
2260
    operands[4] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2261
  else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC
2262
        || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
2263
    operands[4] = operands[1];
2264
  else
2265
    operands[4] = adjust_address (operands[1], SImode, 4);
2266
  if (GET_CODE (operands[1]) == MEM
2267
   && GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
2268
    output_asm_insn ("move%.l %4,%3", operands);
2269
  output_asm_insn ("move%.l %1,%0\;smi %2", operands);
2270
  if (TARGET_68020 || TARGET_COLDFIRE)
2271
    output_asm_insn ("extb%.l %2", operands);
2272
  else
2273
    output_asm_insn ("ext%.w %2\;ext%.l %2", operands);
2274
  if (GET_CODE (operands[1]) != MEM
2275
   || GET_CODE (XEXP (operands[1], 0)) != PRE_DEC)
2276
    output_asm_insn ("move%.l %4,%3", operands);
2277
  return "sub%.l %2,%3\;subx%.l %2,%0";
2278
})
2279
 
2280
(define_insn "adddi_sexthishl32"
2281
  [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
2282
    (plus:DI (ashift:DI (sign_extend:DI
2283
          (match_operand:HI 1 "general_operand" "rm,rm,rm,rm"))
2284
            (const_int 32))
2285
        (match_operand:DI 2 "general_operand" "0,0,0,0")))
2286
   (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
2287
  "!TARGET_COLDFIRE"
2288
{
2289
  CC_STATUS_INIT;
2290
  if (ADDRESS_REG_P (operands[0]))
2291
    return "add%.w %1,%0";
2292
  else if (ADDRESS_REG_P (operands[3]))
2293
    return "move%.w %1,%3\;add%.l %3,%0";
2294
  else
2295
    return "move%.w %1,%3\;ext%.l %3\;add%.l %3,%0";
2296
})
2297
 
2298
(define_insn "*adddi_dilshr32"
2299
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,o")
2300
        (plus:DI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro,d")
2301
                              (const_int 32))
2302
                 (match_operand:DI 2 "general_operand" "0,0")))]
2303
  "!TARGET_COLDFIRE"
2304
{
2305
  CC_STATUS_INIT;
2306
  if (GET_CODE (operands[0]) == REG)
2307
    operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
2308
  else
2309
    operands[2] = adjust_address (operands[0], SImode, 4);
2310
  return "add%.l %1,%2\;negx%.l %0\;neg%.l %0";
2311
})
2312
 
2313
(define_insn "*adddi_dilshr32_cf"
2314
  [(set (match_operand:DI 0 "register_operand" "=d")
2315
        (plus:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro")
2316
                              (const_int 32))
2317
                 (match_operand:DI 2 "register_operand" "0")))]
2318
  "TARGET_COLDFIRE"
2319
{
2320
  CC_STATUS_INIT;
2321
  return "add%.l %1,%R0\;negx%.l %0\;neg%.l %0";
2322
})
2323
 
2324
(define_insn "adddi_dishl32"
2325
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
2326
;;    (plus:DI (match_operand:DI 2 "general_operand" "%0")
2327
;;      (ashift:DI (match_operand:DI 1 "general_operand" "ro")
2328
;;            (const_int 32))))]
2329
    (plus:DI (ashift:DI (match_operand:DI 1 "general_operand" "ro,d")
2330
            (const_int 32))
2331
        (match_operand:DI 2 "general_operand" "0,0")))]
2332
  ""
2333
{
2334
  CC_STATUS_INIT;
2335
  if (GET_CODE (operands[1]) == REG)
2336
    operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2337
  else
2338
    operands[1] = adjust_address (operands[1], SImode, 4);
2339
  return "add%.l %1,%0";
2340
}
2341
  [(set_attr "type" "alu_l")])
2342
 
2343
(define_insn "adddi3"
2344
  [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d")
2345
        (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0")
2346
                 (match_operand:DI 2 "general_operand" "d,no>,d,a")))
2347
   (clobber (match_scratch:SI 3 "=&d,&d,X,&d"))]
2348
  ""
2349
{
2350
  if (DATA_REG_P (operands[0]))
2351
    {
2352
      if (DATA_REG_P (operands[2]))
2353
        return "add%.l %R2,%R0\;addx%.l %2,%0";
2354
      else if (GET_CODE (operands[2]) == MEM
2355
          && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
2356
        return "move%.l %2,%3\;add%.l %2,%R0\;addx%.l %3,%0";
2357
      else
2358
        {
2359
          rtx high, low;
2360
          rtx xoperands[2];
2361
 
2362
          if (GET_CODE (operands[2]) == REG)
2363
            {
2364
              low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2365
              high = operands[2];
2366
            }
2367
          else if (CONSTANT_P (operands[2]))
2368
            split_double (operands[2], &high, &low);
2369
          else
2370
            {
2371
              low = adjust_address (operands[2], SImode, 4);
2372
              high = operands[2];
2373
            }
2374
 
2375
          operands[1] = low, operands[2] = high;
2376
          xoperands[0] = operands[3];
2377
          if (GET_CODE (operands[1]) == CONST_INT
2378
              && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2379
            xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
2380
          else
2381
            xoperands[1] = operands[2];
2382
 
2383
          output_asm_insn (output_move_simode (xoperands), xoperands);
2384
          if (GET_CODE (operands[1]) == CONST_INT)
2385
            {
2386
              if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
2387
                return "addq%.l %1,%R0\;addx%.l %3,%0";
2388
              else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2389
                {
2390
                  operands[1] = GEN_INT (-INTVAL (operands[1]));
2391
                  return "subq%.l %1,%R0\;subx%.l %3,%0";
2392
                }
2393
            }
2394
          return "add%.l %1,%R0\;addx%.l %3,%0";
2395
        }
2396
    }
2397
  else
2398
    {
2399
      gcc_assert (GET_CODE (operands[0]) == MEM);
2400
      CC_STATUS_INIT;
2401
      if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2402
        {
2403
          operands[1] = gen_rtx_MEM (SImode,
2404
                                     plus_constant (XEXP(operands[0], 0), -8));
2405
          return "move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1";
2406
        }
2407
      else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2408
        {
2409
          operands[1] = XEXP(operands[0], 0);
2410
          return "add%.l %R2,%0\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%1";
2411
        }
2412
      else
2413
        {
2414
          operands[1] = adjust_address (operands[0], SImode, 4);
2415
          return "add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0";
2416
        }
2417
    }
2418
})
2419
 
2420
(define_insn "addsi_lshrsi_31"
2421
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,dm,d")
2422
    (plus:SI (lshiftrt:SI (match_operand:SI 1 "general_operand" "rm,r,rm")
2423
            (const_int 31))
2424
        (match_dup 1)))]
2425
  ""
2426
{
2427
  operands[2] = operands[0];
2428
  operands[3] = gen_label_rtx();
2429
  if (GET_CODE (operands[0]) == MEM)
2430
    {
2431
      if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2432
        operands[0] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2433
      else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2434
        operands[2] = gen_rtx_MEM (SImode, XEXP (XEXP (operands[0], 0), 0));
2435
    }
2436
  output_asm_insn ("move%.l %1,%0", operands);
2437
  output_asm_insn ("jpl %l3", operands);
2438
  output_asm_insn ("addq%.l #1,%2", operands);
2439
  (*targetm.asm_out.internal_label) (asm_out_file, "L",
2440
                                CODE_LABEL_NUMBER (operands[3]));
2441
  return "";
2442
}
2443
  [(set_attr "ok_for_coldfire" "no,yes,yes")])
2444
 
2445
(define_expand "addsi3"
2446
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
2447
        (plus:SI (match_operand:SI 1 "general_operand" "")
2448
                 (match_operand:SI 2 "general_src_operand" "")))]
2449
  ""
2450
  "")
2451
 
2452
;; Note that the middle two alternatives are near-duplicates
2453
;; in order to handle insns generated by reload.
2454
;; This is needed since they are not themselves reloaded,
2455
;; so commutativity won't apply to them.
2456
(define_insn "*addsi3_internal"
2457
  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,d,a")
2458
        (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0")
2459
                 (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))]
2460
 
2461
 
2462
  "! TARGET_COLDFIRE"
2463
  "* return output_addsi3 (operands);")
2464
 
2465
(define_insn_and_split "*addsi3_5200"
2466
  [(set (match_operand:SI 0 "nonimmediate_operand"         "=mr,mr,a,  m,r,  ?a, ?a,?a,?a")
2467
        (plus:SI (match_operand:SI 1 "general_operand"     "%0, 0, 0,  0,0,   a,  a, r, a")
2468
                 (match_operand:SI 2 "general_src_operand" " I, L, JCu,d,mrKi,Cj, r, a, JCu")))]
2469
  "TARGET_COLDFIRE"
2470
{
2471
  switch (which_alternative)
2472
    {
2473
    case 0:
2474
      return "addq%.l %2,%0";
2475
 
2476
    case 1:
2477
      operands[2] = GEN_INT (- INTVAL (operands[2]));
2478
      return "subq%.l %2,%0";
2479
 
2480
    case 3:
2481
    case 4:
2482
      return "add%.l %2,%0";
2483
 
2484
    case 5:
2485
      /* move%.l %2,%0\n\tadd%.l %1,%0 */
2486
      return "#";
2487
 
2488
    case 6:
2489
      return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
2490
 
2491
    case 7:
2492
      return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0";
2493
 
2494
    case 2:
2495
    case 8:
2496
      return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
2497
 
2498
    default:
2499
      gcc_unreachable ();
2500
      return "";
2501
    }
2502
}
2503
  "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 5) && !operands_match_p (operands[0], operands[1])"
2504
  [(set (match_dup 0)
2505
        (match_dup 2))
2506
   (set (match_dup 0)
2507
        (plus:SI (match_dup 0)
2508
                 (match_dup 1)))]
2509
  ""
2510
  [(set_attr "type"     "aluq_l,aluq_l,lea, alu_l,alu_l,*,lea, lea, lea")
2511
   (set_attr "opy"      "2,     2,     *,   2,    2,    *,*,   *,   *")
2512
   (set_attr "opy_type" "*,     *,     mem5,*,    *,    *,mem6,mem6,mem5")])
2513
 
2514
(define_insn ""
2515
  [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
2516
        (plus:SI (match_operand:SI 1 "general_operand" "0")
2517
                 (sign_extend:SI
2518
                  (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2519
  "!TARGET_COLDFIRE"
2520
  "add%.w %2,%0")
2521
 
2522
(define_insn "addhi3"
2523
  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
2524
        (plus:HI (match_operand:HI 1 "general_operand" "%0,0")
2525
                 (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2526
  "!TARGET_COLDFIRE"
2527
{
2528
  if (GET_CODE (operands[2]) == CONST_INT)
2529
    {
2530
      /* If the constant would be a negative number when interpreted as
2531
         HImode, make it negative.  This is usually, but not always, done
2532
         elsewhere in the compiler.  First check for constants out of range,
2533
         which could confuse us.  */
2534
 
2535
      if (INTVAL (operands[2]) >= 32768)
2536
        operands[2] = GEN_INT (INTVAL (operands[2]) - 65536);
2537
 
2538
      if (INTVAL (operands[2]) > 0
2539
          && INTVAL (operands[2]) <= 8)
2540
        return "addq%.w %2,%0";
2541
      if (INTVAL (operands[2]) < 0
2542
          && INTVAL (operands[2]) >= -8)
2543
        {
2544
          operands[2] = GEN_INT (- INTVAL (operands[2]));
2545
          return "subq%.w %2,%0";
2546
        }
2547
      /* On the CPU32 it is faster to use two addqw instructions to
2548
         add a small integer (8 < N <= 16) to a register.
2549
         Likewise for subqw.  */
2550
      if (TUNE_CPU32 && REG_P (operands[0]))
2551
        {
2552
          if (INTVAL (operands[2]) > 8
2553
              && INTVAL (operands[2]) <= 16)
2554
            {
2555
              operands[2] = GEN_INT (INTVAL (operands[2]) - 8);
2556
              return "addq%.w #8,%0\;addq%.w %2,%0";
2557
            }
2558
          if (INTVAL (operands[2]) < -8
2559
              && INTVAL (operands[2]) >= -16)
2560
            {
2561
              operands[2] = GEN_INT (- INTVAL (operands[2]) - 8);
2562
              return "subq%.w #8,%0\;subq%.w %2,%0";
2563
            }
2564
        }
2565
      if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
2566
        return MOTOROLA ? "lea (%c2,%0),%0" : "lea %0@(%c2),%0";
2567
    }
2568
  return "add%.w %2,%0";
2569
})
2570
 
2571
;; These insns must use MATCH_DUP instead of the more expected
2572
;; use of a matching constraint because the "output" here is also
2573
;; an input, so you can't use the matching constraint.  That also means
2574
;; that you can't use the "%", so you need patterns with the matched
2575
;; operand in both positions.
2576
 
2577
(define_insn ""
2578
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2579
        (plus:HI (match_dup 0)
2580
                 (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2581
  "!TARGET_COLDFIRE"
2582
{
2583
  if (GET_CODE (operands[1]) == CONST_INT)
2584
    {
2585
      /* If the constant would be a negative number when interpreted as
2586
         HImode, make it negative.  This is usually, but not always, done
2587
         elsewhere in the compiler.  First check for constants out of range,
2588
         which could confuse us.  */
2589
 
2590
      if (INTVAL (operands[1]) >= 32768)
2591
        operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2592
 
2593
      if (INTVAL (operands[1]) > 0
2594
          && INTVAL (operands[1]) <= 8)
2595
        return "addq%.w %1,%0";
2596
      if (INTVAL (operands[1]) < 0
2597
          && INTVAL (operands[1]) >= -8)
2598
        {
2599
          operands[1] = GEN_INT (- INTVAL (operands[1]));
2600
          return "subq%.w %1,%0";
2601
        }
2602
      /* On the CPU32 it is faster to use two addqw instructions to
2603
         add a small integer (8 < N <= 16) to a register.
2604
         Likewise for subqw.  */
2605
      if (TUNE_CPU32 && REG_P (operands[0]))
2606
        {
2607
          if (INTVAL (operands[1]) > 8
2608
              && INTVAL (operands[1]) <= 16)
2609
            {
2610
              operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2611
              return "addq%.w #8,%0\;addq%.w %1,%0";
2612
            }
2613
          if (INTVAL (operands[1]) < -8
2614
              && INTVAL (operands[1]) >= -16)
2615
            {
2616
              operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
2617
              return "subq%.w #8,%0\;subq%.w %1,%0";
2618
            }
2619
        }
2620
      if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
2621
        return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0";
2622
    }
2623
  return "add%.w %1,%0";
2624
})
2625
 
2626
(define_insn ""
2627
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2628
        (plus:HI (match_operand:HI 1 "general_src_operand" "dn,rmSn")
2629
                 (match_dup 0)))]
2630
  "!TARGET_COLDFIRE"
2631
{
2632
  if (GET_CODE (operands[1]) == CONST_INT)
2633
    {
2634
      /* If the constant would be a negative number when interpreted as
2635
         HImode, make it negative.  This is usually, but not always, done
2636
         elsewhere in the compiler.  First check for constants out of range,
2637
         which could confuse us.  */
2638
 
2639
      if (INTVAL (operands[1]) >= 32768)
2640
        operands[1] = GEN_INT (INTVAL (operands[1]) - 65536);
2641
 
2642
      if (INTVAL (operands[1]) > 0
2643
          && INTVAL (operands[1]) <= 8)
2644
        return "addq%.w %1,%0";
2645
      if (INTVAL (operands[1]) < 0
2646
          && INTVAL (operands[1]) >= -8)
2647
        {
2648
          operands[1] = GEN_INT (- INTVAL (operands[1]));
2649
          return "subq%.w %1,%0";
2650
        }
2651
      /* On the CPU32 it is faster to use two addqw instructions to
2652
         add a small integer (8 < N <= 16) to a register.
2653
         Likewise for subqw.  */
2654
      if (TUNE_CPU32 && REG_P (operands[0]))
2655
        {
2656
          if (INTVAL (operands[1]) > 8
2657
              && INTVAL (operands[1]) <= 16)
2658
            {
2659
              operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
2660
              return "addq%.w #8,%0\;addq%.w %1,%0";
2661
            }
2662
          if (INTVAL (operands[1]) < -8
2663
              && INTVAL (operands[1]) >= -16)
2664
            {
2665
              operands[1] = GEN_INT (- INTVAL (operands[1]) - 8);
2666
              return "subq%.w #8,%0\;subq%.w %1,%0";
2667
            }
2668
        }
2669
      if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
2670
        return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0";
2671
    }
2672
  return "add%.w %1,%0";
2673
})
2674
 
2675
(define_insn "addqi3"
2676
  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
2677
        (plus:QI (match_operand:QI 1 "general_operand" "%0,0")
2678
                 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2679
  "!TARGET_COLDFIRE"
2680
{
2681
  if (GET_CODE (operands[2]) == CONST_INT)
2682
    {
2683
      if (INTVAL (operands[2]) >= 128)
2684
        operands[2] = GEN_INT (INTVAL (operands[2]) - 256);
2685
 
2686
      if (INTVAL (operands[2]) > 0
2687
          && INTVAL (operands[2]) <= 8)
2688
        return "addq%.b %2,%0";
2689
      if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8)
2690
       {
2691
         operands[2] = GEN_INT (- INTVAL (operands[2]));
2692
         return "subq%.b %2,%0";
2693
       }
2694
    }
2695
  return "add%.b %2,%0";
2696
})
2697
 
2698
(define_insn ""
2699
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2700
        (plus:QI (match_dup 0)
2701
                 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2702
  "!TARGET_COLDFIRE"
2703
{
2704
  if (GET_CODE (operands[1]) == CONST_INT)
2705
    {
2706
      if (INTVAL (operands[1]) >= 128)
2707
        operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2708
 
2709
      if (INTVAL (operands[1]) > 0
2710
          && INTVAL (operands[1]) <= 8)
2711
        return "addq%.b %1,%0";
2712
      if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2713
       {
2714
         operands[1] = GEN_INT (- INTVAL (operands[1]));
2715
         return "subq%.b %1,%0";
2716
       }
2717
    }
2718
  return "add%.b %1,%0";
2719
})
2720
 
2721
(define_insn ""
2722
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2723
        (plus:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
2724
                 (match_dup 0)))]
2725
  "!TARGET_COLDFIRE"
2726
{
2727
  if (GET_CODE (operands[1]) == CONST_INT)
2728
    {
2729
      if (INTVAL (operands[1]) >= 128)
2730
        operands[1] = GEN_INT (INTVAL (operands[1]) - 256);
2731
 
2732
      if (INTVAL (operands[1]) > 0
2733
          && INTVAL (operands[1]) <= 8)
2734
        return "addq%.b %1,%0";
2735
      if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8)
2736
       {
2737
         operands[1] = GEN_INT (- INTVAL (operands[1]));
2738
         return "subq%.b %1,%0";
2739
       }
2740
    }
2741
  return "add%.b %1,%0";
2742
})
2743
 
2744
(define_expand "add3"
2745
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
2746
        (plus:FP (match_operand:FP 1 "general_operand" "")
2747
                 (match_operand:FP 2 "general_operand" "")))]
2748
  "TARGET_HARD_FLOAT"
2749
  "")
2750
 
2751
(define_insn "add3_floatsi_68881"
2752
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2753
        (plus:FP (float:FP (match_operand:SI 2 "general_operand" "dmi"))
2754
                 (match_operand:FP 1 "general_operand" "0")))]
2755
  "TARGET_68881"
2756
  "fadd%.l %2,%0"
2757
  [(set_attr "type" "falu")
2758
   (set_attr "opy" "2")])
2759
 
2760
(define_insn "add3_floathi_68881"
2761
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2762
        (plus:FP (float:FP (match_operand:HI 2 "general_operand" "dmn"))
2763
                 (match_operand:FP 1 "general_operand" "0")))]
2764
  "TARGET_68881"
2765
  "fadd%.w %2,%0"
2766
  [(set_attr "type" "falu")
2767
   (set_attr "opy" "2")])
2768
 
2769
(define_insn "add3_floatqi_68881"
2770
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2771
        (plus:FP (float:FP (match_operand:QI 2 "general_operand" "dmn"))
2772
                 (match_operand:FP 1 "general_operand" "0")))]
2773
  "TARGET_68881"
2774
  "fadd%.b %2,%0"
2775
  [(set_attr "type" "falu")
2776
   (set_attr "opy" "2")])
2777
 
2778
(define_insn "add3_68881"
2779
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2780
        (plus:FP (match_operand:FP 1 "general_operand" "%0")
2781
                 (match_operand:FP 2 "general_operand" "fm")))]
2782
  "TARGET_68881"
2783
{
2784
  if (FP_REG_P (operands[2]))
2785
    return "fadd%.x %2,%0";
2786
  return "fadd%. %f2,%0";
2787
}
2788
  [(set_attr "type" "falu")
2789
   (set_attr "opy" "2")])
2790
 
2791
(define_insn "add3_cf"
2792
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2793
        (plus:FP (match_operand:FP 1 "general_operand" "%0")
2794
                 (match_operand:FP 2 "general_operand" "fU")))]
2795
  "TARGET_COLDFIRE_FPU"
2796
{
2797
  if (FP_REG_P (operands[2]))
2798
    return "fadd%.d %2,%0";
2799
  return "fadd%. %2,%0";
2800
}
2801
  [(set_attr "type" "falu")
2802
   (set_attr "opy" "2")])
2803
 
2804
;; subtract instructions
2805
 
2806
(define_insn "subdi_sexthishl32"
2807
  [(set (match_operand:DI 0 "nonimmediate_operand" "=o,a,*d,*d")
2808
    (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
2809
        (ashift:DI (sign_extend:DI (match_operand:HI 2 "general_operand" "rm,rm,rm,rm"))
2810
            (const_int 32))))
2811
   (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
2812
  "!TARGET_COLDFIRE"
2813
{
2814
  CC_STATUS_INIT;
2815
  if (ADDRESS_REG_P (operands[0]))
2816
    return "sub%.w %2,%0";
2817
  else if (ADDRESS_REG_P (operands[3]))
2818
    return "move%.w %2,%3\;sub%.l %3,%0";
2819
  else
2820
    return "move%.w %2,%3\;ext%.l %3\;sub%.l %3,%0";
2821
})
2822
 
2823
(define_insn "subdi_dishl32"
2824
  [(set (match_operand:DI 0 "nonimmediate_operand" "+ro")
2825
    (minus:DI (match_dup 0)
2826
        (ashift:DI (match_operand:DI 1 "general_operand" "ro")
2827
            (const_int 32))))]
2828
  ""
2829
{
2830
  CC_STATUS_INIT;
2831
  if (GET_CODE (operands[1]) == REG)
2832
    operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
2833
  else
2834
    operands[1] = adjust_address (operands[1], SImode, 4);
2835
  return "sub%.l %1,%0";
2836
}
2837
  [(set_attr "type" "alu_l")])
2838
 
2839
(define_insn "subdi3"
2840
  [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,d,d,d")
2841
        (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0")
2842
                 (match_operand:DI 2 "general_operand" "d,no>,d,a")))
2843
   (clobber (match_scratch:SI 3 "=&d,&d,X,&d"))]
2844
  ""
2845
{
2846
  if (DATA_REG_P (operands[0]))
2847
    {
2848
      if (DATA_REG_P (operands[2]))
2849
        return "sub%.l %R2,%R0\;subx%.l %2,%0";
2850
      else if (GET_CODE (operands[2]) == MEM
2851
          && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
2852
        {
2853
          return "move%.l %2,%3\;sub%.l %2,%R0\;subx%.l %3,%0";
2854
        }
2855
      else
2856
        {
2857
          rtx high, low;
2858
          rtx xoperands[2];
2859
 
2860
          if (GET_CODE (operands[2]) == REG)
2861
            {
2862
              low = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
2863
              high = operands[2];
2864
            }
2865
          else if (CONSTANT_P (operands[2]))
2866
            split_double (operands[2], &high, &low);
2867
          else
2868
            {
2869
              low = adjust_address (operands[2], SImode, 4);
2870
              high = operands[2];
2871
            }
2872
 
2873
          operands[1] = low, operands[2] = high;
2874
          xoperands[0] = operands[3];
2875
          if (GET_CODE (operands[1]) == CONST_INT
2876
              && INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2877
            xoperands[1] = GEN_INT (-INTVAL (operands[2]) - 1);
2878
          else
2879
            xoperands[1] = operands[2];
2880
 
2881
          output_asm_insn (output_move_simode (xoperands), xoperands);
2882
          if (GET_CODE (operands[1]) == CONST_INT)
2883
            {
2884
              if (INTVAL (operands[1]) > 0 && INTVAL (operands[1]) <= 8)
2885
                return "subq%.l %1,%R0\;subx%.l %3,%0";
2886
              else if (INTVAL (operands[1]) >= -8 && INTVAL (operands[1]) < 0)
2887
                {
2888
                  operands[1] = GEN_INT (-INTVAL (operands[1]));
2889
                  return "addq%.l %1,%R0\;addx%.l %3,%0";
2890
                }
2891
            }
2892
          return "sub%.l %1,%R0\;subx%.l %3,%0";
2893
        }
2894
    }
2895
  else
2896
    {
2897
      gcc_assert (GET_CODE (operands[0]) == MEM);
2898
      CC_STATUS_INIT;
2899
      if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
2900
        {
2901
          operands[1]
2902
            = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[0], 0), -8));
2903
          return "move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1";
2904
        }
2905
      else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2906
        {
2907
          operands[1] = XEXP(operands[0], 0);
2908
          return "sub%.l %R2,%0\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%1";
2909
        }
2910
      else
2911
        {
2912
          operands[1] = adjust_address (operands[0], SImode, 4);
2913
          return "sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0";
2914
        }
2915
    }
2916
})
2917
 
2918
(define_insn "subsi3"
2919
  [(set (match_operand:SI 0 "nonimmediate_operand" "=mda,m,d,a")
2920
        (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
2921
                  (match_operand:SI 2 "general_src_operand" "I,dT,mSrT,mSrs")))]
2922
  ""
2923
  "@
2924
   subq%.l %2, %0
2925
   sub%.l %2,%0
2926
   sub%.l %2,%0
2927
   sub%.l %2,%0"
2928
  [(set_attr "type" "aluq_l,alu_l,alu_l,alu_l")
2929
   (set_attr "opy" "2")])
2930
 
2931
(define_insn ""
2932
  [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
2933
        (minus:SI (match_operand:SI 1 "general_operand" "0")
2934
                  (sign_extend:SI
2935
                   (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
2936
  "!TARGET_COLDFIRE"
2937
  "sub%.w %2,%0")
2938
 
2939
(define_insn "subhi3"
2940
  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,r")
2941
        (minus:HI (match_operand:HI 1 "general_operand" "0,0")
2942
                  (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
2943
  "!TARGET_COLDFIRE"
2944
  "sub%.w %2,%0")
2945
 
2946
(define_insn ""
2947
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
2948
        (minus:HI (match_dup 0)
2949
                  (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
2950
  "!TARGET_COLDFIRE"
2951
  "sub%.w %1,%0")
2952
 
2953
(define_insn "subqi3"
2954
  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
2955
        (minus:QI (match_operand:QI 1 "general_operand" "0,0")
2956
                  (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
2957
  "!TARGET_COLDFIRE"
2958
  "sub%.b %2,%0")
2959
 
2960
(define_insn ""
2961
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
2962
        (minus:QI (match_dup 0)
2963
                  (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
2964
  "!TARGET_COLDFIRE"
2965
  "sub%.b %1,%0")
2966
 
2967
(define_expand "sub3"
2968
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
2969
        (minus:FP (match_operand:FP 1 "general_operand" "")
2970
                  (match_operand:FP 2 "general_operand" "")))]
2971
  "TARGET_HARD_FLOAT"
2972
  "")
2973
 
2974
(define_insn "sub3_floatsi_68881"
2975
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2976
        (minus:FP (match_operand:FP 1 "general_operand" "0")
2977
                  (float:FP (match_operand:SI 2 "general_operand" "dmi"))))]
2978
  "TARGET_68881"
2979
  "fsub%.l %2,%0"
2980
  [(set_attr "type" "falu")
2981
   (set_attr "opy" "2")])
2982
 
2983
(define_insn "sub3_floathi_68881"
2984
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2985
        (minus:FP (match_operand:FP 1 "general_operand" "0")
2986
                  (float:FP (match_operand:HI 2 "general_operand" "dmn"))))]
2987
  "TARGET_68881"
2988
  "fsub%.w %2,%0"
2989
  [(set_attr "type" "falu")
2990
   (set_attr "opy" "2")])
2991
 
2992
(define_insn "sub3_floatqi_68881"
2993
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
2994
        (minus:FP (match_operand:FP 1 "general_operand" "0")
2995
                  (float:FP (match_operand:QI 2 "general_operand" "dmn"))))]
2996
  "TARGET_68881"
2997
  "fsub%.b %2,%0"
2998
  [(set_attr "type" "falu")
2999
   (set_attr "opy" "2")])
3000
 
3001
(define_insn "sub3_68881"
3002
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3003
        (minus:FP (match_operand:FP 1 "general_operand" "0")
3004
                  (match_operand:FP 2 "general_operand" "fm")))]
3005
  "TARGET_68881"
3006
{
3007
  if (FP_REG_P (operands[2]))
3008
    return "fsub%.x %2,%0";
3009
  return "fsub%. %f2,%0";
3010
}
3011
  [(set_attr "type" "falu")
3012
   (set_attr "opy" "2")])
3013
 
3014
(define_insn "sub3_cf"
3015
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3016
        (minus:FP (match_operand:FP 1 "general_operand" "0")
3017
                  (match_operand:FP 2 "general_operand" "fU")))]
3018
  "TARGET_COLDFIRE_FPU"
3019
{
3020
  if (FP_REG_P (operands[2]))
3021
    return "fsub%.d %2,%0";
3022
  return "fsub%. %2,%0";
3023
}
3024
  [(set_attr "type" "falu")
3025
   (set_attr "opy" "2")])
3026
 
3027
;; multiply instructions
3028
 
3029
(define_insn "mulhi3"
3030
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3031
        (mult:HI (match_operand:HI 1 "general_operand" "%0")
3032
                 (match_operand:HI 2 "general_src_operand" "dmSn")))]
3033
  ""
3034
{
3035
  return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
3036
}
3037
  [(set_attr "type" "mul_w")
3038
   (set_attr "opy" "2")])
3039
 
3040
(define_insn "mulhisi3"
3041
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3042
        (mult:SI (sign_extend:SI
3043
                  (match_operand:HI 1 "nonimmediate_operand" "%0"))
3044
                 (sign_extend:SI
3045
                  (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
3046
  ""
3047
{
3048
  return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
3049
}
3050
  [(set_attr "type" "mul_w")
3051
   (set_attr "opy" "2")])
3052
 
3053
(define_insn "*mulhisisi3_s"
3054
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3055
        (mult:SI (sign_extend:SI
3056
                  (match_operand:HI 1 "nonimmediate_operand" "%0"))
3057
                 (match_operand:SI 2 "const_int_operand" "n")))]
3058
  "INTVAL (operands[2]) >= -0x8000 && INTVAL (operands[2]) <= 0x7fff"
3059
{
3060
  return MOTOROLA ? "muls%.w %2,%0" : "muls %2,%0";
3061
}
3062
  [(set_attr "type" "mul_w")
3063
   (set_attr "opy" "2")])
3064
 
3065
(define_expand "mulsi3"
3066
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
3067
        (mult:SI (match_operand:SI 1 "general_operand" "")
3068
                 (match_operand:SI 2 "general_operand" "")))]
3069
  "TARGET_68020 || TARGET_COLDFIRE"
3070
  "")
3071
 
3072
(define_insn "*mulsi3_68020"
3073
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3074
        (mult:SI (match_operand:SI 1 "general_operand" "%0")
3075
                 (match_operand:SI 2 "general_src_operand" "dmSTK")))]
3076
 
3077
  "TARGET_68020"
3078
  "muls%.l %2,%0"
3079
  [(set_attr "type" "mul_l")
3080
   (set_attr "opy" "2")])
3081
 
3082
(define_insn "*mulsi3_cf"
3083
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3084
        (mult:SI (match_operand:SI 1 "general_operand" "%0")
3085
                 (match_operand:SI 2 "general_operand" "d")))]
3086
  "TARGET_COLDFIRE"
3087
  "muls%.l %2,%0"
3088
  [(set_attr "type" "mul_l")
3089
   (set_attr "opy" "2")])
3090
 
3091
(define_insn "umulhisi3"
3092
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3093
        (mult:SI (zero_extend:SI
3094
                  (match_operand:HI 1 "nonimmediate_operand" "%0"))
3095
                 (zero_extend:SI
3096
                  (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
3097
  ""
3098
{
3099
  return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
3100
}
3101
  [(set_attr "type" "mul_w")
3102
   (set_attr "opy" "2")])
3103
 
3104
(define_insn "*mulhisisi3_z"
3105
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3106
        (mult:SI (zero_extend:SI
3107
                  (match_operand:HI 1 "nonimmediate_operand" "%0"))
3108
                 (match_operand:SI 2 "const_int_operand" "n")))]
3109
  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 0xffff"
3110
{
3111
  return MOTOROLA ? "mulu%.w %2,%0" : "mulu %2,%0";
3112
}
3113
  [(set_attr "type" "mul_w")
3114
   (set_attr "opy" "2")])
3115
 
3116
;; We need a separate DEFINE_EXPAND for u?mulsidi3 to be able to use the
3117
;; proper matching constraint.  This is because the matching is between
3118
;; the high-numbered word of the DImode operand[0] and operand[1].
3119
(define_expand "umulsidi3"
3120
  [(parallel
3121
    [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
3122
          (mult:SI (match_operand:SI 1 "register_operand" "")
3123
                   (match_operand:SI 2 "register_operand" "")))
3124
     (set (subreg:SI (match_dup 0) 0)
3125
          (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3126
                                             (zero_extend:DI (match_dup 2)))
3127
                                    (const_int 32))))])]
3128
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3129
  "")
3130
 
3131
(define_insn ""
3132
  [(set (match_operand:SI 0 "register_operand" "=d")
3133
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
3134
                  (match_operand:SI 2 "nonimmediate_operand" "dm")))
3135
   (set (match_operand:SI 3 "register_operand" "=d")
3136
        (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3137
                                           (zero_extend:DI (match_dup 2)))
3138
                                  (const_int 32))))]
3139
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3140
  "mulu%.l %2,%3:%0")
3141
 
3142
; Match immediate case.  For 2.4 only match things < 2^31.
3143
; It's tricky with larger values in these patterns since we need to match
3144
; values between the two parallel multiplies, between a CONST_DOUBLE and
3145
; a CONST_INT.
3146
(define_insn ""
3147
  [(set (match_operand:SI 0 "register_operand" "=d")
3148
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
3149
                 (match_operand:SI 2 "const_int_operand" "n")))
3150
   (set (match_operand:SI 3 "register_operand" "=d")
3151
        (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
3152
                                           (match_dup 2))
3153
                                  (const_int 32))))]
3154
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE
3155
   && (unsigned) INTVAL (operands[2]) <= 0x7fffffff"
3156
  "mulu%.l %2,%3:%0")
3157
 
3158
(define_expand "mulsidi3"
3159
  [(parallel
3160
    [(set (subreg:SI (match_operand:DI 0 "register_operand" "") 4)
3161
          (mult:SI (match_operand:SI 1 "register_operand" "")
3162
                   (match_operand:SI 2 "register_operand" "")))
3163
     (set (subreg:SI (match_dup 0) 0)
3164
          (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3165
                                             (sign_extend:DI (match_dup 2)))
3166
                                    (const_int 32))))])]
3167
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3168
  "")
3169
 
3170
(define_insn ""
3171
  [(set (match_operand:SI 0 "register_operand" "=d")
3172
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
3173
                 (match_operand:SI 2 "nonimmediate_operand" "dm")))
3174
   (set (match_operand:SI 3 "register_operand" "=d")
3175
        (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3176
                                           (sign_extend:DI (match_dup 2)))
3177
                                  (const_int 32))))]
3178
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3179
  "muls%.l %2,%3:%0")
3180
 
3181
(define_insn ""
3182
  [(set (match_operand:SI 0 "register_operand" "=d")
3183
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
3184
                 (match_operand:SI 2 "const_int_operand" "n")))
3185
   (set (match_operand:SI 3 "register_operand" "=d")
3186
        (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
3187
                                           (match_dup 2))
3188
                                  (const_int 32))))]
3189
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3190
  "muls%.l %2,%3:%0")
3191
 
3192
(define_expand "umulsi3_highpart"
3193
  [(parallel
3194
    [(set (match_operand:SI 0 "register_operand" "")
3195
          (truncate:SI
3196
           (lshiftrt:DI
3197
            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3198
                     (zero_extend:DI (match_operand:SI 2 "general_operand" "")))
3199
            (const_int 32))))
3200
     (clobber (match_dup 3))])]
3201
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3202
{
3203
  operands[3] = gen_reg_rtx (SImode);
3204
 
3205
  if (GET_CODE (operands[2]) == CONST_INT)
3206
    {
3207
      operands[2] = immed_double_const (INTVAL (operands[2]) & 0xffffffff,
3208
                                        0, DImode);
3209
 
3210
      /* We have to adjust the operand order for the matching constraints.  */
3211
      emit_insn (gen_const_umulsi3_highpart (operands[0], operands[3],
3212
                                             operands[1], operands[2]));
3213
      DONE;
3214
    }
3215
})
3216
 
3217
(define_insn ""
3218
  [(set (match_operand:SI 0 "register_operand" "=d")
3219
        (truncate:SI
3220
         (lshiftrt:DI
3221
          (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "%1"))
3222
                   (zero_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
3223
          (const_int 32))))
3224
   (clobber (match_operand:SI 1 "register_operand" "=d"))]
3225
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3226
  "mulu%.l %3,%0:%1")
3227
 
3228
(define_insn "const_umulsi3_highpart"
3229
  [(set (match_operand:SI 0 "register_operand" "=d")
3230
        (truncate:SI
3231
         (lshiftrt:DI
3232
          (mult:DI (zero_extend:DI (match_operand:SI 2 "register_operand" "1"))
3233
                   (match_operand:DI 3 "const_uint32_operand" "n"))
3234
          (const_int 32))))
3235
   (clobber (match_operand:SI 1 "register_operand" "=d"))]
3236
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3237
  "mulu%.l %3,%0:%1")
3238
 
3239
(define_expand "smulsi3_highpart"
3240
  [(parallel
3241
    [(set (match_operand:SI 0 "register_operand" "")
3242
          (truncate:SI
3243
           (lshiftrt:DI
3244
            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3245
                     (sign_extend:DI (match_operand:SI 2 "general_operand" "")))
3246
            (const_int 32))))
3247
     (clobber (match_dup 3))])]
3248
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3249
{
3250
  operands[3] = gen_reg_rtx (SImode);
3251
  if (GET_CODE (operands[2]) == CONST_INT)
3252
    {
3253
      /* We have to adjust the operand order for the matching constraints.  */
3254
      emit_insn (gen_const_smulsi3_highpart (operands[0], operands[3],
3255
                                             operands[1], operands[2]));
3256
      DONE;
3257
    }
3258
})
3259
 
3260
(define_insn ""
3261
  [(set (match_operand:SI 0 "register_operand" "=d")
3262
        (truncate:SI
3263
         (lshiftrt:DI
3264
          (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "%1"))
3265
                   (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "dm")))
3266
          (const_int 32))))
3267
   (clobber (match_operand:SI 1 "register_operand" "=d"))]
3268
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3269
  "muls%.l %3,%0:%1")
3270
 
3271
(define_insn "const_smulsi3_highpart"
3272
  [(set (match_operand:SI 0 "register_operand" "=d")
3273
        (truncate:SI
3274
         (lshiftrt:DI
3275
          (mult:DI (sign_extend:DI (match_operand:SI 2 "register_operand" "1"))
3276
                   (match_operand:DI 3 "const_sint32_operand" "n"))
3277
          (const_int 32))))
3278
   (clobber (match_operand:SI 1 "register_operand" "=d"))]
3279
  "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
3280
  "muls%.l %3,%0:%1")
3281
 
3282
(define_expand "mul3"
3283
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
3284
        (mult:FP (match_operand:FP 1 "general_operand" "")
3285
                 (match_operand:FP 2 "general_operand" "")))]
3286
  "TARGET_HARD_FLOAT"
3287
  "")
3288
 
3289
(define_insn "mul3_floatsi_68881"
3290
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3291
        (mult:FP (float:FP (match_operand:SI 2 "general_operand" "dmi"))
3292
                 (match_operand:FP 1 "general_operand" "0")))]
3293
  "TARGET_68881"
3294
{
3295
  return TARGET_68040
3296
         ? "fmul%.l %2,%0"
3297
         : "fmul%.l %2,%0";
3298
}
3299
  [(set_attr "type" "fmul")
3300
   (set_attr "opy" "2")])
3301
 
3302
(define_insn "mul3_floathi_68881"
3303
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3304
        (mult:FP (float:FP (match_operand:HI 2 "general_operand" "dmn"))
3305
                 (match_operand:FP 1 "general_operand" "0")))]
3306
  "TARGET_68881"
3307
{
3308
  return TARGET_68040
3309
         ? "fmul%.w %2,%0"
3310
         : "fmul%.w %2,%0";
3311
}
3312
  [(set_attr "type" "fmul")
3313
   (set_attr "opy" "2")])
3314
 
3315
(define_insn "mul3_floatqi_68881"
3316
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3317
        (mult:FP (float:FP (match_operand:QI 2 "general_operand" "dmn"))
3318
                 (match_operand:FP 1 "general_operand" "0")))]
3319
  "TARGET_68881"
3320
{
3321
  return TARGET_68040
3322
         ? "fmul%.b %2,%0"
3323
         : "fmul%.b %2,%0";
3324
}
3325
  [(set_attr "type" "fmul")
3326
   (set_attr "opy" "2")])
3327
 
3328
(define_insn "muldf_68881"
3329
  [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
3330
        (mult:DF (match_operand:DF 1 "general_operand" "%0")
3331
                 (match_operand:DF 2 "general_operand" "fmG")))]
3332
  "TARGET_68881"
3333
{
3334
  if (GET_CODE (operands[2]) == CONST_DOUBLE
3335
      && floating_exact_log2 (operands[2]) && !TUNE_68040_60)
3336
    {
3337
      int i = floating_exact_log2 (operands[2]);
3338
      operands[2] = GEN_INT (i);
3339
      return "fscale%.l %2,%0";
3340
    }
3341
  if (REG_P (operands[2]))
3342
    return "f%&mul%.x %2,%0";
3343
  return "f%&mul%.d %f2,%0";
3344
})
3345
 
3346
(define_insn "mulsf_68881"
3347
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
3348
        (mult:SF (match_operand:SF 1 "general_operand" "%0")
3349
                 (match_operand:SF 2 "general_operand" "fdmF")))]
3350
  "TARGET_68881"
3351
{
3352
  if (FP_REG_P (operands[2]))
3353
    return (TARGET_68040
3354
            ? "fsmul%.x %2,%0"
3355
            : "fsglmul%.x %2,%0");
3356
  return (TARGET_68040
3357
          ? "fsmul%.s %f2,%0"
3358
          : "fsglmul%.s %f2,%0");
3359
})
3360
 
3361
(define_insn "mulxf3_68881"
3362
  [(set (match_operand:XF 0 "nonimmediate_operand" "=f")
3363
        (mult:XF (match_operand:XF 1 "nonimmediate_operand" "%0")
3364
                 (match_operand:XF 2 "nonimmediate_operand" "fm")))]
3365
  "TARGET_68881"
3366
{
3367
  return "fmul%.x %f2,%0";
3368
})
3369
 
3370
(define_insn "fmul3_cf"
3371
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3372
        (mult:FP (match_operand:FP 1 "general_operand" "%0")
3373
                 (match_operand:FP 2 "general_operand" "fU")))]
3374
  "TARGET_COLDFIRE_FPU"
3375
{
3376
  if (FP_REG_P (operands[2]))
3377
    return "fmul%.d %2,%0";
3378
  return "fmul%. %2,%0";
3379
}
3380
  [(set_attr "type" "fmul")
3381
   (set_attr "opy" "2")])
3382
 
3383
;; divide instructions
3384
 
3385
(define_expand "div3"
3386
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
3387
        (div:FP (match_operand:FP 1 "general_operand" "")
3388
                (match_operand:FP 2 "general_operand" "")))]
3389
  "TARGET_HARD_FLOAT"
3390
  "")
3391
 
3392
(define_insn "div3_floatsi_68881"
3393
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3394
        (div:FP (match_operand:FP 1 "general_operand" "0")
3395
                (float:FP (match_operand:SI 2 "general_operand" "dmi"))))]
3396
  "TARGET_68881"
3397
{
3398
  return TARGET_68040
3399
         ? "fdiv%.l %2,%0"
3400
         : "fdiv%.l %2,%0";
3401
})
3402
 
3403
(define_insn "div3_floathi_68881"
3404
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3405
        (div:FP (match_operand:FP 1 "general_operand" "0")
3406
                (float:FP (match_operand:HI 2 "general_operand" "dmn"))))]
3407
  "TARGET_68881"
3408
{
3409
  return TARGET_68040
3410
         ? "fdiv%.w %2,%0"
3411
         : "fdiv%.w %2,%0";
3412
})
3413
 
3414
(define_insn "div3_floatqi_68881"
3415
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3416
        (div:FP (match_operand:FP 1 "general_operand" "0")
3417
                (float:FP (match_operand:QI 2 "general_operand" "dmn"))))]
3418
  "TARGET_68881"
3419
{
3420
  return TARGET_68040
3421
         ? "fdiv%.b %2,%0"
3422
         : "fdiv%.b %2,%0";
3423
})
3424
 
3425
(define_insn "div3_68881"
3426
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3427
        (div:FP (match_operand:FP 1 "general_operand" "0")
3428
                (match_operand:FP 2 "general_operand" "fm")))]
3429
  "TARGET_68881"
3430
{
3431
  if (FP_REG_P (operands[2]))
3432
    return (TARGET_68040
3433
            ? "fdiv%.x %2,%0"
3434
            : "fdiv%.x %2,%0");
3435
  return (TARGET_68040
3436
          ? "fdiv%. %f2,%0"
3437
          : "fdiv%. %f2,%0");
3438
})
3439
 
3440
(define_insn "div3_cf"
3441
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
3442
        (div:FP (match_operand:FP 1 "general_operand" "0")
3443
                (match_operand:FP 2 "general_operand" "fU")))]
3444
  "TARGET_COLDFIRE_FPU"
3445
{
3446
  if (FP_REG_P (operands[2]))
3447
    return "fdiv%.d %2,%0";
3448
  return "fdiv%. %2,%0";
3449
}
3450
  [(set_attr "type" "fdiv")
3451
   (set_attr "opy" "2")])
3452
 
3453
;; Remainder instructions.
3454
 
3455
(define_expand "divmodsi4"
3456
  [(parallel
3457
    [(set (match_operand:SI 0 "nonimmediate_operand" "")
3458
          (div:SI (match_operand:SI 1 "general_operand" "")
3459
                  (match_operand:SI 2 "general_src_operand" "")))
3460
     (set (match_operand:SI 3 "nonimmediate_operand" "")
3461
          (mod:SI (match_dup 1) (match_dup 2)))])]
3462
  "TARGET_68020 || TARGET_CF_HWDIV"
3463
  "")
3464
 
3465
(define_insn ""
3466
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3467
        (div:SI (match_operand:SI 1 "general_operand" "0")
3468
                (match_operand:SI 2 "general_src_operand" "dU")))
3469
   (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
3470
        (mod:SI (match_dup 1) (match_dup 2)))]
3471
  "TARGET_CF_HWDIV"
3472
{
3473
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
3474
    return "divs%.l %2,%0";
3475
  else if (find_reg_note (insn, REG_UNUSED, operands[0]))
3476
    return "rems%.l %2,%3:%0";
3477
  else
3478
    return "rems%.l %2,%3:%0\;divs%.l %2,%0";
3479
}
3480
  [(set_attr "type" "div_l")
3481
   (set_attr "opy" "2")])
3482
 
3483
(define_insn ""
3484
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3485
        (div:SI (match_operand:SI 1 "general_operand" "0")
3486
                (match_operand:SI 2 "general_src_operand" "dmSTK")))
3487
   (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3488
        (mod:SI (match_dup 1) (match_dup 2)))]
3489
  "TARGET_68020"
3490
{
3491
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
3492
    return "divs%.l %2,%0";
3493
  else
3494
    return "divsl%.l %2,%3:%0";
3495
})
3496
 
3497
(define_expand "udivmodsi4"
3498
  [(parallel
3499
    [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3500
          (udiv:SI (match_operand:SI 1 "general_operand" "0")
3501
                   (match_operand:SI 2 "general_src_operand" "dmSTK")))
3502
     (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3503
          (umod:SI (match_dup 1) (match_dup 2)))])]
3504
  "TARGET_68020 || TARGET_CF_HWDIV"
3505
  "")
3506
 
3507
(define_insn ""
3508
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3509
        (udiv:SI (match_operand:SI 1 "general_operand" "0")
3510
                 (match_operand:SI 2 "general_src_operand" "dU")))
3511
   (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
3512
        (umod:SI (match_dup 1) (match_dup 2)))]
3513
  "TARGET_CF_HWDIV"
3514
{
3515
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
3516
    return "divu%.l %2,%0";
3517
  else if (find_reg_note (insn, REG_UNUSED, operands[0]))
3518
    return "remu%.l %2,%3:%0";
3519
  else
3520
    return "remu%.l %2,%3:%0\;divu%.l %2,%0";
3521
}
3522
  [(set_attr "type" "div_l")
3523
   (set_attr "opy" "2")])
3524
 
3525
(define_insn ""
3526
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3527
        (udiv:SI (match_operand:SI 1 "general_operand" "0")
3528
                 (match_operand:SI 2 "general_src_operand" "dmSTK")))
3529
   (set (match_operand:SI 3 "nonimmediate_operand" "=d")
3530
        (umod:SI (match_dup 1) (match_dup 2)))]
3531
  "TARGET_68020 && !TARGET_COLDFIRE"
3532
{
3533
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
3534
    return "divu%.l %2,%0";
3535
  else
3536
    return "divul%.l %2,%3:%0";
3537
})
3538
 
3539
(define_insn "divmodhi4"
3540
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3541
        (div:HI (match_operand:HI 1 "general_operand" "0")
3542
                (match_operand:HI 2 "general_src_operand" "dmSKT")))
3543
   (set (match_operand:HI 3 "nonimmediate_operand" "=d")
3544
        (mod:HI (match_dup 1) (match_dup 2)))]
3545
  "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
3546
{
3547
  output_asm_insn (MOTOROLA ?
3548
    "ext%.l %0\;divs%.w %2,%0" :
3549
    "extl %0\;divs %2,%0",
3550
    operands);
3551
  if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3552
    {
3553
      CC_STATUS_INIT;
3554
      return "move%.l %0,%3\;swap %3";
3555
    }
3556
  else
3557
    return "";
3558
})
3559
 
3560
(define_insn "udivmodhi4"
3561
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
3562
        (udiv:HI (match_operand:HI 1 "general_operand" "0")
3563
                 (match_operand:HI 2 "general_src_operand" "dmSKT")))
3564
   (set (match_operand:HI 3 "nonimmediate_operand" "=d")
3565
        (umod:HI (match_dup 1) (match_dup 2)))]
3566
  "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
3567
{
3568
  if (ISA_HAS_MVS_MVZ)
3569
    output_asm_insn (MOTOROLA ?
3570
      "mvz%.w %0,%0\;divu%.w %2,%0" :
3571
      "mvz%.w %0,%0\;divu %2,%0",
3572
      operands);
3573
  else
3574
    output_asm_insn (MOTOROLA ?
3575
      "and%.l #0xFFFF,%0\;divu%.w %2,%0" :
3576
      "and%.l #0xFFFF,%0\;divu %2,%0",
3577
      operands);
3578
 
3579
  if (!find_reg_note(insn, REG_UNUSED, operands[3]))
3580
    {
3581
      CC_STATUS_INIT;
3582
      return "move%.l %0,%3\;swap %3";
3583
    }
3584
  else
3585
    return "";
3586
})
3587
 
3588
;; logical-and instructions
3589
 
3590
;; "anddi3" is mainly here to help combine().
3591
(define_insn "anddi3"
3592
  [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3593
        (and:DI (match_operand:DI 1 "general_operand" "%0,0")
3594
                (match_operand:DI 2 "general_operand" "dn,don")))]
3595
  "!TARGET_COLDFIRE"
3596
{
3597
  CC_STATUS_INIT;
3598
  /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3599
  if (CONSTANT_P (operands[2]))
3600
    {
3601
      rtx hi, lo;
3602
 
3603
      split_double (operands[2], &hi, &lo);
3604
 
3605
      switch (INTVAL (hi))
3606
        {
3607
          case 0 :
3608
            output_asm_insn ("clr%.l %0", operands);
3609
            break;
3610
          case -1 :
3611
            break;
3612
          default :
3613
            {
3614
            rtx xoperands[3];
3615
 
3616
            xoperands[0] = operands[0];
3617
            xoperands[2] = hi;
3618
            output_asm_insn (output_andsi3 (xoperands), xoperands);
3619
            }
3620
        }
3621
      if (GET_CODE (operands[0]) == REG)
3622
        operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3623
      else
3624
        operands[0] = adjust_address (operands[0], SImode, 4);
3625
      switch (INTVAL (lo))
3626
        {
3627
          case 0 :
3628
            output_asm_insn ("clr%.l %0", operands);
3629
            break;
3630
          case -1 :
3631
            break;
3632
          default :
3633
            {
3634
            rtx xoperands[3];
3635
 
3636
            xoperands[0] = operands[0];
3637
            xoperands[2] = lo;
3638
            output_asm_insn (output_andsi3 (xoperands), xoperands);
3639
            }
3640
        }
3641
      return "";
3642
    }
3643
  if (GET_CODE (operands[0]) != REG)
3644
    {
3645
      operands[1] = adjust_address (operands[0], SImode, 4);
3646
      return "and%.l %2,%0\;and%.l %R2,%1";
3647
    }
3648
  if (GET_CODE (operands[2]) != REG)
3649
    {
3650
      operands[1] = adjust_address (operands[2], SImode, 4);
3651
      return "and%.l %2,%0\;and%.l %1,%R0";
3652
    }
3653
  return "and%.l %2,%0\;and%.l %R2,%R0";
3654
})
3655
 
3656
;; Prevent AND from being made with sp.  This doesn't exist in the machine
3657
;; and reload will cause inefficient code.  Since sp is a FIXED_REG, we
3658
;; can't allocate pseudos into it.
3659
 
3660
(define_expand "andsi3"
3661
  [(set (match_operand:SI 0 "not_sp_operand" "")
3662
        (and:SI (match_operand:SI 1 "general_operand" "")
3663
                (match_operand:SI 2 "general_src_operand" "")))]
3664
  ""
3665
  "")
3666
 
3667
;; produced by split operations after reload finished
3668
(define_insn "*andsi3_split"
3669
  [(set (match_operand:SI 0 "register_operand" "=d")
3670
        (and:SI (match_operand:SI 1 "register_operand" "0")
3671
                (match_operand:SI 2 "const_int_operand" "i")))]
3672
  "reload_completed && !TARGET_COLDFIRE"
3673
{
3674
  return output_andsi3 (operands);
3675
})
3676
 
3677
(define_insn "andsi3_internal"
3678
  [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3679
        (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3680
                (match_operand:SI 2 "general_src_operand" "dKT,dmSM")))]
3681
  "!TARGET_COLDFIRE"
3682
{
3683
  return output_andsi3 (operands);
3684
})
3685
 
3686
(define_insn "andsi3_5200"
3687
  [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
3688
        (and:SI (match_operand:SI 1 "general_operand" "%0,0")
3689
                (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
3690
  "TARGET_COLDFIRE"
3691
{
3692
  if (ISA_HAS_MVS_MVZ
3693
      && DATA_REG_P (operands[0])
3694
      && GET_CODE (operands[2]) == CONST_INT)
3695
    {
3696
      if (INTVAL (operands[2]) == 0x000000ff)
3697
        return "mvz%.b %0,%0";
3698
      else if (INTVAL (operands[2]) == 0x0000ffff)
3699
        return "mvz%.w %0,%0";
3700
    }
3701
  return output_andsi3 (operands);
3702
})
3703
 
3704
(define_insn "andhi3"
3705
  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
3706
        (and:HI (match_operand:HI 1 "general_operand" "%0,0")
3707
                (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
3708
  "!TARGET_COLDFIRE"
3709
  "and%.w %2,%0")
3710
 
3711
(define_insn ""
3712
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3713
        (and:HI (match_dup 0)
3714
                (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
3715
  "!TARGET_COLDFIRE"
3716
  "and%.w %1,%0")
3717
 
3718
(define_insn ""
3719
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3720
        (and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
3721
                (match_dup 0)))]
3722
  "!TARGET_COLDFIRE"
3723
  "and%.w %1,%0")
3724
 
3725
(define_insn "andqi3"
3726
  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
3727
        (and:QI (match_operand:QI 1 "general_operand" "%0,0")
3728
                (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
3729
  "!TARGET_COLDFIRE"
3730
  "and%.b %2,%0")
3731
 
3732
(define_insn ""
3733
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3734
        (and:QI (match_dup 0)
3735
                (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
3736
  "!TARGET_COLDFIRE"
3737
  "and%.b %1,%0")
3738
 
3739
(define_insn ""
3740
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3741
        (and:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
3742
                (match_dup 0)))]
3743
  "!TARGET_COLDFIRE"
3744
  "and%.b %1,%0")
3745
 
3746
;; inclusive-or instructions
3747
 
3748
(define_insn "iordi_zext"
3749
  [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3750
    (ior:DI (zero_extend:DI (match_operand 1 "general_operand" "dn,dmn"))
3751
        (match_operand:DI 2 "general_operand" "0,0")))]
3752
  "!TARGET_COLDFIRE"
3753
{
3754
  int byte_mode;
3755
 
3756
  CC_STATUS_INIT;
3757
  if (GET_CODE (operands[0]) == REG)
3758
    operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3759
  else
3760
    operands[0] = adjust_address (operands[0], SImode, 4);
3761
  if (GET_MODE (operands[1]) == SImode)
3762
    return "or%.l %1,%0";
3763
  byte_mode = (GET_MODE (operands[1]) == QImode);
3764
  if (GET_CODE (operands[0]) == MEM)
3765
    operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
3766
                                  byte_mode ? 3 : 2);
3767
  if (byte_mode)
3768
    return "or%.b %1,%0";
3769
  else
3770
    return "or%.w %1,%0";
3771
})
3772
 
3773
;; "iordi3" is mainly here to help combine().
3774
(define_insn "iordi3"
3775
  [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
3776
        (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
3777
                (match_operand:DI 2 "general_operand" "dn,don")))]
3778
  "!TARGET_COLDFIRE"
3779
{
3780
  CC_STATUS_INIT;
3781
  /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3782
  if (CONSTANT_P (operands[2]))
3783
    {
3784
      rtx hi, lo;
3785
 
3786
      split_double (operands[2], &hi, &lo);
3787
 
3788
      switch (INTVAL (hi))
3789
        {
3790
          case 0 :
3791
            break;
3792
          case -1 :
3793
            /* FIXME : a scratch register would be welcome here if operand[0]
3794
               is not a register */
3795
            output_asm_insn ("move%.l #-1,%0", operands);
3796
            break;
3797
          default :
3798
            {
3799
            rtx xoperands[3];
3800
 
3801
            xoperands[0] = operands[0];
3802
            xoperands[2] = hi;
3803
            output_asm_insn (output_iorsi3 (xoperands), xoperands);
3804
            }
3805
        }
3806
      if (GET_CODE (operands[0]) == REG)
3807
        operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3808
      else
3809
        operands[0] = adjust_address (operands[0], SImode, 4);
3810
      switch (INTVAL (lo))
3811
        {
3812
          case 0 :
3813
            break;
3814
          case -1 :
3815
            /* FIXME : a scratch register would be welcome here if operand[0]
3816
               is not a register */
3817
            output_asm_insn ("move%.l #-1,%0", operands);
3818
            break;
3819
          default :
3820
            {
3821
            rtx xoperands[3];
3822
 
3823
            xoperands[0] = operands[0];
3824
            xoperands[2] = lo;
3825
            output_asm_insn (output_iorsi3 (xoperands), xoperands);
3826
            }
3827
        }
3828
      return "";
3829
    }
3830
  if (GET_CODE (operands[0]) != REG)
3831
    {
3832
      operands[1] = adjust_address (operands[0], SImode, 4);
3833
      return "or%.l %2,%0\;or%.l %R2,%1";
3834
    }
3835
  if (GET_CODE (operands[2]) != REG)
3836
    {
3837
      operands[1] = adjust_address (operands[2], SImode, 4);
3838
      return "or%.l %2,%0\;or%.l %1,%R0";
3839
    }
3840
  return "or%.l %2,%0\;or%.l %R2,%R0";
3841
})
3842
 
3843
(define_expand "iorsi3"
3844
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
3845
        (ior:SI (match_operand:SI 1 "general_operand" "")
3846
                (match_operand:SI 2 "general_src_operand" "")))]
3847
  ""
3848
  "")
3849
 
3850
(define_insn "iorsi3_internal"
3851
  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d")
3852
        (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3853
                (match_operand:SI 2 "general_src_operand" "dKT,dmSMT")))]
3854
  "! TARGET_COLDFIRE"
3855
{
3856
  return output_iorsi3 (operands);
3857
})
3858
 
3859
(define_insn "iorsi3_5200"
3860
  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d")
3861
        (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
3862
                (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
3863
  "TARGET_COLDFIRE"
3864
{
3865
  return output_iorsi3 (operands);
3866
})
3867
 
3868
(define_insn "iorhi3"
3869
  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
3870
        (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
3871
                (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
3872
  "!TARGET_COLDFIRE"
3873
  "or%.w %2,%0")
3874
 
3875
(define_insn ""
3876
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3877
        (ior:HI (match_dup 0)
3878
                (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
3879
  "!TARGET_COLDFIRE"
3880
  "or%.w %1,%0")
3881
 
3882
(define_insn ""
3883
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
3884
        (ior:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
3885
                (match_dup 0)))]
3886
  "!TARGET_COLDFIRE"
3887
  "or%.w %1,%0")
3888
 
3889
(define_insn "iorqi3"
3890
  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
3891
        (ior:QI (match_operand:QI 1 "general_operand" "%0,0")
3892
                (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
3893
  "!TARGET_COLDFIRE"
3894
  "or%.b %2,%0")
3895
 
3896
(define_insn ""
3897
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3898
        (ior:QI (match_dup 0)
3899
                (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
3900
  "!TARGET_COLDFIRE"
3901
  "or%.b %1,%0")
3902
 
3903
(define_insn ""
3904
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
3905
        (ior:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
3906
                (match_dup 0)))]
3907
  "!TARGET_COLDFIRE"
3908
  "or%.b %1,%0")
3909
 
3910
;; On all 68k models, this makes faster code in a special case.
3911
;; See also ashlsi_16, ashrsi_16 and lshrsi_16.
3912
 
3913
(define_insn "iorsi_zexthi_ashl16"
3914
  [(set (match_operand:SI 0 "nonimmediate_operand" "=&d")
3915
    (ior:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "rmn"))
3916
        (ashift:SI (match_operand:SI 2 "general_operand" "or")
3917
            (const_int 16))))]
3918
  ""
3919
{
3920
  CC_STATUS_INIT;
3921
  if (GET_CODE (operands[2]) != REG)
3922
      operands[2] = adjust_address (operands[2], HImode, 2);
3923
  if (GET_CODE (operands[2]) != REG
3924
  || REGNO (operands[2]) != REGNO (operands[0]))
3925
    output_asm_insn ("move%.w %2,%0", operands);
3926
  return "swap %0\;mov%.w %1,%0";
3927
})
3928
 
3929
(define_insn "iorsi_zext"
3930
  [(set (match_operand:SI 0 "nonimmediate_operand" "=o,d")
3931
    (ior:SI (zero_extend:SI (match_operand 1 "general_operand" "dn,dmn"))
3932
        (match_operand:SI 2 "general_operand" "0,0")))]
3933
  "!TARGET_COLDFIRE"
3934
{
3935
  int byte_mode;
3936
 
3937
  CC_STATUS_INIT;
3938
  byte_mode = (GET_MODE (operands[1]) == QImode);
3939
  if (GET_CODE (operands[0]) == MEM)
3940
    operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
3941
                                  byte_mode ? 3 : 2);
3942
  if (byte_mode)
3943
    return "or%.b %1,%0";
3944
  else
3945
    return "or%.w %1,%0";
3946
})
3947
 
3948
;; xor instructions
3949
 
3950
;; "xordi3" is mainly here to help combine().
3951
(define_insn "xordi3"
3952
  [(set (match_operand:DI 0 "nonimmediate_operand" "=od")
3953
        (xor:DI (match_operand:DI 1 "general_operand" "%0")
3954
                (match_operand:DI 2 "general_operand" "dn")))]
3955
  "!TARGET_COLDFIRE"
3956
{
3957
  CC_STATUS_INIT;
3958
  /* We can get CONST_DOUBLE, but also const1_rtx etc.  */
3959
 
3960
  if (CONSTANT_P (operands[2]))
3961
    {
3962
      rtx hi, lo;
3963
 
3964
      split_double (operands[2], &hi, &lo);
3965
 
3966
      switch (INTVAL (hi))
3967
        {
3968
          case 0 :
3969
            break;
3970
          case -1 :
3971
            output_asm_insn ("not%.l %0", operands);
3972
            break;
3973
          default :
3974
            /* FIXME : a scratch register would be welcome here if
3975
               -128 <= INTVAL (hi) < -1 */
3976
            {
3977
            rtx xoperands[3];
3978
 
3979
            xoperands[0] = operands[0];
3980
            xoperands[2] = hi;
3981
            output_asm_insn (output_xorsi3 (xoperands), xoperands);
3982
            }
3983
        }
3984
      if (GET_CODE (operands[0]) == REG)
3985
        operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
3986
      else
3987
        operands[0] = adjust_address (operands[0], SImode, 4);
3988
      switch (INTVAL (lo))
3989
        {
3990
          case 0 :
3991
            break;
3992
          case -1 :
3993
            output_asm_insn ("not%.l %0", operands);
3994
            break;
3995
          default :
3996
            /* FIXME : a scratch register would be welcome here if
3997
               -128 <= INTVAL (lo) < -1 */
3998
            operands[2] = lo;
3999
            /* FIXME : this should be merged with xorsi3 */
4000
            {
4001
            rtx xoperands[3];
4002
 
4003
            xoperands[0] = operands[0];
4004
            xoperands[2] = lo;
4005
            output_asm_insn (output_xorsi3 (xoperands), xoperands);
4006
            }
4007
        }
4008
      return "";
4009
    }
4010
  if (GET_CODE (operands[0]) != REG)
4011
    {
4012
      operands[1] = adjust_address (operands[0], SImode, 4);
4013
      return "eor%.l %2,%0\;eor%.l %R2,%1";
4014
    }
4015
  if (GET_CODE (operands[2]) != REG)
4016
    {
4017
      operands[1] = adjust_address (operands[2], SImode, 4);
4018
      return "eor%.l %2,%0\;eor%.l %1,%R0";
4019
    }
4020
  return "eor%.l %2,%0\;eor%.l %R2,%R0";
4021
})
4022
 
4023
(define_expand "xorsi3"
4024
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4025
        (xor:SI (match_operand:SI 1 "general_operand" "")
4026
                (match_operand:SI 2 "general_operand" "")))]
4027
  ""
4028
  "")
4029
 
4030
(define_insn "xorsi3_internal"
4031
  [(set (match_operand:SI 0 "nonimmediate_operand" "=do,m")
4032
        (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
4033
                (match_operand:SI 2 "general_operand" "di,dKT")))]
4034
 
4035
  "!TARGET_COLDFIRE"
4036
{
4037
  return output_xorsi3 (operands);
4038
})
4039
 
4040
(define_insn "xorsi3_5200"
4041
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,d")
4042
        (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
4043
                (match_operand:SI 2 "general_operand" "d,Ks")))]
4044
  "TARGET_COLDFIRE"
4045
{
4046
  return output_xorsi3 (operands);
4047
})
4048
 
4049
(define_insn "xorhi3"
4050
  [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
4051
        (xor:HI (match_operand:HI 1 "general_operand" "%0")
4052
                (match_operand:HI 2 "general_operand" "dn")))]
4053
  "!TARGET_COLDFIRE"
4054
  "eor%.w %2,%0")
4055
 
4056
(define_insn ""
4057
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
4058
        (xor:HI (match_dup 0)
4059
                (match_operand:HI 1 "general_operand" "dn")))]
4060
  "!TARGET_COLDFIRE"
4061
  "eor%.w %1,%0")
4062
 
4063
(define_insn ""
4064
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
4065
        (xor:HI (match_operand:HI 1 "general_operand" "dn")
4066
                (match_dup 0)))]
4067
  "!TARGET_COLDFIRE"
4068
  "eor%.w %1,%0")
4069
 
4070
(define_insn "xorqi3"
4071
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
4072
        (xor:QI (match_operand:QI 1 "general_operand" "%0")
4073
                (match_operand:QI 2 "general_operand" "dn")))]
4074
  "!TARGET_COLDFIRE"
4075
  "eor%.b %2,%0")
4076
 
4077
(define_insn ""
4078
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
4079
        (xor:QI (match_dup 0)
4080
                (match_operand:QI 1 "general_operand" "dn")))]
4081
  "!TARGET_COLDFIRE"
4082
  "eor%.b %1,%0")
4083
 
4084
(define_insn ""
4085
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
4086
        (xor:QI (match_operand:QI 1 "general_operand" "dn")
4087
                (match_dup 0)))]
4088
  "!TARGET_COLDFIRE"
4089
  "eor%.b %1,%0")
4090
 
4091
;; negation instructions
4092
 
4093
(define_expand "negdi2"
4094
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4095
        (neg:DI (match_operand:DI 1 "general_operand" "")))]
4096
  ""
4097
{
4098
  if (TARGET_COLDFIRE)
4099
    emit_insn (gen_negdi2_5200 (operands[0], operands[1]));
4100
  else
4101
    emit_insn (gen_negdi2_internal (operands[0], operands[1]));
4102
  DONE;
4103
})
4104
 
4105
(define_insn "negdi2_internal"
4106
  [(set (match_operand:DI 0 "nonimmediate_operand" "=<,do,!*a")
4107
        (neg:DI (match_operand:DI 1 "general_operand" "0,0,0")))]
4108
  "!TARGET_COLDFIRE"
4109
{
4110
  if (which_alternative == 0)
4111
    return "neg%.l %0\;negx%.l %0";
4112
  if (GET_CODE (operands[0]) == REG)
4113
    operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4114
  else
4115
    operands[1] = adjust_address (operands[0], SImode, 4);
4116
  if (ADDRESS_REG_P (operands[0]))
4117
    return "exg %/d0,%1\;neg%.l %/d0\;exg %/d0,%1\;exg %/d0,%0\;negx%.l %/d0\;exg %/d0,%0";
4118
  else
4119
    return "neg%.l %1\;negx%.l %0";
4120
})
4121
 
4122
(define_insn "negdi2_5200"
4123
  [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4124
        (neg:DI (match_operand:DI 1 "general_operand" "0")))]
4125
  "TARGET_COLDFIRE"
4126
{
4127
  operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4128
  return "neg%.l %1\;negx%.l %0";
4129
})
4130
 
4131
(define_expand "negsi2"
4132
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4133
        (neg:SI (match_operand:SI 1 "general_operand" "")))]
4134
  ""
4135
{
4136
  if (TARGET_COLDFIRE)
4137
    emit_insn (gen_negsi2_5200 (operands[0], operands[1]));
4138
  else
4139
    emit_insn (gen_negsi2_internal (operands[0], operands[1]));
4140
  DONE;
4141
})
4142
 
4143
(define_insn "negsi2_internal"
4144
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
4145
        (neg:SI (match_operand:SI 1 "general_operand" "0")))]
4146
  "!TARGET_COLDFIRE"
4147
  "neg%.l %0"
4148
  [(set_attr "type" "neg_l")])
4149
 
4150
(define_insn "negsi2_5200"
4151
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4152
        (neg:SI (match_operand:SI 1 "general_operand" "0")))]
4153
  "TARGET_COLDFIRE"
4154
  "neg%.l %0"
4155
  [(set_attr "type" "neg_l")])
4156
 
4157
(define_insn "neghi2"
4158
  [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
4159
        (neg:HI (match_operand:HI 1 "general_operand" "0")))]
4160
  "!TARGET_COLDFIRE"
4161
  "neg%.w %0")
4162
 
4163
(define_insn ""
4164
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
4165
        (neg:HI (match_dup 0)))]
4166
  "!TARGET_COLDFIRE"
4167
  "neg%.w %0")
4168
 
4169
(define_insn "negqi2"
4170
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
4171
        (neg:QI (match_operand:QI 1 "general_operand" "0")))]
4172
  "!TARGET_COLDFIRE"
4173
  "neg%.b %0")
4174
 
4175
(define_insn ""
4176
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
4177
        (neg:QI (match_dup 0)))]
4178
  "!TARGET_COLDFIRE"
4179
  "neg%.b %0")
4180
 
4181
;; If using software floating point, just flip the sign bit.
4182
 
4183
(define_expand "negsf2"
4184
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
4185
        (neg:SF (match_operand:SF 1 "general_operand" "")))]
4186
  ""
4187
{
4188
  if (!TARGET_HARD_FLOAT)
4189
    {
4190
      rtx result;
4191
      rtx target;
4192
 
4193
      target = operand_subword_force (operands[0], 0, SFmode);
4194
      result = expand_binop (SImode, xor_optab,
4195
                             operand_subword_force (operands[1], 0, SFmode),
4196
                             GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
4197
      gcc_assert (result);
4198
 
4199
      if (result != target)
4200
        emit_move_insn (result, target);
4201
 
4202
      /* Make a place for REG_EQUAL.  */
4203
      emit_move_insn (operands[0], operands[0]);
4204
      DONE;
4205
    }
4206
})
4207
 
4208
(define_expand "negdf2"
4209
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
4210
        (neg:DF (match_operand:DF 1 "general_operand" "")))]
4211
  ""
4212
{
4213
  if (!TARGET_HARD_FLOAT)
4214
    {
4215
      rtx result;
4216
      rtx target;
4217
      rtx insns;
4218
 
4219
      start_sequence ();
4220
      target = operand_subword (operands[0], 0, 1, DFmode);
4221
      result = expand_binop (SImode, xor_optab,
4222
                             operand_subword_force (operands[1], 0, DFmode),
4223
                             GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
4224
      gcc_assert (result);
4225
 
4226
      if (result != target)
4227
        emit_move_insn (result, target);
4228
 
4229
      emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
4230
                      operand_subword_force (operands[1], 1, DFmode));
4231
 
4232
      insns = get_insns ();
4233
      end_sequence ();
4234
 
4235
      emit_insn (insns);
4236
      DONE;
4237
    }
4238
})
4239
 
4240
(define_expand "negxf2"
4241
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
4242
        (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
4243
  ""
4244
{
4245
  if (!TARGET_68881)
4246
    {
4247
      rtx result;
4248
      rtx target;
4249
      rtx insns;
4250
 
4251
      start_sequence ();
4252
      target = operand_subword (operands[0], 0, 1, XFmode);
4253
      result = expand_binop (SImode, xor_optab,
4254
                             operand_subword_force (operands[1], 0, XFmode),
4255
                             GEN_INT (-2147483647 - 1), target, 0, OPTAB_WIDEN);
4256
      gcc_assert (result);
4257
 
4258
      if (result != target)
4259
        emit_move_insn (result, target);
4260
 
4261
      emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
4262
                      operand_subword_force (operands[1], 1, XFmode));
4263
      emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
4264
                      operand_subword_force (operands[1], 2, XFmode));
4265
 
4266
      insns = get_insns ();
4267
      end_sequence ();
4268
 
4269
      emit_insn (insns);
4270
      DONE;
4271
    }
4272
})
4273
 
4274
(define_insn "neg2_68881"
4275
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
4276
        (neg:FP (match_operand:FP 1 "general_operand" "fm,0")))]
4277
  "TARGET_68881"
4278
{
4279
  if (DATA_REG_P (operands[0]))
4280
    {
4281
      operands[1] = GEN_INT (31);
4282
      return "bchg %1,%0";
4283
    }
4284
  if (FP_REG_P (operands[1]))
4285
    return "fneg%.x %1,%0";
4286
  return "fneg%. %f1,%0";
4287
})
4288
 
4289
(define_insn "neg2_cf"
4290
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
4291
        (neg:FP (match_operand:FP 1 "general_operand" "fU,0")))]
4292
  "TARGET_COLDFIRE_FPU"
4293
{
4294
  if (DATA_REG_P (operands[0]))
4295
    {
4296
      operands[1] = GEN_INT (31);
4297
      return "bchg %1,%0";
4298
    }
4299
  if (FP_REG_P (operands[1]))
4300
    return "fneg%.d %1,%0";
4301
  return "fneg%. %1,%0";
4302
})
4303
 
4304
;; Sqrt instruction for the 68881
4305
 
4306
(define_expand "sqrt2"
4307
  [(set (match_operand:FP 0 "nonimmediate_operand" "")
4308
        (sqrt:FP (match_operand:FP 1 "general_operand" "")))]
4309
  "TARGET_HARD_FLOAT"
4310
  "")
4311
 
4312
(define_insn "sqrt2_68881"
4313
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
4314
        (sqrt:FP (match_operand:FP 1 "general_operand" "fm")))]
4315
  "TARGET_68881"
4316
{
4317
  if (FP_REG_P (operands[1]))
4318
    return "fsqrt%.x %1,%0";
4319
  return "fsqrt%. %1,%0";
4320
}
4321
  [(set_attr "type" "fsqrt")])
4322
 
4323
(define_insn "sqrt2_cf"
4324
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
4325
        (sqrt:FP (match_operand:FP 1 "general_operand" "fU")))]
4326
  "TARGET_COLDFIRE_FPU"
4327
{
4328
  if (FP_REG_P (operands[1]))
4329
    return "fsqrt%.d %1,%0";
4330
  return "fsqrt%. %1,%0";
4331
}
4332
  [(set_attr "type" "fsqrt")])
4333
;; Absolute value instructions
4334
;; If using software floating point, just zero the sign bit.
4335
 
4336
(define_expand "abssf2"
4337
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
4338
        (abs:SF (match_operand:SF 1 "general_operand" "")))]
4339
  ""
4340
{
4341
  if (!TARGET_HARD_FLOAT)
4342
    {
4343
      rtx result;
4344
      rtx target;
4345
 
4346
      target = operand_subword_force (operands[0], 0, SFmode);
4347
      result = expand_binop (SImode, and_optab,
4348
                             operand_subword_force (operands[1], 0, SFmode),
4349
                             GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
4350
      gcc_assert (result);
4351
 
4352
      if (result != target)
4353
        emit_move_insn (result, target);
4354
 
4355
      /* Make a place for REG_EQUAL.  */
4356
      emit_move_insn (operands[0], operands[0]);
4357
      DONE;
4358
    }
4359
})
4360
 
4361
(define_expand "absdf2"
4362
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
4363
        (abs:DF (match_operand:DF 1 "general_operand" "")))]
4364
  ""
4365
{
4366
  if (!TARGET_HARD_FLOAT)
4367
    {
4368
      rtx result;
4369
      rtx target;
4370
      rtx insns;
4371
 
4372
      start_sequence ();
4373
      target = operand_subword (operands[0], 0, 1, DFmode);
4374
      result = expand_binop (SImode, and_optab,
4375
                             operand_subword_force (operands[1], 0, DFmode),
4376
                             GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
4377
      gcc_assert (result);
4378
 
4379
      if (result != target)
4380
        emit_move_insn (result, target);
4381
 
4382
      emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
4383
                      operand_subword_force (operands[1], 1, DFmode));
4384
 
4385
      insns = get_insns ();
4386
      end_sequence ();
4387
 
4388
      emit_insn (insns);
4389
      DONE;
4390
    }
4391
})
4392
 
4393
(define_expand "absxf2"
4394
  [(set (match_operand:XF 0 "nonimmediate_operand" "")
4395
        (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
4396
  ""
4397
{
4398
  if (!TARGET_68881)
4399
    {
4400
      rtx result;
4401
      rtx target;
4402
      rtx insns;
4403
 
4404
      start_sequence ();
4405
      target = operand_subword (operands[0], 0, 1, XFmode);
4406
      result = expand_binop (SImode, and_optab,
4407
                             operand_subword_force (operands[1], 0, XFmode),
4408
                             GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
4409
      gcc_assert (result);
4410
 
4411
      if (result != target)
4412
        emit_move_insn (result, target);
4413
 
4414
      emit_move_insn (operand_subword (operands[0], 1, 1, XFmode),
4415
                      operand_subword_force (operands[1], 1, XFmode));
4416
      emit_move_insn (operand_subword (operands[0], 2, 1, XFmode),
4417
                      operand_subword_force (operands[1], 2, XFmode));
4418
 
4419
      insns = get_insns ();
4420
      end_sequence ();
4421
 
4422
      emit_insn (insns);
4423
      DONE;
4424
    }
4425
})
4426
 
4427
(define_insn "abs2_68881"
4428
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
4429
        (abs:FP (match_operand:FP 1 "general_operand" "fm,0")))]
4430
  "TARGET_68881"
4431
{
4432
  if (DATA_REG_P (operands[0]))
4433
    {
4434
      operands[1] = GEN_INT (31);
4435
      return "bclr %1,%0";
4436
    }
4437
  if (FP_REG_P (operands[1]))
4438
    return "fabs%.x %1,%0";
4439
  return "fabs%. %f1,%0";
4440
})
4441
 
4442
(define_insn "abs2_cf"
4443
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f,d")
4444
        (abs:FP (match_operand:FP 1 "general_operand" "fU,0")))]
4445
  "TARGET_COLDFIRE_FPU"
4446
{
4447
  if (DATA_REG_P (operands[0]))
4448
    {
4449
      operands[1] = GEN_INT (31);
4450
      return "bclr %1,%0";
4451
    }
4452
  if (FP_REG_P (operands[1]))
4453
    return "fabs%.d %1,%0";
4454
  return "fabs%. %1,%0";
4455
}
4456
  [(set_attr "type" "bitrw,fneg")])
4457
 
4458
;; bit indexing instructions
4459
 
4460
;; ColdFire ff1 instruction implements clz.
4461
(define_insn "clzsi2"
4462
  [(set (match_operand:SI 0 "register_operand" "=d")
4463
        (clz:SI (match_operand:SI 1 "register_operand" "0")))]
4464
  "ISA_HAS_FF1"
4465
  "ff1 %0"
4466
  [(set_attr "type" "ext")])
4467
 
4468
;; one complement instructions
4469
 
4470
;; "one_cmpldi2" is mainly here to help combine().
4471
(define_insn "one_cmpldi2"
4472
  [(set (match_operand:DI 0 "nonimmediate_operand" "=dm")
4473
        (not:DI (match_operand:DI 1 "general_operand" "0")))]
4474
  "!TARGET_COLDFIRE"
4475
{
4476
  CC_STATUS_INIT;
4477
  if (GET_CODE (operands[0]) == REG)
4478
    operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4479
  else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC
4480
        || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4481
    operands[1] = operands[0];
4482
  else
4483
    operands[1] = adjust_address (operands[0], SImode, 4);
4484
  return "not%.l %1\;not%.l %0";
4485
})
4486
 
4487
(define_expand "one_cmplsi2"
4488
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
4489
        (not:SI (match_operand:SI 1 "general_operand" "")))]
4490
  ""
4491
{
4492
  if (TARGET_COLDFIRE)
4493
    emit_insn (gen_one_cmplsi2_5200 (operands[0], operands[1]));
4494
  else
4495
    emit_insn (gen_one_cmplsi2_internal (operands[0], operands[1]));
4496
  DONE;
4497
})
4498
 
4499
(define_insn "one_cmplsi2_internal"
4500
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
4501
        (not:SI (match_operand:SI 1 "general_operand" "0")))]
4502
  "!TARGET_COLDFIRE"
4503
  "not%.l %0")
4504
 
4505
(define_insn "one_cmplsi2_5200"
4506
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4507
        (not:SI (match_operand:SI 1 "general_operand" "0")))]
4508
  "TARGET_COLDFIRE"
4509
  "not%.l %0"
4510
  [(set_attr "type" "neg_l")])
4511
 
4512
(define_insn "one_cmplhi2"
4513
  [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
4514
        (not:HI (match_operand:HI 1 "general_operand" "0")))]
4515
  "!TARGET_COLDFIRE"
4516
  "not%.w %0")
4517
 
4518
(define_insn ""
4519
  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
4520
        (not:HI (match_dup 0)))]
4521
  "!TARGET_COLDFIRE"
4522
  "not%.w %0")
4523
 
4524
(define_insn "one_cmplqi2"
4525
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
4526
        (not:QI (match_operand:QI 1 "general_operand" "0")))]
4527
  "!TARGET_COLDFIRE"
4528
  "not%.b %0")
4529
 
4530
(define_insn ""
4531
  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
4532
        (not:QI (match_dup 0)))]
4533
  "!TARGET_COLDFIRE"
4534
  "not%.b %0")
4535
 
4536
;; arithmetic shift instructions
4537
;; We don't need the shift memory by 1 bit instruction
4538
 
4539
(define_insn "ashldi_extsi"
4540
  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
4541
    (ashift:DI
4542
      (match_operator:DI 2 "extend_operator"
4543
        [(match_operand:SI 1 "general_operand" "rm")])
4544
      (const_int 32)))]
4545
  ""
4546
{
4547
  CC_STATUS_INIT;
4548
  if (GET_CODE (operands[0]) == REG)
4549
    operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4550
  else
4551
    operands[2] = adjust_address (operands[0], SImode, 4);
4552
  if (ADDRESS_REG_P (operands[0]))
4553
    return "move%.l %1,%0\;sub%.l %2,%2";
4554
  else
4555
    return "move%.l %1,%0\;clr%.l %2";
4556
})
4557
 
4558
(define_insn "ashldi_sexthi"
4559
  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,a*d")
4560
    (ashift:DI (sign_extend:DI (match_operand:HI 1 "general_operand" "rm,rm"))
4561
        (const_int 32)))
4562
    (clobber (match_scratch:SI 2 "=a,X"))]
4563
  ""
4564
{
4565
  CC_STATUS_INIT;
4566
  if (GET_CODE (operands[0]) == MEM)
4567
    {
4568
    if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4569
      return "clr%.l %0\;move%.w %1,%2\;move%.l %2,%0";
4570
    else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
4571
      return "move%.w %1,%2\;move%.l %2,%0\;clr%.l %0";
4572
    else
4573
      {
4574
        operands[3] = adjust_address (operands[0], SImode, 4);
4575
        return "move%.w %1,%2\;move%.l %2,%0\;clr%.l %3";
4576
      }
4577
    }
4578
  else if (DATA_REG_P (operands[0]))
4579
    return "move%.w %1,%0\;ext%.l %0\;clr%.l %R0";
4580
  else
4581
    return "move%.w %1,%0\;sub%.l %R0,%R0";
4582
})
4583
 
4584
(define_insn "*ashldi3_const1"
4585
  [(set (match_operand:DI 0 "register_operand" "=d")
4586
        (ashift:DI (match_operand:DI 1 "register_operand" "0")
4587
                   (const_int 1)))]
4588
  "!TARGET_COLDFIRE"
4589
  "add%.l %R0,%R0\;addx%.l %0,%0")
4590
 
4591
(define_split
4592
  [(set (match_operand:DI 0 "register_operand" "")
4593
        (ashift:DI (match_operand:DI 1 "register_operand" "")
4594
                   (const_int 2)))]
4595
  "reload_completed && !TARGET_COLDFIRE"
4596
  [(set (match_dup 0)
4597
        (ashift:DI (match_dup 1) (const_int 1)))
4598
   (set (match_dup 0)
4599
        (ashift:DI (match_dup 0) (const_int 1)))]
4600
  "")
4601
 
4602
(define_split
4603
  [(set (match_operand:DI 0 "register_operand" "")
4604
        (ashift:DI (match_operand:DI 1 "register_operand" "")
4605
                   (const_int 3)))]
4606
  "reload_completed && !TARGET_COLDFIRE"
4607
  [(set (match_dup 0)
4608
        (ashift:DI (match_dup 1) (const_int 2)))
4609
   (set (match_dup 0)
4610
        (ashift:DI (match_dup 0) (const_int 1)))]
4611
  "")
4612
 
4613
(define_split
4614
  [(set (match_operand:DI 0 "register_operand" "")
4615
        (ashift:DI (match_operand:DI 1 "register_operand" "")
4616
                   (const_int 8)))]
4617
  "reload_completed && !TARGET_COLDFIRE"
4618
  [(set (match_dup 2)
4619
        (rotate:SI (match_dup 2) (const_int 8)))
4620
   (set (match_dup 3)
4621
        (rotate:SI (match_dup 3) (const_int 8)))
4622
   (set (strict_low_part (subreg:QI (match_dup 0) 3))
4623
        (subreg:QI (match_dup 0) 7))
4624
   (set (strict_low_part (subreg:QI (match_dup 0) 7))
4625
        (const_int 0))]
4626
{
4627
  operands[2] = gen_highpart (SImode, operands[0]);
4628
  operands[3] = gen_lowpart (SImode, operands[0]);
4629
})
4630
 
4631
(define_split
4632
  [(set (match_operand:DI 0 "register_operand" "")
4633
        (ashift:DI (match_operand:DI 1 "register_operand" "")
4634
                   (const_int 16)))]
4635
  "reload_completed && !TARGET_COLDFIRE"
4636
  [(set (match_dup 2)
4637
        (rotate:SI (match_dup 2) (const_int 16)))
4638
   (set (match_dup 3)
4639
        (rotate:SI (match_dup 3) (const_int 16)))
4640
   (set (strict_low_part (subreg:HI (match_dup 0) 2))
4641
        (subreg:HI (match_dup 0) 6))
4642
   (set (strict_low_part (subreg:HI (match_dup 0) 6))
4643
        (const_int 0))]
4644
{
4645
  operands[2] = gen_highpart (SImode, operands[0]);
4646
  operands[3] = gen_lowpart (SImode, operands[0]);
4647
})
4648
 
4649
(define_split
4650
  [(set (match_operand:DI 0 "pre_dec_operand" "")
4651
        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "")
4652
                   (const_int 32)))]
4653
  "reload_completed"
4654
  [(set (match_dup 0) (const_int 0))
4655
   (set (match_dup 0) (match_dup 1))]
4656
{
4657
  operands[0] = adjust_address(operands[0], SImode, 0);
4658
  operands[1] = gen_lowpart(SImode, operands[1]);
4659
})
4660
 
4661
(define_split
4662
  [(set (match_operand:DI 0 "post_inc_operand" "")
4663
        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "")
4664
                   (const_int 32)))]
4665
  "reload_completed"
4666
  [(set (match_dup 0) (match_dup 1))
4667
   (set (match_dup 0) (const_int 0))]
4668
{
4669
  operands[0] = adjust_address(operands[0], SImode, 0);
4670
  operands[1] = gen_lowpart(SImode, operands[1]);
4671
})
4672
 
4673
(define_insn_and_split "*ashldi3_const32"
4674
  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro<>")
4675
        (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro")
4676
                   (const_int 32)))]
4677
  ""
4678
  "#"
4679
  "&& reload_completed"
4680
  [(set (match_dup 4) (match_dup 3))
4681
   (set (match_dup 2) (const_int 0))]
4682
  "split_di(operands, 2, operands + 2, operands + 4);")
4683
 
4684
(define_split
4685
  [(set (match_operand:DI 0 "register_operand" "")
4686
        (ashift:DI (match_operand:DI 1 "register_operand" "")
4687
                   (match_operand 2 "const_int_operand" "")))]
4688
  "reload_completed && !TARGET_COLDFIRE
4689
   && INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 40"
4690
  [(set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 2)))
4691
   (set (match_dup 3) (match_dup 4))
4692
   (set (match_dup 4) (const_int 0))]
4693
{
4694
  operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
4695
  operands[3] = gen_highpart (SImode, operands[0]);
4696
  operands[4] = gen_lowpart (SImode, operands[0]);
4697
})
4698
 
4699
(define_split
4700
  [(set (match_operand:DI 0 "register_operand" "")
4701
        (ashift:DI (match_operand:DI 1 "register_operand" "")
4702
                   (const_int 48)))]
4703
  "reload_completed && !TARGET_COLDFIRE"
4704
  [(set (match_dup 2) (match_dup 3))
4705
   (set (match_dup 2)
4706
        (rotate:SI (match_dup 2) (const_int 16)))
4707
   (set (match_dup 3) (const_int 0))
4708
   (set (strict_low_part (subreg:HI (match_dup 0) 2))
4709
        (const_int 0))]
4710
{
4711
  operands[2] = gen_highpart (SImode, operands[0]);
4712
  operands[3] = gen_lowpart (SImode, operands[0]);
4713
})
4714
 
4715
(define_split
4716
  [(set (match_operand:DI 0 "register_operand" "")
4717
        (ashift:DI (match_operand:DI 1 "register_operand" "")
4718
                   (match_operand 2 "const_int_operand" "")))]
4719
  "reload_completed && !TARGET_COLDFIRE
4720
   && INTVAL (operands[2]) > 40 && INTVAL (operands[2]) <= 63"
4721
  [(set (match_dup 3) (match_dup 2))
4722
   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
4723
   (set (match_dup 3) (match_dup 4))
4724
   (set (match_dup 4) (const_int 0))]
4725
{
4726
  operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
4727
  operands[3] = gen_highpart (SImode, operands[0]);
4728
  operands[4] = gen_lowpart (SImode, operands[0]);
4729
})
4730
 
4731
(define_insn "*ashldi3"
4732
  [(set (match_operand:DI 0 "register_operand" "=d")
4733
        (ashift:DI (match_operand:DI 1 "register_operand" "0")
4734
                   (match_operand 2 "const_int_operand" "n")))]
4735
  "!TARGET_COLDFIRE
4736
    && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4737
        || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4738
        || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))"
4739
  "#")
4740
 
4741
(define_expand "ashldi3"
4742
  [(set (match_operand:DI 0 "register_operand" "")
4743
        (ashift:DI (match_operand:DI 1 "register_operand" "")
4744
                   (match_operand 2 "const_int_operand" "")))]
4745
  "!TARGET_COLDFIRE"
4746
{
4747
  /* ???  This is a named pattern like this is not allowed to FAIL based
4748
     on its operands.  */
4749
  if (GET_CODE (operands[2]) != CONST_INT
4750
      || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
4751
          && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
4752
          && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
4753
    FAIL;
4754
})
4755
 
4756
;; On most 68k models, this makes faster code in a special case.
4757
 
4758
(define_insn "ashlsi_16"
4759
  [(set (match_operand:SI 0 "register_operand" "=d")
4760
        (ashift:SI (match_operand:SI 1 "register_operand" "0")
4761
                   (const_int 16)))]
4762
  "!TUNE_68060"
4763
{
4764
  CC_STATUS_INIT;
4765
  return "swap %0\;clr%.w %0";
4766
})
4767
 
4768
;; ashift patterns : use lsl instead of asl, because lsl always clears the
4769
;; overflow bit, so we must not set CC_NO_OVERFLOW.
4770
 
4771
;; On the 68000, this makes faster code in a special case.
4772
 
4773
(define_insn "ashlsi_17_24"
4774
  [(set (match_operand:SI 0 "register_operand" "=d")
4775
        (ashift:SI (match_operand:SI 1 "register_operand" "0")
4776
                   (match_operand:SI 2 "const_int_operand" "n")))]
4777
  "TUNE_68000_10
4778
   && INTVAL (operands[2]) > 16
4779
   && INTVAL (operands[2]) <= 24"
4780
{
4781
  CC_STATUS_INIT;
4782
 
4783
  operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
4784
  return "lsl%.w %2,%0\;swap %0\;clr%.w %0";
4785
})
4786
 
4787
(define_insn "ashlsi3"
4788
  [(set (match_operand:SI 0 "register_operand" "=d")
4789
        (ashift:SI (match_operand:SI 1 "register_operand" "0")
4790
                   (match_operand:SI 2 "general_operand" "dI")))]
4791
  ""
4792
{
4793
  if (operands[2] == const1_rtx)
4794
    {
4795
      cc_status.flags = CC_NO_OVERFLOW;
4796
      return "add%.l %0,%0";
4797
    }
4798
  return "lsl%.l %2,%0";
4799
})
4800
 
4801
(define_insn "ashlhi3"
4802
  [(set (match_operand:HI 0 "register_operand" "=d")
4803
        (ashift:HI (match_operand:HI 1 "register_operand" "0")
4804
                   (match_operand:HI 2 "general_operand" "dI")))]
4805
  "!TARGET_COLDFIRE"
4806
  "lsl%.w %2,%0")
4807
 
4808
(define_insn ""
4809
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
4810
        (ashift:HI (match_dup 0)
4811
                   (match_operand:HI 1 "general_operand" "dI")))]
4812
  "!TARGET_COLDFIRE"
4813
  "lsl%.w %1,%0")
4814
 
4815
(define_insn "ashlqi3"
4816
  [(set (match_operand:QI 0 "register_operand" "=d")
4817
        (ashift:QI (match_operand:QI 1 "register_operand" "0")
4818
                   (match_operand:QI 2 "general_operand" "dI")))]
4819
  "!TARGET_COLDFIRE"
4820
  "lsl%.b %2,%0")
4821
 
4822
(define_insn ""
4823
  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
4824
        (ashift:QI (match_dup 0)
4825
                   (match_operand:QI 1 "general_operand" "dI")))]
4826
  "!TARGET_COLDFIRE"
4827
  "lsl%.b %1,%0")
4828
 
4829
;; On most 68k models, this makes faster code in a special case.
4830
 
4831
(define_insn "ashrsi_16"
4832
  [(set (match_operand:SI 0 "register_operand" "=d")
4833
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4834
                     (const_int 16)))]
4835
  "!TUNE_68060"
4836
  "swap %0\;ext%.l %0")
4837
 
4838
;; On the 68000, this makes faster code in a special case.
4839
 
4840
(define_insn ""
4841
  [(set (match_operand:SI 0 "register_operand" "=d")
4842
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
4843
                     (match_operand:SI 2 "const_int_operand" "n")))]
4844
  "TUNE_68000_10
4845
   && INTVAL (operands[2]) > 16
4846
   && INTVAL (operands[2]) <= 24"
4847
{
4848
  operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
4849
  return "swap %0\;asr%.w %2,%0\;ext%.l %0";
4850
})
4851
 
4852
(define_insn "subreghi1ashrdi_const32"
4853
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
4854
    (subreg:HI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4855
            (const_int 32)) 6))]
4856
  ""
4857
{
4858
  if (GET_CODE (operands[1]) != REG)
4859
    operands[1] = adjust_address (operands[1], HImode, 2);
4860
  return "move%.w %1,%0";
4861
}
4862
  [(set_attr "type" "move")])
4863
 
4864
(define_insn "subregsi1ashrdi_const32"
4865
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
4866
    (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro")
4867
            (const_int 32)) 4))]
4868
  ""
4869
{
4870
  return "move%.l %1,%0";
4871
}
4872
  [(set_attr "type" "move_l")])
4873
 
4874
(define_insn "*ashrdi3_const1"
4875
  [(set (match_operand:DI 0 "register_operand" "=d")
4876
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
4877
                     (const_int 1)))]
4878
  "!TARGET_COLDFIRE"
4879
{
4880
  operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4881
  return "asr%.l #1,%0\;roxr%.l #1,%1";
4882
})
4883
 
4884
(define_split
4885
  [(set (match_operand:DI 0 "register_operand" "")
4886
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4887
                     (const_int 2)))]
4888
  "reload_completed && !TARGET_COLDFIRE"
4889
  [(set (match_dup 0)
4890
        (ashiftrt:DI (match_dup 1) (const_int 1)))
4891
   (set (match_dup 0)
4892
        (ashiftrt:DI (match_dup 0) (const_int 1)))]
4893
  "")
4894
 
4895
(define_split
4896
  [(set (match_operand:DI 0 "register_operand" "")
4897
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4898
                     (const_int 3)))]
4899
  "reload_completed && !TARGET_COLDFIRE"
4900
  [(set (match_dup 0)
4901
        (ashiftrt:DI (match_dup 1) (const_int 2)))
4902
   (set (match_dup 0)
4903
        (ashiftrt:DI (match_dup 0) (const_int 1)))]
4904
  "")
4905
 
4906
(define_split
4907
  [(set (match_operand:DI 0 "register_operand" "")
4908
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4909
                     (const_int 8)))]
4910
  "reload_completed && !TARGET_COLDFIRE"
4911
  [(set (strict_low_part (subreg:QI (match_dup 0) 7))
4912
        (subreg:QI (match_dup 0) 3))
4913
   (set (match_dup 2)
4914
        (ashiftrt:SI (match_dup 2) (const_int 8)))
4915
   (set (match_dup 3)
4916
        (rotatert:SI (match_dup 3) (const_int 8)))]
4917
{
4918
  operands[2] = gen_highpart (SImode, operands[0]);
4919
  operands[3] = gen_lowpart (SImode, operands[0]);
4920
})
4921
 
4922
(define_split
4923
  [(set (match_operand:DI 0 "register_operand" "")
4924
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4925
                     (const_int 16)))]
4926
  "reload_completed && !TARGET_COLDFIRE"
4927
  [(set (strict_low_part (subreg:HI (match_dup 0) 6))
4928
        (subreg:HI (match_dup 0) 2))
4929
   (set (match_dup 2)
4930
        (rotate:SI (match_dup 2) (const_int 16)))
4931
   (set (match_dup 3)
4932
        (rotate:SI (match_dup 3) (const_int 16)))
4933
   (set (match_dup 2)
4934
        (sign_extend:SI (subreg:HI (match_dup 2) 2)))]
4935
{
4936
  operands[2] = gen_highpart (SImode, operands[0]);
4937
  operands[3] = gen_lowpart (SImode, operands[0]);
4938
})
4939
 
4940
(define_insn "*ashrdi_const32"
4941
  [(set (match_operand:DI 0 "register_operand" "=d")
4942
        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_src_operand" "ro")
4943
                     (const_int 32)))]
4944
  ""
4945
{
4946
  CC_STATUS_INIT;
4947
  if (TARGET_68020)
4948
    return "move%.l %1,%R0\;smi %0\;extb%.l %0";
4949
  else
4950
    return "move%.l %1,%R0\;smi %0\;ext%.w %0\;ext%.l %0";
4951
})
4952
 
4953
(define_insn "*ashrdi_const32_mem"
4954
  [(set (match_operand:DI 0 "memory_operand" "=o,<")
4955
        (ashiftrt:DI (match_operand:DI 1 "nonimmediate_src_operand" "ro,ro")
4956
                     (const_int 32)))
4957
   (clobber (match_scratch:SI 2 "=d,d"))]
4958
  ""
4959
{
4960
  CC_STATUS_INIT;
4961
  operands[3] = adjust_address (operands[0], SImode,
4962
                                which_alternative == 0 ? 4 : 0);
4963
  operands[0] = adjust_address (operands[0], SImode, 0);
4964
  if (TARGET_68020 || TARGET_COLDFIRE)
4965
    return "move%.l %1,%3\;smi %2\;extb%.l %2\;move%.l %2,%0";
4966
  else
4967
    return "move%.l %1,%3\;smi %2\;ext%.w %2\;ext%.l %2\;move%.l %2,%0";
4968
})
4969
 
4970
(define_split
4971
  [(set (match_operand:DI 0 "register_operand" "")
4972
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
4973
                     (const_int 63)))]
4974
  "reload_completed && !TARGET_COLDFIRE"
4975
  [(set (match_dup 3)
4976
        (ashiftrt:SI (match_dup 3) (const_int 31)))
4977
   (set (match_dup 2)
4978
        (match_dup 3))]
4979
  "split_di(operands, 1, operands + 2, operands + 3);")
4980
 
4981
;; The predicate below must be general_operand, because ashrdi3 allows that
4982
(define_insn "ashrdi_const"
4983
  [(set (match_operand:DI 0 "register_operand" "=d")
4984
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
4985
                     (match_operand 2 "const_int_operand" "n")))]
4986
  "!TARGET_COLDFIRE
4987
    && ((INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3)
4988
        || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
4989
        || INTVAL (operands[2]) == 31
4990
        || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))"
4991
{
4992
  operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
4993
  CC_STATUS_INIT;
4994
  if (INTVAL (operands[2]) == 48)
4995
    return "swap %0\;ext%.l %0\;move%.l %0,%1\;smi %0\;ext%.w %0";
4996
  if (INTVAL (operands[2]) == 31)
4997
    return "add%.l %1,%1\;addx%.l %0,%0\;move%.l %0,%1\;subx%.l %0,%0";
4998
  if (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)
4999
    {
5000
      operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5001
      output_asm_insn (INTVAL (operands[2]) <= 8 ? "asr%.l %2,%0" :
5002
                        "moveq %2,%1\;asr%.l %1,%0", operands);
5003
      output_asm_insn ("mov%.l %0,%1\;smi %0", operands);
5004
      return INTVAL (operands[2]) >= 15 ? "ext%.w %d0" :
5005
             TARGET_68020 ? "extb%.l %0" : "ext%.w %0\;ext%.l %0";
5006
    }
5007
  return "#";
5008
})
5009
 
5010
(define_expand "ashrdi3"
5011
  [(set (match_operand:DI 0 "register_operand" "")
5012
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5013
                     (match_operand 2 "const_int_operand" "")))]
5014
  "!TARGET_COLDFIRE"
5015
{
5016
  /* ???  This is a named pattern like this is not allowed to FAIL based
5017
     on its operands.  */
5018
  if (GET_CODE (operands[2]) != CONST_INT
5019
      || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
5020
          && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
5021
          && (INTVAL (operands[2]) < 31 || INTVAL (operands[2]) > 63)))
5022
    FAIL;
5023
})
5024
 
5025
;; On all 68k models, this makes faster code in a special case.
5026
 
5027
(define_insn "ashrsi_31"
5028
  [(set (match_operand:SI 0 "register_operand" "=d")
5029
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
5030
                     (const_int 31)))]
5031
  ""
5032
{
5033
  return "add%.l %0,%0\;subx%.l %0,%0";
5034
})
5035
 
5036
(define_insn "ashrsi3"
5037
  [(set (match_operand:SI 0 "register_operand" "=d")
5038
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
5039
                     (match_operand:SI 2 "general_operand" "dI")))]
5040
  ""
5041
  "asr%.l %2,%0"
5042
  [(set_attr "type" "shift")
5043
   (set_attr "opy" "2")])
5044
 
5045
(define_insn "ashrhi3"
5046
  [(set (match_operand:HI 0 "register_operand" "=d")
5047
        (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
5048
                     (match_operand:HI 2 "general_operand" "dI")))]
5049
  "!TARGET_COLDFIRE"
5050
  "asr%.w %2,%0")
5051
 
5052
(define_insn ""
5053
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
5054
        (ashiftrt:HI (match_dup 0)
5055
                     (match_operand:HI 1 "general_operand" "dI")))]
5056
  "!TARGET_COLDFIRE"
5057
  "asr%.w %1,%0")
5058
 
5059
(define_insn "ashrqi3"
5060
  [(set (match_operand:QI 0 "register_operand" "=d")
5061
        (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
5062
                     (match_operand:QI 2 "general_operand" "dI")))]
5063
  "!TARGET_COLDFIRE"
5064
  "asr%.b %2,%0")
5065
 
5066
(define_insn ""
5067
  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
5068
        (ashiftrt:QI (match_dup 0)
5069
                     (match_operand:QI 1 "general_operand" "dI")))]
5070
  "!TARGET_COLDFIRE"
5071
  "asr%.b %1,%0")
5072
 
5073
;; logical shift instructions
5074
 
5075
;; commented out because of reload problems in 950612-1.c
5076
;;(define_insn ""
5077
;;        [(set (cc0)
5078
;;            (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
5079
;;                    (const_int 32)) 4))
5080
;;        (set (match_operand:SI 1 "nonimmediate_operand" "=dm")
5081
;;            (subreg:SI (lshiftrt:DI (match_dup 0)
5082
;;                    (const_int 32)) 4))]
5083
;;  ""
5084
;;{
5085
;;  return "move%.l %0,%1";
5086
;;})
5087
;;
5088
;;(define_insn ""
5089
;;        [(set (cc0)
5090
;;            (subreg:SI (lshiftrt:DI (match_operand:DI 0 "general_operand" "ro")
5091
;;                    (const_int 32)) 0))
5092
;;        (set (match_operand:DI 1 "nonimmediate_operand" "=do")
5093
;;            (lshiftrt:DI (match_dup 0)
5094
;;                (const_int 32)))]
5095
;;  ""
5096
;;{
5097
;;  if (GET_CODE (operands[1]) == REG)
5098
;;    operands[2] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
5099
;;  else
5100
;;    operands[2] = adjust_address (operands[1], SImode, 4);
5101
;;  return "move%.l %0,%2\;clr%.l %1";
5102
;;})
5103
 
5104
(define_insn "subreg1lshrdi_const32"
5105
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5106
    (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
5107
            (const_int 32)) 4))]
5108
  ""
5109
  "move%.l %1,%0"
5110
  [(set_attr "type" "move_l")])
5111
 
5112
(define_insn "*lshrdi3_const1"
5113
  [(set (match_operand:DI 0 "register_operand" "=d")
5114
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5115
                     (const_int 1)))]
5116
  "!TARGET_COLDFIRE"
5117
  "lsr%.l #1,%0\;roxr%.l #1,%R0")
5118
 
5119
(define_split
5120
  [(set (match_operand:DI 0 "register_operand" "")
5121
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5122
                     (const_int 2)))]
5123
  "reload_completed && !TARGET_COLDFIRE"
5124
  [(set (match_dup 0)
5125
        (lshiftrt:DI (match_dup 1) (const_int 1)))
5126
   (set (match_dup 0)
5127
        (lshiftrt:DI (match_dup 0) (const_int 1)))]
5128
  "")
5129
 
5130
(define_split
5131
  [(set (match_operand:DI 0 "register_operand" "")
5132
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5133
                     (const_int 3)))]
5134
  "reload_completed && !TARGET_COLDFIRE"
5135
  [(set (match_dup 0)
5136
        (lshiftrt:DI (match_dup 1) (const_int 2)))
5137
   (set (match_dup 0)
5138
        (lshiftrt:DI (match_dup 0) (const_int 1)))]
5139
  "")
5140
 
5141
(define_split
5142
  [(set (match_operand:DI 0 "register_operand" "")
5143
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5144
                     (const_int 8)))]
5145
  "reload_completed && !TARGET_COLDFIRE"
5146
  [(set (strict_low_part (subreg:QI (match_dup 0) 7))
5147
        (subreg:QI (match_dup 0) 3))
5148
   (set (match_dup 2)
5149
        (lshiftrt:SI (match_dup 2) (const_int 8)))
5150
   (set (match_dup 3)
5151
        (rotatert:SI (match_dup 3) (const_int 8)))]
5152
{
5153
  operands[2] = gen_highpart (SImode, operands[0]);
5154
  operands[3] = gen_lowpart (SImode, operands[0]);
5155
})
5156
 
5157
(define_split
5158
  [(set (match_operand:DI 0 "register_operand" "")
5159
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5160
                     (const_int 16)))]
5161
  "reload_completed && !TARGET_COLDFIRE"
5162
  [(set (strict_low_part (subreg:HI (match_dup 0) 6))
5163
        (subreg:HI (match_dup 0) 2))
5164
   (set (strict_low_part (subreg:HI (match_dup 0) 2))
5165
        (const_int 0))
5166
   (set (match_dup 3)
5167
        (rotate:SI (match_dup 3) (const_int 16)))
5168
   (set (match_dup 2)
5169
        (rotate:SI (match_dup 2) (const_int 16)))]
5170
{
5171
  operands[2] = gen_highpart (SImode, operands[0]);
5172
  operands[3] = gen_lowpart (SImode, operands[0]);
5173
})
5174
 
5175
(define_split
5176
  [(set (match_operand:DI 0 "pre_dec_operand" "")
5177
        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "")
5178
                     (const_int 32)))]
5179
  "reload_completed"
5180
  [(set (match_dup 0) (match_dup 1))
5181
   (set (match_dup 0) (const_int 0))]
5182
{
5183
  operands[0] = adjust_address(operands[0], SImode, 0);
5184
  operands[1] = gen_highpart(SImode, operands[1]);
5185
})
5186
 
5187
(define_split
5188
  [(set (match_operand:DI 0 "post_inc_operand" "")
5189
        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "")
5190
                     (const_int 32)))]
5191
  "reload_completed"
5192
  [(set (match_dup 0) (const_int 0))
5193
   (set (match_dup 0) (match_dup 1))]
5194
{
5195
  operands[0] = adjust_address(operands[0], SImode, 0);
5196
  operands[1] = gen_highpart(SImode, operands[1]);
5197
})
5198
 
5199
(define_split
5200
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5201
        (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "")
5202
                     (const_int 32)))]
5203
  "reload_completed"
5204
  [(set (match_dup 2) (match_dup 5))
5205
   (set (match_dup 4) (const_int 0))]
5206
  "split_di(operands, 2, operands + 2, operands + 4);")
5207
 
5208
(define_insn "*lshrdi_const32"
5209
  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro<>")
5210
        (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro")
5211
                     (const_int 32)))]
5212
  ""
5213
  "#")
5214
 
5215
(define_split
5216
  [(set (match_operand:DI 0 "register_operand" "")
5217
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5218
                     (match_operand 2 "const_int_operand" "")))]
5219
  "reload_completed && !TARGET_COLDFIRE
5220
   && INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 40"
5221
  [(set (match_dup 3) (lshiftrt:SI (match_dup 3) (match_dup 2)))
5222
   (set (match_dup 4) (match_dup 3))
5223
   (set (match_dup 3) (const_int 0))]
5224
{
5225
  operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5226
  operands[3] = gen_highpart (SImode, operands[0]);
5227
  operands[4] = gen_lowpart (SImode, operands[0]);
5228
})
5229
 
5230
(define_split
5231
  [(set (match_operand:DI 0 "register_operand" "")
5232
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5233
                     (const_int 48)))]
5234
  "reload_completed"
5235
  [(set (match_dup 3) (match_dup 2))
5236
   (set (strict_low_part (subreg:HI (match_dup 0) 6))
5237
        (const_int 0))
5238
   (set (match_dup 2) (const_int 0))
5239
   (set (match_dup 3)
5240
        (rotate:SI (match_dup 3) (const_int 16)))]
5241
{
5242
  operands[2] = gen_highpart (SImode, operands[0]);
5243
  operands[3] = gen_lowpart (SImode, operands[0]);
5244
})
5245
 
5246
(define_split
5247
  [(set (match_operand:DI 0 "register_operand" "")
5248
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5249
                     (match_operand 2 "const_int_operand" "")))]
5250
  "reload_completed && !TARGET_COLDFIRE
5251
   && INTVAL (operands[2]) > 40 && INTVAL (operands[2]) <= 62"
5252
  [(set (match_dup 4) (match_dup 2))
5253
   (set (match_dup 3) (lshiftrt:SI (match_dup 3) (match_dup 4)))
5254
   (set (match_dup 4) (match_dup 3))
5255
   (set (match_dup 3) (const_int 0))]
5256
{
5257
  operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5258
  operands[3] = gen_highpart (SImode, operands[0]);
5259
  operands[4] = gen_lowpart (SImode, operands[0]);
5260
})
5261
 
5262
(define_insn "*lshrdi_const63"
5263
  [(set (match_operand:DI 0 "register_operand" "=d")
5264
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5265
                     (const_int 63)))]
5266
  ""
5267
  "add%.l %0,%0\;clr%.l %0\;clr%.l %R1\;addx%.l %R1,%R1")
5268
 
5269
(define_insn "*lshrdi3_const"
5270
  [(set (match_operand:DI 0 "register_operand" "=d")
5271
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
5272
                     (match_operand 2 "const_int_operand" "n")))]
5273
  "(!TARGET_COLDFIRE
5274
    && ((INTVAL (operands[2]) >= 2 && INTVAL (operands[2]) <= 3)
5275
         || INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16
5276
         || (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63)))"
5277
  "#")
5278
 
5279
(define_expand "lshrdi3"
5280
  [(set (match_operand:DI 0 "register_operand" "")
5281
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5282
                     (match_operand 2 "const_int_operand" "")))]
5283
  "!TARGET_COLDFIRE"
5284
{
5285
  /* ???  This is a named pattern like this is not allowed to FAIL based
5286
     on its operands.  */
5287
  if (GET_CODE (operands[2]) != CONST_INT
5288
      || ((INTVAL (operands[2]) < 1 || INTVAL (operands[2]) > 3)
5289
          && INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16
5290
          && (INTVAL (operands[2]) < 32 || INTVAL (operands[2]) > 63)))
5291
    FAIL;
5292
})
5293
 
5294
;; On all 68k models, this makes faster code in a special case.
5295
 
5296
(define_insn "lshrsi_31"
5297
  [(set (match_operand:SI 0 "register_operand" "=d")
5298
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
5299
                     (const_int 31)))]
5300
  ""
5301
{
5302
  return "add%.l %0,%0\;subx%.l %0,%0\;neg%.l %0";
5303
})
5304
 
5305
;; On most 68k models, this makes faster code in a special case.
5306
 
5307
(define_insn "lshrsi_16"
5308
  [(set (match_operand:SI 0 "register_operand" "=d")
5309
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
5310
                     (const_int 16)))]
5311
  "!TUNE_68060"
5312
{
5313
  CC_STATUS_INIT;
5314
  return "clr%.w %0\;swap %0";
5315
})
5316
 
5317
;; On the 68000, this makes faster code in a special case.
5318
 
5319
(define_insn "lshrsi_17_24"
5320
  [(set (match_operand:SI 0 "register_operand" "=d")
5321
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
5322
                     (match_operand:SI 2 "const_int_operand" "n")))]
5323
  "TUNE_68000_10
5324
   && INTVAL (operands[2]) > 16
5325
   && INTVAL (operands[2]) <= 24"
5326
{
5327
  /* I think lsr%.w sets the CC properly.  */
5328
  operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
5329
  return "clr%.w %0\;swap %0\;lsr%.w %2,%0";
5330
})
5331
 
5332
(define_insn "lshrsi3"
5333
  [(set (match_operand:SI 0 "register_operand" "=d")
5334
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
5335
                     (match_operand:SI 2 "general_operand" "dI")))]
5336
  ""
5337
  "lsr%.l %2,%0"
5338
  [(set_attr "type" "shift")
5339
   (set_attr "opy" "2")])
5340
 
5341
(define_insn "lshrhi3"
5342
  [(set (match_operand:HI 0 "register_operand" "=d")
5343
        (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
5344
                     (match_operand:HI 2 "general_operand" "dI")))]
5345
  "!TARGET_COLDFIRE"
5346
  "lsr%.w %2,%0")
5347
 
5348
(define_insn ""
5349
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
5350
        (lshiftrt:HI (match_dup 0)
5351
                     (match_operand:HI 1 "general_operand" "dI")))]
5352
  "!TARGET_COLDFIRE"
5353
  "lsr%.w %1,%0")
5354
 
5355
(define_insn "lshrqi3"
5356
  [(set (match_operand:QI 0 "register_operand" "=d")
5357
        (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
5358
                     (match_operand:QI 2 "general_operand" "dI")))]
5359
  "!TARGET_COLDFIRE"
5360
  "lsr%.b %2,%0")
5361
 
5362
(define_insn ""
5363
  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
5364
        (lshiftrt:QI (match_dup 0)
5365
                     (match_operand:QI 1 "general_operand" "dI")))]
5366
  "!TARGET_COLDFIRE"
5367
  "lsr%.b %1,%0")
5368
 
5369
;; rotate instructions
5370
 
5371
(define_insn "rotlsi_16"
5372
  [(set (match_operand:SI 0 "register_operand" "=d")
5373
        (rotate:SI (match_operand:SI 1 "register_operand" "0")
5374
                   (const_int 16)))]
5375
  ""
5376
  "swap %0"
5377
  [(set_attr "type" "shift")])
5378
 
5379
(define_insn "rotlsi3"
5380
  [(set (match_operand:SI 0 "register_operand" "=d")
5381
        (rotate:SI (match_operand:SI 1 "register_operand" "0")
5382
                   (match_operand:SI 2 "general_operand" "dINO")))]
5383
  "!TARGET_COLDFIRE"
5384
{
5385
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)
5386
    return "swap %0";
5387
  else if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 16)
5388
    {
5389
      operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5390
      return "ror%.l %2,%0";
5391
    }
5392
  else
5393
    return "rol%.l %2,%0";
5394
})
5395
 
5396
(define_insn "rotlhi3"
5397
  [(set (match_operand:HI 0 "register_operand" "=d")
5398
        (rotate:HI (match_operand:HI 1 "register_operand" "0")
5399
                   (match_operand:HI 2 "general_operand" "dIP")))]
5400
  "!TARGET_COLDFIRE"
5401
{
5402
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
5403
    {
5404
      operands[2] = GEN_INT (16 - INTVAL (operands[2]));
5405
      return "ror%.w %2,%0";
5406
    }
5407
  else
5408
    return "rol%.w %2,%0";
5409
})
5410
 
5411
(define_insn ""
5412
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
5413
        (rotate:HI (match_dup 0)
5414
                   (match_operand:HI 1 "general_operand" "dIP")))]
5415
  "!TARGET_COLDFIRE"
5416
{
5417
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8)
5418
    {
5419
      operands[2] = GEN_INT (16 - INTVAL (operands[2]));
5420
      return "ror%.w %2,%0";
5421
    }
5422
  else
5423
    return "rol%.w %2,%0";
5424
})
5425
 
5426
(define_insn "rotlqi3"
5427
  [(set (match_operand:QI 0 "register_operand" "=d")
5428
        (rotate:QI (match_operand:QI 1 "register_operand" "0")
5429
                   (match_operand:QI 2 "general_operand" "dI")))]
5430
  "!TARGET_COLDFIRE"
5431
{
5432
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
5433
    {
5434
      operands[2] = GEN_INT (8 - INTVAL (operands[2]));
5435
      return "ror%.b %2,%0";
5436
    }
5437
  else
5438
    return "rol%.b %2,%0";
5439
})
5440
 
5441
(define_insn ""
5442
  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
5443
        (rotate:QI (match_dup 0)
5444
                   (match_operand:QI 1 "general_operand" "dI")))]
5445
  "!TARGET_COLDFIRE"
5446
{
5447
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4)
5448
    {
5449
      operands[2] = GEN_INT (8 - INTVAL (operands[2]));
5450
      return "ror%.b %2,%0";
5451
    }
5452
  else
5453
    return "rol%.b %2,%0";
5454
})
5455
 
5456
(define_insn "rotrsi3"
5457
  [(set (match_operand:SI 0 "register_operand" "=d")
5458
        (rotatert:SI (match_operand:SI 1 "register_operand" "0")
5459
                     (match_operand:SI 2 "general_operand" "dI")))]
5460
  "!TARGET_COLDFIRE"
5461
  "ror%.l %2,%0")
5462
 
5463
(define_insn "rotrhi3"
5464
  [(set (match_operand:HI 0 "register_operand" "=d")
5465
        (rotatert:HI (match_operand:HI 1 "register_operand" "0")
5466
                     (match_operand:HI 2 "general_operand" "dI")))]
5467
  "!TARGET_COLDFIRE"
5468
  "ror%.w %2,%0")
5469
 
5470
(define_insn ""
5471
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
5472
        (rotatert:HI (match_dup 0)
5473
                     (match_operand:HI 1 "general_operand" "dI")))]
5474
  "!TARGET_COLDFIRE"
5475
  "ror%.w %1,%0")
5476
 
5477
(define_insn "rotrqi3"
5478
  [(set (match_operand:QI 0 "register_operand" "=d")
5479
        (rotatert:QI (match_operand:QI 1 "register_operand" "0")
5480
                     (match_operand:QI 2 "general_operand" "dI")))]
5481
  "!TARGET_COLDFIRE"
5482
  "ror%.b %2,%0")
5483
 
5484
(define_insn ""
5485
  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
5486
        (rotatert:QI (match_dup 0)
5487
                     (match_operand:QI 1 "general_operand" "dI")))]
5488
  "!TARGET_COLDFIRE"
5489
  "ror%.b %1,%0")
5490
 
5491
 
5492
;; Bit set/clear in memory byte.
5493
 
5494
;; set bit, bit number is int
5495
(define_insn "bsetmemqi"
5496
  [(set (match_operand:QI 0 "memory_operand" "+m")
5497
        (ior:QI (subreg:QI (ashift:SI (const_int 1)
5498
                (match_operand:SI 1 "general_operand" "d")) 3)
5499
        (match_dup 0)))]
5500
  ""
5501
{
5502
  CC_STATUS_INIT;
5503
  return "bset %1,%0";
5504
}
5505
  [(set_attr "type" "bitrw")])
5506
 
5507
;; set bit, bit number is (sign/zero)_extended from HImode/QImode
5508
(define_insn "*bsetmemqi_ext"
5509
  [(set (match_operand:QI 0 "memory_operand" "+m")
5510
        (ior:QI (subreg:QI (ashift:SI (const_int 1)
5511
            (match_operator:SI 2 "extend_operator"
5512
                [(match_operand 1 "general_operand" "d")])) 3)
5513
        (match_dup 0)))]
5514
  ""
5515
{
5516
  CC_STATUS_INIT;
5517
  return "bset %1,%0";
5518
}
5519
  [(set_attr "type" "bitrw")])
5520
 
5521
;; clear bit, bit number is int
5522
(define_insn "bclrmemqi"
5523
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
5524
        (const_int 1)
5525
        (minus:SI (const_int 7)
5526
            (match_operand:SI 1 "general_operand" "d")))
5527
    (const_int 0))]
5528
  ""
5529
{
5530
  CC_STATUS_INIT;
5531
  return "bclr %1,%0";
5532
}
5533
  [(set_attr "type" "bitrw")])
5534
 
5535
;; clear bit, bit number is (sign/zero)_extended from HImode/QImode
5536
(define_insn "*bclrmemqi_ext"
5537
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
5538
        (const_int 1)
5539
        (minus:SI (const_int 7)
5540
            (match_operator:SI 2 "extend_operator"
5541
                [(match_operand 1 "general_operand" "d")])))
5542
    (const_int 0))]
5543
  ""
5544
{
5545
  CC_STATUS_INIT;
5546
  return "bclr %1,%0";
5547
}
5548
  [(set_attr "type" "bitrw")])
5549
 
5550
;; Special cases of bit-field insns which we should
5551
;; recognize in preference to the general case.
5552
;; These handle aligned 8-bit and 16-bit fields,
5553
;; which can usually be done with move instructions.
5554
 
5555
;
5556
; Special case for 32-bit field in memory.  This only occurs when 32-bit
5557
; alignment of structure members is specified.
5558
;
5559
; The move is allowed to be odd byte aligned, because that's still faster
5560
; than an odd byte aligned bit-field instruction.
5561
;
5562
(define_insn ""
5563
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5564
                         (const_int 32)
5565
                         (match_operand:SI 1 "const_int_operand" "n"))
5566
        (match_operand:SI 2 "general_src_operand" "rmSi"))]
5567
  "TARGET_68020 && TARGET_BITFIELD
5568
   && (INTVAL (operands[1]) % 8) == 0
5569
   && ! mode_dependent_address_p (XEXP (operands[0], 0))"
5570
{
5571
  operands[0]
5572
    = adjust_address (operands[0], SImode, INTVAL (operands[1]) / 8);
5573
 
5574
  return "move%.l %2,%0";
5575
})
5576
 
5577
(define_insn ""
5578
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+do")
5579
                         (match_operand:SI 1 "const_int_operand" "n")
5580
                         (match_operand:SI 2 "const_int_operand" "n"))
5581
        (match_operand:SI 3 "register_operand" "d"))]
5582
  "TARGET_68020 && TARGET_BITFIELD
5583
   && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
5584
   && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
5585
   && (GET_CODE (operands[0]) == REG
5586
       || ! mode_dependent_address_p (XEXP (operands[0], 0)))"
5587
{
5588
  if (REG_P (operands[0]))
5589
    {
5590
      if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
5591
        return "bfins %3,%0{%b2:%b1}";
5592
    }
5593
  else
5594
    operands[0] = adjust_address (operands[0],
5595
                                  INTVAL (operands[1]) == 8 ? QImode : HImode,
5596
                                  INTVAL (operands[2]) / 8);
5597
 
5598
  if (GET_CODE (operands[3]) == MEM)
5599
    operands[3] = adjust_address (operands[3],
5600
                                  INTVAL (operands[1]) == 8 ? QImode : HImode,
5601
                                  (32 - INTVAL (operands[1])) / 8);
5602
 
5603
  if (INTVAL (operands[1]) == 8)
5604
    return "move%.b %3,%0";
5605
  return "move%.w %3,%0";
5606
})
5607
 
5608
 
5609
;
5610
; Special case for 32-bit field in memory.  This only occurs when 32-bit
5611
; alignment of structure members is specified.
5612
;
5613
; The move is allowed to be odd byte aligned, because that's still faster
5614
; than an odd byte aligned bit-field instruction.
5615
;
5616
(define_insn ""
5617
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5618
        (zero_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
5619
                         (const_int 32)
5620
                         (match_operand:SI 2 "const_int_operand" "n")))]
5621
  "TARGET_68020 && TARGET_BITFIELD
5622
   && (INTVAL (operands[2]) % 8) == 0
5623
   && ! mode_dependent_address_p (XEXP (operands[1], 0))"
5624
{
5625
  operands[1]
5626
    = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8);
5627
 
5628
  return "move%.l %1,%0";
5629
})
5630
 
5631
(define_insn ""
5632
  [(set (match_operand:SI 0 "nonimmediate_operand" "=&d")
5633
        (zero_extract:SI (match_operand:SI 1 "register_operand" "do")
5634
                         (match_operand:SI 2 "const_int_operand" "n")
5635
                         (match_operand:SI 3 "const_int_operand" "n")))]
5636
  "TARGET_68020 && TARGET_BITFIELD
5637
   && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
5638
   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
5639
   && (GET_CODE (operands[1]) == REG
5640
       || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
5641
{
5642
  cc_status.flags |= CC_NOT_NEGATIVE;
5643
  if (REG_P (operands[1]))
5644
    {
5645
      if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
5646
        return "bfextu %1{%b3:%b2},%0";
5647
    }
5648
  else
5649
    operands[1]
5650
      = adjust_address (operands[1], SImode, INTVAL (operands[3]) / 8);
5651
 
5652
  output_asm_insn ("clr%.l %0", operands);
5653
  if (GET_CODE (operands[0]) == MEM)
5654
    operands[0] = adjust_address (operands[0],
5655
                                  INTVAL (operands[2]) == 8 ? QImode : HImode,
5656
                                  (32 - INTVAL (operands[1])) / 8);
5657
 
5658
  if (INTVAL (operands[2]) == 8)
5659
    return "move%.b %1,%0";
5660
  return "move%.w %1,%0";
5661
})
5662
 
5663
;
5664
; Special case for 32-bit field in memory.  This only occurs when 32-bit
5665
; alignment of structure members is specified.
5666
;
5667
; The move is allowed to be odd byte aligned, because that's still faster
5668
; than an odd byte aligned bit-field instruction.
5669
;
5670
(define_insn ""
5671
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5672
        (sign_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
5673
                         (const_int 32)
5674
                         (match_operand:SI 2 "const_int_operand" "n")))]
5675
  "TARGET_68020 && TARGET_BITFIELD
5676
   && (INTVAL (operands[2]) % 8) == 0
5677
   && ! mode_dependent_address_p (XEXP (operands[1], 0))"
5678
{
5679
  operands[1]
5680
    = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8);
5681
 
5682
  return "move%.l %1,%0";
5683
})
5684
 
5685
(define_insn ""
5686
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
5687
        (sign_extract:SI (match_operand:SI 1 "register_operand" "do")
5688
                         (match_operand:SI 2 "const_int_operand" "n")
5689
                         (match_operand:SI 3 "const_int_operand" "n")))]
5690
  "TARGET_68020 && TARGET_BITFIELD
5691
   && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
5692
   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
5693
   && (GET_CODE (operands[1]) == REG
5694
       || ! mode_dependent_address_p (XEXP (operands[1], 0)))"
5695
{
5696
  if (REG_P (operands[1]))
5697
    {
5698
      if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
5699
        return "bfexts %1{%b3:%b2},%0";
5700
    }
5701
  else
5702
    operands[1]
5703
      = adjust_address (operands[1],
5704
                        INTVAL (operands[2]) == 8 ? QImode : HImode,
5705
                        INTVAL (operands[3]) / 8);
5706
 
5707
  if (INTVAL (operands[2]) == 8)
5708
    return "move%.b %1,%0\;extb%.l %0";
5709
  return "move%.w %1,%0\;ext%.l %0";
5710
})
5711
 
5712
;; Bit-field instructions, general cases.
5713
;; "o,d" constraint causes a nonoffsettable memref to match the "o"
5714
;; so that its address is reloaded.
5715
 
5716
(define_expand "extv"
5717
  [(set (match_operand:SI 0 "register_operand" "")
5718
        (sign_extract:SI (match_operand:SI 1 "general_operand" "")
5719
                         (match_operand:SI 2 "const_int_operand" "")
5720
                         (match_operand:SI 3 "const_int_operand" "")))]
5721
  "TARGET_68020 && TARGET_BITFIELD"
5722
  "")
5723
 
5724
(define_insn ""
5725
  [(set (match_operand:SI 0 "register_operand" "=d")
5726
        (sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
5727
                         (match_operand:SI 2 "nonmemory_operand" "dn")
5728
                         (match_operand:SI 3 "nonmemory_operand" "dn")))]
5729
  "TARGET_68020 && TARGET_BITFIELD"
5730
  "bfexts %1{%b3:%b2},%0")
5731
 
5732
(define_expand "extzv"
5733
  [(set (match_operand:SI 0 "register_operand" "")
5734
        (zero_extract:SI (match_operand:SI 1 "general_operand" "")
5735
                         (match_operand:SI 2 "const_int_operand" "")
5736
                         (match_operand:SI 3 "const_int_operand" "")))]
5737
  "TARGET_68020 && TARGET_BITFIELD"
5738
  "")
5739
 
5740
(define_insn ""
5741
  [(set (match_operand:SI 0 "register_operand" "=d")
5742
        (zero_extract:SI (match_operand:QI 1 "memory_operand" "o")
5743
                         (match_operand:SI 2 "nonmemory_operand" "dn")
5744
                         (match_operand:SI 3 "nonmemory_operand" "dn")))]
5745
  "TARGET_68020 && TARGET_BITFIELD"
5746
{
5747
  if (GET_CODE (operands[2]) == CONST_INT)
5748
    {
5749
      if (INTVAL (operands[2]) != 32)
5750
        cc_status.flags |= CC_NOT_NEGATIVE;
5751
    }
5752
  else
5753
    {
5754
      CC_STATUS_INIT;
5755
    }
5756
  return "bfextu %1{%b3:%b2},%0";
5757
})
5758
 
5759
(define_insn ""
5760
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5761
                         (match_operand:SI 1 "nonmemory_operand" "dn")
5762
                         (match_operand:SI 2 "nonmemory_operand" "dn"))
5763
        (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
5764
                (match_operand 3 "const_int_operand" "n")))]
5765
  "TARGET_68020 && TARGET_BITFIELD
5766
   && (INTVAL (operands[3]) == -1
5767
       || (GET_CODE (operands[1]) == CONST_INT
5768
           && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
5769
{
5770
  CC_STATUS_INIT;
5771
  return "bfchg %0{%b2:%b1}";
5772
})
5773
 
5774
(define_insn ""
5775
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5776
                         (match_operand:SI 1 "nonmemory_operand" "dn")
5777
                         (match_operand:SI 2 "nonmemory_operand" "dn"))
5778
        (const_int 0))]
5779
  "TARGET_68020 && TARGET_BITFIELD"
5780
{
5781
  CC_STATUS_INIT;
5782
  return "bfclr %0{%b2:%b1}";
5783
})
5784
 
5785
(define_insn ""
5786
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5787
                         (match_operand:SI 1 "general_operand" "dn")
5788
                         (match_operand:SI 2 "general_operand" "dn"))
5789
        (const_int -1))]
5790
  "TARGET_68020 && TARGET_BITFIELD"
5791
{
5792
  CC_STATUS_INIT;
5793
  return "bfset %0{%b2:%b1}";
5794
})
5795
 
5796
(define_expand "insv"
5797
  [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "")
5798
                         (match_operand:SI 1 "const_int_operand" "")
5799
                         (match_operand:SI 2 "const_int_operand" ""))
5800
        (match_operand:SI 3 "register_operand" ""))]
5801
  "TARGET_68020 && TARGET_BITFIELD"
5802
  "")
5803
 
5804
(define_insn ""
5805
  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
5806
                         (match_operand:SI 1 "nonmemory_operand" "dn")
5807
                         (match_operand:SI 2 "nonmemory_operand" "dn"))
5808
        (match_operand:SI 3 "register_operand" "d"))]
5809
  "TARGET_68020 && TARGET_BITFIELD"
5810
  "bfins %3,%0{%b2:%b1}")
5811
 
5812
;; Now recognize bit-field insns that operate on registers
5813
;; (or at least were intended to do so).
5814
 
5815
(define_insn ""
5816
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
5817
        (sign_extract:SI (match_operand:SI 1 "register_operand" "d")
5818
                         (match_operand:SI 2 "const_int_operand" "n")
5819
                         (match_operand:SI 3 "const_int_operand" "n")))]
5820
  "TARGET_68020 && TARGET_BITFIELD"
5821
  "bfexts %1{%b3:%b2},%0")
5822
 
5823
(define_insn ""
5824
  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
5825
        (zero_extract:SI (match_operand:SI 1 "register_operand" "d")
5826
                         (match_operand:SI 2 "const_int_operand" "n")
5827
                         (match_operand:SI 3 "const_int_operand" "n")))]
5828
  "TARGET_68020 && TARGET_BITFIELD"
5829
{
5830
  if (GET_CODE (operands[2]) == CONST_INT)
5831
    {
5832
      if (INTVAL (operands[2]) != 32)
5833
        cc_status.flags |= CC_NOT_NEGATIVE;
5834
    }
5835
  else
5836
    {
5837
      CC_STATUS_INIT;
5838
    }
5839
  return "bfextu %1{%b3:%b2},%0";
5840
})
5841
 
5842
(define_insn ""
5843
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5844
                         (match_operand:SI 1 "const_int_operand" "n")
5845
                         (match_operand:SI 2 "const_int_operand" "n"))
5846
        (const_int 0))]
5847
  "TARGET_68020 && TARGET_BITFIELD"
5848
{
5849
  CC_STATUS_INIT;
5850
  return "bfclr %0{%b2:%b1}";
5851
})
5852
 
5853
(define_insn ""
5854
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5855
                         (match_operand:SI 1 "const_int_operand" "n")
5856
                         (match_operand:SI 2 "const_int_operand" "n"))
5857
        (const_int -1))]
5858
  "TARGET_68020 && TARGET_BITFIELD"
5859
{
5860
  CC_STATUS_INIT;
5861
  return "bfset %0{%b2:%b1}";
5862
})
5863
 
5864
(define_insn ""
5865
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
5866
                         (match_operand:SI 1 "const_int_operand" "n")
5867
                         (match_operand:SI 2 "const_int_operand" "n"))
5868
        (match_operand:SI 3 "register_operand" "d"))]
5869
  "TARGET_68020 && TARGET_BITFIELD"
5870
{
5871
#if 0
5872
  /* These special cases are now recognized by a specific pattern.  */
5873
  if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
5874
      && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
5875
    return "move%.w %3,%0";
5876
  if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
5877
      && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
5878
    return "move%.b %3,%0";
5879
#endif
5880
  return "bfins %3,%0{%b2:%b1}";
5881
})
5882
 
5883
;; Special patterns for optimizing bit-field instructions.
5884
 
5885
(define_insn ""
5886
  [(set (cc0)
5887
        (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
5888
                                  (match_operand:SI 1 "const_int_operand" "n")
5889
                                  (match_operand:SI 2 "general_operand" "dn"))
5890
                 (const_int 0)))]
5891
  "TARGET_68020 && TARGET_BITFIELD"
5892
{
5893
  if (operands[1] == const1_rtx
5894
      && GET_CODE (operands[2]) == CONST_INT)
5895
    {
5896
      int width = GET_CODE (operands[0]) == REG ? 31 : 7;
5897
      return output_btst (operands,
5898
                          GEN_INT (width - INTVAL (operands[2])),
5899
                          operands[0], insn, 1000);
5900
      /* Pass 1000 as SIGNPOS argument so that btst will
5901
         not think we are testing the sign bit for an `and'
5902
         and assume that nonzero implies a negative result.  */
5903
    }
5904
  if (INTVAL (operands[1]) != 32)
5905
    cc_status.flags = CC_NOT_NEGATIVE;
5906
  return "bftst %0{%b2:%b1}";
5907
})
5908
 
5909
 
5910
;;; now handle the register cases
5911
(define_insn ""
5912
  [(set (cc0)
5913
        (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
5914
                                  (match_operand:SI 1 "const_int_operand" "n")
5915
                                  (match_operand:SI 2 "general_operand" "dn"))
5916
                 (const_int 0)))]
5917
  "TARGET_68020 && TARGET_BITFIELD"
5918
{
5919
  if (operands[1] == const1_rtx
5920
      && GET_CODE (operands[2]) == CONST_INT)
5921
    {
5922
      int width = GET_CODE (operands[0]) == REG ? 31 : 7;
5923
      return output_btst (operands, GEN_INT (width - INTVAL (operands[2])),
5924
                          operands[0], insn, 1000);
5925
      /* Pass 1000 as SIGNPOS argument so that btst will
5926
         not think we are testing the sign bit for an `and'
5927
         and assume that nonzero implies a negative result.  */
5928
    }
5929
  if (INTVAL (operands[1]) != 32)
5930
    cc_status.flags = CC_NOT_NEGATIVE;
5931
  return "bftst %0{%b2:%b1}";
5932
})
5933
 
5934
(define_insn "scc0_di"
5935
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
5936
    (match_operator 1 "ordered_comparison_operator"
5937
      [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
5938
  "! TARGET_COLDFIRE"
5939
{
5940
  return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
5941
})
5942
 
5943
(define_insn "scc0_di_5200"
5944
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d")
5945
    (match_operator 1 "ordered_comparison_operator"
5946
      [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
5947
  "TARGET_COLDFIRE"
5948
{
5949
  return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
5950
})
5951
 
5952
(define_insn "scc_di"
5953
  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,dm")
5954
    (match_operator 1 "ordered_comparison_operator"
5955
      [(match_operand:DI 2 "general_operand" "ro,r")
5956
       (match_operand:DI 3 "general_operand" "r,ro")]))]
5957
  "! TARGET_COLDFIRE"
5958
{
5959
  return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
5960
})
5961
 
5962
(define_insn "scc_di_5200"
5963
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d")
5964
    (match_operator 1 "ordered_comparison_operator"
5965
      [(match_operand:DI 2 "general_operand" "ro,r")
5966
       (match_operand:DI 3 "general_operand" "r,ro")]))]
5967
  "TARGET_COLDFIRE"
5968
{
5969
  return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
5970
})
5971
 
5972
;; Note that operand 0 of an SCC insn is supported in the hardware as
5973
;; memory, but we cannot allow it to be in memory in case the address
5974
;; needs to be reloaded.
5975
 
5976
(define_insn ""
5977
  [(set (match_operand:QI 0 "register_operand" "=d")
5978
        (eq:QI (cc0) (const_int 0)))]
5979
  ""
5980
{
5981
  cc_status = cc_prev_status;
5982
  OUTPUT_JUMP ("seq %0", "fseq %0", "seq %0");
5983
})
5984
 
5985
(define_insn ""
5986
  [(set (match_operand:QI 0 "register_operand" "=d")
5987
        (ne:QI (cc0) (const_int 0)))]
5988
  ""
5989
{
5990
  cc_status = cc_prev_status;
5991
  OUTPUT_JUMP ("sne %0", "fsne %0", "sne %0");
5992
})
5993
 
5994
(define_insn ""
5995
  [(set (match_operand:QI 0 "register_operand" "=d")
5996
        (gt:QI (cc0) (const_int 0)))]
5997
  ""
5998
{
5999
  cc_status = cc_prev_status;
6000
  OUTPUT_JUMP ("sgt %0", "fsgt %0", 0);
6001
})
6002
 
6003
(define_insn ""
6004
  [(set (match_operand:QI 0 "register_operand" "=d")
6005
        (gtu:QI (cc0) (const_int 0)))]
6006
  ""
6007
{
6008
  cc_status = cc_prev_status;
6009
  return "shi %0";
6010
})
6011
 
6012
(define_insn ""
6013
  [(set (match_operand:QI 0 "register_operand" "=d")
6014
        (lt:QI (cc0) (const_int 0)))]
6015
  ""
6016
{
6017
   cc_status = cc_prev_status;
6018
   OUTPUT_JUMP ("slt %0", "fslt %0", "smi %0");
6019
})
6020
 
6021
(define_insn ""
6022
  [(set (match_operand:QI 0 "register_operand" "=d")
6023
        (ltu:QI (cc0) (const_int 0)))]
6024
  ""
6025
{
6026
   cc_status = cc_prev_status;
6027
   return "scs %0";
6028
})
6029
 
6030
(define_insn ""
6031
  [(set (match_operand:QI 0 "register_operand" "=d")
6032
        (ge:QI (cc0) (const_int 0)))]
6033
  ""
6034
{
6035
   cc_status = cc_prev_status;
6036
   OUTPUT_JUMP ("sge %0", "fsge %0", "spl %0");
6037
})
6038
 
6039
(define_insn "*scc"
6040
  [(set (match_operand:QI 0 "register_operand" "=d")
6041
        (geu:QI (cc0) (const_int 0)))]
6042
  ""
6043
{
6044
   cc_status = cc_prev_status;
6045
   return "scc %0";
6046
}
6047
  [(set_attr "type" "scc")])
6048
 
6049
(define_insn ""
6050
  [(set (match_operand:QI 0 "register_operand" "=d")
6051
        (le:QI (cc0) (const_int 0)))]
6052
  ""
6053
{
6054
  cc_status = cc_prev_status;
6055
  OUTPUT_JUMP ("sle %0", "fsle %0", 0);
6056
})
6057
 
6058
(define_insn "*sls"
6059
  [(set (match_operand:QI 0 "register_operand" "=d")
6060
        (leu:QI (cc0) (const_int 0)))]
6061
  ""
6062
{
6063
   cc_status = cc_prev_status;
6064
   return "sls %0";
6065
}
6066
  [(set_attr "type" "scc")])
6067
 
6068
(define_insn "*sordered_1"
6069
  [(set (match_operand:QI 0 "register_operand" "=d")
6070
        (ordered:QI (cc0) (const_int 0)))]
6071
  "TARGET_68881 && !TUNE_68060"
6072
{
6073
  cc_status = cc_prev_status;
6074
  return "fsor %0";
6075
})
6076
 
6077
(define_insn "*sunordered_1"
6078
  [(set (match_operand:QI 0 "register_operand" "=d")
6079
        (unordered:QI (cc0) (const_int 0)))]
6080
  "TARGET_68881 && !TUNE_68060"
6081
{
6082
  cc_status = cc_prev_status;
6083
  return "fsun %0";
6084
})
6085
 
6086
(define_insn "*suneq_1"
6087
  [(set (match_operand:QI 0 "register_operand" "=d")
6088
        (uneq:QI (cc0) (const_int 0)))]
6089
  "TARGET_68881 && !TUNE_68060"
6090
{
6091
  cc_status = cc_prev_status;
6092
  return "fsueq %0";
6093
})
6094
 
6095
(define_insn "*sunge_1"
6096
  [(set (match_operand:QI 0 "register_operand" "=d")
6097
        (unge:QI (cc0) (const_int 0)))]
6098
  "TARGET_68881 && !TUNE_68060"
6099
{
6100
  cc_status = cc_prev_status;
6101
  return "fsuge %0";
6102
})
6103
 
6104
(define_insn "*sungt_1"
6105
  [(set (match_operand:QI 0 "register_operand" "=d")
6106
        (ungt:QI (cc0) (const_int 0)))]
6107
  "TARGET_68881 && !TUNE_68060"
6108
{
6109
  cc_status = cc_prev_status;
6110
  return "fsugt %0";
6111
})
6112
 
6113
(define_insn "*sunle_1"
6114
  [(set (match_operand:QI 0 "register_operand" "=d")
6115
        (unle:QI (cc0) (const_int 0)))]
6116
  "TARGET_68881 && !TUNE_68060"
6117
{
6118
  cc_status = cc_prev_status;
6119
  return "fsule %0";
6120
})
6121
 
6122
(define_insn "*sunlt_1"
6123
  [(set (match_operand:QI 0 "register_operand" "=d")
6124
        (unlt:QI (cc0) (const_int 0)))]
6125
  "TARGET_68881 && !TUNE_68060"
6126
{
6127
  cc_status = cc_prev_status;
6128
  return "fsult %0";
6129
})
6130
 
6131
(define_insn "*sltgt_1"
6132
  [(set (match_operand:QI 0 "register_operand" "=d")
6133
        (ltgt:QI (cc0) (const_int 0)))]
6134
  "TARGET_68881 && !TUNE_68060"
6135
{
6136
  cc_status = cc_prev_status;
6137
  return "fsogl %0";
6138
})
6139
 
6140
(define_insn "*fsogt_1"
6141
  [(set (match_operand:QI 0 "register_operand" "=d")
6142
        (not:QI (unle:QI (cc0) (const_int 0))))]
6143
  "TARGET_68881 && !TUNE_68060"
6144
{
6145
  cc_status = cc_prev_status;
6146
  return "fsogt %0";
6147
})
6148
 
6149
(define_insn "*fsoge_1"
6150
  [(set (match_operand:QI 0 "register_operand" "=d")
6151
        (not:QI (unlt:QI (cc0) (const_int 0))))]
6152
  "TARGET_68881 && !TUNE_68060"
6153
{
6154
  cc_status = cc_prev_status;
6155
  return "fsoge %0";
6156
})
6157
 
6158
(define_insn "*fsolt_1"
6159
  [(set (match_operand:QI 0 "register_operand" "=d")
6160
        (not:QI (unge:QI (cc0) (const_int 0))))]
6161
  "TARGET_68881 && !TUNE_68060"
6162
{
6163
  cc_status = cc_prev_status;
6164
  return "fsolt %0";
6165
})
6166
 
6167
(define_insn "*fsole_1"
6168
  [(set (match_operand:QI 0 "register_operand" "=d")
6169
        (not:QI (ungt:QI (cc0) (const_int 0))))]
6170
  "TARGET_68881 && !TUNE_68060"
6171
{
6172
  cc_status = cc_prev_status;
6173
  return "fsole %0";
6174
})
6175
 
6176
;; Basic conditional jump instructions.
6177
 
6178
(define_insn "beq0_di"
6179
  [(set (pc)
6180
    (if_then_else (eq (match_operand:DI 0 "general_operand" "d*ao,<>")
6181
            (const_int 0))
6182
        (label_ref (match_operand 1 "" ","))
6183
        (pc)))
6184
   (clobber (match_scratch:SI 2 "=d,d"))]
6185
  ""
6186
{
6187
  CC_STATUS_INIT;
6188
  if (which_alternative == 1)
6189
    return "move%.l %0,%2\;or%.l %0,%2\;jeq %l1";
6190
  if ((cc_prev_status.value1
6191
      && rtx_equal_p (cc_prev_status.value1, operands[0]))
6192
    || (cc_prev_status.value2
6193
      && rtx_equal_p (cc_prev_status.value2, operands[0])))
6194
    {
6195
      cc_status = cc_prev_status;
6196
      return "jeq %l1";
6197
    }
6198
  if (GET_CODE (operands[0]) == REG)
6199
    operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
6200
  else
6201
    operands[3] = adjust_address (operands[0], SImode, 4);
6202
  if (! ADDRESS_REG_P (operands[0]))
6203
    {
6204
      if (reg_overlap_mentioned_p (operands[2], operands[0]))
6205
        {
6206
          if (reg_overlap_mentioned_p (operands[2], operands[3]))
6207
            return "or%.l %0,%2\;jeq %l1";
6208
          else
6209
            return "or%.l %3,%2\;jeq %l1";
6210
        }
6211
      return "move%.l %0,%2\;or%.l %3,%2\;jeq %l1";
6212
    }
6213
  operands[4] = gen_label_rtx();
6214
  if (TARGET_68020 || TARGET_COLDFIRE)
6215
    output_asm_insn ("tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1", operands);
6216
  else
6217
    output_asm_insn ("cmp%.w #0,%0\;jne %l4\;cmp%.w #0,%3\;jeq %l1", operands);
6218
  (*targetm.asm_out.internal_label) (asm_out_file, "L",
6219
                                CODE_LABEL_NUMBER (operands[4]));
6220
  return "";
6221
})
6222
 
6223
(define_insn "bne0_di"
6224
  [(set (pc)
6225
    (if_then_else (ne (match_operand:DI 0 "general_operand" "do,*a")
6226
            (const_int 0))
6227
        (label_ref (match_operand 1 "" ","))
6228
        (pc)))
6229
   (clobber (match_scratch:SI 2 "=d,X"))]
6230
  ""
6231
{
6232
  if ((cc_prev_status.value1
6233
      && rtx_equal_p (cc_prev_status.value1, operands[0]))
6234
    || (cc_prev_status.value2
6235
      && rtx_equal_p (cc_prev_status.value2, operands[0])))
6236
    {
6237
      cc_status = cc_prev_status;
6238
      return "jne %l1";
6239
    }
6240
  CC_STATUS_INIT;
6241
  if (GET_CODE (operands[0]) == REG)
6242
    operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
6243
  else
6244
    operands[3] = adjust_address (operands[0], SImode, 4);
6245
  if (!ADDRESS_REG_P (operands[0]))
6246
    {
6247
      if (reg_overlap_mentioned_p (operands[2], operands[0]))
6248
        {
6249
          if (reg_overlap_mentioned_p (operands[2], operands[3]))
6250
            return "or%.l %0,%2\;jne %l1";
6251
          else
6252
            return "or%.l %3,%2\;jne %l1";
6253
        }
6254
      return "move%.l %0,%2\;or%.l %3,%2\;jne %l1";
6255
    }
6256
  if (TARGET_68020 || TARGET_COLDFIRE)
6257
    return "tst%.l %0\;jne %l1\;tst%.l %3\;jne %l1";
6258
  else
6259
    return "cmp%.w #0,%0\;jne %l1\;cmp%.w #0,%3\;jne %l1";
6260
})
6261
 
6262
(define_insn "bge0_di"
6263
  [(set (pc)
6264
    (if_then_else (ge (match_operand:DI 0 "general_operand" "ro")
6265
            (const_int 0))
6266
        (label_ref (match_operand 1 "" ""))
6267
        (pc)))]
6268
  ""
6269
{
6270
  if ((cc_prev_status.value1
6271
      && rtx_equal_p (cc_prev_status.value1, operands[0]))
6272
    || (cc_prev_status.value2
6273
      && rtx_equal_p (cc_prev_status.value2, operands[0])))
6274
    {
6275
      cc_status = cc_prev_status;
6276
      return cc_status.flags & CC_REVERSED ? "jle %l1" : "jpl %l1";
6277
    }
6278
  CC_STATUS_INIT;
6279
  if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0]))
6280
    output_asm_insn("tst%.l %0", operands);
6281
  else
6282
    {
6283
      /* On an address reg, cmpw may replace cmpl.  */
6284
      output_asm_insn("cmp%.w #0,%0", operands);
6285
    }
6286
  return "jpl %l1";
6287
})
6288
 
6289
(define_insn "blt0_di"
6290
  [(set (pc)
6291
    (if_then_else (lt (match_operand:DI 0 "general_operand" "ro")
6292
            (const_int 0))
6293
        (label_ref (match_operand 1 "" ""))
6294
        (pc)))]
6295
  ""
6296
{
6297
  if ((cc_prev_status.value1
6298
      && rtx_equal_p (cc_prev_status.value1, operands[0]))
6299
    || (cc_prev_status.value2
6300
      && rtx_equal_p (cc_prev_status.value2, operands[0])))
6301
    {
6302
      cc_status = cc_prev_status;
6303
      return cc_status.flags & CC_REVERSED ? "jgt %l1" : "jmi %l1";
6304
    }
6305
  CC_STATUS_INIT;
6306
  if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0]))
6307
    output_asm_insn("tst%.l %0", operands);
6308
  else
6309
    {
6310
      /* On an address reg, cmpw may replace cmpl.  */
6311
      output_asm_insn("cmp%.w #0,%0", operands);
6312
    }
6313
  return "jmi %l1";
6314
})
6315
 
6316
(define_insn "beq"
6317
  [(set (pc)
6318
        (if_then_else (eq (cc0)
6319
                          (const_int 0))
6320
                      (label_ref (match_operand 0 "" ""))
6321
                      (pc)))]
6322
  ""
6323
{
6324
  OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
6325
}
6326
  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
6327
 
6328
(define_insn "bne"
6329
  [(set (pc)
6330
        (if_then_else (ne (cc0)
6331
                          (const_int 0))
6332
                      (label_ref (match_operand 0 "" ""))
6333
                      (pc)))]
6334
  ""
6335
{
6336
  OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
6337
}
6338
  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
6339
 
6340
(define_insn "bgt"
6341
  [(set (pc)
6342
        (if_then_else (gt (cc0)
6343
                          (const_int 0))
6344
                      (label_ref (match_operand 0 "" ""))
6345
                      (pc)))]
6346
  ""
6347
{
6348
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6349
    {
6350
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6351
      return 0;
6352
    }
6353
 
6354
  OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0);
6355
}
6356
  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
6357
 
6358
(define_insn "bgtu"
6359
  [(set (pc)
6360
        (if_then_else (gtu (cc0)
6361
                           (const_int 0))
6362
                      (label_ref (match_operand 0 "" ""))
6363
                      (pc)))]
6364
  ""
6365
{
6366
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6367
    {
6368
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6369
      return 0;
6370
    }
6371
 
6372
  return "jhi %l0";
6373
}
6374
  [(set_attr "type" "bcc")])
6375
 
6376
(define_insn "blt"
6377
  [(set (pc)
6378
        (if_then_else (lt (cc0)
6379
                          (const_int 0))
6380
                      (label_ref (match_operand 0 "" ""))
6381
                      (pc)))]
6382
  ""
6383
{
6384
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6385
    {
6386
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6387
      return 0;
6388
    }
6389
 
6390
  OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0");
6391
}
6392
  [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))])
6393
 
6394
(define_insn "bltu"
6395
  [(set (pc)
6396
        (if_then_else (ltu (cc0)
6397
                           (const_int 0))
6398
                      (label_ref (match_operand 0 "" ""))
6399
                      (pc)))]
6400
  ""
6401
{
6402
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6403
    {
6404
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6405
      return 0;
6406
    }
6407
 
6408
  return "jcs %l0";
6409
}
6410
  [(set_attr "type" "bcc")])
6411
 
6412
(define_insn "bge"
6413
  [(set (pc)
6414
        (if_then_else (ge (cc0)
6415
                          (const_int 0))
6416
                      (label_ref (match_operand 0 "" ""))
6417
                      (pc)))]
6418
  ""
6419
{
6420
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6421
    {
6422
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6423
      return 0;
6424
    }
6425
 
6426
  OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0");
6427
})
6428
 
6429
(define_insn "bgeu"
6430
  [(set (pc)
6431
        (if_then_else (geu (cc0)
6432
                           (const_int 0))
6433
                      (label_ref (match_operand 0 "" ""))
6434
                      (pc)))]
6435
  ""
6436
{
6437
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6438
    {
6439
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6440
      return 0;
6441
    }
6442
 
6443
  return "jcc %l0";
6444
}
6445
  [(set_attr "type" "bcc")])
6446
 
6447
(define_insn "ble"
6448
  [(set (pc)
6449
        (if_then_else (le (cc0)
6450
                          (const_int 0))
6451
                      (label_ref (match_operand 0 "" ""))
6452
                      (pc)))]
6453
  ""
6454
{
6455
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6456
    {
6457
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6458
      return 0;
6459
    }
6460
 
6461
  OUTPUT_JUMP ("jle %l0", "fjle %l0", 0);
6462
}
6463
  [(set_attr "type" "bcc")])
6464
 
6465
(define_insn "bleu"
6466
  [(set (pc)
6467
        (if_then_else (leu (cc0)
6468
                           (const_int 0))
6469
                      (label_ref (match_operand 0 "" ""))
6470
                      (pc)))]
6471
  ""
6472
{
6473
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6474
    {
6475
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6476
      return 0;
6477
    }
6478
 
6479
  return "jls %l0";
6480
}
6481
  [(set_attr "type" "bcc")])
6482
 
6483
(define_insn "bordered"
6484
  [(set (pc)
6485
        (if_then_else (ordered (cc0) (const_int 0))
6486
                      (label_ref (match_operand 0 "" ""))
6487
                      (pc)))]
6488
  "TARGET_HARD_FLOAT"
6489
{
6490
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6491
  return "fjor %l0";
6492
}
6493
  [(set_attr "type" "fbcc")])
6494
 
6495
(define_insn "bunordered"
6496
  [(set (pc)
6497
        (if_then_else (unordered (cc0) (const_int 0))
6498
                      (label_ref (match_operand 0 "" ""))
6499
                      (pc)))]
6500
  "TARGET_HARD_FLOAT"
6501
{
6502
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6503
  return "fjun %l0";
6504
}
6505
  [(set_attr "type" "fbcc")])
6506
 
6507
(define_insn "buneq"
6508
  [(set (pc)
6509
        (if_then_else (uneq (cc0) (const_int 0))
6510
                      (label_ref (match_operand 0 "" ""))
6511
                      (pc)))]
6512
  "TARGET_HARD_FLOAT"
6513
{
6514
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6515
  return "fjueq %l0";
6516
}
6517
  [(set_attr "type" "fbcc")])
6518
 
6519
(define_insn "bunge"
6520
  [(set (pc)
6521
        (if_then_else (unge (cc0) (const_int 0))
6522
                      (label_ref (match_operand 0 "" ""))
6523
                      (pc)))]
6524
  "TARGET_HARD_FLOAT"
6525
{
6526
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6527
  return "fjuge %l0";
6528
}
6529
  [(set_attr "type" "fbcc")])
6530
 
6531
(define_insn "bungt"
6532
  [(set (pc)
6533
        (if_then_else (ungt (cc0) (const_int 0))
6534
                      (label_ref (match_operand 0 "" ""))
6535
                      (pc)))]
6536
  "TARGET_HARD_FLOAT"
6537
{
6538
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6539
  return "fjugt %l0";
6540
}
6541
  [(set_attr "type" "fbcc")])
6542
 
6543
(define_insn "bunle"
6544
  [(set (pc)
6545
        (if_then_else (unle (cc0) (const_int 0))
6546
                      (label_ref (match_operand 0 "" ""))
6547
                      (pc)))]
6548
  "TARGET_HARD_FLOAT"
6549
{
6550
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6551
  return "fjule %l0";
6552
}
6553
  [(set_attr "type" "fbcc")])
6554
 
6555
(define_insn "bunlt"
6556
  [(set (pc)
6557
        (if_then_else (unlt (cc0) (const_int 0))
6558
                      (label_ref (match_operand 0 "" ""))
6559
                      (pc)))]
6560
  "TARGET_HARD_FLOAT"
6561
{
6562
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6563
  return "fjult %l0";
6564
}
6565
  [(set_attr "type" "fbcc")])
6566
 
6567
(define_insn "bltgt"
6568
  [(set (pc)
6569
        (if_then_else (ltgt (cc0) (const_int 0))
6570
                      (label_ref (match_operand 0 "" ""))
6571
                      (pc)))]
6572
  "TARGET_HARD_FLOAT"
6573
{
6574
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6575
  return "fjogl %l0";
6576
}
6577
  [(set_attr "type" "fbcc")])
6578
 
6579
;; Negated conditional jump instructions.
6580
 
6581
(define_insn "*beq_rev"
6582
  [(set (pc)
6583
        (if_then_else (eq (cc0)
6584
                          (const_int 0))
6585
                      (pc)
6586
                      (label_ref (match_operand 0 "" ""))))]
6587
  ""
6588
{
6589
  OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
6590
}
6591
  [(set_attr "type" "bcc")])
6592
 
6593
(define_insn "*bne_rev"
6594
  [(set (pc)
6595
        (if_then_else (ne (cc0)
6596
                          (const_int 0))
6597
                      (pc)
6598
                      (label_ref (match_operand 0 "" ""))))]
6599
  ""
6600
{
6601
  OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
6602
}
6603
  [(set_attr "type" "bcc")])
6604
 
6605
(define_insn "*bgt_rev"
6606
  [(set (pc)
6607
        (if_then_else (gt (cc0)
6608
                          (const_int 0))
6609
                      (pc)
6610
                      (label_ref (match_operand 0 "" ""))))]
6611
  ""
6612
{
6613
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6614
    {
6615
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6616
      return 0;
6617
    }
6618
 
6619
  OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0);
6620
}
6621
  [(set_attr "type" "bcc")])
6622
 
6623
(define_insn "*bgtu_rev"
6624
  [(set (pc)
6625
        (if_then_else (gtu (cc0)
6626
                           (const_int 0))
6627
                      (pc)
6628
                      (label_ref (match_operand 0 "" ""))))]
6629
  ""
6630
{
6631
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6632
    {
6633
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6634
      return 0;
6635
    }
6636
 
6637
  return "jls %l0";
6638
}
6639
  [(set_attr "type" "bcc")])
6640
 
6641
(define_insn "*blt_rev"
6642
  [(set (pc)
6643
        (if_then_else (lt (cc0)
6644
                          (const_int 0))
6645
                      (pc)
6646
                      (label_ref (match_operand 0 "" ""))))]
6647
  ""
6648
{
6649
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6650
    {
6651
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6652
      return 0;
6653
    }
6654
 
6655
  OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0");
6656
}
6657
  [(set_attr "type" "bcc")])
6658
 
6659
(define_insn "*bltu_rev"
6660
  [(set (pc)
6661
        (if_then_else (ltu (cc0)
6662
                           (const_int 0))
6663
                      (pc)
6664
                      (label_ref (match_operand 0 "" ""))))]
6665
  ""
6666
{
6667
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6668
    {
6669
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6670
      return 0;
6671
    }
6672
 
6673
  return "jcc %l0";
6674
}
6675
  [(set_attr "type" "bcc")])
6676
 
6677
(define_insn "*bge_rev"
6678
  [(set (pc)
6679
        (if_then_else (ge (cc0)
6680
                          (const_int 0))
6681
                      (pc)
6682
                      (label_ref (match_operand 0 "" ""))))]
6683
  ""
6684
{
6685
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6686
    {
6687
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6688
      return 0;
6689
    }
6690
 
6691
  OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0");
6692
}
6693
  [(set_attr "type" "bcc")])
6694
 
6695
(define_insn "*bgeu_rev"
6696
  [(set (pc)
6697
        (if_then_else (geu (cc0)
6698
                           (const_int 0))
6699
                      (pc)
6700
                      (label_ref (match_operand 0 "" ""))))]
6701
  ""
6702
{
6703
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6704
    {
6705
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6706
      return 0;
6707
    }
6708
 
6709
  return "jcs %l0";
6710
}
6711
  [(set_attr "type" "bcc")])
6712
 
6713
(define_insn "*ble_rev"
6714
  [(set (pc)
6715
        (if_then_else (le (cc0)
6716
                          (const_int 0))
6717
                      (pc)
6718
                      (label_ref (match_operand 0 "" ""))))]
6719
  ""
6720
{
6721
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6722
    {
6723
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6724
      return 0;
6725
    }
6726
 
6727
  OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0);
6728
}
6729
  [(set_attr "type" "bcc")])
6730
 
6731
(define_insn "*bleu_rev"
6732
  [(set (pc)
6733
        (if_then_else (leu (cc0)
6734
                           (const_int 0))
6735
                      (pc)
6736
                      (label_ref (match_operand 0 "" ""))))]
6737
  ""
6738
{
6739
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
6740
    {
6741
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
6742
      return 0;
6743
    }
6744
 
6745
  return "jhi %l0";
6746
}
6747
  [(set_attr "type" "bcc")])
6748
 
6749
(define_insn "*bordered_rev"
6750
  [(set (pc)
6751
        (if_then_else (ordered (cc0) (const_int 0))
6752
                      (pc)
6753
                      (label_ref (match_operand 0 "" ""))))]
6754
  "TARGET_HARD_FLOAT"
6755
{
6756
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6757
  return "fjun %l0";
6758
}
6759
  [(set_attr "type" "fbcc")])
6760
 
6761
(define_insn "*bunordered_rev"
6762
  [(set (pc)
6763
        (if_then_else (unordered (cc0) (const_int 0))
6764
                      (pc)
6765
                      (label_ref (match_operand 0 "" ""))))]
6766
  "TARGET_HARD_FLOAT"
6767
{
6768
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6769
  return "fjor %l0";
6770
}
6771
  [(set_attr "type" "fbcc")])
6772
 
6773
(define_insn "*buneq_rev"
6774
  [(set (pc)
6775
        (if_then_else (uneq (cc0) (const_int 0))
6776
                      (pc)
6777
                      (label_ref (match_operand 0 "" ""))))]
6778
  "TARGET_HARD_FLOAT"
6779
{
6780
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6781
  return "fjogl %l0";
6782
}
6783
  [(set_attr "type" "fbcc")])
6784
 
6785
(define_insn "*bunge_rev"
6786
  [(set (pc)
6787
        (if_then_else (unge (cc0) (const_int 0))
6788
                      (pc)
6789
                      (label_ref (match_operand 0 "" ""))))]
6790
  "TARGET_HARD_FLOAT"
6791
{
6792
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6793
  return "fjolt %l0";
6794
}
6795
  [(set_attr "type" "fbcc")])
6796
 
6797
(define_insn "*bungt_rev"
6798
  [(set (pc)
6799
        (if_then_else (ungt (cc0) (const_int 0))
6800
                      (pc)
6801
                      (label_ref (match_operand 0 "" ""))))]
6802
  "TARGET_HARD_FLOAT"
6803
{
6804
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6805
  return "fjole %l0";
6806
}
6807
  [(set_attr "type" "fbcc")])
6808
 
6809
(define_insn "*bunle_rev"
6810
  [(set (pc)
6811
        (if_then_else (unle (cc0) (const_int 0))
6812
                      (pc)
6813
                      (label_ref (match_operand 0 "" ""))))]
6814
  "TARGET_HARD_FLOAT"
6815
{
6816
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6817
  return "fjogt %l0";
6818
}
6819
  [(set_attr "type" "fbcc")])
6820
 
6821
(define_insn "*bunlt_rev"
6822
  [(set (pc)
6823
        (if_then_else (unlt (cc0) (const_int 0))
6824
                      (pc)
6825
                      (label_ref (match_operand 0 "" ""))))]
6826
  "TARGET_HARD_FLOAT"
6827
{
6828
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6829
  return "fjoge %l0";
6830
}
6831
  [(set_attr "type" "fbcc")])
6832
 
6833
(define_insn "*bltgt_rev"
6834
  [(set (pc)
6835
        (if_then_else (ltgt (cc0) (const_int 0))
6836
                      (pc)
6837
                      (label_ref (match_operand 0 "" ""))))]
6838
  "TARGET_HARD_FLOAT"
6839
{
6840
  gcc_assert (cc_prev_status.flags & CC_IN_68881);
6841
  return "fjueq %l0";
6842
}
6843
  [(set_attr "type" "fbcc")])
6844
 
6845
;; Unconditional and other jump instructions
6846
(define_insn "jump"
6847
  [(set (pc)
6848
        (label_ref (match_operand 0 "" "")))]
6849
  ""
6850
  "jra %l0"
6851
  [(set_attr "type" "bra")])
6852
 
6853
(define_expand "tablejump"
6854
  [(parallel [(set (pc) (match_operand 0 "" ""))
6855
              (use (label_ref (match_operand 1 "" "")))])]
6856
  ""
6857
{
6858
#ifdef CASE_VECTOR_PC_RELATIVE
6859
    operands[0] = gen_rtx_PLUS (SImode, pc_rtx,
6860
                                gen_rtx_SIGN_EXTEND (SImode, operands[0]));
6861
#endif
6862
})
6863
 
6864
;; Jump to variable address from dispatch table of absolute addresses.
6865
(define_insn "*tablejump_internal"
6866
  [(set (pc) (match_operand:SI 0 "register_operand" "a"))
6867
   (use (label_ref (match_operand 1 "" "")))]
6868
  ""
6869
{
6870
  return MOTOROLA ? "jmp (%0)" : "jmp %0@";
6871
}
6872
  [(set_attr "type" "jmp")])
6873
 
6874
;; Jump to variable address from dispatch table of relative addresses.
6875
(define_insn ""
6876
  [(set (pc)
6877
        (plus:SI (pc)
6878
                 (sign_extend:SI (match_operand:HI 0 "register_operand" "r"))))
6879
   (use (label_ref (match_operand 1 "" "")))]
6880
  ""
6881
{
6882
#ifdef ASM_RETURN_CASE_JUMP
6883
  ASM_RETURN_CASE_JUMP;
6884
#else
6885
  if (TARGET_COLDFIRE)
6886
    {
6887
      if (ADDRESS_REG_P (operands[0]))
6888
        return MOTOROLA ? "jmp (2,pc,%0.l)" : "jmp pc@(2,%0:l)";
6889
      else if (MOTOROLA)
6890
        return "ext%.l %0\;jmp (2,pc,%0.l)";
6891
      else
6892
        return "extl %0\;jmp pc@(2,%0:l)";
6893
    }
6894
  else
6895
    return MOTOROLA ? "jmp (2,pc,%0.w)" : "jmp pc@(2,%0:w)";
6896
#endif
6897
})
6898
 
6899
;; Decrement-and-branch insns.
6900
(define_insn "*dbne_hi"
6901
  [(set (pc)
6902
        (if_then_else
6903
         (ne (match_operand:HI 0 "nonimmediate_operand" "+d*g")
6904
             (const_int 0))
6905
         (label_ref (match_operand 1 "" ""))
6906
         (pc)))
6907
   (set (match_dup 0)
6908
        (plus:HI (match_dup 0)
6909
                 (const_int -1)))]
6910
  "!TARGET_COLDFIRE"
6911
{
6912
  CC_STATUS_INIT;
6913
  if (DATA_REG_P (operands[0]))
6914
    return "dbra %0,%l1";
6915
  if (GET_CODE (operands[0]) == MEM)
6916
    return "subq%.w #1,%0\;jcc %l1";
6917
  return "subq%.w #1,%0\;cmp%.w #-1,%0\;jne %l1";
6918
})
6919
 
6920
(define_insn "*dbne_si"
6921
  [(set (pc)
6922
        (if_then_else
6923
         (ne (match_operand:SI 0 "nonimmediate_operand" "+d*g")
6924
             (const_int 0))
6925
         (label_ref (match_operand 1 "" ""))
6926
         (pc)))
6927
   (set (match_dup 0)
6928
        (plus:SI (match_dup 0)
6929
                 (const_int -1)))]
6930
  "!TARGET_COLDFIRE"
6931
{
6932
  CC_STATUS_INIT;
6933
  if (DATA_REG_P (operands[0]))
6934
    return "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1";
6935
  if (GET_CODE (operands[0]) == MEM)
6936
    return "subq%.l #1,%0\;jcc %l1";
6937
  return "subq%.l #1,%0\;cmp%.l #-1,%0\;jne %l1";
6938
})
6939
 
6940
;; Two dbra patterns that use REG_NOTES info generated by strength_reduce.
6941
 
6942
(define_insn "*dbge_hi"
6943
  [(set (pc)
6944
        (if_then_else
6945
          (ge (plus:HI (match_operand:HI 0 "nonimmediate_operand" "+d*am")
6946
                       (const_int -1))
6947
              (const_int 0))
6948
          (label_ref (match_operand 1 "" ""))
6949
          (pc)))
6950
   (set (match_dup 0)
6951
        (plus:HI (match_dup 0)
6952
                 (const_int -1)))]
6953
  "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)"
6954
{
6955
  CC_STATUS_INIT;
6956
  if (DATA_REG_P (operands[0]))
6957
    return "dbra %0,%l1";
6958
  if (GET_CODE (operands[0]) == MEM)
6959
    return "subq%.w #1,%0\;jcc %l1";
6960
  return "subq%.w #1,%0\;cmp%.w #-1,%0\;jne %l1";
6961
})
6962
 
6963
(define_expand "decrement_and_branch_until_zero"
6964
  [(parallel [(set (pc)
6965
                   (if_then_else
6966
                    (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "")
6967
                                 (const_int -1))
6968
                        (const_int 0))
6969
                    (label_ref (match_operand 1 "" ""))
6970
                    (pc)))
6971
              (set (match_dup 0)
6972
                   (plus:SI (match_dup 0)
6973
                            (const_int -1)))])]
6974
  ""
6975
  "")
6976
 
6977
(define_insn "*dbge_si"
6978
  [(set (pc)
6979
        (if_then_else
6980
          (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+d*am")
6981
                       (const_int -1))
6982
              (const_int 0))
6983
          (label_ref (match_operand 1 "" ""))
6984
          (pc)))
6985
   (set (match_dup 0)
6986
        (plus:SI (match_dup 0)
6987
                 (const_int -1)))]
6988
  "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)"
6989
{
6990
  CC_STATUS_INIT;
6991
  if (DATA_REG_P (operands[0]))
6992
    return "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1";
6993
  if (GET_CODE (operands[0]) == MEM)
6994
    return "subq%.l #1,%0\;jcc %l1";
6995
  return "subq%.l #1,%0\;cmp%.l #-1,%0\;jne %l1";
6996
})
6997
 
6998
(define_expand "sibcall"
6999
  [(call (match_operand:QI 0 "memory_operand" "")
7000
         (match_operand:SI 1 "general_operand" ""))]
7001
  ""
7002
{
7003
  operands[0] = m68k_legitimize_sibcall_address (operands[0]);
7004
})
7005
 
7006
(define_insn "*sibcall"
7007
  [(call (mem:QI (match_operand:SI 0 "sibcall_operand" ""))
7008
         (match_operand:SI 1 "general_operand" ""))]
7009
  "SIBLING_CALL_P (insn)"
7010
{
7011
  return output_sibcall (operands[0]);
7012
})
7013
 
7014
(define_expand "sibcall_value"
7015
  [(set (match_operand 0 "" "")
7016
        (call (match_operand:QI 1 "memory_operand" "")
7017
              (match_operand:SI 2 "general_operand" "")))]
7018
  ""
7019
{
7020
  operands[1] = m68k_legitimize_sibcall_address (operands[1]);
7021
})
7022
 
7023
(define_insn "*sibcall_value"
7024
  [(set (match_operand 0 "" "=rf,rf")
7025
        (call (mem:QI (match_operand:SI 1 "sibcall_operand" ""))
7026
              (match_operand:SI 2 "general_operand" "")))]
7027
  "SIBLING_CALL_P (insn)"
7028
{
7029
  operands[0] = operands[1];
7030
  return output_sibcall (operands[0]);
7031
})
7032
 
7033
;; Call subroutine with no return value.
7034
(define_expand "call"
7035
  [(call (match_operand:QI 0 "memory_operand" "")
7036
         (match_operand:SI 1 "general_operand" ""))]
7037
  ;; Operand 1 not really used on the m68000.
7038
  ""
7039
{
7040
  operands[0] = m68k_legitimize_call_address (operands[0]);
7041
})
7042
 
7043
(define_insn "*call"
7044
  [(call (mem:QI (match_operand:SI 0 "call_operand" "a,W"))
7045
         (match_operand:SI 1 "general_operand" "g,g"))]
7046
  ;; Operand 1 not really used on the m68000.
7047
  "!SIBLING_CALL_P (insn)"
7048
{
7049
  return output_call (operands[0]);
7050
}
7051
  [(set_attr "type" "jsr")])
7052
 
7053
;; Call subroutine, returning value in operand 0
7054
;; (which must be a hard register).
7055
(define_expand "call_value"
7056
  [(set (match_operand 0 "" "")
7057
        (call (match_operand:QI 1 "memory_operand" "")
7058
              (match_operand:SI 2 "general_operand" "")))]
7059
  ;; Operand 2 not really used on the m68000.
7060
  ""
7061
{
7062
  operands[1] = m68k_legitimize_call_address (operands[1]);
7063
})
7064
 
7065
(define_insn "*non_symbolic_call_value"
7066
  [(set (match_operand 0 "" "=rf,rf")
7067
        (call (mem:QI (match_operand:SI 1 "non_symbolic_call_operand" "a,W"))
7068
              (match_operand:SI 2 "general_operand" "g,g")))]
7069
  ;; Operand 2 not really used on the m68000.
7070
  "!SIBLING_CALL_P (insn)"
7071
  "jsr %a1"
7072
  [(set_attr "type" "jsr")
7073
   (set_attr "opx" "1")])
7074
 
7075
(define_insn "*symbolic_call_value_jsr"
7076
  [(set (match_operand 0 "" "=rf,rf")
7077
        (call (mem:QI (match_operand:SI 1 "symbolic_operand" "a,W"))
7078
              (match_operand:SI 2 "general_operand" "g,g")))]
7079
  ;; Operand 2 not really used on the m68000.
7080
  "!SIBLING_CALL_P (insn) && m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_JSR"
7081
{
7082
  operands[0] = operands[1];
7083
  return m68k_symbolic_call;
7084
}
7085
  [(set_attr "type" "jsr")
7086
   (set_attr "opx" "1")])
7087
 
7088
(define_insn "*symbolic_call_value_bsr"
7089
  [(set (match_operand 0 "" "=rf,rf")
7090
        (call (mem:QI (match_operand:SI 1 "symbolic_operand" "a,W"))
7091
              (match_operand:SI 2 "general_operand" "g,g")))]
7092
  ;; Operand 2 not really used on the m68000.
7093
  "!SIBLING_CALL_P (insn)
7094
   && (m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_BSR_C
7095
       || m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_BSR_P)"
7096
{
7097
  operands[0] = operands[1];
7098
  return m68k_symbolic_call;
7099
}
7100
  [(set_attr "type" "bsr")
7101
   (set_attr "opx" "1")])
7102
 
7103
;; Call subroutine returning any type.
7104
 
7105
(define_expand "untyped_call"
7106
  [(parallel [(call (match_operand 0 "" "")
7107
                    (const_int 0))
7108
              (match_operand 1 "" "")
7109
              (match_operand 2 "" "")])]
7110
  "NEEDS_UNTYPED_CALL"
7111
{
7112
  int i;
7113
 
7114
  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
7115
 
7116
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
7117
    {
7118
      rtx set = XVECEXP (operands[2], 0, i);
7119
      emit_move_insn (SET_DEST (set), SET_SRC (set));
7120
    }
7121
 
7122
  /* The optimizer does not know that the call sets the function value
7123
     registers we stored in the result block.  We avoid problems by
7124
     claiming that all hard registers are used and clobbered at this
7125
     point.  */
7126
  emit_insn (gen_blockage ());
7127
 
7128
  DONE;
7129
})
7130
 
7131
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7132
;; all of memory.  This blocks insns from being moved across this point.
7133
 
7134
(define_insn "blockage"
7135
  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7136
  ""
7137
  "")
7138
 
7139
(define_insn "nop"
7140
  [(const_int 0)]
7141
  ""
7142
  "nop"
7143
  [(set_attr "type" "nop")])
7144
 
7145
(define_expand "prologue"
7146
  [(const_int 0)]
7147
  ""
7148
{
7149
  m68k_expand_prologue ();
7150
  DONE;
7151
})
7152
 
7153
(define_expand "epilogue"
7154
  [(return)]
7155
  ""
7156
{
7157
  m68k_expand_epilogue (false);
7158
  DONE;
7159
})
7160
 
7161
(define_expand "sibcall_epilogue"
7162
  [(return)]
7163
  ""
7164
{
7165
  m68k_expand_epilogue (true);
7166
  DONE;
7167
})
7168
 
7169
;; Used for frameless functions which save no regs and allocate no locals.
7170
(define_expand "return"
7171
  [(return)]
7172
  "m68k_use_return_insn ()"
7173
  "")
7174
 
7175
(define_insn "*return"
7176
  [(return)]
7177
  ""
7178
{
7179
  switch (m68k_get_function_kind (current_function_decl))
7180
    {
7181
    case m68k_fk_interrupt_handler:
7182
      return "rte";
7183
 
7184
    case m68k_fk_interrupt_thread:
7185
      return "sleep";
7186
 
7187
    default:
7188
      if (crtl->args.pops_args)
7189
        {
7190
          operands[0] = GEN_INT (crtl->args.pops_args);
7191
          return "rtd %0";
7192
        }
7193
      else
7194
        return "rts";
7195
    }
7196
}
7197
  [(set_attr "type" "rts")])
7198
 
7199
(define_insn "*m68k_store_multiple"
7200
  [(match_parallel 0 "" [(match_operand 1 "")])]
7201
  "m68k_movem_pattern_p (operands[0], NULL, 0, true)"
7202
{
7203
  return m68k_output_movem (operands, operands[0], 0, true);
7204
})
7205
 
7206
(define_insn "*m68k_store_multiple_automod"
7207
  [(match_parallel 0 ""
7208
     [(set (match_operand:SI 1 "register_operand" "=a")
7209
           (plus:SI (match_operand:SI 2 "register_operand" "1")
7210
                    (match_operand:SI 3 "const_int_operand")))])]
7211
  "m68k_movem_pattern_p (operands[0], operands[1], INTVAL (operands[3]), true)"
7212
{
7213
  return m68k_output_movem (operands, operands[0], INTVAL (operands[3]), true);
7214
})
7215
 
7216
(define_insn "*m68k_load_multiple"
7217
  [(match_parallel 0 "" [(match_operand 1 "")])]
7218
  "m68k_movem_pattern_p (operands[0], NULL, 0, false)"
7219
{
7220
  return m68k_output_movem (operands, operands[0], 0, false);
7221
})
7222
 
7223
(define_insn "*m68k_load_multiple_automod"
7224
  [(match_parallel 0 ""
7225
     [(set (match_operand:SI 1 "register_operand" "=a")
7226
           (plus:SI (match_operand:SI 2 "register_operand" "1")
7227
                    (match_operand:SI 3 "const_int_operand")))])]
7228
  "m68k_movem_pattern_p (operands[0], operands[1],
7229
                         INTVAL (operands[3]), false)"
7230
{
7231
  return m68k_output_movem (operands, operands[0],
7232
                            INTVAL (operands[3]), false);
7233
})
7234
 
7235
(define_expand "link"
7236
  [(parallel
7237
       [(set (match_operand:SI 0 "register_operand")
7238
             (plus:SI (reg:SI SP_REG) (const_int -4)))
7239
        (set (match_dup 2)
7240
             (match_dup 0))
7241
        (set (reg:SI SP_REG)
7242
             (plus:SI (reg:SI SP_REG)
7243
                      (match_operand:SI 1 "const_int_operand")))])]
7244
  "TARGET_68020 || INTVAL (operands[1]) >= -0x8004"
7245
{
7246
  operands[2] = gen_frame_mem (SImode, plus_constant (stack_pointer_rtx, -4));
7247
})
7248
 
7249
(define_insn "*link"
7250
  [(set (match_operand:SI 0 "register_operand" "+r")
7251
        (plus:SI (reg:SI SP_REG) (const_int -4)))
7252
   (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
7253
        (match_dup 0))
7254
   (set (reg:SI SP_REG)
7255
        (plus:SI (reg:SI SP_REG)
7256
                 (match_operand:SI 1 "const_int_operand")))]
7257
  "TARGET_68020 || INTVAL (operands[1]) >= -0x8004"
7258
{
7259
  operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
7260
  if (!MOTOROLA)
7261
    return "link %0,%1";
7262
  else if (INTVAL (operands[1]) >= -0x8000)
7263
    return "link.w %0,%1";
7264
  else
7265
    return "link.l %0,%1";
7266
}
7267
  [(set_attr "type" "link")])
7268
 
7269
(define_expand "unlink"
7270
  [(parallel
7271
      [(set (match_operand:SI 0 "register_operand")
7272
            (match_dup 1))
7273
       (set (reg:SI SP_REG)
7274
            (plus:SI (match_dup 0)
7275
                     (const_int 4)))])]
7276
  ""
7277
{
7278
  operands[1] = gen_frame_mem (SImode, copy_rtx (operands[0]));
7279
})
7280
 
7281
(define_insn "*unlink"
7282
  [(set (match_operand:SI 0 "register_operand" "+r")
7283
        (mem:SI (match_dup 0)))
7284
   (set (reg:SI SP_REG)
7285
        (plus:SI (match_dup 0)
7286
                 (const_int 4)))]
7287
  ""
7288
  "unlk %0"
7289
  [(set_attr "type" "unlk")])
7290
 
7291
(define_insn "load_got"
7292
  [(set (match_operand:SI 0 "register_operand" "=a")
7293
        (unspec:SI [(const_int 0)] UNSPEC_GOT))]
7294
  ""
7295
{
7296
  if (TARGET_ID_SHARED_LIBRARY)
7297
    {
7298
      operands[1] = gen_rtx_REG (Pmode, PIC_REG);
7299
      return MOTOROLA ? "move.l %?(%1),%0" : "movel %1@(%?), %0";
7300
    }
7301
  else if (MOTOROLA)
7302
    {
7303
      if (TARGET_COLDFIRE)
7304
        /* Load the full 32-bit PC-relative offset of
7305
           _GLOBAL_OFFSET_TABLE_ into the PIC register, then use it to
7306
           calculate the absolute value.  The offset and "lea"
7307
           operation word together occupy 6 bytes.  */
7308
        return ("move.l #_GLOBAL_OFFSET_TABLE_@GOTPC, %0\n\t"
7309
                "lea (-6, %%pc, %0), %0");
7310
      else
7311
        return "lea (%%pc, _GLOBAL_OFFSET_TABLE_@GOTPC), %0";
7312
    }
7313
  else
7314
    return ("movel #_GLOBAL_OFFSET_TABLE_, %0\n\t"
7315
            "lea %%pc@(0,%0:l),%0");
7316
})
7317
 
7318
(define_insn "indirect_jump"
7319
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7320
  ""
7321
  "jmp %a0"
7322
  [(set_attr "type" "jmp")])
7323
 
7324
;; This should not be used unless the add/sub insns can't be.
7325
 
7326
(define_insn "*lea"
7327
  [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
7328
        (match_operand:QI 1 "address_operand" "p"))]
7329
  ""
7330
  "lea %a1,%0")
7331
 
7332
;; This is the first machine-dependent peephole optimization.
7333
;; It is useful when a floating value is returned from a function call
7334
;; and then is moved into an FP register.
7335
;; But it is mainly intended to test the support for these optimizations.
7336
 
7337
(define_peephole2
7338
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
7339
   (set (match_operand:DF 0 "register_operand" "")
7340
        (match_operand:DF 1 "register_operand" ""))]
7341
  "FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
7342
  [(set (mem:SI (reg:SI SP_REG)) (match_dup 1))
7343
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 2))
7344
   (set (match_dup 0) (mem:DF (post_inc:SI (reg:SI SP_REG))))]
7345
  "split_di(operands + 1, 1, operands + 1, operands + 2);")
7346
 
7347
;; Optimize a stack-adjust followed by a push of an argument.
7348
;; This is said to happen frequently with -msoft-float
7349
;; when there are consecutive library calls.
7350
 
7351
(define_peephole2
7352
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
7353
   (set (match_operand:SF 0 "push_operand" "")
7354
        (match_operand:SF 1 "general_operand" ""))]
7355
  "!reg_mentioned_p (stack_pointer_rtx, operands[0])"
7356
  [(set (match_dup 0) (match_dup 1))]
7357
  "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
7358
 
7359
(define_peephole2
7360
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7361
                                 (match_operand:SI 0 "const_int_operand" "")))
7362
   (set (match_operand:SF 1 "push_operand" "")
7363
        (match_operand:SF 2 "general_operand" ""))]
7364
  "INTVAL (operands[0]) > 4
7365
   && !reg_mentioned_p (stack_pointer_rtx, operands[2])"
7366
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
7367
   (set (match_dup 1) (match_dup 2))]
7368
{
7369
  operands[0] = GEN_INT (INTVAL (operands[0]) - 4);
7370
  operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
7371
})
7372
 
7373
;; Speed up stack adjust followed by a fullword fixedpoint push.
7374
;; Constant operands need special care, as replacing a "pea X.w" with
7375
;; "move.l #X,(%sp)" is often not a win.
7376
 
7377
;; Already done by the previous csa pass, left as reference.
7378
(define_peephole2
7379
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
7380
   (set (match_operand:SI 0 "push_operand" "")
7381
        (match_operand:SI 1 "general_operand" ""))]
7382
  "!reg_mentioned_p (stack_pointer_rtx, operands[1])"
7383
  [(set (match_dup 0) (match_dup 1))]
7384
  "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
7385
 
7386
;; Try to use moveq, after stack push has been changed into a simple move.
7387
(define_peephole2
7388
  [(match_scratch:SI 2 "d")
7389
   (set (match_operand:SI 0 "memory_operand" "")
7390
        (match_operand:SI 1 "const_int_operand" ""))]
7391
  "GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
7392
   && INTVAL (operands[1]) != 0
7393
   && IN_RANGE (INTVAL (operands[1]), -0x80, 0x7f)
7394
   && !valid_mov3q_const (INTVAL (operands[1]))"
7395
  [(set (match_dup 2) (match_dup 1))
7396
   (set (match_dup 0) (match_dup 2))])
7397
 
7398
;; This sequence adds an instruction, but is two bytes shorter.
7399
(define_peephole2
7400
  [(match_scratch:SI 2 "d")
7401
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 12)))
7402
   (set (match_operand:SI 0 "push_operand" "")
7403
        (match_operand:SI 1 "const_int_operand" ""))]
7404
  "INTVAL (operands[1]) != 0
7405
   && IN_RANGE (INTVAL (operands[1]), -0x80, 0x7f)
7406
   && !valid_mov3q_const (INTVAL (operands[1]))"
7407
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
7408
   (set (match_dup 2) (match_dup 1))
7409
   (set (match_dup 0) (match_dup 2))]
7410
  "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
7411
 
7412
;; Changing pea X.w into a move.l is no real win here.
7413
(define_peephole2
7414
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7415
                                 (match_operand:SI 0 "const_int_operand" "")))
7416
   (set (match_operand:SI 1 "push_operand" "")
7417
        (match_operand:SI 2 "general_operand" ""))]
7418
  "INTVAL (operands[0]) > 4
7419
   && !reg_mentioned_p (stack_pointer_rtx, operands[2])
7420
   && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0
7421
        && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff)
7422
        && !valid_mov3q_const (INTVAL (operands[2])))"
7423
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
7424
   (set (match_dup 1) (match_dup 2))]
7425
{
7426
  operands[0] = GEN_INT (INTVAL (operands[0]) - 4);
7427
  operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
7428
})
7429
 
7430
;; Speed up pushing a single byte/two bytes but leaving four bytes of space
7431
;; (which differs slightly between m680x0 and ColdFire).
7432
 
7433
(define_peephole2
7434
  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
7435
   (set (match_operand:QI 0 "memory_operand" "")
7436
        (match_operand:QI 1 "register_operand" ""))]
7437
  "!reg_mentioned_p (stack_pointer_rtx, operands[1])
7438
   && GET_CODE (XEXP (operands[0], 0)) == PLUS
7439
   && rtx_equal_p (XEXP (XEXP (operands[0], 0), 0), stack_pointer_rtx)
7440
   && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
7441
   && INTVAL (XEXP (XEXP (operands[0], 0), 1)) == 3"
7442
  [(set (match_dup 0) (match_dup 1))]
7443
{
7444
  rtx addr = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
7445
  operands[0] = adjust_automodify_address (operands[0], SImode, addr, -3);
7446
  operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
7447
})
7448
 
7449
(define_peephole2
7450
  [(set (match_operand:QI 0 "push_operand" "")
7451
        (match_operand:QI 1 "register_operand" ""))
7452
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -3)))]
7453
  "!reg_mentioned_p (stack_pointer_rtx, operands[1])"
7454
  [(set (match_dup 0) (match_dup 1))]
7455
{
7456
  operands[0] = adjust_automodify_address (operands[0], SImode,
7457
                                           XEXP (operands[0], 0), -3);
7458
  operands[1] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
7459
})
7460
 
7461
(define_peephole2
7462
  [(set (match_operand:HI 0 "push_operand" "")
7463
        (match_operand:HI 1 "register_operand" ""))
7464
   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -2)))]
7465
  "!reg_mentioned_p (stack_pointer_rtx, operands[1])"
7466
  [(set (match_dup 0) (match_dup 1))]
7467
{
7468
  operands[0] = adjust_automodify_address (operands[0], SImode,
7469
                                           XEXP (operands[0], 0), -2);
7470
  operands[1] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
7471
})
7472
 
7473
;; Optimize a series of strict_low_part assignments
7474
 
7475
(define_peephole2
7476
  [(set (match_operand:SI 0 "register_operand" "")
7477
        (const_int 0))
7478
   (set (strict_low_part (match_operand:HI 1 "register_operand" ""))
7479
        (match_operand:HI 2 "general_operand" ""))]
7480
  "REGNO (operands[0]) == REGNO (operands[1])
7481
   && strict_low_part_peephole_ok (HImode, insn, operands[0])"
7482
  [(set (strict_low_part (match_dup 1)) (match_dup 2))]
7483
  "")
7484
 
7485
(define_peephole2
7486
  [(set (match_operand:SI 0 "register_operand" "")
7487
        (const_int 0))
7488
   (set (strict_low_part (match_operand:QI 1 "register_operand" ""))
7489
        (match_operand:QI 2 "general_operand" ""))]
7490
  "REGNO (operands[0]) == REGNO (operands[1])
7491
   && strict_low_part_peephole_ok (QImode, insn, operands[0])"
7492
  [(set (strict_low_part (match_dup 1)) (match_dup 2))]
7493
  "")
7494
 
7495
;; dbCC peepholes
7496
;;
7497
;; Turns
7498
;;   loop:
7499
;;           [ ... ]
7500
;;           jCC label          ; abnormal loop termination
7501
;;           dbra dN, loop      ; normal loop termination
7502
;;
7503
;; Into
7504
;;   loop:
7505
;;           [ ... ]
7506
;;           dbCC dN, loop
7507
;;           jCC label
7508
;;
7509
;; Which moves the jCC condition outside the inner loop for free.
7510
;;
7511
 
7512
(define_peephole
7513
  [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
7514
                             [(cc0) (const_int 0)])
7515
                           (label_ref (match_operand 2 "" ""))
7516
                           (pc)))
7517
   (parallel
7518
    [(set (pc)
7519
          (if_then_else
7520
            (ne (match_operand:HI 0 "register_operand" "")
7521
                (const_int 0))
7522
            (label_ref (match_operand 1 "" ""))
7523
            (pc)))
7524
     (set (match_dup 0)
7525
          (plus:HI (match_dup 0)
7526
                   (const_int -1)))])]
7527
  "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
7528
{
7529
  CC_STATUS_INIT;
7530
  output_dbcc_and_branch (operands);
7531
  return "";
7532
})
7533
 
7534
(define_peephole
7535
  [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
7536
                             [(cc0) (const_int 0)])
7537
                           (label_ref (match_operand 2 "" ""))
7538
                           (pc)))
7539
   (parallel
7540
    [(set (pc)
7541
          (if_then_else
7542
            (ne (match_operand:SI 0 "register_operand" "")
7543
                (const_int 0))
7544
            (label_ref (match_operand 1 "" ""))
7545
            (pc)))
7546
     (set (match_dup 0)
7547
          (plus:SI (match_dup 0)
7548
                   (const_int -1)))])]
7549
  "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
7550
{
7551
  CC_STATUS_INIT;
7552
  output_dbcc_and_branch (operands);
7553
  return "";
7554
})
7555
 
7556
(define_peephole
7557
  [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
7558
                             [(cc0) (const_int 0)])
7559
                           (label_ref (match_operand 2 "" ""))
7560
                           (pc)))
7561
   (parallel
7562
    [(set (pc)
7563
          (if_then_else
7564
            (ge (plus:HI (match_operand:HI 0 "register_operand" "")
7565
                         (const_int -1))
7566
                (const_int 0))
7567
            (label_ref (match_operand 1 "" ""))
7568
            (pc)))
7569
     (set (match_dup 0)
7570
          (plus:HI (match_dup 0)
7571
                   (const_int -1)))])]
7572
  "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
7573
{
7574
  CC_STATUS_INIT;
7575
  output_dbcc_and_branch (operands);
7576
  return "";
7577
})
7578
 
7579
(define_peephole
7580
  [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
7581
                             [(cc0) (const_int 0)])
7582
                           (label_ref (match_operand 2 "" ""))
7583
                           (pc)))
7584
   (parallel
7585
    [(set (pc)
7586
          (if_then_else
7587
            (ge (plus:SI (match_operand:SI 0 "register_operand" "")
7588
                         (const_int -1))
7589
                (const_int 0))
7590
            (label_ref (match_operand 1 "" ""))
7591
            (pc)))
7592
     (set (match_dup 0)
7593
          (plus:SI (match_dup 0)
7594
                   (const_int -1)))])]
7595
  "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
7596
{
7597
  CC_STATUS_INIT;
7598
  output_dbcc_and_branch (operands);
7599
  return "";
7600
})
7601
 
7602
 
7603
(define_insn "extendsfxf2"
7604
  [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f")
7605
        (float_extend:XF (match_operand:SF 1 "general_operand" "f,rmF")))]
7606
  "TARGET_68881"
7607
{
7608
  if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
7609
    {
7610
      if (REGNO (operands[0]) == REGNO (operands[1]))
7611
        {
7612
          /* Extending float to double in an fp-reg is a no-op.
7613
             NOTICE_UPDATE_CC has already assumed that the
7614
             cc will be set.  So cancel what it did.  */
7615
          cc_status = cc_prev_status;
7616
          return "";
7617
        }
7618
      return "f%$move%.x %1,%0";
7619
    }
7620
  if (FP_REG_P (operands[0]))
7621
    {
7622
      if (FP_REG_P (operands[1]))
7623
        return "f%$move%.x %1,%0";
7624
      else if (ADDRESS_REG_P (operands[1]))
7625
        return "move%.l %1,%-\;f%$move%.s %+,%0";
7626
      else if (GET_CODE (operands[1]) == CONST_DOUBLE)
7627
        return output_move_const_single (operands);
7628
      return "f%$move%.s %f1,%0";
7629
    }
7630
  return "fmove%.x %f1,%0";
7631
})
7632
 
7633
 
7634
(define_insn "extenddfxf2"
7635
  [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f")
7636
        (float_extend:XF
7637
          (match_operand:DF 1 "general_operand" "f,rmE")))]
7638
  "TARGET_68881"
7639
{
7640
  if (FP_REG_P (operands[0]) && FP_REG_P (operands[1]))
7641
    {
7642
      if (REGNO (operands[0]) == REGNO (operands[1]))
7643
        {
7644
          /* Extending float to double in an fp-reg is a no-op.
7645
             NOTICE_UPDATE_CC has already assumed that the
7646
             cc will be set.  So cancel what it did.  */
7647
          cc_status = cc_prev_status;
7648
          return "";
7649
        }
7650
      return "fmove%.x %1,%0";
7651
    }
7652
  if (FP_REG_P (operands[0]))
7653
    {
7654
      if (REG_P (operands[1]))
7655
        {
7656
          rtx xoperands[2];
7657
          xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
7658
          output_asm_insn ("move%.l %1,%-", xoperands);
7659
          output_asm_insn ("move%.l %1,%-", operands);
7660
          return "f%&move%.d %+,%0";
7661
        }
7662
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
7663
        return output_move_const_double (operands);
7664
      return "f%&move%.d %f1,%0";
7665
    }
7666
  return "fmove%.x %f1,%0";
7667
})
7668
 
7669
(define_insn "truncxfdf2"
7670
  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!r")
7671
        (float_truncate:DF
7672
          (match_operand:XF 1 "general_operand" "f,f")))]
7673
  "TARGET_68881"
7674
{
7675
  if (REG_P (operands[0]))
7676
    {
7677
      output_asm_insn ("fmove%.d %f1,%-\;move%.l %+,%0", operands);
7678
      operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
7679
      return "move%.l %+,%0";
7680
    }
7681
  return "fmove%.d %f1,%0";
7682
})
7683
 
7684
(define_insn "truncxfsf2"
7685
  [(set (match_operand:SF 0 "nonimmediate_operand" "=dm")
7686
        (float_truncate:SF
7687
          (match_operand:XF 1 "general_operand" "f")))]
7688
  "TARGET_68881"
7689
  "fmove%.s %f1,%0")
7690
 
7691
(define_insn "sin2"
7692
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
7693
        (unspec:FP
7694
          [(match_operand:FP 1 "general_operand" "fm")] UNSPEC_SIN))]
7695
  "TARGET_68881 && flag_unsafe_math_optimizations"
7696
{
7697
  if (FP_REG_P (operands[1]))
7698
    return "fsin%.x %1,%0";
7699
  else
7700
    return "fsin%. %1,%0";
7701
})
7702
 
7703
(define_insn "cos2"
7704
  [(set (match_operand:FP 0 "nonimmediate_operand" "=f")
7705
        (unspec:FP
7706
          [(match_operand:FP 1 "general_operand" "fm")] UNSPEC_COS))]
7707
  "TARGET_68881 && flag_unsafe_math_optimizations"
7708
{
7709
  if (FP_REG_P (operands[1]))
7710
    return "fcos%.x %1,%0";
7711
  else
7712
    return "fcos%. %1,%0";
7713
})
7714
 
7715
;; Unconditional traps are assumed to have (const_int 1) for the condition.
7716
(define_insn "trap"
7717
  [(trap_if (const_int 1) (const_int 7))]
7718
  ""
7719
  "trap #7"
7720
  [(set_attr "type" "trap")])
7721
 
7722
(define_expand "ctrapdi4"
7723
  [(trap_if (match_operator 0 "ordered_comparison_operator"
7724
                            [(cc0) (const_int 0)])
7725
            (match_operand:SI 3 "const1_operand" ""))]
7726
  "TARGET_68020"
7727
{
7728
  if (operands[2] == const0_rtx)
7729
    emit_insn (gen_tstdi (operands[1]));
7730
  else
7731
    emit_insn (gen_cmpdi (operands[1], operands[2]));
7732
  operands[1] = cc0_rtx;
7733
  operands[2] = const0_rtx;
7734
})
7735
 
7736
(define_expand "ctrapsi4"
7737
  [(set (cc0)
7738
        (compare (match_operand:SI 1 "nonimmediate_operand" "")
7739
                 (match_operand:SI 2 "general_operand" "")))
7740
   (trap_if (match_operator 0 "ordered_comparison_operator"
7741
                            [(cc0) (const_int 0)])
7742
            (match_operand:SI 3 "const1_operand" ""))]
7743
  "TARGET_68020"
7744
  "")
7745
 
7746
(define_expand "ctraphi4"
7747
  [(set (cc0)
7748
        (compare (match_operand:HI 1 "nonimmediate_src_operand" "")
7749
                 (match_operand:HI 2 "general_src_operand" "")))
7750
   (trap_if (match_operator 0 "ordered_comparison_operator"
7751
                            [(cc0) (const_int 0)])
7752
            (match_operand:SI 3 "const1_operand" ""))]
7753
  "TARGET_68020"
7754
  "")
7755
 
7756
(define_expand "ctrapqi4"
7757
  [(set (cc0)
7758
        (compare (match_operand:QI 1 "nonimmediate_src_operand" "")
7759
                 (match_operand:QI 2 "general_src_operand" "")))
7760
   (trap_if (match_operator 0 "ordered_comparison_operator"
7761
                            [(cc0) (const_int 0)])
7762
            (match_operand:SI 3 "const1_operand" ""))]
7763
  "TARGET_68020"
7764
  "")
7765
 
7766
(define_insn "*conditional_trap"
7767
  [(trap_if (match_operator 0 "ordered_comparison_operator"
7768
                            [(cc0) (const_int 0)])
7769
            (match_operand:SI 1 "const1_operand" "I"))]
7770
  "TARGET_68020 && ! flags_in_68881 ()"
7771
{
7772
  switch (GET_CODE (operands[0]))
7773
  {
7774
  case EQ:  return "trapeq";
7775
  case NE:  return "trapne";
7776
  case GT:  return "trapgt";
7777
  case GTU: return "traphi";
7778
  case LT:  return "traplt";
7779
  case LTU: return "trapcs";
7780
  case GE:  return "trapge";
7781
  case GEU: return "trapcc";
7782
  case LE:  return "traple";
7783
  case LEU: return "trapls";
7784
  default: gcc_unreachable ();
7785
  }
7786
})
7787
 
7788
;; These are to prevent the scheduler from moving stores to the frame
7789
;; before the stack adjustment.
7790
(define_insn "stack_tie"
7791
  [(set (mem:BLK (scratch))
7792
        (unspec:BLK [(match_operand:SI 0 "register_operand" "r")
7793
                     (match_operand:SI 1 "register_operand" "r")]
7794
                    UNSPEC_TIE))]
7795
  ""
7796
  ""
7797
  [(set_attr "type" "ignore")])
7798
 
7799
;; Instruction that subscribes one word in ColdFire instruction buffer.
7800
;; This instruction is used within scheduler only and should not appear
7801
;; in the instruction stream.
7802
(define_insn "ib"
7803
  [(unspec [(const_int 0)] UNSPEC_IB)]
7804
  ""
7805
  "#"
7806
  [(set_attr "type" "ib")])
7807
 
7808
(include "cf.md")

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.