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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [config/] [mn10300/] [mn10300.md] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
;; GCC machine description for Matsushita MN10300
2
;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3
;; Free Software Foundation, Inc.
4
;; Contributed by Jeff Law (law@cygnus.com).
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 2, 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 COPYING.  If not, write to
20
;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21
;; Boston, MA 02110-1301, USA.
22
 
23
;; The original PO technology requires these to be ordered by speed,
24
;; so that assigner will pick the fastest.
25
 
26
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
 
28
;; Condition code settings.
29
;; none - insn does not affect cc
30
;; none_0hit - insn does not affect cc but it does modify operand 0
31
;;      This attribute is used to keep track of when operand 0 changes.
32
;;      See the description of NOTICE_UPDATE_CC for more info.
33
;; set_znv - insn sets z,n,v to usable values; c is unusable.
34
;; set_zn  - insn sets z,n to usable values; v,c are unusable.
35
;; compare - compare instruction
36
;; clobber - value of cc is unknown
37
(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
38
  (const_string "clobber"))
39
 
40
(define_constants [
41
  (PIC_REG      6)
42
  (SP_REG       9)
43
 
44
  (UNSPEC_INT_LABEL     0)
45
  (UNSPEC_PIC           1)
46
  (UNSPEC_GOT           2)
47
  (UNSPEC_GOTOFF        3)
48
  (UNSPEC_PLT           4)
49
])
50
 
51
(include "predicates.md")
52
 
53
;; ----------------------------------------------------------------------
54
;; MOVE INSTRUCTIONS
55
;; ----------------------------------------------------------------------
56
 
57
;; movqi
58
 
59
(define_expand "movqi"
60
  [(set (match_operand:QI 0 "general_operand" "")
61
        (match_operand:QI 1 "general_operand" ""))]
62
  ""
63
  "
64
{
65
  /* One of the ops has to be in a register */
66
  if (!register_operand (operand0, QImode)
67
      && !register_operand (operand1, QImode))
68
    operands[1] = copy_to_mode_reg (QImode, operand1);
69
}")
70
 
71
(define_insn ""
72
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
73
        (match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa,d*xa*f,*f"))]
74
  "TARGET_AM33
75
   && (register_operand (operands[0], QImode)
76
       || register_operand (operands[1], QImode))"
77
  "*
78
{
79
  switch (which_alternative)
80
    {
81
    case 0:
82
      return \"nop\";
83
    case 1:
84
      return \"clr %0\";
85
    case 2:
86
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
87
        {
88
          rtx xoperands[2];
89
          xoperands[0] = operands[0];
90
          xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
91
          output_asm_insn (\"mov %1,%0\", xoperands);
92
          return \"\";
93
        }
94
 
95
      if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
96
          && GET_CODE (operands[1]) == CONST_INT)
97
        {
98
          HOST_WIDE_INT val = INTVAL (operands[1]);
99
 
100
          if (((val & 0x80) && ! (val & 0xffffff00))
101
              || ((val & 0x800000) && ! (val & 0xff000000)))
102
            return \"movu %1,%0\";
103
        }
104
      return \"mov %1,%0\";
105
    case 3:
106
    case 4:
107
      return \"movbu %1,%0\";
108
    case 5:
109
    case 6:
110
      return \"fmov %1,%0\";
111
    default:
112
      gcc_unreachable ();
113
    }
114
}"
115
  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
116
 
117
(define_insn ""
118
  [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
119
        (match_operand:QI 1 "general_operand" "0,I,dai,m,d"))]
120
  "register_operand (operands[0], QImode)
121
   || register_operand (operands[1], QImode)"
122
  "*
123
{
124
  switch (which_alternative)
125
    {
126
    case 0:
127
      return \"nop\";
128
    case 1:
129
      return \"clr %0\";
130
    case 2:
131
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
132
        {
133
          rtx xoperands[2];
134
          xoperands[0] = operands[0];
135
          xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
136
          output_asm_insn (\"mov %1,%0\", xoperands);
137
          return \"\";
138
        }
139
 
140
      return \"mov %1,%0\";
141
    case 3:
142
    case 4:
143
      return \"movbu %1,%0\";
144
    default:
145
      gcc_unreachable ();
146
    }
147
}"
148
  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
149
 
150
;; movhi
151
 
152
(define_expand "movhi"
153
  [(set (match_operand:HI 0 "general_operand" "")
154
        (match_operand:HI 1 "general_operand" ""))]
155
  ""
156
  "
157
{
158
  /* One of the ops has to be in a register */
159
  if (!register_operand (operand1, HImode)
160
      && !register_operand (operand0, HImode))
161
    operands[1] = copy_to_mode_reg (HImode, operand1);
162
}")
163
 
164
(define_insn ""
165
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
166
        (match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
167
  "TARGET_AM33
168
   && (register_operand (operands[0], HImode)
169
       || register_operand (operands[1], HImode))"
170
  "*
171
{
172
  switch (which_alternative)
173
    {
174
    case 0:
175
      return \"nop\";
176
    case 1:
177
      return \"clr %0\";
178
    case 2:
179
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
180
        {
181
          rtx xoperands[2];
182
          xoperands[0] = operands[0];
183
          xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
184
          output_asm_insn (\"mov %1,%0\", xoperands);
185
          return \"\";
186
        }
187
 
188
      if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
189
          && GET_CODE (operands[1]) == CONST_INT)
190
        {
191
          HOST_WIDE_INT val = INTVAL (operands[1]);
192
 
193
          if (((val & 0x80) && ! (val & 0xffffff00))
194
              || ((val & 0x800000) && ! (val & 0xff000000)))
195
            return \"movu %1,%0\";
196
        }
197
      return \"mov %1,%0\";
198
    case 3:
199
    case 4:
200
      return \"movhu %1,%0\";
201
    case 5:
202
    case 6:
203
      return \"fmov %1,%0\";
204
    default:
205
      gcc_unreachable ();
206
    }
207
}"
208
  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
209
 
210
(define_insn ""
211
  [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
212
        (match_operand:HI 1 "general_operand" "0,I,dai,m,d"))]
213
  "register_operand (operands[0], HImode)
214
   || register_operand (operands[1], HImode)"
215
  "*
216
{
217
  switch (which_alternative)
218
    {
219
    case 0:
220
      return \"nop\";
221
    case 1:
222
      return \"clr %0\";
223
    case 2:
224
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
225
        {
226
          rtx xoperands[2];
227
          xoperands[0] = operands[0];
228
          xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
229
          output_asm_insn (\"mov %1,%0\", xoperands);
230
          return \"\";
231
        }
232
      return \"mov %1,%0\";
233
    case 3:
234
    case 4:
235
      return \"movhu %1,%0\";
236
    default:
237
      gcc_unreachable ();
238
    }
239
}"
240
  [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
241
 
242
;; movsi and helpers
243
 
244
;; We use this to handle addition of two values when one operand is the
245
;; stack pointer and the other is a memory reference of some kind.  Reload
246
;; does not handle them correctly without this expander.
247
(define_expand "reload_insi"
248
  [(set (match_operand:SI 0 "register_operand" "=a")
249
        (match_operand:SI 1 "impossible_plus_operand" ""))
250
   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
251
  ""
252
  "
253
{
254
  if (XEXP (operands[1], 0) == stack_pointer_rtx)
255
    {
256
      if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
257
          && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 1)))
258
              > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 1))))))
259
        emit_move_insn (operands[2],
260
                        gen_rtx_ZERO_EXTEND
261
                        (GET_MODE (XEXP (operands[1], 1)),
262
                         SUBREG_REG (XEXP (operands[1], 1))));
263
      else
264
        emit_move_insn (operands[2], XEXP (operands[1], 1));
265
      emit_move_insn (operands[0], XEXP (operands[1], 0));
266
    }
267
  else
268
    {
269
      if (GET_CODE (XEXP (operands[1], 0)) == SUBREG
270
          && (GET_MODE_SIZE (GET_MODE (XEXP (operands[1], 0)))
271
              > GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (operands[1], 0))))))
272
        emit_move_insn (operands[2],
273
                        gen_rtx_ZERO_EXTEND
274
                        (GET_MODE (XEXP (operands[1], 0)),
275
                         SUBREG_REG (XEXP (operands[1], 0))));
276
      else
277
        emit_move_insn (operands[2], XEXP (operands[1], 0));
278
      emit_move_insn (operands[0], XEXP (operands[1], 1));
279
    }
280
  emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
281
  DONE;
282
}")
283
 
284
(define_insn "pop_pic_reg"
285
  [(set (reg:SI PIC_REG)
286
        (mem:SI (post_inc:SI (reg:SI SP_REG))))]
287
  "reload_completed"
288
  "movm (sp),[a2]")
289
 
290
(define_expand "movsi"
291
  [(set (match_operand:SI 0 "general_operand" "")
292
        (match_operand:SI 1 "general_operand" ""))]
293
  ""
294
  "
295
{
296
  /* One of the ops has to be in a register */
297
  if (!register_operand (operand1, SImode)
298
      && !register_operand (operand0, SImode))
299
    operands[1] = copy_to_mode_reg (SImode, operand1);
300
  if (flag_pic)
301
    {
302
      rtx temp;
303
      if (SYMBOLIC_CONST_P (operands[1]))
304
        {
305
          if (GET_CODE (operands[0]) == MEM)
306
            operands[1] = force_reg (Pmode, operands[1]);
307
          else
308
            {
309
              temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
310
              operands[1] = legitimize_pic_address (operands[1], temp);
311
            }
312
        }
313
      else if (GET_CODE (operands[1]) == CONST
314
               && GET_CODE (XEXP (operands[1], 0)) == PLUS
315
               && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
316
        {
317
          temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
318
          temp = legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
319
                                         temp);
320
          operands[1] = expand_binop (SImode, add_optab, temp,
321
                                      XEXP (XEXP (operands[1], 0), 1),
322
                                      no_new_pseudos ? temp
323
                                      : gen_reg_rtx (Pmode),
324
                                      0, OPTAB_LIB_WIDEN);
325
        }
326
    }
327
}")
328
 
329
(define_insn ""
330
  [(set (match_operand:SI 0 "nonimmediate_operand"
331
                                "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
332
        (match_operand:SI 1 "general_operand"
333
                                "0,0,I,I,dx,ax,dx,ax,dixm,aixm,dixm,aixm,!*y,axR,0,dxaQi*f,*f"))]
334
  "register_operand (operands[0], SImode)
335
   || register_operand (operands[1], SImode)"
336
  "*
337
{
338
  switch (which_alternative)
339
    {
340
    case 0:
341
    case 1:
342
      return \"nop\";
343
    case 2:
344
      return \"clr %0\";
345
    case 3:
346
    case 4:
347
    case 5:
348
    case 6:
349
    case 7:
350
    case 8:
351
    case 9:
352
    case 10:
353
    case 11:
354
    case 12:
355
    case 13:
356
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
357
        {
358
          rtx xoperands[2];
359
          xoperands[0] = operands[0];
360
          xoperands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
361
          output_asm_insn (\"mov %1,%0\", xoperands);
362
          return \"\";
363
        }
364
 
365
      if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
366
          && GET_CODE (operands[1]) == CONST_INT)
367
        {
368
          HOST_WIDE_INT val = INTVAL (operands[1]);
369
 
370
          if (((val & 0x80) && ! (val & 0xffffff00))
371
              || ((val & 0x800000) && ! (val & 0xff000000)))
372
            return \"movu %1,%0\";
373
        }
374
      return \"mov %1,%0\";
375
    case 14:
376
      return \"nop\";
377
    case 15:
378
    case 16:
379
      return \"fmov %1,%0\";
380
    default:
381
      gcc_unreachable ();
382
    }
383
}"
384
  [(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none,none_0hit,none_0hit")])
385
 
386
(define_expand "movsf"
387
  [(set (match_operand:SF 0 "general_operand" "")
388
        (match_operand:SF 1 "general_operand" ""))]
389
  ""
390
  "
391
{
392
  /* One of the ops has to be in a register */
393
  if (!register_operand (operand1, SFmode)
394
      && !register_operand (operand0, SFmode))
395
    operands[1] = copy_to_mode_reg (SFmode, operand1);
396
}")
397
 
398
(define_insn ""
399
  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
400
        (match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
401
  "register_operand (operands[0], SFmode)
402
   || register_operand (operands[1], SFmode)"
403
  "*
404
{
405
  switch (which_alternative)
406
    {
407
    case 0:
408
    case 1:
409
    case 2:
410
      return \"nop\";
411
    case 3:
412
      return \"clr %0\";
413
    /* case 4: below */
414
    case 5:
415
    case 6:
416
      return \"fmov %1, %0\";
417
    case 4:
418
    case 7:
419
    case 8:
420
      if (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS
421
          && GET_CODE (operands[1]) == CONST_INT)
422
        {
423
          HOST_WIDE_INT val = INTVAL (operands[1]);
424
 
425
          if (((val & 0x80) && ! (val & 0xffffff00))
426
              || ((val & 0x800000) && ! (val & 0xff000000)))
427
            return \"movu %1,%0\";
428
        }
429
      return \"mov %1,%0\";
430
    default:
431
      gcc_unreachable ();
432
    }
433
}"
434
  [(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
435
 
436
(define_expand "movdi"
437
  [(set (match_operand:DI 0 "general_operand" "")
438
        (match_operand:DI 1 "general_operand" ""))]
439
  ""
440
  "
441
{
442
  /* One of the ops has to be in a register */
443
  if (!register_operand (operand1, DImode)
444
      && !register_operand (operand0, DImode))
445
    operands[1] = copy_to_mode_reg (DImode, operand1);
446
}")
447
 
448
(define_insn ""
449
  [(set (match_operand:DI 0 "nonimmediate_operand"
450
                                "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
451
        (match_operand:DI 1 "general_operand"
452
                                "0,0,I,I,dx,ax,dx,ax,dxim,axim,dxim,axim,0,*f,dxai,*f,Q,*f"))]
453
  "register_operand (operands[0], DImode)
454
   || register_operand (operands[1], DImode)"
455
  "*
456
{
457
  long val[2];
458
  REAL_VALUE_TYPE rv;
459
 
460
  switch (which_alternative)
461
    {
462
      case 0:
463
      case 1:
464
        return \"nop\";
465
 
466
      case 2:
467
        return \"clr %L0\;clr %H0\";
468
 
469
      case 3:
470
        if (rtx_equal_p (operands[0], operands[1]))
471
          return \"sub %L1,%L0\;mov %L0,%H0\";
472
        else
473
          return \"mov %1,%L0\;mov %L0,%H0\";
474
      case 4:
475
      case 5:
476
      case 6:
477
      case 7:
478
      case 8:
479
      case 9:
480
      case 10:
481
      case 11:
482
        if (GET_CODE (operands[1]) == CONST_INT)
483
          {
484
            rtx low, high;
485
            split_double (operands[1], &low, &high);
486
            val[0] = INTVAL (low);
487
            val[1] = INTVAL (high);
488
          }
489
        if (GET_CODE (operands[1]) == CONST_DOUBLE)
490
          {
491
            if (GET_MODE (operands[1]) == DFmode)
492
              {
493
                REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
494
                REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
495
              }
496
            else if (GET_MODE (operands[1]) == VOIDmode
497
                     || GET_MODE (operands[1]) == DImode)
498
              {
499
                val[0] = CONST_DOUBLE_LOW (operands[1]);
500
                val[1] = CONST_DOUBLE_HIGH (operands[1]);
501
              }
502
          }
503
 
504
        if (GET_CODE (operands[1]) == MEM
505
            && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
506
          {
507
            rtx temp = operands[0];
508
 
509
            while (GET_CODE (temp) == SUBREG)
510
              temp = SUBREG_REG (temp);
511
 
512
            gcc_assert (GET_CODE (temp) == REG);
513
 
514
            if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
515
                                         XEXP (operands[1], 0)))
516
              return \"mov %H1,%H0\;mov %L1,%L0\";
517
            else
518
              return \"mov %L1,%L0\;mov %H1,%H0\";
519
 
520
          }
521
        else if (GET_CODE (operands[1]) == MEM
522
                 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
523
                 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
524
          {
525
            rtx xoperands[2];
526
 
527
            xoperands[0] = operands[0];
528
            xoperands[1] = XEXP (operands[1], 0);
529
 
530
            output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
531
                             xoperands);
532
            return \"\";
533
          }
534
        else
535
          {
536
            if ((GET_CODE (operands[1]) == CONST_INT
537
                 || GET_CODE (operands[1]) == CONST_DOUBLE)
538
                && val[0] == 0)
539
              {
540
                if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
541
                  output_asm_insn (\"clr %L0\", operands);
542
                else
543
                  output_asm_insn (\"mov %L1,%L0\", operands);
544
              }
545
            else if ((GET_CODE (operands[1]) == CONST_INT
546
                      || GET_CODE (operands[1]) == CONST_DOUBLE)
547
                     && (REGNO_REG_CLASS (true_regnum (operands[0]))
548
                         == EXTENDED_REGS)
549
                     && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
550
                         || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
551
              output_asm_insn (\"movu %L1,%L0\", operands);
552
            else
553
              output_asm_insn (\"mov %L1,%L0\", operands);
554
 
555
            if ((GET_CODE (operands[1]) == CONST_INT
556
                 || GET_CODE (operands[1]) == CONST_DOUBLE)
557
                && val[1] == 0)
558
              {
559
                if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
560
                  output_asm_insn (\"clr %H0\", operands);
561
                else
562
                  output_asm_insn (\"mov %H1,%H0\", operands);
563
              }
564
            else if ((GET_CODE (operands[1]) == CONST_INT
565
                      || GET_CODE (operands[1]) == CONST_DOUBLE)
566
                     && val[0] == val[1])
567
              output_asm_insn (\"mov %L0,%H0\", operands);
568
            else if ((GET_CODE (operands[1]) == CONST_INT
569
                      || GET_CODE (operands[1]) == CONST_DOUBLE)
570
                     && (REGNO_REG_CLASS (true_regnum (operands[0]))
571
                         == EXTENDED_REGS)
572
                     && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
573
                         || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
574
              output_asm_insn (\"movu %H1,%H0\", operands);
575
            else
576
              output_asm_insn (\"mov %H1,%H0\", operands);
577
            return \"\";
578
          }
579
      case 12:
580
        return \"nop\";
581
      case 13:
582
      case 14:
583
      case 15:
584
        return \"fmov %L1, %L0\;fmov %H1, %H0\";
585
      case 16:
586
        if (GET_CODE (operands[1]) == MEM
587
            && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
588
            && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
589
          return \"fmov %D1, %D0\";
590
        else
591
          return \"fmov %L1, %L0\;fmov %H1, %H0\";
592
      case 17:
593
        if (GET_CODE (operands[0]) == MEM
594
            && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
595
            && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
596
          return \"fmov %D1, %D0\";
597
        else
598
          return \"fmov %L1, %L0\;fmov %H1, %H0\";
599
    default:
600
      gcc_unreachable ();
601
    }
602
}"
603
  [(set (attr "cc")
604
        (cond
605
         [
606
         (ior (lt (symbol_ref "which_alternative") (const_int 2))
607
              (eq (symbol_ref "which_alternative") (const_int 12))
608
              ) (const_string "none")
609
         (eq (symbol_ref "which_alternative") (const_int 2)
610
             ) (const_string "clobber")
611
         (eq (symbol_ref "which_alternative") (const_int 3)
612
             ) (if_then_else
613
                (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
614
                    (const_int 0)) (const_string "clobber")
615
                    (const_string "none_0hit"))
616
         (ior (eq (symbol_ref "which_alternative") (const_int 8))
617
              (eq (symbol_ref "which_alternative") (const_int 9))
618
              ) (if_then_else
619
                 (ne (symbol_ref "mn10300_wide_const_load_uses_clr
620
                                  (operands)")
621
                     (const_int 0)) (const_string "clobber")
622
                     (const_string "none_0hit"))
623
         ] (const_string "none_0hit")))])
624
 
625
(define_expand "movdf"
626
  [(set (match_operand:DF 0 "general_operand" "")
627
        (match_operand:DF 1 "general_operand" ""))]
628
  ""
629
  "
630
{
631
  /* One of the ops has to be in a register */
632
  if (!register_operand (operand1, DFmode)
633
      && !register_operand (operand0, DFmode))
634
    operands[1] = copy_to_mode_reg (DFmode, operand1);
635
}")
636
 
637
(define_insn ""
638
  [(set (match_operand:DF 0 "nonimmediate_operand"
639
                                "=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
640
        (match_operand:DF 1 "general_operand"
641
                                "0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
642
  "register_operand (operands[0], DFmode)
643
   || register_operand (operands[1], DFmode)"
644
  "*
645
{
646
  long val[2];
647
  REAL_VALUE_TYPE rv;
648
 
649
  switch (which_alternative)
650
    {
651
      case 0:
652
      case 1:
653
      case 2:
654
        return \"nop\";
655
 
656
      case 3:
657
        return \"clr %L0\;clr %H0\";
658
 
659
      case 4:
660
      case 5:
661
      case 6:
662
        return \"fmov %L1, %L0\;fmov %H1, %H0\";
663
 
664
      case 7:
665
        if (GET_CODE (operands[1]) == MEM
666
            && GET_CODE (XEXP (operands[1], 0)) == CONST_INT
667
            && (INTVAL (XEXP (operands[1], 0)) & 7) == 0)
668
          return \"fmov %D1, %D0\";
669
        else
670
          return \"fmov %L1, %L0\;fmov %H1, %H0\";
671
 
672
      case 8:
673
        if (GET_CODE (operands[0]) == MEM
674
            && GET_CODE (XEXP (operands[0], 0)) == CONST_INT
675
            && (INTVAL (XEXP (operands[0], 0)) & 7) == 0)
676
          return \"fmov %D1, %D0\";
677
        else
678
          return \"fmov %L1, %L0\;fmov %H1, %H0\";
679
 
680
      case 9:
681
         if (rtx_equal_p (operands[0], operands[1]))
682
           return \"sub %L1,%L0\;mov %L0,%H0\";
683
         else
684
           return \"mov %1,%L0\;mov %L0,%H0\";
685
      case 10:
686
      case 11:
687
      case 12:
688
      case 13:
689
      case 14:
690
      case 15:
691
      case 16:
692
      case 17:
693
        if (GET_CODE (operands[1]) == CONST_INT)
694
          {
695
            rtx low, high;
696
            split_double (operands[1], &low, &high);
697
            val[0] = INTVAL (low);
698
            val[1] = INTVAL (high);
699
          }
700
        if (GET_CODE (operands[1]) == CONST_DOUBLE)
701
          {
702
            if (GET_MODE (operands[1]) == DFmode)
703
              {
704
                REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
705
                REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
706
              }
707
            else if (GET_MODE (operands[1]) == VOIDmode
708
                     || GET_MODE (operands[1]) == DImode)
709
              {
710
                val[0] = CONST_DOUBLE_LOW (operands[1]);
711
                val[1] = CONST_DOUBLE_HIGH (operands[1]);
712
              }
713
          }
714
 
715
        if (GET_CODE (operands[1]) == MEM
716
            && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
717
          {
718
            rtx temp = operands[0];
719
 
720
            while (GET_CODE (temp) == SUBREG)
721
              temp = SUBREG_REG (temp);
722
 
723
            gcc_assert (GET_CODE (temp) == REG);
724
 
725
            if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
726
                                         XEXP (operands[1], 0)))
727
              return \"mov %H1,%H0\;mov %L1,%L0\";
728
            else
729
              return \"mov %L1,%L0\;mov %H1,%H0\";
730
 
731
          }
732
        else if (GET_CODE (operands[1]) == MEM
733
                 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
734
                 && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
735
          {
736
            rtx xoperands[2];
737
 
738
            xoperands[0] = operands[0];
739
            xoperands[1] = XEXP (operands[1], 0);
740
 
741
            output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
742
                             xoperands);
743
            return \"\";
744
          }
745
        else
746
          {
747
            if ((GET_CODE (operands[1]) == CONST_INT
748
                 || GET_CODE (operands[1]) == CONST_DOUBLE)
749
                && val[0] == 0)
750
              {
751
                if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
752
                  output_asm_insn (\"clr %L0\", operands);
753
                else
754
                  output_asm_insn (\"mov %L1,%L0\", operands);
755
              }
756
            else if ((GET_CODE (operands[1]) == CONST_INT
757
                      || GET_CODE (operands[1]) == CONST_DOUBLE)
758
                     && (REGNO_REG_CLASS (true_regnum (operands[0]))
759
                         == EXTENDED_REGS)
760
                     && (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
761
                         || ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
762
              output_asm_insn (\"movu %L1,%L0\", operands);
763
            else
764
              output_asm_insn (\"mov %L1,%L0\", operands);
765
 
766
            if ((GET_CODE (operands[1]) == CONST_INT
767
                 || GET_CODE (operands[1]) == CONST_DOUBLE)
768
                && val[1] == 0)
769
              {
770
                if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
771
                  output_asm_insn (\"clr %H0\", operands);
772
                else
773
                  output_asm_insn (\"mov %H1,%H0\", operands);
774
              }
775
            else if ((GET_CODE (operands[1]) == CONST_INT
776
                      || GET_CODE (operands[1]) == CONST_DOUBLE)
777
                     && val[0] == val[1])
778
              output_asm_insn (\"mov %L0,%H0\", operands);
779
            else if ((GET_CODE (operands[1]) == CONST_INT
780
                      || GET_CODE (operands[1]) == CONST_DOUBLE)
781
                     && (REGNO_REG_CLASS (true_regnum (operands[0]))
782
                         == EXTENDED_REGS)
783
                     && (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
784
                         || ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
785
              output_asm_insn (\"movu %H1,%H0\", operands);
786
            else
787
              output_asm_insn (\"mov %H1,%H0\", operands);
788
            return \"\";
789
          }
790
    default:
791
      gcc_unreachable ();
792
    }
793
}"
794
  [(set (attr "cc")
795
        (cond
796
         [
797
         (lt (symbol_ref "which_alternative") (const_int 3)
798
             ) (const_string "none")
799
         (eq (symbol_ref "which_alternative") (const_int 3)
800
             ) (const_string "clobber")
801
         (eq (symbol_ref "which_alternative") (const_int 9)
802
             ) (if_then_else
803
                (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
804
                    (const_int 0)) (const_string "clobber")
805
                    (const_string "none_0hit"))
806
         (ior (eq (symbol_ref "which_alternative") (const_int 14))
807
              (eq (symbol_ref "which_alternative") (const_int 15))
808
              ) (if_then_else
809
                 (ne (symbol_ref "mn10300_wide_const_load_uses_clr
810
                                  (operands)")
811
                     (const_int 0)) (const_string "clobber")
812
                     (const_string "none_0hit"))
813
         ] (const_string "none_0hit")))])
814
 
815
 
816
 
817
;; ----------------------------------------------------------------------
818
;; TEST INSTRUCTIONS
819
;; ----------------------------------------------------------------------
820
 
821
;; Go ahead and define tstsi so we can eliminate redundant tst insns
822
;; when we start trying to optimize this port.
823
(define_insn "tstsi"
824
  [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
825
  ""
826
  "* return output_tst (operands[0], insn);"
827
  [(set_attr "cc" "set_znv")])
828
 
829
(define_insn ""
830
  [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
831
  "TARGET_AM33"
832
  "* return output_tst (operands[0], insn);"
833
  [(set_attr "cc" "set_znv")])
834
 
835
(define_insn ""
836
  [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
837
  ""
838
  "* return output_tst (operands[0], insn);"
839
  [(set_attr "cc" "set_znv")])
840
 
841
(define_insn ""
842
  [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
843
  "TARGET_AM33"
844
  "* return output_tst (operands[0], insn);"
845
  [(set_attr "cc" "set_znv")])
846
 
847
(define_insn ""
848
  [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
849
  ""
850
  "* return output_tst (operands[0], insn);"
851
  [(set_attr "cc" "set_znv")])
852
 
853
;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
854
;; its operands hold equal values, but the operands of a cmp
855
;; instruction must be distinct registers.  In the case where we'd
856
;; like to compare a register to itself, we can achieve this effect
857
;; with a btst 0,d0 instead.  (This will not alter the contents of d0
858
;; but will have the proper effect on cc0.  Using d0 is arbitrary; any
859
;; data register would work.)
860
 
861
;; Even though the first alternative would be preferable if it can
862
;; possibly match, reload must not be given the opportunity to attempt
863
;; to use it.  It assumes that such matches can only occur when one of
864
;; the operands is used for input and the other for output.  Since
865
;; this is not the case, it abort()s.  Indeed, such a reload cannot be
866
;; possibly satisfied, so just mark the alternative with a `!', so
867
;; that it is not considered by reload.
868
 
869
(define_insn "cmpsi"
870
  [(set (cc0)
871
        (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
872
                 (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
873
  ""
874
  "@
875
  btst 0,d0
876
  cmp %1,%0"
877
  [(set_attr "cc" "compare,compare")])
878
 
879
(define_insn "cmpsf"
880
  [(set (cc0)
881
        (compare (match_operand:SF 0 "register_operand" "f,f")
882
                 (match_operand:SF 1 "nonmemory_operand" "f,F")))]
883
  "TARGET_AM33_2"
884
  "fcmp %1,%0"
885
  [(set_attr "cc" "compare,compare")])
886
 
887
;; ----------------------------------------------------------------------
888
;; ADD INSTRUCTIONS
889
;; ----------------------------------------------------------------------
890
 
891
(define_expand "addsi3"
892
  [(set (match_operand:SI 0 "register_operand" "")
893
        (plus:SI (match_operand:SI 1 "register_operand" "")
894
                 (match_operand:SI 2 "nonmemory_operand" "")))]
895
  ""
896
  "")
897
 
898
(define_insn ""
899
  [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
900
        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
901
                 (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
902
  "TARGET_AM33"
903
  "*
904
{
905
  switch (which_alternative)
906
    {
907
    case 0:
908
    case 1:
909
      return \"inc %0\";
910
    case 2:
911
    case 3:
912
      return \"inc4 %0\";
913
    case 4:
914
    case 5:
915
      return \"add %2,%0\";
916
    case 6:
917
      {
918
        enum reg_class src1_class, src2_class, dst_class;
919
 
920
        src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
921
        src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
922
        dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
923
 
924
        /* I'm not sure if this can happen or not.  Might as well be prepared
925
          and generate the best possible code if it does happen.  */
926
        if (true_regnum (operands[0]) == true_regnum (operands[1]))
927
          return \"add %2,%0\";
928
        if (true_regnum (operands[0]) == true_regnum (operands[2]))
929
          return \"add %1,%0\";
930
 
931
        /* Catch cases where no extended register was used.  These should be
932
           handled just like the mn10300.  */
933
        if (src1_class != EXTENDED_REGS
934
            && src2_class != EXTENDED_REGS
935
            && dst_class != EXTENDED_REGS)
936
          {
937
            /* We have to copy one of the sources into the destination, then
938
               add the other source to the destination.
939
 
940
               Carefully select which source to copy to the destination; a naive
941
               implementation will waste a byte when the source classes are
942
               different and the destination is an address register.  Selecting
943
               the lowest cost register copy will optimize this sequence.  */
944
            if (REGNO_REG_CLASS (true_regnum (operands[1]))
945
                == REGNO_REG_CLASS (true_regnum (operands[0])))
946
              return \"mov %1,%0\;add %2,%0\";
947
            return \"mov %2,%0\;add %1,%0\";
948
          }
949
 
950
        /* At least one register is an extended register.  */
951
 
952
        /* The three operand add instruction on the am33 is a win iff the
953
           output register is an extended register, or if both source
954
           registers are extended registers.  */
955
        if (dst_class == EXTENDED_REGS
956
            || src1_class == src2_class)
957
          return \"add %2,%1,%0\";
958
 
959
      /* It is better to copy one of the sources to the destination, then
960
         perform a 2 address add.  The destination in this case must be
961
         an address or data register and one of the sources must be an
962
         extended register and the remaining source must not be an extended
963
         register.
964
 
965
         The best code for this case is to copy the extended reg to the
966
         destination, then emit a two address add.  */
967
      if (src1_class == EXTENDED_REGS)
968
        return \"mov %1,%0\;add %2,%0\";
969
      return \"mov %2,%0\;add %1,%0\";
970
      }
971
    default:
972
      gcc_unreachable ();
973
    }
974
}"
975
  [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
976
 
977
(define_insn ""
978
  [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
979
        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
980
                 (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
981
  ""
982
  "*
983
{
984
  switch (which_alternative)
985
    {
986
    case 0:
987
    case 1:
988
      return \"inc %0\";
989
    case 2:
990
      return \"inc4 %0\";
991
    case 3:
992
    case 4:
993
      return \"add %2,%0\";
994
    case 5:
995
      /* I'm not sure if this can happen or not.  Might as well be prepared
996
         and generate the best possible code if it does happen.  */
997
      if (true_regnum (operands[0]) == true_regnum (operands[1]))
998
        return \"add %2,%0\";
999
      if (true_regnum (operands[0]) == true_regnum (operands[2]))
1000
        return \"add %1,%0\";
1001
 
1002
      /* We have to copy one of the sources into the destination, then add
1003
         the other source to the destination.
1004
 
1005
         Carefully select which source to copy to the destination; a naive
1006
         implementation will waste a byte when the source classes are different
1007
         and the destination is an address register.  Selecting the lowest
1008
         cost register copy will optimize this sequence.  */
1009
      if (REGNO_REG_CLASS (true_regnum (operands[1]))
1010
          == REGNO_REG_CLASS (true_regnum (operands[0])))
1011
        return \"mov %1,%0\;add %2,%0\";
1012
      return \"mov %2,%0\;add %1,%0\";
1013
    default:
1014
      gcc_unreachable ();
1015
    }
1016
}"
1017
  [(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
1018
 
1019
;; ----------------------------------------------------------------------
1020
;; SUBTRACT INSTRUCTIONS
1021
;; ----------------------------------------------------------------------
1022
 
1023
(define_expand "subsi3"
1024
  [(set (match_operand:SI 0 "register_operand" "")
1025
        (minus:SI (match_operand:SI 1 "register_operand" "")
1026
                  (match_operand:SI 2 "nonmemory_operand" "")))]
1027
  ""
1028
  "")
1029
 
1030
(define_insn ""
1031
  [(set (match_operand:SI 0 "register_operand" "=dax,!dax")
1032
        (minus:SI (match_operand:SI 1 "register_operand" "0,dax")
1033
                  (match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
1034
  "TARGET_AM33"
1035
  "*
1036
{
1037
  if (true_regnum (operands[0]) == true_regnum (operands[1]))
1038
    return \"sub %2,%0\";
1039
  else
1040
    {
1041
      enum reg_class src1_class, src2_class, dst_class;
1042
 
1043
      src1_class = REGNO_REG_CLASS (true_regnum (operands[1]));
1044
      src2_class = REGNO_REG_CLASS (true_regnum (operands[2]));
1045
      dst_class = REGNO_REG_CLASS (true_regnum (operands[0]));
1046
 
1047
      /* If no extended registers are used, then the best way to handle
1048
         this is to copy the first source operand into the destination
1049
         and emit a two address subtraction.  */
1050
      if (src1_class != EXTENDED_REGS
1051
          && src2_class != EXTENDED_REGS
1052
          && dst_class != EXTENDED_REGS
1053
          && true_regnum (operands[0]) != true_regnum (operands[2]))
1054
        return \"mov %1,%0\;sub %2,%0\";
1055
      return \"sub %2,%1,%0\";
1056
    }
1057
}"
1058
  [(set_attr "cc" "set_zn")])
1059
 
1060
(define_insn ""
1061
  [(set (match_operand:SI 0 "register_operand" "=dax")
1062
        (minus:SI (match_operand:SI 1 "register_operand" "0")
1063
                  (match_operand:SI 2 "nonmemory_operand" "daxi")))]
1064
  ""
1065
  "sub %2,%0"
1066
  [(set_attr "cc" "set_zn")])
1067
 
1068
(define_expand "negsi2"
1069
  [(set (match_operand:SI 0 "register_operand" "")
1070
        (neg:SI (match_operand:SI 1 "register_operand" "")))]
1071
  ""
1072
  "
1073
{
1074
  rtx target = gen_reg_rtx (SImode);
1075
 
1076
  emit_move_insn (target, const0_rtx);
1077
  emit_insn (gen_subsi3 (target, target, operands[1]));
1078
  emit_move_insn (operands[0], target);
1079
  DONE;
1080
}")
1081
 
1082
;; ----------------------------------------------------------------------
1083
;; MULTIPLY INSTRUCTIONS
1084
;; ----------------------------------------------------------------------
1085
 
1086
(define_insn "mulsidi3"
1087
  [(set (match_operand:DI 0 "register_operand" "=dax")
1088
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1089
                 (sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1090
  "TARGET_AM33"
1091
  "mul %1,%2,%H0,%L0"
1092
  [(set_attr "cc" "set_zn")])
1093
 
1094
(define_insn "umulsidi3"
1095
  [(set (match_operand:DI 0 "register_operand" "=dax")
1096
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
1097
                 (zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
1098
  "TARGET_AM33"
1099
  "mulu %1,%2,%H0,%L0"
1100
  [(set_attr "cc" "set_zn")])
1101
 
1102
(define_expand "mulsi3"
1103
  [(set (match_operand:SI 0 "register_operand" "")
1104
        (mult:SI (match_operand:SI 1 "register_operand" "")
1105
                 (match_operand:SI 2 "register_operand" "")))]
1106
  ""
1107
  "")
1108
 
1109
(define_insn ""
1110
  [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1111
        (mult:SI (match_operand:SI 1 "register_operand" "%0,0")
1112
                 (match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
1113
  "TARGET_AM33"
1114
  "*
1115
{
1116
  if (TARGET_MULT_BUG)
1117
    return \"nop\;nop\;mul %2,%0\";
1118
  else
1119
    return \"mul %2,%0\";
1120
}"
1121
  [(set_attr "cc" "set_zn")])
1122
 
1123
(define_insn ""
1124
  [(set (match_operand:SI 0 "register_operand" "=dx")
1125
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
1126
                 (match_operand:SI 2 "register_operand" "dx")))]
1127
  ""
1128
  "*
1129
{
1130
  if (TARGET_MULT_BUG)
1131
    return \"nop\;nop\;mul %2,%0\";
1132
  else
1133
    return \"mul %2,%0\";
1134
}"
1135
  [(set_attr "cc" "set_zn")])
1136
 
1137
(define_insn "udivmodsi4"
1138
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1139
        (udiv:SI (match_operand:SI 1 "general_operand" "0")
1140
                 (match_operand:SI 2 "general_operand" "dx")))
1141
   (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
1142
        (umod:SI (match_dup 1) (match_dup 2)))]
1143
  ""
1144
  "*
1145
{
1146
  output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
1147
 
1148
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
1149
    return \"divu %2,%0\";
1150
  else
1151
    return \"divu %2,%0\;mov mdr,%3\";
1152
}"
1153
  [(set_attr "cc" "set_zn")])
1154
 
1155
(define_insn "divmodsi4"
1156
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
1157
        (div:SI (match_operand:SI 1 "general_operand" "0")
1158
                 (match_operand:SI 2 "general_operand" "dx")))
1159
   (set (match_operand:SI 3 "nonimmediate_operand" "=d")
1160
        (mod:SI (match_dup 1) (match_dup 2)))]
1161
  ""
1162
  "*
1163
{
1164
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
1165
    return \"ext %0\;div %2,%0\";
1166
  else
1167
    return \"ext %0\;div %2,%0\;mov mdr,%3\";
1168
}"
1169
  [(set_attr "cc" "set_zn")])
1170
 
1171
 
1172
;; ----------------------------------------------------------------------
1173
;; AND INSTRUCTIONS
1174
;; ----------------------------------------------------------------------
1175
 
1176
(define_expand "andsi3"
1177
  [(set (match_operand:SI 0 "register_operand" "")
1178
        (and:SI (match_operand:SI 1 "register_operand" "")
1179
                (match_operand:SI 2 "nonmemory_operand" "")))]
1180
  ""
1181
  "")
1182
 
1183
(define_insn ""
1184
  [(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
1185
        (and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
1186
                (match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
1187
  "TARGET_AM33"
1188
  "*
1189
{
1190
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1191
    return \"extbu %0\";
1192
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1193
    return \"exthu %0\";
1194
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1195
    return \"add %0,%0\;lsr 1,%0\";
1196
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1197
    return \"asl2 %0\;lsr 2,%0\";
1198
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1199
    return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1200
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1201
    return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1202
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1203
    return \"lsr 1,%0\;add %0,%0\";
1204
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1205
    return \"lsr 2,%0\;asl2 %0\";
1206
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1207
    return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1208
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1209
    return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1210
  if (REG_P (operands[2]) && REG_P (operands[1])
1211
      && true_regnum (operands[0]) != true_regnum (operands[1])
1212
      && true_regnum (operands[0]) != true_regnum (operands[2])
1213
      && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1214
      && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1215
      && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1216
    return \"mov %1,%0\;and %2,%0\";
1217
  if (REG_P (operands[2]) && REG_P (operands[1])
1218
      && true_regnum (operands[0]) != true_regnum (operands[1])
1219
      && true_regnum (operands[0]) != true_regnum (operands[2]))
1220
    return \"and %1,%2,%0\";
1221
  if (REG_P (operands[2]) && REG_P (operands[0])
1222
      && true_regnum (operands[2]) == true_regnum (operands[0]))
1223
    return \"and %1,%0\";
1224
  return \"and %2,%0\";
1225
}"
1226
  [(set (attr "cc")
1227
        (cond
1228
         [
1229
         (eq (symbol_ref "which_alternative") (const_int 0)
1230
             ) (const_string "none_0hit")
1231
         (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1232
                          && (INTVAL (operands[2]) == 0x7fffffff
1233
                              || INTVAL (operands[2]) == 0x3fffffff
1234
                              || INTVAL (operands[2]) == 0x1fffffff
1235
                              || INTVAL (operands[2]) == 0x0fffffff
1236
                              || INTVAL (operands[2]) == 0xfffffffe
1237
                              || INTVAL (operands[2]) == 0xfffffffc
1238
                              || INTVAL (operands[2]) == 0xfffffff8
1239
                              || INTVAL (operands[2]) == 0xfffffff0)")
1240
             (const_int 0)) (const_string "set_zn")
1241
          ] (const_string "set_znv")))])
1242
 
1243
(define_insn ""
1244
  [(set (match_operand:SI 0 "register_operand" "=dx,dx")
1245
        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1246
                (match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
1247
  ""
1248
  "*
1249
{
1250
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
1251
    return \"extbu %0\";
1252
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xffff)
1253
    return \"exthu %0\";
1254
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fffffff)
1255
    return \"add %0,%0\;lsr 1,%0\";
1256
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x3fffffff)
1257
    return \"asl2 %0\;lsr 2,%0\";
1258
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x1fffffff)
1259
    return \"add %0,%0\;asl2 %0\;lsr 3,%0\";
1260
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x0fffffff)
1261
    return \"asl2 %0\;asl2 %0\;lsr 4,%0\";
1262
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffe)
1263
    return \"lsr 1,%0\;add %0,%0\";
1264
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffffc)
1265
    return \"lsr 2,%0\;asl2 %0\";
1266
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff8)
1267
    return \"lsr 3,%0\;add %0,%0\;asl2 %0\";
1268
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffffff0)
1269
    return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
1270
  return \"and %2,%0\";
1271
}"
1272
  [(set (attr "cc")
1273
        (cond
1274
         [
1275
         (eq (symbol_ref "which_alternative") (const_int 0)
1276
             ) (const_string "none_0hit")
1277
         ;; Shifts don't set the V flag, but bitwise operations clear
1278
         ;; it (which correctly reflects the absence of overflow in a
1279
         ;; compare-with-zero that might follow).  As for the
1280
         ;; 0xfffffffe case, the add may overflow, so we can't use the
1281
         ;; V flag.
1282
         (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
1283
                          && (INTVAL (operands[2]) == 0x7fffffff
1284
                              || INTVAL (operands[2]) == 0x3fffffff
1285
                              || INTVAL (operands[2]) == 0x1fffffff
1286
                              || INTVAL (operands[2]) == 0x0fffffff
1287
                              || INTVAL (operands[2]) == 0xfffffffe
1288
                              || INTVAL (operands[2]) == 0xfffffffc
1289
                              || INTVAL (operands[2]) == 0xfffffff8
1290
                              || INTVAL (operands[2]) == 0xfffffff0)")
1291
             (const_int 0)) (const_string "set_zn")
1292
          ] (const_string "set_znv")))])
1293
 
1294
;; ----------------------------------------------------------------------
1295
;; OR INSTRUCTIONS
1296
;; ----------------------------------------------------------------------
1297
 
1298
(define_expand "iorsi3"
1299
  [(set (match_operand:SI 0 "register_operand" "")
1300
        (ior:SI (match_operand:SI 1 "register_operand" "")
1301
                (match_operand:SI 2 "nonmemory_operand" "")))]
1302
  ""
1303
  "")
1304
 
1305
(define_insn ""
1306
  [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1307
        (ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
1308
                (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1309
  "TARGET_AM33"
1310
  "*
1311
{
1312
  if (REG_P (operands[2]) && REG_P (operands[1])
1313
      && true_regnum (operands[0]) != true_regnum (operands[1])
1314
      && true_regnum (operands[0]) != true_regnum (operands[2])
1315
      && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1316
      && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1317
      && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1318
    return \"mov %1,%0\;or %2,%0\";
1319
  if (REG_P (operands[2]) && REG_P (operands[1])
1320
      && true_regnum (operands[0]) != true_regnum (operands[1])
1321
      && true_regnum (operands[0]) != true_regnum (operands[2]))
1322
    return \"or %1,%2,%0\";
1323
  if (REG_P (operands[2]) && REG_P (operands[0])
1324
      && true_regnum (operands[2]) == true_regnum (operands[0]))
1325
    return \"or %1,%0\";
1326
  return \"or %2,%0\";
1327
}"
1328
  [(set_attr "cc" "set_znv")])
1329
 
1330
(define_insn ""
1331
  [(set (match_operand:SI 0 "register_operand" "=dx")
1332
        (ior:SI (match_operand:SI 1 "register_operand" "%0")
1333
                (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1334
  ""
1335
  "or %2,%0"
1336
  [(set_attr "cc" "set_znv")])
1337
 
1338
;; ----------------------------------------------------------------------
1339
;; XOR INSTRUCTIONS
1340
;; ----------------------------------------------------------------------
1341
 
1342
(define_expand "xorsi3"
1343
  [(set (match_operand:SI 0 "register_operand" "")
1344
        (xor:SI (match_operand:SI 1 "register_operand" "")
1345
                (match_operand:SI 2 "nonmemory_operand" "")))]
1346
  ""
1347
  "")
1348
 
1349
(define_insn ""
1350
  [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1351
        (xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
1352
                (match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
1353
  "TARGET_AM33"
1354
  "*
1355
{
1356
  if (REG_P (operands[2]) && REG_P (operands[1])
1357
      && true_regnum (operands[0]) != true_regnum (operands[1])
1358
      && true_regnum (operands[0]) != true_regnum (operands[2])
1359
      && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
1360
      && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
1361
      && REGNO_REG_CLASS (true_regnum (operands[2])) == DATA_REGS)
1362
    return \"mov %1,%0\;xor %2,%0\";
1363
  if (REG_P (operands[2]) && REG_P (operands[1])
1364
      && true_regnum (operands[0]) != true_regnum (operands[1])
1365
      && true_regnum (operands[0]) != true_regnum (operands[2]))
1366
    return \"xor %1,%2,%0\";
1367
  if (REG_P (operands[2]) && REG_P (operands[0])
1368
      && true_regnum (operands[2]) == true_regnum (operands[0]))
1369
    return \"xor %1,%0\";
1370
  return \"xor %2,%0\";
1371
}"
1372
  [(set_attr "cc" "set_znv")])
1373
 
1374
(define_insn ""
1375
  [(set (match_operand:SI 0 "register_operand" "=dx")
1376
        (xor:SI (match_operand:SI 1 "register_operand" "%0")
1377
                (match_operand:SI 2 "nonmemory_operand" "dxi")))]
1378
  ""
1379
  "xor %2,%0"
1380
  [(set_attr "cc" "set_znv")])
1381
 
1382
;; ----------------------------------------------------------------------
1383
;; NOT INSTRUCTIONS
1384
;; ----------------------------------------------------------------------
1385
 
1386
(define_expand "one_cmplsi2"
1387
  [(set (match_operand:SI 0 "register_operand" "")
1388
        (not:SI (match_operand:SI 1 "register_operand" "")))]
1389
  ""
1390
  "")
1391
 
1392
(define_insn ""
1393
  [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
1394
        (not:SI (match_operand:SI 1 "register_operand" "0,0")))]
1395
  "TARGET_AM33"
1396
  "not %0"
1397
  [(set_attr "cc" "set_znv")])
1398
 
1399
(define_insn ""
1400
  [(set (match_operand:SI 0 "register_operand" "=dx")
1401
        (not:SI (match_operand:SI 1 "register_operand" "0")))]
1402
  ""
1403
  "not %0"
1404
  [(set_attr "cc" "set_znv")])
1405
 
1406
;; -----------------------------------------------------------------
1407
;; BIT FIELDS
1408
;; -----------------------------------------------------------------
1409
 
1410
 
1411
;; These set/clear memory in byte sized chunks.
1412
;;
1413
;; They are no smaller/faster than loading the value into a register
1414
;; and storing the register, but they don't need a scratch register
1415
;; which may allow for better code generation.
1416
(define_insn ""
1417
  [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
1418
  ""
1419
  "@
1420
  bclr 255,%A0
1421
  clr %0"
1422
  [(set_attr "cc" "clobber")])
1423
 
1424
(define_insn ""
1425
  [(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
1426
  ""
1427
  "@
1428
  bset 255,%A0
1429
  mov -1,%0"
1430
  [(set_attr "cc" "clobber,none_0hit")])
1431
 
1432
(define_insn ""
1433
  [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1434
        (subreg:QI
1435
          (and:SI (subreg:SI (match_dup 0) 0)
1436
                  (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1437
  ""
1438
  "@
1439
  bclr %N1,%A0
1440
  and %1,%0"
1441
  [(set_attr "cc" "clobber,set_znv")])
1442
 
1443
(define_insn ""
1444
  [(set (match_operand:QI 0 "memory_operand" "=R,T")
1445
        (and:QI
1446
         (match_dup 0)
1447
         (not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
1448
  ""
1449
  "@
1450
  bclr %U1,%A0
1451
  bclr %1,%0"
1452
  [(set_attr "cc" "clobber,clobber")])
1453
 
1454
(define_insn ""
1455
  [(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
1456
        (subreg:QI
1457
          (ior:SI (subreg:SI (match_dup 0) 0)
1458
                  (match_operand:SI 1 "const_int_operand" "i,i")) 0))]
1459
  ""
1460
  "@
1461
  bset %U1,%A0
1462
  or %1,%0"
1463
  [(set_attr "cc" "clobber,set_znv")])
1464
 
1465
(define_expand "iorqi3"
1466
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467
        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
1468
                (match_operand:QI 2 "nonmemory_operand" "")))]
1469
  ""
1470
  "")
1471
 
1472
(define_insn ""
1473
  [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
1474
        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1475
                ;; This constraint should really be nonmemory_operand,
1476
                ;; but making it general_operand, along with the
1477
                ;; condition that not both input operands are MEMs, it
1478
                ;; here helps combine do a better job.
1479
                (match_operand:QI 2 "general_operand" "i,d,ir")))]
1480
  "TARGET_AM33 &&
1481
   (GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
1482
  "@
1483
  bset %U2,%A0
1484
  bset %2,%0
1485
  or %2,%0"
1486
  [(set_attr "cc" "clobber,clobber,set_znv")])
1487
 
1488
(define_insn ""
1489
  [(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
1490
        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
1491
                ;; This constraint should really be nonmemory_operand,
1492
                ;; but making it general_operand, along with the
1493
                ;; condition that not both input operands are MEMs, it
1494
                ;; here helps combine do a better job.
1495
                (match_operand:QI 2 "general_operand" "i,d,id")))]
1496
  "GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
1497
  "@
1498
  bset %U2,%A0
1499
  bset %2,%0
1500
  or %2,%0"
1501
  [(set_attr "cc" "clobber,clobber,set_znv")])
1502
 
1503
(define_insn ""
1504
  [(set (cc0)
1505
     (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
1506
                      (match_operand 1 "const_int_operand" "")
1507
                      (match_operand 2 "const_int_operand" "")))]
1508
  ""
1509
  "*
1510
{
1511
  int len = INTVAL (operands[1]);
1512
  int bit = INTVAL (operands[2]);
1513
  int mask = 0;
1514
  rtx xoperands[2];
1515
 
1516
  while (len > 0)
1517
    {
1518
      mask |= (1 << bit);
1519
      bit++;
1520
      len--;
1521
    }
1522
 
1523
  xoperands[0] = operands[0];
1524
  xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1525
  output_asm_insn (\"btst %1,%0\", xoperands);
1526
  return \"\";
1527
}"
1528
  [(set_attr "cc" "clobber")])
1529
 
1530
(define_insn ""
1531
  [(set (cc0)
1532
     (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
1533
                      (match_operand 1 "const_int_operand" "")
1534
                      (match_operand 2 "const_int_operand" "")))]
1535
  "mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
1536
  "*
1537
{
1538
  int len = INTVAL (operands[1]);
1539
  int bit = INTVAL (operands[2]);
1540
  int mask = 0;
1541
  rtx xoperands[2];
1542
 
1543
  while (len > 0)
1544
    {
1545
      mask |= (1 << bit);
1546
      bit++;
1547
      len--;
1548
    }
1549
 
1550
  /* If the source operand is not a reg (i.e. it is memory), then extract the
1551
     bits from mask that we actually want to test.  Note that the mask will
1552
     never cross a byte boundary.  */
1553
  if (!REG_P (operands[0]))
1554
    {
1555
      if (mask & 0xff)
1556
        mask = mask & 0xff;
1557
      else if (mask & 0xff00)
1558
        mask = (mask >> 8) & 0xff;
1559
      else if (mask & 0xff0000)
1560
        mask = (mask >> 16) & 0xff;
1561
      else if (mask & 0xff000000)
1562
        mask = (mask >> 24) & 0xff;
1563
    }
1564
 
1565
  xoperands[0] = operands[0];
1566
  xoperands[1] = GEN_INT (trunc_int_for_mode (mask, SImode));
1567
  if (GET_CODE (operands[0]) == REG)
1568
    output_asm_insn (\"btst %1,%0\", xoperands);
1569
  else
1570
    output_asm_insn (\"btst %U1,%A0\", xoperands);
1571
  return \"\";
1572
}"
1573
  [(set_attr "cc" "clobber")])
1574
 
1575
(define_insn ""
1576
  [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
1577
                      (match_operand:SI 1 "const_int_operand" "")))]
1578
  ""
1579
  "btst %1,%0"
1580
  [(set_attr "cc" "clobber")])
1581
 
1582
(define_insn ""
1583
  [(set (cc0)
1584
     (and:SI
1585
       (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
1586
       (match_operand:SI 1 "const_8bit_operand" "")))]
1587
  ""
1588
  "@
1589
  btst %U1,%A0
1590
  btst %1,%0"
1591
  [(set_attr "cc" "clobber")])
1592
 
1593
 
1594
;; ----------------------------------------------------------------------
1595
;; JUMP INSTRUCTIONS
1596
;; ----------------------------------------------------------------------
1597
 
1598
;; Conditional jump instructions
1599
 
1600
(define_expand "ble"
1601
  [(set (pc)
1602
        (if_then_else (le (cc0)
1603
                          (const_int 0))
1604
                      (label_ref (match_operand 0 "" ""))
1605
                      (pc)))]
1606
  ""
1607
  "")
1608
 
1609
(define_expand "bleu"
1610
  [(set (pc)
1611
        (if_then_else (leu (cc0)
1612
                           (const_int 0))
1613
                      (label_ref (match_operand 0 "" ""))
1614
                      (pc)))]
1615
  ""
1616
  "")
1617
 
1618
(define_expand "bge"
1619
  [(set (pc)
1620
        (if_then_else (ge (cc0)
1621
                          (const_int 0))
1622
                      (label_ref (match_operand 0 "" ""))
1623
                      (pc)))]
1624
  ""
1625
  "")
1626
 
1627
(define_expand "bgeu"
1628
  [(set (pc)
1629
        (if_then_else (geu (cc0)
1630
                           (const_int 0))
1631
                      (label_ref (match_operand 0 "" ""))
1632
                      (pc)))]
1633
  ""
1634
  "")
1635
 
1636
(define_expand "blt"
1637
  [(set (pc)
1638
        (if_then_else (lt (cc0)
1639
                          (const_int 0))
1640
                      (label_ref (match_operand 0 "" ""))
1641
                      (pc)))]
1642
  ""
1643
  "")
1644
 
1645
(define_expand "bltu"
1646
  [(set (pc)
1647
        (if_then_else (ltu (cc0)
1648
                           (const_int 0))
1649
                      (label_ref (match_operand 0 "" ""))
1650
                      (pc)))]
1651
  ""
1652
  "")
1653
 
1654
(define_expand "bgt"
1655
  [(set (pc)
1656
        (if_then_else (gt (cc0)
1657
                          (const_int 0))
1658
                      (label_ref (match_operand 0 "" ""))
1659
                      (pc)))]
1660
  ""
1661
  "")
1662
 
1663
(define_expand "bgtu"
1664
  [(set (pc)
1665
        (if_then_else (gtu (cc0)
1666
                           (const_int 0))
1667
                      (label_ref (match_operand 0 "" ""))
1668
                      (pc)))]
1669
  ""
1670
  "")
1671
 
1672
(define_expand "beq"
1673
  [(set (pc)
1674
        (if_then_else (eq (cc0)
1675
                          (const_int 0))
1676
                      (label_ref (match_operand 0 "" ""))
1677
                      (pc)))]
1678
  ""
1679
  "")
1680
 
1681
(define_expand "bne"
1682
  [(set (pc)
1683
        (if_then_else (ne (cc0)
1684
                          (const_int 0))
1685
                      (label_ref (match_operand 0 "" ""))
1686
                      (pc)))]
1687
  ""
1688
  "")
1689
 
1690
(define_insn ""
1691
  [(set (pc)
1692
        (if_then_else (match_operator 1 "comparison_operator"
1693
                                      [(cc0) (const_int 0)])
1694
                      (label_ref (match_operand 0 "" ""))
1695
                      (pc)))]
1696
  ""
1697
  "*
1698
{
1699
  if (cc_status.mdep.fpCC)
1700
    return \"fb%b1 %0\";
1701
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1702
      && (GET_CODE (operands[1]) == GT
1703
          || GET_CODE (operands[1]) == GE
1704
          || GET_CODE (operands[1]) == LE
1705
          || GET_CODE (operands[1]) == LT))
1706
    return 0;
1707
  return \"b%b1 %0\";
1708
}"
1709
 [(set_attr "cc" "none")])
1710
 
1711
(define_insn ""
1712
  [(set (pc)
1713
        (if_then_else (match_operator 1 "comparison_operator"
1714
                                      [(cc0) (const_int 0)])
1715
                      (pc)
1716
                      (label_ref (match_operand 0 "" ""))))]
1717
  ""
1718
  "*
1719
{
1720
  if (cc_status.mdep.fpCC)
1721
    return \"fb%B1 %0\";
1722
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
1723
      && (GET_CODE (operands[1]) == GT
1724
          || GET_CODE (operands[1]) == GE
1725
          || GET_CODE (operands[1]) == LE
1726
          || GET_CODE (operands[1]) == LT))
1727
    return 0;
1728
  return \"b%B1 %0\";
1729
}"
1730
 [(set_attr "cc" "none")])
1731
 
1732
;; Unconditional and other jump instructions.
1733
 
1734
(define_insn "jump"
1735
  [(set (pc)
1736
        (label_ref (match_operand 0 "" "")))]
1737
  ""
1738
  "jmp %l0"
1739
 [(set_attr "cc" "none")])
1740
 
1741
(define_insn "indirect_jump"
1742
  [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1743
  ""
1744
  "jmp (%0)"
1745
  [(set_attr "cc" "none")])
1746
 
1747
(define_expand "builtin_setjmp_receiver"
1748
  [(match_operand 0 "" "")]
1749
  "flag_pic"
1750
  "
1751
{
1752
  if (flag_pic)
1753
    emit_insn (gen_GOTaddr2picreg ());
1754
 
1755
  DONE;
1756
}")
1757
 
1758
(define_expand "casesi"
1759
  [(match_operand:SI 0 "register_operand" "")
1760
   (match_operand:SI 1 "immediate_operand" "")
1761
   (match_operand:SI 2 "immediate_operand" "")
1762
   (match_operand 3 "" "") (match_operand 4 "" "")]
1763
  ""
1764
  "
1765
{
1766
  rtx table = gen_reg_rtx (SImode);
1767
  rtx index = gen_reg_rtx (SImode);
1768
  rtx addr = gen_reg_rtx (Pmode);
1769
 
1770
  emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1771
  emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
1772
  emit_insn (gen_cmpsi (index, operands[2]));
1773
  emit_jump_insn (gen_bgtu (operands[4]));
1774
  emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, const2_rtx));
1775
  emit_move_insn (addr, gen_rtx_MEM (SImode,
1776
                                     gen_rtx_PLUS (SImode, table, index)));
1777
  if (flag_pic)
1778
    emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
1779
 
1780
  emit_jump_insn (gen_tablejump (addr, operands[3]));
1781
  DONE;
1782
}")
1783
 
1784
(define_insn "tablejump"
1785
  [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1786
   (use (label_ref (match_operand 1 "" "")))]
1787
  ""
1788
  "jmp (%0)"
1789
  [(set_attr "cc" "none")])
1790
 
1791
;; Call subroutine with no return value.
1792
 
1793
(define_expand "call"
1794
  [(call (match_operand:QI 0 "general_operand" "")
1795
         (match_operand:SI 1 "general_operand" ""))]
1796
  ""
1797
  "
1798
{
1799
  if (flag_pic && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
1800
    {
1801
      if (MN10300_GLOBAL_P (XEXP (operands[0], 0)))
1802
        {
1803
          /* The PLT code won't run on AM30, but then, there's no
1804
             shared library support for AM30 either, so we just assume
1805
             the linker is going to adjust all @PLT relocs to the
1806
             actual symbols.  */
1807
          emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1808
          XEXP (operands[0], 0) = gen_sym2PLT (XEXP (operands[0], 0));
1809
        }
1810
      else
1811
        XEXP (operands[0], 0) = gen_sym2PIC (XEXP (operands[0], 0));
1812
    }
1813
  if (! call_address_operand (XEXP (operands[0], 0), VOIDmode))
1814
    XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
1815
  emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
1816
  DONE;
1817
}")
1818
 
1819
(define_insn "call_internal"
1820
  [(call (mem:QI (match_operand:SI 0 "call_address_operand" "aS"))
1821
         (match_operand:SI 1 "general_operand" "g"))]
1822
  ""
1823
  "*
1824
{
1825
  if (REG_P (operands[0]))
1826
    return \"calls %C0\";
1827
  else
1828
    return \"call %C0,[],0\";
1829
}"
1830
  [(set_attr "cc" "clobber")])
1831
 
1832
;; Call subroutine, returning value in operand 0
1833
;; (which must be a hard register).
1834
 
1835
(define_expand "call_value"
1836
  [(set (match_operand 0 "" "")
1837
        (call (match_operand:QI 1 "general_operand" "")
1838
              (match_operand:SI 2 "general_operand" "")))]
1839
  ""
1840
  "
1841
{
1842
  if (flag_pic && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
1843
    {
1844
      if (MN10300_GLOBAL_P (XEXP (operands[1], 0)))
1845
        {
1846
          /* The PLT code won't run on AM30, but then, there's no
1847
             shared library support for AM30 either, so we just assume
1848
             the linker is going to adjust all @PLT relocs to the
1849
             actual symbols.  */
1850
          emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1851
          XEXP (operands[1], 0) = gen_sym2PLT (XEXP (operands[1], 0));
1852
        }
1853
      else
1854
        XEXP (operands[1], 0) = gen_sym2PIC (XEXP (operands[1], 0));
1855
    }
1856
  if (! call_address_operand (XEXP (operands[1], 0), VOIDmode))
1857
    XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
1858
  emit_call_insn (gen_call_value_internal (operands[0],
1859
                                           XEXP (operands[1], 0),
1860
                                           operands[2]));
1861
  DONE;
1862
}")
1863
 
1864
(define_insn "call_value_internal"
1865
  [(set (match_operand 0 "" "=dax")
1866
        (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
1867
              (match_operand:SI 2 "general_operand" "g")))]
1868
  ""
1869
  "*
1870
{
1871
  if (REG_P (operands[1]))
1872
    return \"calls %C1\";
1873
  else
1874
    return \"call %C1,[],0\";
1875
}"
1876
  [(set_attr "cc" "clobber")])
1877
 
1878
(define_expand "untyped_call"
1879
  [(parallel [(call (match_operand 0 "" "")
1880
                    (const_int 0))
1881
              (match_operand 1 "" "")
1882
              (match_operand 2 "" "")])]
1883
  ""
1884
  "
1885
{
1886
  int i;
1887
 
1888
  emit_call_insn (gen_call (operands[0], const0_rtx));
1889
 
1890
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1891
    {
1892
      rtx set = XVECEXP (operands[2], 0, i);
1893
      emit_move_insn (SET_DEST (set), SET_SRC (set));
1894
    }
1895
  DONE;
1896
}")
1897
 
1898
(define_insn "nop"
1899
  [(const_int 0)]
1900
  ""
1901
  "nop"
1902
  [(set_attr "cc" "none")])
1903
 
1904
;; ----------------------------------------------------------------------
1905
;; EXTEND INSTRUCTIONS
1906
;; ----------------------------------------------------------------------
1907
 
1908
(define_expand "zero_extendqisi2"
1909
  [(set (match_operand:SI 0 "general_operand" "")
1910
        (zero_extend:SI
1911
         (match_operand:QI 1 "general_operand" "")))]
1912
  ""
1913
  "")
1914
 
1915
(define_insn ""
1916
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1917
        (zero_extend:SI
1918
         (match_operand:QI 1 "general_operand" "0,dax,m,0,dax,m")))]
1919
  "TARGET_AM33"
1920
  "@
1921
  extbu %0
1922
  mov %1,%0\;extbu %0
1923
  movbu %1,%0
1924
  extbu %0
1925
  mov %1,%0\;extbu %0
1926
  movbu %1,%0"
1927
  [(set_attr "cc" "none_0hit")])
1928
 
1929
(define_insn ""
1930
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1931
        (zero_extend:SI
1932
         (match_operand:QI 1 "general_operand" "0,d,m")))]
1933
  ""
1934
  "@
1935
  extbu %0
1936
  mov %1,%0\;extbu %0
1937
  movbu %1,%0"
1938
  [(set_attr "cc" "none_0hit")])
1939
 
1940
(define_expand "zero_extendhisi2"
1941
  [(set (match_operand:SI 0 "general_operand" "")
1942
        (zero_extend:SI
1943
         (match_operand:HI 1 "general_operand" "")))]
1944
  ""
1945
  "")
1946
 
1947
(define_insn ""
1948
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx,!dax,!dax,!dax")
1949
        (zero_extend:SI
1950
         (match_operand:HI 1 "general_operand" "0,dax,m,0,dax,m")))]
1951
  "TARGET_AM33"
1952
  "@
1953
  exthu %0
1954
  mov %1,%0\;exthu %0
1955
  movhu %1,%0
1956
  exthu %0
1957
  mov %1,%0\;exthu %0
1958
  movhu %1,%0"
1959
  [(set_attr "cc" "none_0hit")])
1960
 
1961
(define_insn ""
1962
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
1963
        (zero_extend:SI
1964
         (match_operand:HI 1 "general_operand" "0,dx,m")))]
1965
  ""
1966
  "@
1967
  exthu %0
1968
  mov %1,%0\;exthu %0
1969
  movhu %1,%0"
1970
  [(set_attr "cc" "none_0hit")])
1971
 
1972
;;- sign extension instructions
1973
 
1974
(define_expand "extendqisi2"
1975
  [(set (match_operand:SI 0 "general_operand" "")
1976
        (sign_extend:SI
1977
         (match_operand:QI 1 "general_operand" "")))]
1978
  ""
1979
  "")
1980
 
1981
(define_insn ""
1982
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
1983
        (sign_extend:SI
1984
         (match_operand:QI 1 "general_operand" "0,dx,0,dax")))]
1985
  "TARGET_AM33"
1986
  "@
1987
  extb %0
1988
  mov %1,%0\;extb %0
1989
  extb %0
1990
  mov %1,%0\;extb %0"
1991
  [(set_attr "cc" "none_0hit")])
1992
 
1993
(define_insn ""
1994
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
1995
        (sign_extend:SI
1996
         (match_operand:QI 1 "general_operand" "0,dx")))]
1997
  ""
1998
  "@
1999
  extb %0
2000
  mov %1,%0\;extb %0"
2001
  [(set_attr "cc" "none_0hit")])
2002
 
2003
(define_expand "extendhisi2"
2004
  [(set (match_operand:SI 0 "general_operand" "")
2005
        (sign_extend:SI
2006
         (match_operand:HI 1 "general_operand" "")))]
2007
  ""
2008
  "")
2009
 
2010
(define_insn ""
2011
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,!dax,!dax")
2012
        (sign_extend:SI
2013
         (match_operand:HI 1 "general_operand" "0,dax,0,dax")))]
2014
  "TARGET_AM33"
2015
  "@
2016
  exth %0
2017
  mov %1,%0\;exth %0
2018
  exth %0
2019
  mov %1,%0\;exth %0"
2020
  [(set_attr "cc" "none_0hit")])
2021
 
2022
(define_insn ""
2023
  [(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
2024
        (sign_extend:SI
2025
         (match_operand:HI 1 "general_operand" "0,dx")))]
2026
  ""
2027
  "@
2028
  exth %0
2029
  mov %1,%0\;exth %0"
2030
  [(set_attr "cc" "none_0hit")])
2031
 
2032
;; ----------------------------------------------------------------------
2033
;; SHIFTS
2034
;; ----------------------------------------------------------------------
2035
 
2036
(define_expand "ashlsi3"
2037
  [(set (match_operand:SI 0 "register_operand" "")
2038
        (ashift:SI
2039
         (match_operand:SI 1 "register_operand" "")
2040
         (match_operand:QI 2 "nonmemory_operand" "")))]
2041
  ""
2042
  "")
2043
 
2044
(define_insn ""
2045
  [(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
2046
        (ashift:SI
2047
         (match_operand:SI 1 "register_operand" "0,0,dax")
2048
         (match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
2049
  "TARGET_AM33"
2050
  "*
2051
{
2052
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 1)
2053
    return \"add %0,%0\";
2054
 
2055
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 2)
2056
    return \"asl2 %0\";
2057
 
2058
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 3
2059
      && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2060
    return \"asl2 %0\;add %0,%0\";
2061
 
2062
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 4
2063
      && REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS)
2064
    return \"asl2 %0\;asl2 %0\";
2065
 
2066
  if (true_regnum (operands[1]) == true_regnum (operands[0]))
2067
    return \"asl %S2,%0\";
2068
 
2069
  if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2070
      && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2071
      && true_regnum (operands[0]) != true_regnum (operands[2]))
2072
    return \"mov %1,%0\;asl %S2,%0\";
2073
  return \"asl %2,%1,%0\";
2074
}"
2075
  [(set_attr "cc" "set_zn")])
2076
 
2077
(define_insn ""
2078
  [(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
2079
        (ashift:SI
2080
         (match_operand:SI 1 "register_operand" "0,0,0,0,0")
2081
         (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
2082
  ""
2083
  "@
2084
  add %0,%0
2085
  asl2 %0
2086
  asl2 %0\;add %0,%0
2087
  asl2 %0\;asl2 %0
2088
  asl %S2,%0"
2089
  [(set_attr "cc" "set_zn")])
2090
 
2091
(define_expand "lshrsi3"
2092
  [(set (match_operand:SI 0 "register_operand" "")
2093
        (lshiftrt:SI
2094
         (match_operand:SI 1 "register_operand" "")
2095
         (match_operand:QI 2 "nonmemory_operand" "")))]
2096
  ""
2097
  "")
2098
 
2099
(define_insn ""
2100
  [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2101
        (lshiftrt:SI
2102
         (match_operand:SI 1 "register_operand" "0,dax")
2103
         (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2104
  "TARGET_AM33"
2105
  "*
2106
{
2107
  if (true_regnum (operands[1]) == true_regnum (operands[0]))
2108
    return \"lsr %S2,%0\";
2109
 
2110
  if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2111
      && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2112
      && true_regnum (operands[0]) != true_regnum (operands[2]))
2113
    return \"mov %1,%0\;lsr %S2,%0\";
2114
  return \"lsr %2,%1,%0\";
2115
}"
2116
  [(set_attr "cc" "set_zn")])
2117
 
2118
(define_insn ""
2119
  [(set (match_operand:SI 0 "register_operand" "=dx")
2120
        (lshiftrt:SI
2121
         (match_operand:SI 1 "register_operand" "0")
2122
         (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2123
  ""
2124
  "lsr %S2,%0"
2125
  [(set_attr "cc" "set_zn")])
2126
 
2127
(define_expand "ashrsi3"
2128
  [(set (match_operand:SI 0 "register_operand" "")
2129
        (ashiftrt:SI
2130
         (match_operand:SI 1 "register_operand" "")
2131
         (match_operand:QI 2 "nonmemory_operand" "")))]
2132
  ""
2133
  "")
2134
 
2135
(define_insn ""
2136
  [(set (match_operand:SI 0 "register_operand" "=dx,!dax")
2137
        (ashiftrt:SI
2138
         (match_operand:SI 1 "register_operand" "0,dax")
2139
         (match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
2140
  "TARGET_AM33"
2141
  "*
2142
{
2143
  if (true_regnum (operands[1]) == true_regnum (operands[0]))
2144
    return \"asr %S2,%0\";
2145
 
2146
  if (REGNO_REG_CLASS (true_regnum (operands[0])) == DATA_REGS
2147
      && REGNO_REG_CLASS (true_regnum (operands[1])) == DATA_REGS
2148
      && true_regnum (operands[0]) != true_regnum (operands[2]))
2149
    return \"mov %1,%0\;asr %S2,%0\";
2150
  return \"asr %2,%1,%0\";
2151
}"
2152
  [(set_attr "cc" "set_zn")])
2153
 
2154
(define_insn ""
2155
  [(set (match_operand:SI 0 "register_operand" "=dx")
2156
        (ashiftrt:SI
2157
         (match_operand:SI 1 "register_operand" "0")
2158
         (match_operand:QI 2 "nonmemory_operand" "dxi")))]
2159
  ""
2160
  "asr %S2,%0"
2161
  [(set_attr "cc" "set_zn")])
2162
 
2163
;; ----------------------------------------------------------------------
2164
;; FP INSTRUCTIONS
2165
;; ----------------------------------------------------------------------
2166
;;
2167
;; The mn103 series does not have floating point instructions, but since
2168
;; FP values are held in integer regs, we can clear the high bit easily
2169
;; which gives us an efficient inline floating point absolute value.
2170
;;
2171
;; Similarly for negation of a FP value.
2172
;;
2173
 
2174
(define_expand "absdf2"
2175
  [(set (match_operand:DF 0 "register_operand" "")
2176
        (abs:DF (match_operand:DF 1 "register_operand" "")))]
2177
  ""
2178
  "
2179
{
2180
  rtx target, result, insns;
2181
 
2182
  start_sequence ();
2183
  target = operand_subword (operands[0], 1, 1, DFmode);
2184
  result = expand_binop (SImode, and_optab,
2185
                         operand_subword_force (operands[1], 1, DFmode),
2186
                         GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2187
 
2188
  gcc_assert (result);
2189
 
2190
  if (result != target)
2191
    emit_move_insn (result, target);
2192
 
2193
  emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2194
                  operand_subword_force (operands[1], 0, DFmode));
2195
 
2196
  insns = get_insns ();
2197
  end_sequence ();
2198
 
2199
  emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2200
  DONE;
2201
}")
2202
 
2203
(define_expand "abssf2"
2204
  [(set (match_operand:SF 0 "register_operand" "")
2205
        (abs:SF (match_operand:SF 1 "register_operand" "")))]
2206
  ""
2207
  "
2208
{
2209
  rtx result;
2210
  rtx target;
2211
 
2212
  if (TARGET_AM33_2)
2213
    {
2214
      emit_insn (gen_abssf2_am33_2 (operands[0], operands[1]));
2215
      DONE;
2216
    }
2217
 
2218
  target = operand_subword_force (operands[0], 0, SFmode);
2219
  result = expand_binop (SImode, and_optab,
2220
                         operand_subword_force (operands[1], 0, SFmode),
2221
                         GEN_INT (0x7fffffff), target, 0, OPTAB_WIDEN);
2222
  gcc_assert (result);
2223
 
2224
  if (result != target)
2225
    emit_move_insn (result, target);
2226
 
2227
  /* Make a place for REG_EQUAL.  */
2228
  emit_move_insn (operands[0], operands[0]);
2229
  DONE;
2230
}")
2231
 
2232
 
2233
(define_insn "abssf2_am33_2"
2234
  [(set (match_operand:SF 0 "register_operand" "=f,f")
2235
        (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2236
  "TARGET_AM33_2"
2237
  "@
2238
   fabs %0
2239
   fabs %1, %0"
2240
  [(set_attr "cc" "none_0hit")])
2241
 
2242
(define_expand "negdf2"
2243
  [(set (match_operand:DF 0 "register_operand" "")
2244
        (neg:DF (match_operand:DF 1 "register_operand" "")))]
2245
  ""
2246
  "
2247
{
2248
  rtx target, result, insns;
2249
 
2250
  start_sequence ();
2251
  target = operand_subword (operands[0], 1, 1, DFmode);
2252
  result = expand_binop (SImode, xor_optab,
2253
                         operand_subword_force (operands[1], 1, DFmode),
2254
                         GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2255
                         target, 0, OPTAB_WIDEN);
2256
 
2257
  gcc_assert (result);
2258
 
2259
  if (result != target)
2260
    emit_move_insn (result, target);
2261
 
2262
  emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
2263
                  operand_subword_force (operands[1], 0, DFmode));
2264
 
2265
  insns = get_insns ();
2266
  end_sequence ();
2267
 
2268
  emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
2269
  DONE;
2270
}")
2271
 
2272
(define_expand "negsf2"
2273
  [(set (match_operand:SF 0 "register_operand" "")
2274
        (neg:SF (match_operand:SF 1 "register_operand" "")))]
2275
  ""
2276
  "
2277
{
2278
  rtx result;
2279
  rtx target;
2280
 
2281
  if (TARGET_AM33_2)
2282
    {
2283
      emit_insn (gen_negsf2_am33_2 (operands[0], operands[1]));
2284
      DONE;
2285
    }
2286
 
2287
  target = operand_subword_force (operands[0], 0, SFmode);
2288
  result = expand_binop (SImode, xor_optab,
2289
                         operand_subword_force (operands[1], 0, SFmode),
2290
                         GEN_INT (trunc_int_for_mode (0x80000000, SImode)),
2291
                         target, 0, OPTAB_WIDEN);
2292
  gcc_assert (result);
2293
 
2294
  if (result != target)
2295
    emit_move_insn (result, target);
2296
 
2297
  /* Make a place for REG_EQUAL.  */
2298
  emit_move_insn (operands[0], operands[0]);
2299
  DONE;
2300
}")
2301
 
2302
(define_insn "negsf2_am33_2"
2303
  [(set (match_operand:SF 0 "register_operand" "=f,f")
2304
        (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
2305
  "TARGET_AM33_2"
2306
  "@
2307
   fneg %0
2308
   fneg %1, %0"
2309
  [(set_attr "cc" "none_0hit")])
2310
 
2311
(define_expand "sqrtsf2"
2312
  [(set (match_operand:SF 0 "register_operand" "")
2313
        (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
2314
  "TARGET_AM33_2 && flag_unsafe_math_optimizations"
2315
  "
2316
{
2317
  rtx scratch = gen_reg_rtx (SFmode);
2318
  emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
2319
  emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
2320
                         scratch));
2321
  DONE;
2322
}")
2323
 
2324
(define_insn "rsqrtsf2"
2325
  [(set (match_operand:SF 0 "register_operand" "=f,f")
2326
        (div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
2327
                (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
2328
  "TARGET_AM33_2"
2329
  "@
2330
   frsqrt %0
2331
   frsqrt %1, %0"
2332
  [(set_attr "cc" "none_0hit")])
2333
 
2334
(define_insn "addsf3"
2335
  [(set (match_operand:SF 0 "register_operand" "=f,f")
2336
        (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
2337
                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2338
  "TARGET_AM33_2"
2339
  "@
2340
   fadd %2, %0
2341
   fadd %2, %1, %0"
2342
  [(set_attr "cc" "none_0hit")])
2343
 
2344
(define_insn "subsf3"
2345
  [(set (match_operand:SF 0 "register_operand" "=f,f")
2346
        (minus:SF (match_operand:SF 1 "register_operand" "0,f")
2347
                  (match_operand:SF 2 "general_operand" "f,?fF")))]
2348
  "TARGET_AM33_2"
2349
  "@
2350
   fsub %2, %0
2351
   fsub %2, %1, %0"
2352
  [(set_attr "cc" "none_0hit")])
2353
 
2354
(define_insn "mulsf3"
2355
  [(set (match_operand:SF 0 "register_operand" "=f,f")
2356
        (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
2357
                 (match_operand:SF 2 "general_operand" "f,?fF")))]
2358
  "TARGET_AM33_2"
2359
  "@
2360
   fmul %2, %0
2361
   fmul %2, %1, %0"
2362
  [(set_attr "cc" "none_0hit")])
2363
 
2364
(define_insn "divsf3"
2365
  [(set (match_operand:SF 0 "register_operand" "=f,f")
2366
        (div:SF (match_operand:SF 1 "register_operand" "0,f")
2367
                (match_operand:SF 2 "general_operand" "f,?fF")))]
2368
  "TARGET_AM33_2"
2369
  "@
2370
   fdiv %2, %0
2371
   fdiv %2, %1, %0"
2372
  [(set_attr "cc" "none_0hit")])
2373
 
2374
(define_insn "fmaddsf4"
2375
  [(set (match_operand:SF 0 "register_operand" "=A")
2376
        (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2377
                          (match_operand:SF 2 "register_operand" "f"))
2378
                 (match_operand:SF 3 "register_operand" "f")))]
2379
  "TARGET_AM33_2"
2380
  "fmadd %1, %2, %3, %0"
2381
  [(set_attr "cc" "none_0hit")])
2382
 
2383
(define_insn "fmsubsf4"
2384
  [(set (match_operand:SF 0 "register_operand" "=A")
2385
        (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2386
                           (match_operand:SF 2 "register_operand" "f"))
2387
                  (match_operand:SF 3 "register_operand" "f")))]
2388
  "TARGET_AM33_2"
2389
  "fmsub %1, %2, %3, %0"
2390
  [(set_attr "cc" "none_0hit")])
2391
 
2392
(define_insn "fnmaddsf4"
2393
  [(set (match_operand:SF 0 "register_operand" "=A")
2394
        (minus:SF (match_operand:SF 3 "register_operand" "f")
2395
                  (mult:SF (match_operand:SF 1 "register_operand" "%f")
2396
                           (match_operand:SF 2 "register_operand" "f"))))]
2397
  "TARGET_AM33_2"
2398
  "fnmadd %1, %2, %3, %0"
2399
  [(set_attr "cc" "none_0hit")])
2400
 
2401
(define_insn "fnmsubsf4"
2402
  [(set (match_operand:SF 0 "register_operand" "=A")
2403
        (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
2404
                                   (match_operand:SF 2 "register_operand" "f")))
2405
                  (match_operand:SF 3 "register_operand" "f")))]
2406
  "TARGET_AM33_2"
2407
  "fnmsub %1, %2, %3, %0"
2408
  [(set_attr "cc" "none_0hit")])
2409
 
2410
 
2411
;; ----------------------------------------------------------------------
2412
;; PROLOGUE/EPILOGUE
2413
;; ----------------------------------------------------------------------
2414
(define_expand "prologue"
2415
  [(const_int 0)]
2416
  ""
2417
  "expand_prologue (); DONE;")
2418
 
2419
(define_expand "epilogue"
2420
  [(return)]
2421
  ""
2422
  "
2423
{
2424
  expand_epilogue ();
2425
  DONE;
2426
}")
2427
 
2428
(define_insn "return_internal"
2429
  [(const_int 2)
2430
   (return)]
2431
  ""
2432
  "rets"
2433
  [(set_attr "cc" "clobber")])
2434
 
2435
;; This insn restores the callee saved registers and does a return, it
2436
;; can also deallocate stack space.
2437
(define_insn "return_internal_regs"
2438
  [(const_int 0)
2439
   (match_operand:SI 0  "const_int_operand" "i")
2440
   (return)]
2441
  ""
2442
  "*
2443
{
2444
  fputs (\"\\tret \", asm_out_file);
2445
  mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2446
  fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
2447
  return \"\";
2448
}"
2449
  [(set_attr "cc" "clobber")])
2450
 
2451
;; This instruction matches one generated by mn10300_gen_multiple_store()
2452
(define_insn "store_movm"
2453
  [(match_parallel 0 "store_multiple_operation"
2454
    [(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
2455
  ""
2456
  "*
2457
{
2458
  fputs (\"\\tmovm \", asm_out_file);
2459
  mn10300_print_reg_list (asm_out_file,
2460
                          store_multiple_operation (operands[0], VOIDmode));
2461
  fprintf (asm_out_file, \",(sp)\\n\");
2462
  return \"\";
2463
}"
2464
  [(set_attr "cc" "clobber")])
2465
 
2466
(define_insn "return"
2467
  [(return)]
2468
  "can_use_return_insn ()"
2469
  "*
2470
{
2471
  rtx next = next_active_insn (insn);
2472
 
2473
  if (next
2474
      && GET_CODE (next) == JUMP_INSN
2475
      && GET_CODE (PATTERN (next)) == RETURN)
2476
    return \"\";
2477
  else
2478
    return \"rets\";
2479
}"
2480
  [(set_attr "cc" "clobber")])
2481
 
2482
;; Try to combine consecutive updates of the stack pointer (or any
2483
;; other register for that matter).
2484
(define_peephole
2485
  [(set (match_operand:SI 0 "register_operand" "=dxay")
2486
        (plus:SI (match_dup 0)
2487
                 (match_operand 1 "const_int_operand" "")))
2488
   (set (match_dup 0)
2489
        (plus:SI (match_dup 0)
2490
                 (match_operand 2 "const_int_operand" "")))]
2491
  ""
2492
  "*
2493
{
2494
  operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
2495
  return \"add %1,%0\";
2496
}"
2497
  [(set_attr "cc" "clobber")])
2498
 
2499
;;
2500
;; We had patterns to check eq/ne, but the they don't work because
2501
;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
2502
;;
2503
;; The Z flag and C flag would be set, and we have no way to
2504
;; check for the Z flag set and C flag clear.
2505
;;
2506
;; This will work on the mn10200 because we can check the ZX flag
2507
;; if the comparison is in HImode.
2508
(define_peephole
2509
  [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2510
   (set (pc) (if_then_else (ge (cc0) (const_int 0))
2511
                           (match_operand 1 "" "")
2512
                           (pc)))]
2513
  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2514
  "add %0,%0\;bcc %1"
2515
  [(set_attr "cc" "clobber")])
2516
 
2517
(define_peephole
2518
  [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2519
   (set (pc) (if_then_else (lt (cc0) (const_int 0))
2520
                           (match_operand 1 "" "")
2521
                           (pc)))]
2522
  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2523
  "add %0,%0\;bcs %1"
2524
  [(set_attr "cc" "clobber")])
2525
 
2526
(define_peephole
2527
  [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2528
   (set (pc) (if_then_else (ge (cc0) (const_int 0))
2529
                           (pc)
2530
                           (match_operand 1 "" "")))]
2531
  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2532
  "add %0,%0\;bcs %1"
2533
  [(set_attr "cc" "clobber")])
2534
 
2535
(define_peephole
2536
  [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
2537
   (set (pc) (if_then_else (lt (cc0) (const_int 0))
2538
                           (pc)
2539
                           (match_operand 1 "" "")))]
2540
  "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
2541
  "add %0,%0\;bcc %1"
2542
  [(set_attr "cc" "clobber")])
2543
 
2544
(define_expand "int_label"
2545
  [(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
2546
  "" "")
2547
 
2548
(define_expand "GOTaddr2picreg"
2549
  [(match_dup 0)]
2550
  "" "
2551
{
2552
  /* It would be nice to be able to have int_label keep track of the
2553
     counter and all, but if we add C code to it, we'll get an insn
2554
     back, and we just want the pattern.  */
2555
  operands[0] = gen_int_label (GEN_INT (mn10300_unspec_int_label_counter++));
2556
  if (TARGET_AM33)
2557
    emit_insn (gen_am33_loadPC (operands[0]));
2558
  else
2559
    emit_insn (gen_mn10300_loadPC (operands[0]));
2560
  emit_insn (gen_add_GOT_to_pic_reg (operands[0]));
2561
  DONE;
2562
}
2563
")
2564
 
2565
(define_insn "am33_loadPC"
2566
  [(parallel
2567
    [(set (reg:SI PIC_REG) (pc))
2568
     (use (match_operand 0 "" ""))])]
2569
  "TARGET_AM33"
2570
  "%0:\;mov pc,a2")
2571
 
2572
 
2573
(define_insn_and_split "mn10300_loadPC"
2574
  [(parallel
2575
    [(set (reg:SI PIC_REG) (pc))
2576
     (use (match_operand 0 "" ""))])]
2577
  ""
2578
  "#"
2579
  "reload_completed"
2580
  [(match_operand 0 "" "")]
2581
  "
2582
{
2583
  rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
2584
  int need_stack_space = (get_frame_size () == 0
2585
                          && current_function_outgoing_args_size == 0);
2586
 
2587
  if (need_stack_space)
2588
    emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
2589
 
2590
  emit_insn (gen_call_next_insn (operands[0]));
2591
 
2592
  if (need_stack_space)
2593
    emit_insn (gen_pop_pic_reg ());
2594
  else
2595
    emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
2596
 
2597
  DONE;
2598
}")
2599
 
2600
(define_insn "call_next_insn"
2601
  [(parallel
2602
    [(set (mem:SI (reg:SI SP_REG)) (pc))
2603
     (use (match_operand 0 "" ""))])]
2604
  "reload_completed"
2605
  "calls %0\;%0:")
2606
 
2607
(define_expand "add_GOT_to_pic_reg"
2608
  [(set (reg:SI PIC_REG)
2609
        (plus:SI
2610
         (reg:SI PIC_REG)
2611
         (const
2612
          (unspec [(minus:SI
2613
                    (match_dup 1)
2614
                    (const (minus:SI
2615
                            (const (match_operand:SI 0 "" ""))
2616
                            (pc))))
2617
                  ] UNSPEC_PIC))))]
2618
  ""
2619
  "
2620
{
2621
  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2622
}")
2623
 
2624
(define_expand "symGOT2reg"
2625
  [(match_operand:SI 0 "" "")
2626
   (match_operand:SI 1 "" "")]
2627
  ""
2628
  "
2629
{
2630
  rtx insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1]));
2631
 
2632
  MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
2633
 
2634
  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
2635
                                        REG_NOTES (insn));
2636
 
2637
  DONE;
2638
}")
2639
 
2640
(define_expand "symGOT2reg_i"
2641
  [(set (match_operand:SI 0 "" "")
2642
        (mem:SI (plus:SI (reg:SI PIC_REG)
2643
                         (const (unspec [(match_operand:SI 1 "" "")]
2644
                                        UNSPEC_GOT)))))]
2645
  ""
2646
  "")
2647
 
2648
(define_expand "symGOTOFF2reg"
2649
  [(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
2650
  ""
2651
  "
2652
{
2653
  rtx insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1]));
2654
 
2655
  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
2656
                                        REG_NOTES (insn));
2657
 
2658
  DONE;
2659
}")
2660
 
2661
(define_expand "symGOTOFF2reg_i"
2662
  [(set (match_operand:SI 0 "" "")
2663
        (const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
2664
  (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
2665
  ""
2666
  "")
2667
 
2668
(define_expand "sym2PIC"
2669
  [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
2670
  "" "")
2671
 
2672
(define_expand "sym2PLT"
2673
  [(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
2674
  "" "")

powered by: WebSVN 2.1.0

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