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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [m68k/] [m68k.md] - Blame information for rev 820

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

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

powered by: WebSVN 2.1.0

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