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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [mn10300/] [mn10300.md] - Blame information for rev 298

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

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

powered by: WebSVN 2.1.0

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