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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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