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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [mn10300/] [mn10300.md] - Blame information for rev 709

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
;; GCC machine description for Matsushita MN10300
2
;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
;; 2005, 2006, 2007, 2008, 2009, 2010, 2011
4
;; Free Software Foundation, Inc.
5
;; Contributed by Jeff Law (law@cygnus.com).
6
 
7
;; This file is part of GCC.
8
 
9
;; GCC is free software; you can redistribute it and/or modify
10
;; it under the terms of the GNU General Public License as published by
11
;; the Free Software Foundation; either version 3, or (at your option)
12
;; any later version.
13
 
14
;; GCC is distributed in the hope that it will be useful,
15
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
;; GNU General Public License for more details.
18
 
19
;; You should have received a copy of the GNU General Public License
20
;; along with GCC; see the file COPYING3.  If not see
21
;; .
22
 
23
;; The original PO technology requires these to be ordered by speed,
24
;; so that assigner will pick the fastest.
25
 
26
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
 
28
(define_constants [
29
  (PIC_REG   6)
30
  (SP_REG    9)
31
  (MDR_REG  50)
32
  (CC_REG   51)
33
 
34
  (UNSPEC_PIC           1)
35
  (UNSPEC_GOT           2)
36
  (UNSPEC_GOTOFF        3)
37
  (UNSPEC_PLT           4)
38
  (UNSPEC_GOTSYM_OFF    5)
39
 
40
  (UNSPEC_EXT           6)
41
  (UNSPEC_BSCH          7)
42
 
43
  ;; This is used to encode LIW patterns.
44
  (UNSPEC_LIW           8)
45
  ;; This is for the low overhead loop instructions.
46
  (UNSPEC_SETLB         9)
47
])
48
 
49
(include "predicates.md")
50
(include "constraints.md")
51
 
52
;; Processor type.  This attribute must exactly match the processor_type
53
;; enumeration in mn10300.h.
54
(define_attr "cpu" "mn10300,am33,am33_2,am34"
55
  (const (symbol_ref "(enum attr_cpu) mn10300_tune_cpu")))
56
 
57
;; Used to control the "enabled" attribute on a per-instruction basis.
58
(define_attr "isa" "base,am33,am33_2,am34"
59
  (const_string "base"))
60
 
61
(define_attr "enabled" ""
62
  (cond [(eq_attr "isa" "base")
63
         (const_int 1)
64
 
65
         (and (eq_attr "isa" "am33")
66
              (match_test "TARGET_AM33"))
67
         (const_int 1)
68
 
69
         (and (eq_attr "isa" "am33_2")
70
              (match_test "TARGET_AM33_2"))
71
         (const_int 1)
72
 
73
         (and (eq_attr "isa" "am34")
74
              (match_test "TARGET_AM34"))
75
         (const_int 1)
76
        ]
77
        (const_int 0))
78
)
79
 
80
(define_mode_iterator INT [QI HI SI])
81
 
82
 
83
;; Bundling of smaller insns into a long instruction word (LIW)
84
(define_automaton "liw_bundling")
85
(automata_option "ndfa")
86
 
87
(define_cpu_unit "liw_op1_u,liw_op2_u" "liw_bundling")
88
 
89
(define_attr "liw" "op1,op2,both,either"
90
  (const_string "both"))
91
;; Note: this list must match the one defined for liw_op_names[].
92
(define_attr "liw_op" "add,cmp,sub,mov,and,or,xor,asr,lsr,asl,none,max"
93
  (const_string "none"))
94
 
95
(define_insn_reservation "liw_op1" 1
96
  (and (ior (eq_attr "cpu" "am33")
97
            (eq_attr "cpu" "am33_2")
98
            (eq_attr "cpu" "am34"))
99
       (eq_attr "liw" "op1"))
100
  "liw_op1_u");
101
(define_insn_reservation "liw_op2" 1
102
  (and (ior (eq_attr "cpu" "am33")
103
            (eq_attr "cpu" "am33_2")
104
            (eq_attr "cpu" "am34"))
105
       (eq_attr "liw" "op2"))
106
  "liw_op2_u");
107
(define_insn_reservation "liw_both" 1
108
  (and (ior (eq_attr "cpu" "am33")
109
            (eq_attr "cpu" "am33_2")
110
            (eq_attr "cpu" "am34"))
111
       (eq_attr "liw" "both"))
112
  "liw_op1_u + liw_op2_u");
113
(define_insn_reservation "liw_either" 1
114
  (and (ior (eq_attr "cpu" "am33")
115
            (eq_attr "cpu" "am33_2")
116
            (eq_attr "cpu" "am34"))
117
       (eq_attr "liw" "either"))
118
  "liw_op1_u | liw_op2_u");
119
 
120
;; ----------------------------------------------------------------------
121
;; Pipeline description.
122
;; ----------------------------------------------------------------------
123
 
124
;; The AM33 only has a single pipeline.  It has five stages (fetch,
125
;; decode, execute, memory access, writeback) each of which normally
126
;; takes a single CPU clock cycle.
127
 
128
;; The timings attribute consists of two numbers, the first is the
129
;; throughput, which is the number of cycles the instruction takes
130
;; to execute and generate a result.  The second is the latency
131
;; which is the effective number of cycles the instruction takes to
132
;; execute if its result is used by the following instruction.  The
133
;; latency is always greater than or equal to the throughput.
134
;; These values were taken from the Appendix of the "MN103E Series
135
;; Instruction Manual" and the timings for the AM34.
136
 
137
;; Note - it would be nice to use strings rather than integers for
138
;; the possible values of this attribute, so that we can have the
139
;; gcc build mechanism check for values that are not supported by
140
;; the reservations below.  But this will not work because the code
141
;; in mn10300_adjust_sched_cost() needs integers not strings.
142
 
143
(define_attr "timings" "" (const_int 11))
144
 
145
(define_automaton "pipelining")
146
(define_cpu_unit "throughput" "pipelining")
147
 
148
(define_insn_reservation "throughput__1_latency__1"  1
149
  (eq_attr "timings" "11") "throughput")
150
(define_insn_reservation "throughput__1_latency__2"  2
151
  (eq_attr "timings" "12") "throughput,nothing")
152
(define_insn_reservation "throughput__1_latency__3"  3
153
  (eq_attr "timings" "13") "throughput,nothing*2")
154
(define_insn_reservation "throughput__1_latency__4"  4
155
  (eq_attr "timings" "14") "throughput,nothing*3")
156
(define_insn_reservation "throughput__2_latency__2"  2
157
  (eq_attr "timings" "22") "throughput*2")
158
(define_insn_reservation "throughput__2_latency__3"  3
159
  (eq_attr "timings" "23") "throughput*2,nothing")
160
(define_insn_reservation "throughput__2_latency__4"  4
161
  (eq_attr "timings" "24") "throughput*2,nothing*2")
162
(define_insn_reservation "throughput__2_latency__5"  5
163
  (eq_attr "timings" "25") "throughput*2,nothing*3")
164
(define_insn_reservation "throughput__3_latency__3"  3
165
  (eq_attr "timings" "33") "throughput*3")
166
(define_insn_reservation "throughput__3_latency__7"  7
167
  (eq_attr "timings" "37") "throughput*3,nothing*4")
168
(define_insn_reservation "throughput__4_latency__4"  4
169
  (eq_attr "timings" "44") "throughput*4")
170
(define_insn_reservation "throughput__4_latency__7"  7
171
  (eq_attr "timings" "47") "throughput*4,nothing*3")
172
(define_insn_reservation "throughput__4_latency__8"  8
173
  (eq_attr "timings" "48") "throughput*4,nothing*4")
174
(define_insn_reservation "throughput__5_latency__5"  5
175
  (eq_attr "timings" "55") "throughput*5")
176
(define_insn_reservation "throughput__6_latency__6"  6
177
  (eq_attr "timings" "66") "throughput*6")
178
(define_insn_reservation "throughput__7_latency__7"  7
179
  (eq_attr "timings" "77") "throughput*7")
180
(define_insn_reservation "throughput__7_latency__8"  8
181
  (eq_attr "timings" "78") "throughput*7,nothing")
182
(define_insn_reservation "throughput__8_latency__8"  8
183
  (eq_attr "timings" "88") "throughput*8")
184
(define_insn_reservation "throughput__9_latency__9"  9
185
  (eq_attr "timings" "99") "throughput*9")
186
(define_insn_reservation "throughput__8_latency_14" 14
187
  (eq_attr "timings" "814") "throughput*8,nothing*6")
188
(define_insn_reservation "throughput__9_latency_10" 10
189
  (eq_attr "timings" "910") "throughput*9,nothing")
190
(define_insn_reservation "throughput_10_latency_10" 10
191
  (eq_attr "timings" "1010") "throughput*10")
192
(define_insn_reservation "throughput_12_latency_16" 16
193
  (eq_attr "timings" "1216") "throughput*12,nothing*4")
194
(define_insn_reservation "throughput_13_latency_13" 13
195
  (eq_attr "timings" "1313") "throughput*13")
196
(define_insn_reservation "throughput_14_latency_14" 14
197
  (eq_attr "timings" "1414") "throughput*14")
198
(define_insn_reservation "throughput_13_latency_17" 17
199
  (eq_attr "timings" "1317") "throughput*13,nothing*4")
200
(define_insn_reservation "throughput_23_latency_27" 27
201
  (eq_attr "timings" "2327") "throughput*23,nothing*4")
202
(define_insn_reservation "throughput_25_latency_31" 31
203
  (eq_attr "timings" "2531") "throughput*25,nothing*6")
204
(define_insn_reservation "throughput_38_latency_39" 39
205
  (eq_attr "timings" "3839") "throughput*38,nothing")
206
(define_insn_reservation "throughput_39_latency_40" 40
207
  (eq_attr "timings" "3940") "throughput*39,nothing")
208
(define_insn_reservation "throughput_40_latency_40" 40
209
  (eq_attr "timings" "4040") "throughput*40")
210
(define_insn_reservation "throughput_41_latency_42" 42
211
  (eq_attr "timings" "4142") "throughput*41,nothing")
212
(define_insn_reservation "throughput_42_latency_43" 44
213
  (eq_attr "timings" "4243") "throughput*42,nothing")
214
(define_insn_reservation "throughput_43_latency_44" 44
215
  (eq_attr "timings" "4344") "throughput*43,nothing")
216
(define_insn_reservation "throughput_45_latency_46" 46
217
  (eq_attr "timings" "4546") "throughput*45,nothing")
218
(define_insn_reservation "throughput_47_latency_53" 53
219
  (eq_attr "timings" "4753") "throughput*47,nothing*6")
220
 
221
;; Note - the conflict between memory load/store instructions
222
;; and floating point instructions described in section 1-7-4
223
;; of Chapter 3 of the MN103E Series Instruction Manual is
224
;; handled by the mn10300_adjust_sched_cost function.
225
 
226
;; ----------------------------------------------------------------------
227
;; MOVE INSTRUCTIONS
228
;; ----------------------------------------------------------------------
229
 
230
;; movqi
231
 
232
(define_expand "movqi"
233
  [(set (match_operand:QI 0 "nonimmediate_operand")
234
        (match_operand:QI 1 "general_operand"))]
235
  ""
236
{
237
  /* One of the ops has to be in a register.  */
238
  if (!register_operand (operand0, QImode)
239
      && !register_operand (operand1, QImode))
240
    operands[1] = force_reg (QImode, operand1);
241
})
242
 
243
(define_insn "*movqi_internal"
244
  [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d")
245
        (match_operand:QI 1 "general_operand"      "  0,D*r,  i,m,D,d,*z"))]
246
  "(register_operand (operands[0], QImode)
247
    || register_operand (operands[1], QImode))"
248
{
249
  switch (which_alternative)
250
    {
251
    case 0:
252
      return "";
253
    case 1:
254
    case 2:
255
    case 5:
256
    case 6:
257
      return "mov %1,%0";
258
    case 3:
259
    case 4:
260
      return "movbu %1,%0";
261
    default:
262
      gcc_unreachable ();
263
    }
264
}
265
  [(set_attr_alternative "timings"
266
         [(const_int 11)
267
          (const_int 11)
268
          (const_int 11)
269
          (if_then_else (eq_attr "cpu" "am34")
270
                        (const_int 13) (const_int 24))
271
          (if_then_else (eq_attr "cpu" "am34")
272
                        (const_int 11) (const_int 22))
273
          (const_int 11)
274
          (const_int 11)
275
         ])]
276
)
277
 
278
;; movhi
279
 
280
(define_expand "movhi"
281
  [(set (match_operand:HI 0 "nonimmediate_operand")
282
        (match_operand:HI 1 "general_operand"))]
283
  ""
284
{
285
  /* One of the ops has to be in a register.  */
286
  if (!register_operand (operand1, HImode)
287
      && !register_operand (operand0, HImode))
288
    operands[1] = force_reg (HImode, operand1);
289
})
290
 
291
(define_insn "*movhi_internal"
292
  [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d")
293
        (match_operand:HI 1 "general_operand"      "  0,  i,D*r,m,D,d,*z"))]
294
  "(register_operand (operands[0], HImode)
295
    || register_operand (operands[1], HImode))"
296
{
297
  switch (which_alternative)
298
    {
299
    case 0:
300
      return "";
301
    case 1:
302
      /* Note that "MOV imm8,An" is already zero-extending, and is 2 bytes.
303
         We have "MOV imm16,Dn" at 3 bytes.  The only win for the 4 byte
304
         movu is for an 8-bit unsigned move into Rn.  */
305
      if (TARGET_AM33
306
          && CONST_INT_P (operands[1])
307
          && IN_RANGE (INTVAL (operands[1]), 0x80, 0xff)
308
          && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
309
        return "movu %1,%0";
310
      /* FALLTHRU */
311
    case 5:
312
    case 6:
313
    case 2:
314
      return "mov %1,%0";
315
    case 3:
316
    case 4:
317
      return "movhu %1,%0";
318
    default:
319
      gcc_unreachable ();
320
    }
321
}
322
  [(set_attr_alternative "timings"
323
         [(const_int 11)
324
          (const_int 11)
325
          (if_then_else (eq_attr "cpu" "am34")
326
                        (const_int 11) (const_int 22))
327
          (if_then_else (eq_attr "cpu" "am34")
328
                        (const_int 13) (const_int 24))
329
          (if_then_else (eq_attr "cpu" "am34")
330
                        (const_int 11) (const_int 22))
331
          (if_then_else (eq_attr "cpu" "am34")
332
                        (const_int 11) (const_int 22))
333
          (if_then_else (eq_attr "cpu" "am34")
334
                        (const_int 11) (const_int 22))
335
         ])]
336
)
337
 
338
;; movsi and helpers
339
 
340
;; We use this to handle addition of two values when one operand is the
341
;; stack pointer and the other is a memory reference of some kind.  Reload
342
;; does not handle them correctly without this expander.
343
(define_expand "reload_plus_sp_const"
344
  [(set (match_operand:SI     0 "register_operand" "=r")
345
        (match_operand:SI     1 "impossible_plus_operand" ""))
346
   (clobber (match_operand:SI 2 "register_operand" "=&A"))]
347
  ""
348
{
349
  rtx dest, scratch, other;
350
 
351
  dest = operands[0];
352
  scratch = operands[2];
353
 
354
  other = XEXP (operands[1], 1);
355
  if (other == stack_pointer_rtx)
356
    other = XEXP (operands[1], 0);
357
 
358
  if (true_regnum (other) == true_regnum (dest))
359
    {
360
      gcc_assert (true_regnum (scratch) != true_regnum (dest));
361
      emit_move_insn (scratch, stack_pointer_rtx);
362
      emit_insn (gen_addsi3 (dest, dest, scratch));
363
    }
364
  else if (TARGET_AM33 || REGNO_REG_CLASS (true_regnum (dest)) == ADDRESS_REGS)
365
    {
366
      emit_move_insn (dest, stack_pointer_rtx);
367
      if (other == stack_pointer_rtx)
368
        emit_insn (gen_addsi3 (dest, dest, dest));
369
      else if (other != const0_rtx)
370
        emit_insn (gen_addsi3 (dest, dest, other));
371
    }
372
  else
373
    {
374
      emit_move_insn (scratch, stack_pointer_rtx);
375
      if (other == stack_pointer_rtx)
376
        {
377
          emit_move_insn (dest, scratch);
378
          emit_insn (gen_addsi3 (dest, dest, dest));
379
        }
380
      else if (other != const0_rtx)
381
        {
382
          emit_move_insn (dest, other);
383
          emit_insn (gen_addsi3 (dest, dest, scratch));
384
        }
385
      else
386
        emit_move_insn (dest, scratch);
387
    }
388
  DONE;
389
})
390
 
391
(define_expand "movsi"
392
  [(set (match_operand:SI 0 "nonimmediate_operand")
393
        (match_operand:SI 1 "general_operand"))]
394
  ""
395
{
396
  /* One of the ops has to be in a register.  */
397
  if (!register_operand (operand1, SImode)
398
      && !register_operand (operand0, SImode))
399
    operands[1] = force_reg (SImode, operand1);
400
  if (flag_pic)
401
    {
402
      rtx temp;
403
      if (SYMBOLIC_CONST_P (operands[1]))
404
        {
405
          if (MEM_P (operands[0]))
406
            operands[1] = force_reg (Pmode, operands[1]);
407
          else
408
            {
409
              temp = (!can_create_pseudo_p ()
410
                      ? operands[0]
411
                      : gen_reg_rtx (Pmode));
412
              operands[1] = mn10300_legitimize_pic_address (operands[1], temp);
413
            }
414
        }
415
      else if (GET_CODE (operands[1]) == CONST
416
               && GET_CODE (XEXP (operands[1], 0)) == PLUS
417
               && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
418
        {
419
          temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
420
          temp = mn10300_legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
421
                                                 temp);
422
          operands[1] = expand_binop (SImode, add_optab, temp,
423
                                      XEXP (XEXP (operands[1], 0), 1),
424
                                      (!can_create_pseudo_p ()
425
                                       ? temp
426
                                       : gen_reg_rtx (Pmode)),
427
                                      0, OPTAB_LIB_WIDEN);
428
        }
429
    }
430
})
431
 
432
(define_insn "*movsi_internal"
433
  [(set (match_operand:SI 0 "nonimmediate_operand"
434
                          "=r,r,r,r,m,r, A,*y,*y,*z,*d")
435
        (match_operand:SI 1 "general_operand"
436
                          " 0,O,i,r,r,m,*y, A, i,*d,*z"))]
437
  "register_operand (operands[0], SImode)
438
   || register_operand (operands[1], SImode)"
439
{
440
  switch (which_alternative)
441
    {
442
    case 0:
443
      return "";
444
    case 1: /* imm-reg.  */
445
    case 2:
446
      /* See movhi for a discussion of sizes for 8-bit movu.  Note that the
447
         24-bit movu is 6 bytes, which is the same size as the full 32-bit
448
         mov form for An and Dn.  So again movu is only a win for Rn.  */
449
      if (TARGET_AM33
450
          && CONST_INT_P (operands[1])
451
          && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
452
        {
453
          HOST_WIDE_INT val = INTVAL (operands[1]);
454
          if (IN_RANGE (val, 0x80, 0xff)
455
              || IN_RANGE (val, 0x800000, 0xffffff))
456
            return "movu %1,%0";
457
        }
458
      /* FALLTHRU */
459
    case 3:  /* reg-reg */
460
    case 4:  /* reg-mem */
461
    case 5:  /* mem-reg */
462
    case 6:  /* sp-reg */
463
    case 7:  /* reg-sp */
464
    case 8:  /* imm-sp */
465
    case 9:  /* reg-mdr */
466
    case 10:  /* mdr-reg */
467
      return "mov %1,%0";
468
    default:
469
      gcc_unreachable ();
470
    }
471
}
472
  [(set_attr "isa" "*,*,*,*,*,*,*,*,am33,*,*")
473
   (set_attr "liw" "*,either,*,either,*,*,*,*,*,*,*")
474
   (set_attr "liw_op" "mov")
475
   (set_attr_alternative "timings"
476
         [(const_int 11)
477
          (const_int 22)
478
          (const_int 22)
479
          (const_int 11)
480
          (if_then_else (eq_attr "cpu" "am34")
481
                        (const_int 11) (const_int 22))
482
          (if_then_else (eq_attr "cpu" "am34")
483
                        (const_int 13) (const_int 24))
484
          (if_then_else (eq_attr "cpu" "am34")
485
                        (const_int 11) (const_int 22))
486
          (if_then_else (eq_attr "cpu" "am34")
487
                        (const_int 13) (const_int 24))
488
          (const_int 11)
489
          (const_int 11)
490
          (const_int 11)
491
         ])]
492
)
493
 
494
(define_expand "movsf"
495
  [(set (match_operand:SF 0 "nonimmediate_operand")
496
        (match_operand:SF 1 "general_operand"))]
497
  "TARGET_AM33_2"
498
{
499
  /* One of the ops has to be in a register.  */
500
  if (!register_operand (operand1, SFmode)
501
      && !register_operand (operand0, SFmode))
502
    operands[1] = force_reg (SFmode, operand1);
503
})
504
 
505
(define_insn "*movsf_internal"
506
  [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q,z,d")
507
        (match_operand:SF 1 "general_operand"      "  0,F,F,r,f,f,r,m,r,Q,f,d,z"))]
508
  "TARGET_AM33_2
509
   && (register_operand (operands[0], SFmode)
510
       || register_operand (operands[1], SFmode))"
511
{
512
  switch (which_alternative)
513
    {
514
    case 0:
515
      return "";
516
    case 1:
517
    case 3:
518
    case 7:
519
    case 8:
520
    case 11:
521
    case 12:
522
      return "mov %1,%0";
523
    case 2:
524
    case 4:
525
    case 5:
526
    case 6:
527
    case 9:
528
    case 10:
529
      return "fmov %1,%0";
530
    default:
531
      gcc_unreachable ();
532
    }
533
}
534
  [(set_attr_alternative "timings"
535
                 [(const_int 11)
536
                  (const_int 22)
537
                  (if_then_else (eq_attr "cpu" "am34")
538
                                (const_int 47) (const_int 25))
539
                  (const_int 11)
540
                  (if_then_else (eq_attr "cpu" "am34")
541
                                (const_int 13) (const_int 14))
542
                  (if_then_else (eq_attr "cpu" "am34")
543
                                (const_int 13) (const_int 12))
544
                  (if_then_else (eq_attr "cpu" "am34")
545
                                (const_int 13) (const_int 14))
546
                  (if_then_else (eq_attr "cpu" "am34")
547
                                (const_int 13) (const_int 24))
548
                  (if_then_else (eq_attr "cpu" "am34")
549
                                (const_int 13) (const_int 24))
550
                  (if_then_else (eq_attr "cpu" "am34")
551
                                (const_int 13) (const_int 24))
552
                  (if_then_else (eq_attr "cpu" "am34")
553
                                (const_int 13) (const_int 24))
554
                  (const_int 22)
555
                  (const_int 22)
556
                 ])]
557
)
558
 
559
;; If the flags register is not live, generate CLR instead of MOV 0.
560
;; For MN103, this is only legal for DATA_REGS; for AM33 this is legal
561
;; but not a win for ADDRESS_REGS.
562
(define_peephole2
563
  [(set (match_operand:INT 0 "register_operand" "") (const_int 0))]
564
  "peep2_regno_dead_p (0, CC_REG)
565
   && (REGNO_DATA_P (REGNO (operands[0]), 1)
566
       || REGNO_EXTENDED_P (REGNO (operands[0]), 1))"
567
  [(parallel [(set (match_dup 0) (const_int 0))
568
              (clobber (reg:CC CC_REG))])]
569
)
570
 
571
(define_insn "*mov_clr"
572
  [(set (match_operand:INT 0 "register_operand" "=D")
573
        (const_int 0))
574
   (clobber (reg:CC CC_REG))]
575
  ""
576
  "clr %0"
577
)
578
 
579
;; ----------------------------------------------------------------------
580
;; ADD INSTRUCTIONS
581
;; ----------------------------------------------------------------------
582
 
583
(define_insn "addsi3"
584
  [(set (match_operand:SI          0 "register_operand"  "=r,r,r,!*y,!r")
585
        (plus:SI (match_operand:SI 1 "register_operand"  "%0,0,0,  0, r")
586
                 (match_operand:SI 2 "nonmemory_operand"  "r,O,i,  i, r")))
587
   (clobber (reg:CC CC_REG))]
588
  ""
589
  { return mn10300_output_add (operands, false); }
590
  [(set_attr "timings" "11,11,11,11,22")
591
   (set_attr "liw" "either,either,*,*,*")
592
   (set_attr "liw_op" "add")]
593
)
594
 
595
;; Note that ADD IMM,SP does not set the flags, so omit that here.
596
(define_insn "*addsi3_flags"
597
  [(set (match_operand:SI          0 "register_operand"  "=r,!r")
598
        (plus:SI (match_operand:SI 1 "register_operand"  "%0, r")
599
                 (match_operand:SI 2 "nonmemory_operand" "ri, r")))
600
   (set (reg CC_REG)
601
        (compare (plus:SI (match_dup 1) (match_dup 2))
602
                 (const_int 0)))]
603
  "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)"
604
  { return mn10300_output_add (operands, true); }
605
  [(set_attr "timings" "11,22")]
606
)
607
 
608
;; A helper to expand the above, with the CC_MODE filled in.
609
(define_expand "addsi3_flags"
610
  [(parallel [(set (match_operand:SI 0 "register_operand")
611
                   (plus:SI (match_operand:SI 1 "register_operand")
612
                            (match_operand:SI 2 "nonmemory_operand")))
613
              (set (reg:CCZNC CC_REG)
614
                   (compare:CCZNC (plus:SI (match_dup 1) (match_dup 2))
615
                                  (const_int 0)))])]
616
  ""
617
)
618
 
619
(define_insn "addc_internal"
620
  [(set (match_operand:SI 0 "register_operand"            "=D,r,r")
621
        (plus:SI
622
          (plus:SI
623
            (ltu:SI (reg:CC CC_REG) (const_int 0))
624
            (match_operand:SI 1 "register_operand"        "%0,0,r"))
625
          (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r")))
626
    (clobber (reg:CC CC_REG))]
627
  "reload_completed"
628
  "@
629
   addc %2,%0
630
   addc %2,%0
631
   addc %2,%1,%0"
632
  [(set_attr "isa" "*,am33,am33")]
633
)
634
 
635
(define_expand "adddi3"
636
  [(set (match_operand:DI 0 "register_operand" "")
637
        (plus:DI (match_operand:DI 1 "register_operand" "")
638
                 (match_operand:DI 2 "nonmemory_operand" "")))]
639
  ""
640
{
641
  rtx op0l, op0h, op1l, op1h, op2l, op2h;
642
 
643
  op0l = gen_lowpart (SImode, operands[0]);
644
  op1l = gen_lowpart (SImode, operands[1]);
645
  op2l = gen_lowpart (SImode, operands[2]);
646
  op0h = gen_highpart (SImode, operands[0]);
647
  op1h = gen_highpart (SImode, operands[1]);
648
  op2h = gen_highpart_mode (SImode, DImode, operands[2]);
649
 
650
  if (!reg_or_am33_const_operand (op2h, SImode))
651
    op2h = force_reg (SImode, op2h);
652
 
653
  emit_insn (gen_adddi3_internal (op0l, op0h, op1l, op2l, op1h, op2h));
654
  DONE;
655
})
656
 
657
;; Note that reload only supports one commutative operand.  Thus we cannot
658
;; auto-swap both the high and low outputs with their matching constraints.
659
;; For MN103, we're strapped for registers but thankfully the alternatives
660
;; are few.  For AM33, it becomes much easier to not represent the early
661
;; clobber and 6 permutations of immediate and three-operand adds, but
662
;; instead allocate a scratch register and do the expansion by hand.
663
 
664
(define_insn_and_split "adddi3_internal"
665
  [(set (match_operand:SI          0 "register_operand"   "=r, r, r")
666
        (plus:SI (match_operand:SI 2 "register_operand"   "%0, 0, r")
667
                 (match_operand:SI 3 "nonmemory_operand"  "ri,ri,ri")))
668
   (set (match_operand:SI          1 "register_operand"   "=D, D, r")
669
        (plus:SI
670
          (plus:SI
671
            (ltu:SI (plus:SI (match_dup 2) (match_dup 3)) (match_dup 2))
672
            (match_operand:SI      4 "register_operand"   " 1, D, r"))
673
          (match_operand:SI 5 "reg_or_am33_const_operand" " D, 1,ri")))
674
   (clobber (match_scratch:SI      6                      "=X, X,&r"))
675
   (clobber (reg:CC CC_REG))]
676
  ""
677
  "#"
678
  "reload_completed"
679
  [(const_int 0)]
680
{
681
  rtx op0l = operands[0];
682
  rtx op0h = operands[1];
683
  rtx op1l = operands[2];
684
  rtx op2l = operands[3];
685
  rtx op1h = operands[4];
686
  rtx op2h = operands[5];
687
  rtx scratch = operands[6];
688
  rtx x;
689
 
690
  if (reg_overlap_mentioned_p (op0l, op1h))
691
    {
692
      emit_move_insn (scratch, op0l);
693
      op1h = scratch;
694
      if (reg_overlap_mentioned_p (op0l, op2h))
695
        op2h = scratch;
696
    }
697
  else if (reg_overlap_mentioned_p (op0l, op2h))
698
    {
699
      emit_move_insn (scratch, op0l);
700
      op2h = scratch;
701
    }
702
 
703
  if (rtx_equal_p (op0l, op1l))
704
    ;
705
  else if (rtx_equal_p (op0l, op2l))
706
    x = op1l, op1l = op2l, op2l = x;
707
  else
708
    {
709
      gcc_assert (TARGET_AM33);
710
      if (!REG_P (op2l))
711
        {
712
          emit_move_insn (op0l, op2l);
713
          op2l = op1l;
714
          op1l = op0l;
715
        }
716
    }
717
  emit_insn (gen_addsi3_flags (op0l, op1l, op2l));
718
 
719
  if (rtx_equal_p (op0h, op1h))
720
    ;
721
  else if (rtx_equal_p (op0h, op2h))
722
    x = op1h, op1h = op2h, op2h = x;
723
  else
724
    {
725
      gcc_assert (TARGET_AM33);
726
      if (!REG_P (op2h))
727
        {
728
          emit_move_insn (op0h, op2h);
729
          op2h = op1h;
730
          op1h = op0h;
731
        }
732
    }
733
  emit_insn (gen_addc_internal (op0h, op1h, op2h));
734
  DONE;
735
}
736
  [(set_attr "isa" "*,*,am33")]
737
)
738
 
739
;; The following pattern is generated by combine when it proves that one
740
;; of the inputs to the low-part of the double-word add is zero, and thus
741
;; no carry is generated into the high-part.
742
 
743
(define_insn_and_split "*adddi3_degenerate"
744
  [(set (match_operand:SI          0 "register_operand"  "=&r,&r")
745
        (match_operand:SI          2 "nonmemory_operand" "  0, 0"))
746
   (set (match_operand:SI          1 "register_operand"  "=r , r")
747
        (plus:SI (match_operand:SI 3 "register_operand"  "%1 , r")
748
                 (match_operand:SI 4 "nonmemory_operand" "ri, r")))
749
   (clobber (reg:CC CC_REG))]
750
  ""
751
  "#"
752
  ""
753
  [(const_int 0)]
754
{
755
  rtx scratch = NULL_RTX;
756
  if (!rtx_equal_p (operands[0], operands[2]))
757
    {
758
      gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1]));
759
      if (reg_overlap_mentioned_p (operands[0], operands[3])
760
          || reg_overlap_mentioned_p (operands[0], operands[4]))
761
        {
762
          scratch = gen_reg_rtx (SImode);
763
          emit_move_insn (scratch, operands[2]);
764
        }
765
      else
766
        emit_move_insn (operands[0], operands[2]);
767
    }
768
  emit_insn (gen_addsi3 (operands[1], operands[3], operands[4]));
769
  if (scratch)
770
    emit_move_insn (operands[0], scratch);
771
  DONE;
772
})
773
 
774
;; ----------------------------------------------------------------------
775
;; SUBTRACT INSTRUCTIONS
776
;; ----------------------------------------------------------------------
777
 
778
(define_insn "subsi3"
779
  [(set (match_operand:SI           0 "register_operand"  "=r,r,r,r")
780
        (minus:SI (match_operand:SI 1 "register_operand"   "0,0,0,r")
781
                  (match_operand:SI 2 "nonmemory_operand"  "r,O,i,r")))
782
   (clobber (reg:CC CC_REG))]
783
  ""
784
  "@
785
   sub %2,%0
786
   sub %2,%0
787
   sub %2,%0
788
   sub %2,%1,%0"
789
  [(set_attr "isa" "*,*,*,am33")
790
   (set_attr "liw" "either,either,*,*")
791
   (set_attr "liw_op" "sub")
792
   (set_attr "timings" "11,11,11,22")]
793
)
794
 
795
(define_insn "*subsi3_flags"
796
  [(set (match_operand:SI           0 "register_operand"  "=r, r")
797
        (minus:SI (match_operand:SI 1 "register_operand"   "0, r")
798
                  (match_operand:SI 2 "nonmemory_operand"  "ri,r")))
799
   (set (reg CC_REG)
800
        (compare (minus:SI (match_dup 1) (match_dup 2))
801
                 (const_int 0)))]
802
  "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)"
803
  "@
804
   sub %2,%0
805
   sub %2,%1,%0"
806
  [(set_attr "isa" "*,am33")
807
   (set_attr "timings" "11,22")]
808
)
809
 
810
;; A helper to expand the above, with the CC_MODE filled in.
811
(define_expand "subsi3_flags"
812
  [(parallel [(set (match_operand:SI 0 "register_operand")
813
                   (minus:SI (match_operand:SI 1 "register_operand")
814
                             (match_operand:SI 2 "nonmemory_operand")))
815
              (set (reg:CCZNC CC_REG)
816
                   (compare:CCZNC (minus:SI (match_dup 1) (match_dup 2))
817
                                  (const_int 0)))])]
818
  ""
819
)
820
 
821
(define_insn "subc_internal"
822
  [(set (match_operand:SI 0 "register_operand"                      "=D,r,r")
823
        (minus:SI
824
          (minus:SI (match_operand:SI 1 "register_operand"          " 0,0,r")
825
                    (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r"))
826
          (geu:SI (reg:CC CC_REG) (const_int 0))))
827
   (clobber (reg:CC CC_REG))]
828
  "reload_completed"
829
  "@
830
   subc %2,%0
831
   subc %2,%0
832
   subc %2,%1,%0"
833
  [(set_attr "isa" "*,am33,am33")]
834
)
835
 
836
(define_expand "subdi3"
837
  [(set (match_operand:DI 0 "register_operand" "")
838
        (minus:DI (match_operand:DI 1 "register_operand" "")
839
                  (match_operand:DI 2 "nonmemory_operand" "")))]
840
  ""
841
{
842
  rtx op0l, op0h, op1l, op1h, op2l, op2h;
843
 
844
  op0l = gen_lowpart (SImode, operands[0]);
845
  op1l = gen_lowpart (SImode, operands[1]);
846
  op2l = gen_lowpart (SImode, operands[2]);
847
  op0h = gen_highpart (SImode, operands[0]);
848
  op1h = gen_highpart (SImode, operands[1]);
849
  op2h = gen_highpart_mode (SImode, DImode, operands[2]);
850
 
851
  if (!reg_or_am33_const_operand (op2h, SImode))
852
    op2h = force_reg (SImode, op2h);
853
 
854
  emit_insn (gen_subdi3_internal (op0l, op0h, op1l, op1h, op2l, op2h));
855
  DONE;
856
})
857
 
858
;; As with adddi3, the use of the scratch register helps reduce the
859
;; number of permutations for AM33.
860
;; ??? The early clobber on op0 avoids a reload bug wherein both output
861
;; registers are set the same.  Consider negate, where both op2 and op3
862
;; are 0, are csed to the same input register, and reload fails to undo
863
;; the cse when satisfying the matching constraints.
864
 
865
(define_insn_and_split "subdi3_internal"
866
  [(set (match_operand:SI     0 "register_operand"         "=&r, r")
867
        (minus:SI
868
          (match_operand:SI   2 "register_operand"         "  0, r")
869
          (match_operand:SI   4 "nonmemory_operand"        " ri,ri")))
870
   (set (match_operand:SI     1 "register_operand"         "=D , r")
871
        (minus:SI
872
          (minus:SI
873
            (match_operand:SI 3 "register_operand"         "  1, r")
874
            (match_operand:SI 5 "reg_or_am33_const_operand" " D,ri"))
875
          (ltu:SI (match_dup 2) (match_dup 4))))
876
   (clobber (match_scratch:SI 6                            "=X ,&r"))
877
   (clobber (reg:CC CC_REG))]
878
  ""
879
  "#"
880
  "reload_completed"
881
  [(const_int 0)]
882
{
883
  rtx op0l = operands[0];
884
  rtx op0h = operands[1];
885
  rtx op1l = operands[2];
886
  rtx op1h = operands[3];
887
  rtx op2l = operands[4];
888
  rtx op2h = operands[5];
889
  rtx scratch = operands[6];
890
 
891
  if (reg_overlap_mentioned_p (op0l, op1h))
892
    {
893
      emit_move_insn (scratch, op0l);
894
      op1h = scratch;
895
      if (reg_overlap_mentioned_p (op0l, op2h))
896
        op2h = scratch;
897
    }
898
  else if (reg_overlap_mentioned_p (op0l, op2h))
899
    {
900
      emit_move_insn (scratch, op0l);
901
      op2h = scratch;
902
    }
903
 
904
  if (!rtx_equal_p (op0l, op1l))
905
    {
906
      gcc_assert (TARGET_AM33);
907
      if (!REG_P (op2l))
908
        {
909
          emit_move_insn (op0l, op1l);
910
          op1l = op0l;
911
        }
912
    }
913
  emit_insn (gen_subsi3_flags (op0l, op1l, op2l));
914
 
915
  if (!rtx_equal_p (op0h, op1h))
916
    {
917
      gcc_assert (TARGET_AM33);
918
      if (!REG_P (op2h))
919
        {
920
          emit_move_insn (op0h, op1h);
921
          op1h = op0h;
922
        }
923
    }
924
  emit_insn (gen_subc_internal (op0h, op1h, op2h));
925
  DONE;
926
}
927
  [(set_attr "isa" "*,am33")]
928
)
929
 
930
;; The following pattern is generated by combine when it proves that one
931
;; of the inputs to the low-part of the double-word sub is zero, and thus
932
;; no carry is generated into the high-part.
933
 
934
(define_insn_and_split "*subdi3_degenerate"
935
  [(set (match_operand:SI          0 "register_operand"   "=&r,&r")
936
        (match_operand:SI          2 "nonmemory_operand"  "  0, 0"))
937
   (set (match_operand:SI          1 "register_operand"   "=r , r")
938
        (minus:SI (match_operand:SI 3 "register_operand"  "  1, r")
939
                  (match_operand:SI 4 "nonmemory_operand" " ri, r")))
940
   (clobber (reg:CC CC_REG))]
941
  ""
942
  "#"
943
  ""
944
  [(const_int 0)]
945
{
946
  rtx scratch = NULL_RTX;
947
  if (!rtx_equal_p (operands[0], operands[2]))
948
    {
949
      gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1]));
950
      if (reg_overlap_mentioned_p (operands[0], operands[3])
951
          || reg_overlap_mentioned_p (operands[0], operands[4]))
952
        {
953
          scratch = gen_reg_rtx (SImode);
954
          emit_move_insn (scratch, operands[2]);
955
        }
956
      else
957
        emit_move_insn (operands[0], operands[2]);
958
    }
959
  emit_insn (gen_subsi3 (operands[1], operands[3], operands[4]));
960
  if (scratch)
961
    emit_move_insn (operands[0], scratch);
962
  DONE;
963
})
964
 
965
(define_insn_and_split "negsi2"
966
  [(set (match_operand:SI         0 "register_operand"  "=D,&r")
967
        (neg:SI (match_operand:SI 1 "register_operand"  " 0, r")))
968
   (clobber (reg:CC CC_REG))]
969
  ""
970
  "#"
971
  "&& reload_completed"
972
  [(const_int 0)]
973
{
974
  /* Recall that twos-compliment is ones-compliment plus one.  When
975
     allocated in DATA_REGS this is 2+1 bytes; otherwise (for am33)
976
     this is 3+3 bytes.
977
 
978
     For AM33, it would have been possible to load zero and use the
979
     three-address subtract to have a total size of 3+4*N bytes for
980
     multiple negations, plus increased throughput.  Not attempted here.  */
981
 
982
  if (true_regnum (operands[0]) == true_regnum (operands[1]))
983
    {
984
      emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
985
      emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
986
    }
987
  else
988
    {
989
      emit_move_insn (operands[0], const0_rtx);
990
      emit_insn (gen_subsi3 (operands[0], operands[0], operands[1]));
991
    }
992
  DONE;
993
})
994
 
995
;; ----------------------------------------------------------------------
996
;; MULTIPLY INSTRUCTIONS
997
;; ----------------------------------------------------------------------
998
 
999
;; ??? Note that AM33 has a third multiply variant that puts the high part
1000
;; into the MDRQ register, however this variant also constrains the inputs
1001
;; to be in DATA_REGS and thus isn't as helpful as it might be considering
1002
;; the existance of the 4-operand multiply.  Nor is there a set of divide
1003
;; insns that use MDRQ.  Given that there is an IMM->MDRQ insn, this would
1004
;; have been very handy for starting udivmodsi4...
1005
 
1006
(define_expand "mulsidi3"
1007
  [(set (match_operand:DI 0 "register_operand" "")
1008
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1009
                 (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))]
1010
  ""
1011
{
1012
  emit_insn (gen_mulsidi3_internal (gen_lowpart (SImode, operands[0]),
1013
                                    gen_highpart (SImode, operands[0]),
1014
                                    operands[1], operands[2]));
1015
  DONE;
1016
})
1017
 
1018
(define_insn "mulsidi3_internal"
1019
  [(set (match_operand:SI          0 "register_operand" "=D,r")
1020
        (mult:SI (match_operand:SI 2 "register_operand" "%0,r")
1021
                 (match_operand:SI 3 "register_operand" " D,r")))
1022
   (set (match_operand:SI          1 "register_operand" "=z,r")
1023
        (truncate:SI
1024
          (ashiftrt:DI
1025
            (mult:DI (sign_extend:DI (match_dup 2))
1026
                     (sign_extend:DI (match_dup 3)))
1027
            (const_int 32))))
1028
   (clobber (reg:CC CC_REG))]
1029
  ""
1030
{
1031
  if (which_alternative == 1)
1032
    return "mul %2,%3,%1,%0";
1033
  else if (TARGET_MULT_BUG)
1034
    return "nop\;nop\;mul %3,%0";
1035
  else
1036
    return "mul %3,%0";
1037
}
1038
  [(set_attr "isa" "*,am33")
1039
   (set (attr "timings")
1040
        (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
1041
)
1042
 
1043
(define_expand "umulsidi3"
1044
  [(set (match_operand:DI 0 "register_operand" "")
1045
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1046
                 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
1047
   (clobber (reg:CC CC_REG))]
1048
  ""
1049
{
1050
  emit_insn (gen_umulsidi3_internal (gen_lowpart (SImode, operands[0]),
1051
                                     gen_highpart (SImode, operands[0]),
1052
                                     operands[1], operands[2]));
1053
  DONE;
1054
})
1055
 
1056
(define_insn "umulsidi3_internal"
1057
  [(set (match_operand:SI          0 "register_operand" "=D,r")
1058
        (mult:SI (match_operand:SI 2 "register_operand" "%0,r")
1059
                 (match_operand:SI 3 "register_operand" " D,r")))
1060
   (set (match_operand:SI          1 "register_operand" "=z,r")
1061
        (truncate:SI
1062
          (lshiftrt:DI
1063
            (mult:DI (zero_extend:DI (match_dup 2))
1064
                     (zero_extend:DI (match_dup 3)))
1065
            (const_int 32))))
1066
   (clobber (reg:CC CC_REG))]
1067
  ""
1068
{
1069
  if (which_alternative == 1)
1070
    return "mulu %2,%3,%1,%0";
1071
  else if (TARGET_MULT_BUG)
1072
    return "nop\;nop\;mulu %3,%0";
1073
  else
1074
    return "mulu %3,%0";
1075
}
1076
  [(set_attr "isa" "*,am33")
1077
   (set (attr "timings")
1078
        (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
1079
)
1080
 
1081
(define_expand "mulsi3"
1082
  [(parallel [(set (match_operand:SI          0 "register_operand")
1083
                   (mult:SI (match_operand:SI 1 "register_operand")
1084
                            (match_operand:SI 2 "reg_or_am33_const_operand")))
1085
              (clobber (match_scratch:SI      3))
1086
              (clobber (reg:CC CC_REG))])]
1087
  ""
1088
)
1089
 
1090
(define_insn "*mulsi3"
1091
  [(set (match_operand:SI          0 "register_operand"          "=D, r,r")
1092
        (mult:SI (match_operand:SI 2 "register_operand"          "%0, 0,r")
1093
                 (match_operand:SI 3 "reg_or_am33_const_operand" " D,ri,r")))
1094
   (clobber (match_scratch:SI      1                             "=z, z,r"))
1095
   (clobber (reg:CC CC_REG))]
1096
  ""
1097
{
1098
  if (which_alternative == 2)
1099
    return "mul %2,%3,%1,%0";
1100
  else if (TARGET_MULT_BUG)
1101
    return "nop\;nop\;mul %3,%0";
1102
  else
1103
    return "mul %3,%0";
1104
}
1105
  [(set_attr "isa" "*,am33,am33")
1106
   (set (attr "timings")
1107
        (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))]
1108
)
1109
 
1110
(define_expand "udivmodsi4"
1111
  [(parallel [(set (match_operand:SI          0 "register_operand")
1112
                   (udiv:SI (match_operand:SI 1 "register_operand")
1113
                            (match_operand:SI 2 "register_operand")))
1114
              (set (match_operand:SI          3 "register_operand")
1115
                   (umod:SI (match_dup 1) (match_dup 2)))
1116
              (use (const_int 0))
1117
              (clobber (reg:CC CC_REG))])]
1118
  ""
1119
)
1120
 
1121
;; Note the trick to get reload to put the zero into the MDR register,
1122
;; rather than exposing the load early and letting CSE or someone try
1123
;; to share the zeros between division insns.  Which tends to result
1124
;; in sequences like 0->r0->d0->mdr.
1125
 
1126
(define_insn "*udivmodsi4"
1127
  [(set (match_operand:SI          0 "register_operand" "=D")
1128
        (udiv:SI (match_operand:SI 2 "register_operand" " 0")
1129
                 (match_operand:SI 3 "register_operand" " D")))
1130
   (set (match_operand:SI          1 "register_operand" "=z")
1131
        (umod:SI (match_dup 2) (match_dup 3)))
1132
   (use (match_operand:SI          4 "nonmemory_operand" " 1"))
1133
   (clobber (reg:CC CC_REG))]
1134
  ""
1135
  "divu %3,%0"
1136
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1137
                                       (const_int 3839) (const_int 4243)))]
1138
)
1139
 
1140
(define_expand "divmodsi4"
1141
  [(parallel [(set (match_operand:SI          0 "register_operand" "")
1142
                   (div:SI (match_operand:SI  1 "register_operand" "")
1143
                           (match_operand:SI  2 "register_operand" "")))
1144
              (set (match_operand:SI          3 "register_operand" "")
1145
                   (mod:SI (match_dup 1) (match_dup 2)))
1146
              (use (match_dup 4))
1147
              (clobber (reg:CC CC_REG))])]
1148
  ""
1149
{
1150
  operands[4] = gen_reg_rtx (SImode);
1151
  emit_insn (gen_ext_internal (operands[4], operands[1]));
1152
})
1153
 
1154
;; ??? Ideally we'd represent this via shift, but it seems like adding a
1155
;; special-case pattern for (ashiftrt x 31) is just as likely to result
1156
;; in poor register allocation choices.
1157
(define_insn "ext_internal"
1158
  [(set (match_operand:SI 0 "register_operand" "=z")
1159
        (unspec:SI [(match_operand:SI 1 "register_operand" "D")] UNSPEC_EXT))]
1160
  ""
1161
  "ext %1"
1162
)
1163
 
1164
(define_insn "*divmodsi4"
1165
  [(set (match_operand:SI          0 "register_operand" "=D")
1166
        (div:SI (match_operand:SI  2 "register_operand" " 0")
1167
                (match_operand:SI  3 "register_operand" " D")))
1168
   (set (match_operand:SI          1 "register_operand" "=z")
1169
        (mod:SI (match_dup 2) (match_dup 3)))
1170
   (use (match_operand:SI          4 "register_operand" " 1"))
1171
   (clobber (reg:CC CC_REG))]
1172
  ""
1173
  "div %3,%0";
1174
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1175
                                       (const_int 3839) (const_int 4243)))]
1176
)
1177
 
1178
 
1179
;; ----------------------------------------------------------------------
1180
;; AND INSTRUCTIONS
1181
;; ----------------------------------------------------------------------
1182
 
1183
(define_insn "andsi3"
1184
  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
1185
        (and:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1186
                (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1187
   (clobber (reg:CC CC_REG))]
1188
  ""
1189
  "@
1190
   and %2,%0
1191
   and %2,%0
1192
   and %2,%1,%0"
1193
  [(set_attr "isa" "*,*,am33")
1194
   (set_attr "liw" "*,op1,*")
1195
   (set_attr "liw_op" "and")
1196
   (set_attr "timings" "22,11,11")]
1197
)
1198
 
1199
(define_insn "*andsi3_flags"
1200
  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
1201
        (and:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1202
                (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1203
   (set (reg CC_REG)
1204
        (compare (and:SI (match_dup 1) (match_dup 2))
1205
                 (const_int 0)))]
1206
  "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
1207
  "@
1208
   and %2,%0
1209
   and %2,%0
1210
   and %2,%1,%0"
1211
  [(set_attr "isa" "*,*,am33")
1212
   (set_attr "timings" "22,11,11")]
1213
)
1214
 
1215
;; Make sure we generate extensions instead of ANDs.
1216
 
1217
(define_split
1218
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
1219
                   (and:SI (match_operand:SI 1 "register_operand" "")
1220
                           (const_int 255)))
1221
              (clobber (reg:CC CC_REG))])]
1222
  ""
1223
  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
1224
  { operands[1] = gen_lowpart (QImode, operands[1]); }
1225
)
1226
 
1227
(define_split
1228
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
1229
                   (and:SI (match_operand:SI 1 "register_operand" "")
1230
                           (const_int 65535)))
1231
              (clobber (reg:CC CC_REG))])]
1232
  ""
1233
  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
1234
  { operands[1] = gen_lowpart (HImode, operands[1]); }
1235
)
1236
 
1237
;; Split AND by an appropriate constant into two shifts.  Recall that
1238
;; operations with a full 32-bit immediate require an extra cycle, so
1239
;; this is a size optimization with no speed penalty.  This only applies
1240
;; do DATA_REGS; the shift insns that AM33 adds are too large for a win.
1241
 
1242
(define_split
1243
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
1244
                   (and:SI (match_dup 0)
1245
                           (match_operand:SI 1 "const_int_operand" "")))
1246
              (clobber (reg:CC CC_REG))])]
1247
  "reload_completed
1248
   && REGNO_DATA_P (true_regnum (operands[0]), 1)
1249
   && mn10300_split_and_operand_count (operands[1]) != 0"
1250
  [(const_int 0)]
1251
{
1252
  int count = mn10300_split_and_operand_count (operands[1]);
1253
  if (count > 0)
1254
    {
1255
      emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (count)));
1256
      emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (count)));
1257
    }
1258
  else
1259
    {
1260
      emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (-count)));
1261
      emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (-count)));
1262
    }
1263
  DONE;
1264
})
1265
 
1266
;; ----------------------------------------------------------------------
1267
;; OR INSTRUCTIONS
1268
;; ----------------------------------------------------------------------
1269
 
1270
(define_insn "iorsi3"
1271
  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
1272
        (ior:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1273
                (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1274
   (clobber (reg:CC CC_REG))]
1275
  ""
1276
  "@
1277
   or %2,%0
1278
   or %2,%0
1279
   or %2,%1,%0"
1280
  [(set_attr "isa" "*,*,am33")
1281
   (set_attr "liw" "*,op1,*")
1282
   (set_attr "liw_op" "or")
1283
   (set_attr "timings" "22,11,11")]
1284
)
1285
 
1286
(define_insn "*iorsi3_flags"
1287
  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
1288
        (ior:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1289
                (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1290
   (set (reg CC_REG)
1291
        (compare (ior:SI (match_dup 1) (match_dup 2))
1292
                 (const_int 0)))]
1293
  "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
1294
  "@
1295
   or %2,%0
1296
   or %2,%0
1297
   or %2,%1,%0"
1298
  [(set_attr "isa" "*,*,am33")
1299
   (set_attr "timings" "22,11,11")]
1300
)
1301
 
1302
;; ----------------------------------------------------------------------
1303
;; XOR INSTRUCTIONS
1304
;; ----------------------------------------------------------------------
1305
 
1306
(define_insn "xorsi3"
1307
  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
1308
        (xor:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1309
                (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1310
   (clobber (reg:CC CC_REG))]
1311
  ""
1312
  "@
1313
   xor %2,%0
1314
   xor %2,%0
1315
   xor %2,%1,%0"
1316
  [(set_attr "isa" "*,*,am33")
1317
   (set_attr "liw" "*,op1,*")
1318
   (set_attr "liw_op" "xor")
1319
   (set_attr "timings" "22,11,11")]
1320
)
1321
 
1322
(define_insn "*xorsi3_flags"
1323
  [(set (match_operand:SI         0 "register_operand"  "=D,D,r")
1324
        (xor:SI (match_operand:SI 1 "register_operand"  "%0,0,r")
1325
                (match_operand:SI 2 "nonmemory_operand" " i,D,r")))
1326
   (set (reg CC_REG)
1327
        (compare (xor:SI (match_dup 1) (match_dup 2))
1328
                 (const_int 0)))]
1329
  "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
1330
  "@
1331
   xor %2,%0
1332
   xor %2,%0
1333
   xor %2,%1,%0"
1334
  [(set_attr "isa" "*,*,am33")
1335
   (set_attr "timings" "22,11,11")]
1336
)
1337
 
1338
;; ----------------------------------------------------------------------
1339
;; NOT INSTRUCTIONS
1340
;; ----------------------------------------------------------------------
1341
 
1342
(define_insn "one_cmplsi2"
1343
  [(set (match_operand:SI         0 "register_operand" "=D")
1344
        (not:SI (match_operand:SI 1 "register_operand" " 0")))
1345
   (clobber (reg:CC CC_REG))]
1346
  ""
1347
  "not %0"
1348
)
1349
 
1350
(define_insn "*one_cmplsi2_flags"
1351
  [(set (match_operand:SI         0 "register_operand" "=D")
1352
        (not:SI (match_operand:SI 1 "register_operand" " 0")))
1353
   (set (reg CC_REG)
1354
        (compare (not:SI (match_dup 1))
1355
                 (const_int 0)))]
1356
  "reload_completed && mn10300_match_ccmode (insn, CCZNmode)"
1357
  "not %0"
1358
)
1359
 
1360
;; ----------------------------------------------------------------------
1361
;; COMPARE AND BRANCH INSTRUCTIONS
1362
;; ----------------------------------------------------------------------
1363
 
1364
;; We expand the comparison into a single insn so that it will not be split
1365
;; up by reload.
1366
(define_expand "cbranchsi4"
1367
  [(set (pc)
1368
        (if_then_else
1369
              (match_operator                    0 "ordered_comparison_operator"
1370
                              [(match_operand:SI 1 "register_operand")
1371
                               (match_operand:SI 2 "nonmemory_operand")])
1372
              (label_ref (match_operand 3 ""))
1373
              (pc)))]
1374
  ""
1375
  ""
1376
)
1377
 
1378
(define_insn_and_split "*cbranchsi4_cmp"
1379
  [(set (pc)
1380
        (if_then_else (match_operator           3 "ordered_comparison_operator"
1381
                       [(match_operand:SI       0 "register_operand"  "r")
1382
                        (match_operand:SI       1 "nonmemory_operand" "ri")])
1383
                      (match_operand            2 "label_ref_operand" "")
1384
                      (pc)))]
1385
  ""
1386
  "#"
1387
  "reload_completed"
1388
  [(const_int 0)]
1389
{
1390
  mn10300_split_cbranch (CCmode, operands[3], operands[2]);
1391
  DONE;
1392
})
1393
 
1394
(define_insn "cmpsi"
1395
  [(set (reg CC_REG)
1396
        (compare (match_operand:SI 0 "register_operand"  "r,r,r")
1397
                 (match_operand:SI 1 "nonmemory_operand" "r,O,i")))]
1398
  "reload_completed"
1399
{
1400
  /* The operands of CMP must be distinct registers.  In the case where
1401
     we've failed to optimize the comparison of a register to itself, we
1402
     must use another method to set the Z flag.  We can achieve this
1403
     effect with a BTST 0,D0.  This will not alter the contents of D0;
1404
     the use of d0 is arbitrary; any data register would work.  */
1405
  if (rtx_equal_p (operands[0], operands[1]))
1406
    return "btst 0,d0";
1407
  else
1408
    return "cmp %1,%0";
1409
}
1410
  [(set_attr_alternative "timings"
1411
     [(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))
1412
      (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))
1413
      (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))])
1414
   (set_attr "liw" "either,either,*")
1415
   (set_attr "liw_op" "cmp")]
1416
)
1417
 
1418
(define_insn "*integer_conditional_branch"
1419
  [(set (pc)
1420
        (if_then_else (match_operator 0 "comparison_operator"
1421
                        [(match_operand 2 "int_mode_flags" "")
1422
                         (const_int 0)])
1423
                      (label_ref (match_operand 1 "" ""))
1424
                      (pc)))]
1425
  "reload_completed"
1426
  "b%b0 %1"
1427
)
1428
 
1429
(define_insn_and_split "*cbranchsi4_btst"
1430
  [(set (pc)
1431
        (if_then_else
1432
          (match_operator 3 "CCZN_comparison_operator"
1433
            [(and:SI (match_operand:SI 0 "register_operand" "D")
1434
                     (match_operand:SI 1 "immediate_operand" "i"))
1435
             (const_int 0)])
1436
          (match_operand 2 "label_ref_operand" "")
1437
          (pc)))]
1438
  ""
1439
  "#"
1440
  "reload_completed"
1441
  [(const_int 0)]
1442
{
1443
  mn10300_split_cbranch (CCZNmode, operands[3], operands[2]);
1444
  DONE;
1445
})
1446
 
1447
(define_insn "*btstsi"
1448
  [(set (reg:CCZN CC_REG)
1449
        (compare:CCZN
1450
          (and:SI (match_operand:SI 0 "register_operand" "D")
1451
                  (match_operand:SI 1 "immediate_operand" "i"))
1452
          (const_int 0)))]
1453
  "reload_completed"
1454
  "btst %1,%0"
1455
)
1456
 
1457
(define_expand "cbranchsf4"
1458
  [(set (pc)
1459
      (if_then_else
1460
            (match_operator                    0 "ordered_comparison_operator"
1461
                            [(match_operand:SF 1 "register_operand")
1462
                             (match_operand:SF 2 "nonmemory_operand")])
1463
            (label_ref (match_operand 3 ""))
1464
            (pc)))]
1465
  "TARGET_AM33_2"
1466
  ""
1467
)
1468
 
1469
(define_insn_and_split "*cbranchsf4_cmp"
1470
  [(set (pc)
1471
        (if_then_else (match_operator            3 "ordered_comparison_operator"
1472
                        [(match_operand:SF       0 "register_operand"  "f")
1473
                         (match_operand:SF       1 "nonmemory_operand" "fF")])
1474
                      (match_operand             2 "label_ref_operand" "")
1475
                      (pc)))
1476
   ]
1477
  "TARGET_AM33_2"
1478
  "#"
1479
  "&& reload_completed"
1480
  [(const_int 0)]
1481
{
1482
  mn10300_split_cbranch (CC_FLOATmode, operands[3], operands[2]);
1483
  DONE;
1484
})
1485
 
1486
(define_insn "*am33_cmpsf"
1487
  [(set (reg:CC_FLOAT CC_REG)
1488
        (compare:CC_FLOAT (match_operand:SF 0 "register_operand"  "f")
1489
                          (match_operand:SF 1 "nonmemory_operand" "fF")))]
1490
  "TARGET_AM33_2 && reload_completed"
1491
  "fcmp %1, %0"
1492
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1493
                                       (const_int 17) (const_int 25)))]
1494
)
1495
 
1496
(define_insn "*float_conditional_branch"
1497
  [(set (pc)
1498
        (if_then_else (match_operator 0 "comparison_operator"
1499
                                      [(reg:CC_FLOAT CC_REG) (const_int 0)])
1500
                      (label_ref (match_operand 1 "" ""))
1501
                      (pc)))]
1502
  "TARGET_AM33_2 && reload_completed"
1503
  "fb%b0 %1"
1504
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1505
                                       (const_int 44) (const_int 33)))]
1506
)
1507
 
1508
;; Unconditional and other jump instructions.
1509
 
1510
(define_insn "jump"
1511
  [(set (pc)
1512
        (label_ref (match_operand 0 "" "")))]
1513
  ""
1514
  "jmp %l0"
1515
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1516
                                       (const_int 11) (const_int 44)))]
1517
)
1518
 
1519
(define_insn "indirect_jump"
1520
  [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
1521
  ""
1522
  "jmp (%0)"
1523
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1524
                                       (const_int 11) (const_int 33)))]
1525
)
1526
 
1527
(define_expand "builtin_setjmp_receiver"
1528
  [(match_operand 0 "" "")]
1529
  "flag_pic"
1530
{
1531
  emit_insn (gen_load_pic ());
1532
  DONE;
1533
})
1534
 
1535
(define_expand "casesi"
1536
  [(match_operand:SI 0 "register_operand")
1537
   (match_operand:SI 1 "immediate_operand")
1538
   (match_operand:SI 2 "immediate_operand")
1539
   (match_operand 3 "" "") (match_operand 4 "")]
1540
  ""
1541
{
1542
  rtx table = gen_reg_rtx (SImode);
1543
  rtx index = gen_reg_rtx (SImode);
1544
  rtx addr = gen_reg_rtx (Pmode);
1545
  rtx test;
1546
 
1547
  emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
1548
  emit_insn (gen_addsi3 (index, operands[0], GEN_INT (- INTVAL (operands[1]))));
1549
  test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]);
1550
  emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4]));
1551
 
1552
  emit_insn (gen_ashlsi3 (index, index, const2_rtx));
1553
  emit_move_insn (addr, gen_rtx_MEM (SImode,
1554
                                     gen_rtx_PLUS (SImode, table, index)));
1555
  if (flag_pic)
1556
    emit_insn (gen_addsi3 (addr, addr, table));
1557
 
1558
  emit_jump_insn (gen_tablejump (addr, operands[3]));
1559
  DONE;
1560
})
1561
 
1562
(define_insn "tablejump"
1563
  [(set (pc) (match_operand:SI 0 "register_operand" "a"))
1564
   (use (label_ref (match_operand 1 "" "")))]
1565
  ""
1566
  "jmp (%0)"
1567
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1568
                                       (const_int 11) (const_int 33)))]
1569
)
1570
 
1571
;; Call subroutine with no return value.
1572
 
1573
(define_expand "call"
1574
  [(call (match_operand:QI 0 "general_operand")
1575
         (match_operand:SI 1 "general_operand"))]
1576
  ""
1577
{
1578
  rtx fn = XEXP (operands[0], 0);
1579
 
1580
  if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
1581
    {
1582
      if (MN10300_GLOBAL_P (fn))
1583
        {
1584
          /* The PLT code won't run on AM30, but then, there's no
1585
             shared library support for AM30 either, so we just assume
1586
             the linker is going to adjust all @PLT relocs to the
1587
             actual symbols.  */
1588
          emit_use (pic_offset_table_rtx);
1589
          fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
1590
        }
1591
      else
1592
        fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
1593
    }
1594
  if (! call_address_operand (fn, VOIDmode))
1595
    fn = force_reg (SImode, fn);
1596
 
1597
  XEXP (operands[0], 0) = fn;
1598
})
1599
 
1600
(define_insn "*call_internal"
1601
  [(call (mem:QI (match_operand:SI 0 "call_address_operand" "a,S"))
1602
         (match_operand:SI 1 "" ""))]
1603
  ""
1604
  "@
1605
   calls %C0
1606
   call %C0,[],0"
1607
  [(set_attr_alternative "timings"
1608
                         [(if_then_else (eq_attr "cpu" "am34")
1609
                                        (const_int 33) (const_int 44))
1610
                          (if_then_else (eq_attr "cpu" "am34")
1611
                                        (const_int 55) (const_int 33))
1612
                         ])
1613
  ]
1614
)
1615
 
1616
;; Call subroutine, returning value in operand 0
1617
;; (which must be a hard register).
1618
 
1619
(define_expand "call_value"
1620
  [(set (match_operand 0 "")
1621
        (call (match_operand:QI 1 "general_operand")
1622
              (match_operand:SI 2 "general_operand")))]
1623
  ""
1624
{
1625
  rtx fn = XEXP (operands[1], 0);
1626
 
1627
  if (flag_pic && GET_CODE (fn) == SYMBOL_REF)
1628
    {
1629
      if (MN10300_GLOBAL_P (fn))
1630
        {
1631
          /* The PLT code won't run on AM30, but then, there's no
1632
             shared library support for AM30 either, so we just assume
1633
             the linker is going to adjust all @PLT relocs to the
1634
             actual symbols.  */
1635
          emit_use (pic_offset_table_rtx);
1636
          fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT);
1637
        }
1638
      else
1639
        fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC);
1640
    }
1641
  if (! call_address_operand (fn, VOIDmode))
1642
    fn = force_reg (SImode, fn);
1643
 
1644
  XEXP (operands[1], 0) = fn;
1645
})
1646
 
1647
(define_insn "call_value_internal"
1648
  [(set (match_operand 0 "" "")
1649
        (call (mem:QI (match_operand:SI 1 "call_address_operand" "a,S"))
1650
              (match_operand:SI 2 "" "")))]
1651
  ""
1652
  "@
1653
   calls %C1
1654
   call %C1,[],0"
1655
  [(set_attr_alternative "timings"
1656
                         [(if_then_else (eq_attr "cpu" "am34")
1657
                                        (const_int 33) (const_int 44))
1658
                          (if_then_else (eq_attr "cpu" "am34")
1659
                                        (const_int 55) (const_int 33))
1660
                         ])
1661
  ]
1662
)
1663
 
1664
(define_expand "untyped_call"
1665
  [(parallel [(call (match_operand 0 "")
1666
                    (const_int 0))
1667
              (match_operand 1 "")
1668
              (match_operand 2 "")])]
1669
  ""
1670
{
1671
  int i;
1672
 
1673
  emit_call_insn (gen_call (operands[0], const0_rtx));
1674
 
1675
  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1676
    {
1677
      rtx set = XVECEXP (operands[2], 0, i);
1678
      emit_move_insn (SET_DEST (set), SET_SRC (set));
1679
    }
1680
  DONE;
1681
})
1682
 
1683
(define_insn "nop"
1684
  [(const_int 0)]
1685
  ""
1686
  "nop"
1687
)
1688
 
1689
;; ----------------------------------------------------------------------
1690
;; EXTEND INSTRUCTIONS
1691
;; ----------------------------------------------------------------------
1692
 
1693
(define_insn "zero_extendqisi2"
1694
  [(set (match_operand:SI 0 "register_operand"      "=D,D,r")
1695
        (zero_extend:SI
1696
         (match_operand:QI 1 "nonimmediate_operand" " 0,m,r")))]
1697
  ""
1698
  "@
1699
   extbu %0
1700
   movbu %1,%0
1701
   extbu %1,%0"
1702
  [(set_attr "isa" "*,*,am33")
1703
   (set_attr_alternative "timings"
1704
                 [(const_int 11)
1705
                  (if_then_else (eq_attr "cpu" "am34")
1706
                                (const_int 13) (const_int 24))
1707
                  (const_int 11)
1708
                 ])]
1709
)
1710
 
1711
(define_insn "zero_extendhisi2"
1712
  [(set (match_operand:SI 0 "register_operand"      "=D,D,r")
1713
        (zero_extend:SI
1714
         (match_operand:HI 1 "nonimmediate_operand" " 0,m,r")))]
1715
  ""
1716
  "@
1717
   exthu %0
1718
   movhu %1,%0
1719
   exthu %1,%0"
1720
  [(set_attr "isa" "*,*,am33")
1721
   (set_attr_alternative "timings"
1722
                 [(const_int 11)
1723
                  (if_then_else (eq_attr "cpu" "am34")
1724
                                (const_int 13) (const_int 24))
1725
                  (const_int 11)])]
1726
)
1727
 
1728
(define_insn "extendqisi2"
1729
  [(set (match_operand:SI 0 "register_operand" "=D,r")
1730
        (sign_extend:SI
1731
         (match_operand:QI 1 "register_operand" "0,r")))]
1732
  ""
1733
  "@
1734
   extb %0
1735
   extb %1,%0"
1736
  [(set_attr "isa" "*,am33")]
1737
)
1738
 
1739
(define_insn "extendhisi2"
1740
  [(set (match_operand:SI 0 "register_operand" "=D,r")
1741
        (sign_extend:SI
1742
         (match_operand:HI 1 "register_operand" "0,r")))]
1743
  ""
1744
  "@
1745
   exth %0
1746
   exth %1,%0"
1747
  [(set_attr "isa" "*,am33")]
1748
)
1749
 
1750
;; ----------------------------------------------------------------------
1751
;; SHIFTS
1752
;; ----------------------------------------------------------------------
1753
 
1754
(define_insn "ashlsi3"
1755
  [(set (match_operand:SI  0 "register_operand"   "=r,D,d,d,D,D,D,r")
1756
        (ashift:SI
1757
          (match_operand:SI 1 "register_operand"  " 0,0,0,0,0,0,0,r")
1758
          (match_operand:QI 2 "nonmemory_operand" " J,K,M,L,D,O,i,r")))
1759
   (clobber (reg:CC CC_REG))]
1760
  ""
1761
  "@
1762
   add %0,%0
1763
   asl2 %0
1764
   asl2 %0\;add %0,%0
1765
   asl2 %0\;asl2 %0
1766
   asl %S2,%0
1767
   asl %S2,%0
1768
   asl %S2,%0
1769
   asl %2,%1,%0"
1770
  [(set_attr "isa" "*,*,*,*,*,*,*,am33")
1771
   (set_attr "liw" "op2,op2,op2,op2,op2,op2,*,*")
1772
   (set_attr "liw_op" "asl")
1773
   (set_attr "timings" "11,11,22,22,11,11,11,11")]
1774
)
1775
 
1776
(define_insn "lshrsi3"
1777
  [(set (match_operand:SI  0 "register_operand"  "=D,D,D,r")
1778
        (lshiftrt:SI
1779
          (match_operand:SI 1 "register_operand"  "0,0,0,r")
1780
          (match_operand:QI 2 "nonmemory_operand" "D,O,i,r")))
1781
   (clobber (reg:CC CC_REG))]
1782
  ""
1783
  "@
1784
   lsr %S2,%0
1785
   lsr %S2,%0
1786
   lsr %S2,%0
1787
   lsr %2,%1,%0"
1788
  [(set_attr "isa" "*,*,*,am33")
1789
   (set_attr "liw" "op2,op2,*,*")
1790
   (set_attr "liw_op" "lsr")]
1791
)
1792
 
1793
(define_insn "ashrsi3"
1794
  [(set (match_operand:SI  0 "register_operand"  "=D,D,D,r")
1795
        (ashiftrt:SI
1796
          (match_operand:SI 1 "register_operand"  "0,0,0,r")
1797
          (match_operand:QI 2 "nonmemory_operand" "D,O,i,r")))
1798
   (clobber (reg:CC CC_REG))]
1799
  ""
1800
  "@
1801
   asr %S2,%0
1802
   asr %S2,%0
1803
   asr %S2,%0
1804
   asr %2,%1,%0"
1805
  [(set_attr "isa" "*,*,*,am33")
1806
   (set_attr "liw" "op2,op2,*,*")
1807
   (set_attr "liw_op" "asr")]
1808
)
1809
 
1810
;; ----------------------------------------------------------------------
1811
;; MISCELANEOUS
1812
;; ----------------------------------------------------------------------
1813
 
1814
;; Note the use of the (const_int 0) when generating the insn that matches
1815
;; the bsch pattern.  This ensures that the destination register is
1816
;; initialised with 0 which will make the BSCH instruction set searching
1817
;; at bit 31.
1818
;;
1819
;; The XOR in the instruction sequence below is there because the BSCH
1820
;; instruction returns the bit number of the highest set bit and we want
1821
;; the number of zero bits above that bit.  The AM33 does not have a
1822
;; reverse subtraction instruction, but we can use a simple xor instead
1823
;; since we know that the top 27 bits are clear.
1824
(define_expand "clzsi2"
1825
  [(parallel [(set (match_operand:SI 0 "register_operand")
1826
                   (unspec:SI [(match_operand:SI 1 "register_operand")
1827
                               (const_int 0)] UNSPEC_BSCH))
1828
              (clobber (reg:CC CC_REG))])
1829
   (parallel [(set (match_dup 0)
1830
                   (xor:SI (match_dup 0)
1831
                           (const_int 31)))
1832
              (clobber (reg:CC CC_REG))])]
1833
  "TARGET_AM33"
1834
)
1835
 
1836
(define_insn "*bsch"
1837
  [(set (match_operand:SI 0 "register_operand" "=r")
1838
        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1839
                    (match_operand:SI 2 "nonmemory_operand" "0")]
1840
                   UNSPEC_BSCH))
1841
   (clobber (reg:CC CC_REG))]
1842
  "TARGET_AM33"
1843
  "bsch %1, %0"
1844
)
1845
 
1846
;; ----------------------------------------------------------------------
1847
;; FP INSTRUCTIONS
1848
;; ----------------------------------------------------------------------
1849
 
1850
(define_insn "abssf2"
1851
  [(set (match_operand:SF         0 "register_operand" "=f,f")
1852
        (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
1853
  "TARGET_AM33_2"
1854
  "@
1855
   fabs %0
1856
   fabs %1, %0"
1857
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1858
                                       (const_int 17) (const_int 14)))]
1859
)
1860
 
1861
(define_insn "negsf2"
1862
  [(set (match_operand:SF         0 "register_operand" "=f,f")
1863
        (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
1864
  "TARGET_AM33_2"
1865
  "@
1866
   fneg %0
1867
   fneg %1, %0"
1868
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1869
                                       (const_int 17) (const_int 14)))]
1870
)
1871
 
1872
(define_expand "sqrtsf2"
1873
  [(set (match_operand:SF 0 "register_operand" "")
1874
        (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
1875
  "TARGET_AM33_2 && flag_unsafe_math_optimizations"
1876
{
1877
  rtx scratch = gen_reg_rtx (SFmode);
1878
  emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
1879
  emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
1880
                         scratch));
1881
  DONE;
1882
})
1883
 
1884
(define_insn "rsqrtsf2"
1885
  [(set (match_operand:SF                  0 "register_operand" "=f,f")
1886
        (div:SF (match_operand:SF          2 "const_1f_operand" "F,F")
1887
                (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))
1888
   (clobber (reg:CC_FLOAT CC_REG))]
1889
  "TARGET_AM33_2"
1890
  "@
1891
   frsqrt %0
1892
   frsqrt %1, %0"
1893
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1894
                                       (const_int 4753) (const_int 2327)))]
1895
)
1896
 
1897
(define_insn "addsf3"
1898
  [(set (match_operand:SF          0 "register_operand" "=f,f")
1899
        (plus:SF (match_operand:SF 1 "register_operand" "%0,f")
1900
                 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
1901
   (clobber (reg:CC_FLOAT CC_REG))]
1902
  "TARGET_AM33_2"
1903
  "@
1904
   fadd %2, %0
1905
   fadd %2, %1, %0"
1906
  [(set_attr_alternative "timings"
1907
                         [(if_then_else (eq_attr "cpu" "am34")
1908
                                        (const_int 17) (const_int 14))
1909
                          (if_then_else (eq_attr "cpu" "am34")
1910
                                        (const_int 17) (const_int 25))
1911
                         ])]
1912
)
1913
 
1914
(define_insn "subsf3"
1915
  [(set (match_operand:SF           0 "register_operand" "=f,f")
1916
        (minus:SF (match_operand:SF 1 "register_operand" "0,f")
1917
                  (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
1918
   (clobber (reg:CC_FLOAT CC_REG))]
1919
  "TARGET_AM33_2"
1920
  "@
1921
   fsub %2, %0
1922
   fsub %2, %1, %0"
1923
  [(set_attr_alternative "timings"
1924
                         [(if_then_else (eq_attr "cpu" "am34")
1925
                                        (const_int 17) (const_int 14))
1926
                          (if_then_else (eq_attr "cpu" "am34")
1927
                                        (const_int 17) (const_int 25))
1928
                         ])]
1929
)
1930
 
1931
(define_insn "mulsf3"
1932
  [(set (match_operand:SF          0 "register_operand" "=f,f")
1933
        (mult:SF (match_operand:SF 1 "register_operand" "%0,f")
1934
                 (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
1935
  (clobber (reg:CC_FLOAT CC_REG))
1936
  ]
1937
  "TARGET_AM33_2"
1938
  "@
1939
   fmul %2, %0
1940
   fmul %2, %1, %0"
1941
  [(set_attr_alternative "timings"
1942
                         [(if_then_else (eq_attr "cpu" "am34")
1943
                                        (const_int 17) (const_int 14))
1944
                          (if_then_else (eq_attr "cpu" "am34")
1945
                                        (const_int 17) (const_int 25))
1946
                         ])]
1947
)
1948
 
1949
(define_insn "divsf3"
1950
  [(set (match_operand:SF         0 "register_operand" "=f,f")
1951
        (div:SF (match_operand:SF 1 "register_operand"  "0,f")
1952
                (match_operand:SF 2 "nonmemory_operand" "f,?fF")))
1953
   (clobber (reg:CC_FLOAT CC_REG))]
1954
  "TARGET_AM33_2"
1955
  "@
1956
   fdiv %2, %0
1957
   fdiv %2, %1, %0"
1958
  [(set_attr_alternative "timings"
1959
                         [(if_then_else (eq_attr "cpu" "am34")
1960
                                        (const_int 2531) (const_int 1216))
1961
                          (if_then_else (eq_attr "cpu" "am34")
1962
                                        (const_int 2531) (const_int 1317))
1963
                         ])]
1964
)
1965
 
1966
(define_insn "fmasf4"
1967
  [(set (match_operand:SF         0 "register_operand" "=c")
1968
        (fma:SF (match_operand:SF 1 "register_operand" "f")
1969
                (match_operand:SF 2 "register_operand" "f")
1970
                (match_operand:SF 3 "register_operand" "f")))
1971
   (clobber (reg:CC_FLOAT CC_REG))
1972
  ]
1973
  "TARGET_AM33_2"
1974
  "fmadd %1, %2, %3, %0"
1975
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1976
                                       (const_int 17) (const_int 24)))]
1977
)
1978
 
1979
(define_insn "fmssf4"
1980
  [(set (match_operand:SF                 0 "register_operand" "=c")
1981
        (fma:SF (match_operand:SF         1 "register_operand" "f")
1982
                (match_operand:SF         2 "register_operand" "f")
1983
                (neg:SF (match_operand:SF 3 "register_operand" "f"))))
1984
   (clobber (reg:CC_FLOAT CC_REG))
1985
  ]
1986
  "TARGET_AM33_2"
1987
  "fmsub %1, %2, %3, %0"
1988
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
1989
                                       (const_int 17) (const_int 24)))]
1990
)
1991
 
1992
(define_insn "fnmasf4"
1993
  [(set (match_operand:SF                 0 "register_operand" "=c")
1994
        (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
1995
                (match_operand:SF         2 "register_operand" "f")
1996
                (match_operand:SF         3 "register_operand" "f")))
1997
   (clobber (reg:CC_FLOAT CC_REG))
1998
  ]
1999
  "TARGET_AM33_2"
2000
  "fnmadd %1, %2, %3, %0"
2001
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2002
                                       (const_int 17) (const_int 24)))]
2003
)
2004
 
2005
(define_insn "fnmssf4"
2006
  [(set (match_operand:SF                 0 "register_operand" "=c")
2007
        (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
2008
                (match_operand:SF         2 "register_operand" "f")
2009
                (neg:SF (match_operand:SF 3 "register_operand" "f"))))
2010
   (clobber (reg:CC_FLOAT CC_REG))
2011
  ]
2012
  "TARGET_AM33_2"
2013
  "fnmsub %1, %2, %3, %0"
2014
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2015
                                       (const_int 17) (const_int 24)))]
2016
)
2017
 
2018
;; ----------------------------------------------------------------------
2019
;; PROLOGUE/EPILOGUE
2020
;; ----------------------------------------------------------------------
2021
(define_expand "prologue"
2022
  [(const_int 0)]
2023
  ""
2024
  { mn10300_expand_prologue (); DONE; }
2025
)
2026
 
2027
(define_expand "epilogue"
2028
  [(return)]
2029
  ""
2030
  { mn10300_expand_epilogue (); DONE; }
2031
)
2032
 
2033
(define_insn "return"
2034
  [(return)]
2035
  "mn10300_can_use_rets_insn ()"
2036
{
2037
  /* The RETF insn is 4 cycles faster than RETS, though 1 byte larger.  */
2038
  if (optimize_insn_for_speed_p () && mn10300_can_use_retf_insn ())
2039
    return "retf [],0";
2040
  else
2041
    return "rets";
2042
})
2043
 
2044
(define_insn "return_ret"
2045
  [(return)
2046
   (use (match_operand:SI 0 "const_int_operand" ""))]
2047
  ""
2048
{
2049
  /* The RETF insn is up to 3 cycles faster than RET.  */
2050
  fputs ((mn10300_can_use_retf_insn () ? "\tretf " : "\tret "), asm_out_file);
2051
  mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs ());
2052
  fprintf (asm_out_file, ",%d\n", (int) INTVAL (operands[0]));
2053
  return "";
2054
})
2055
 
2056
;; This instruction matches one generated by mn10300_gen_multiple_store()
2057
(define_insn "store_movm"
2058
  [(match_parallel 0 "mn10300_store_multiple_operation"
2059
    [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])]
2060
  ""
2061
{
2062
  fputs ("\tmovm ", asm_out_file);
2063
  mn10300_print_reg_list (asm_out_file,
2064
                          mn10300_store_multiple_operation (operands[0],
2065
                                                            VOIDmode));
2066
  fprintf (asm_out_file, ",(sp)\n");
2067
  return "";
2068
}
2069
  ;; Assume that no more than 8 registers will be pushed.
2070
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2071
                                       (const_int 99) (const_int 88)))]
2072
)
2073
 
2074
(define_expand "load_pic"
2075
  [(const_int 0)]
2076
  "flag_pic"
2077
{
2078
  if (TARGET_AM33)
2079
    emit_insn (gen_am33_load_pic (pic_offset_table_rtx));
2080
  else if (mn10300_frame_size () == 0)
2081
    emit_insn (gen_mn10300_load_pic0 (pic_offset_table_rtx));
2082
  else
2083
    emit_insn (gen_mn10300_load_pic1 (pic_offset_table_rtx));
2084
  DONE;
2085
})
2086
 
2087
(define_insn "am33_load_pic"
2088
  [(set (match_operand:SI 0 "register_operand" "=a")
2089
        (unspec:SI [(const_int 0)] UNSPEC_GOT))
2090
   (clobber (reg:CC CC_REG))]
2091
  "TARGET_AM33"
2092
{
2093
  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2094
  return ".LPIC%=:\;mov pc,%0\;add %1-(.LPIC%=-.),%0";
2095
}
2096
  [(set_attr "timings" "33")]
2097
)
2098
 
2099
;; Load pic register with push/pop of stack.
2100
(define_insn "mn10300_load_pic0"
2101
  [(set (match_operand:SI 0 "register_operand" "=a")
2102
        (unspec:SI [(const_int 0)] UNSPEC_GOT))
2103
   (clobber (reg:SI MDR_REG))
2104
   (clobber (reg:CC CC_REG))]
2105
  ""
2106
{
2107
  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2108
  return ("add -4,sp\;"
2109
          "calls .LPIC%=\n"
2110
          ".LPIC%=:\;"
2111
          "movm (sp),[%0]\;"
2112
          "add %1-(.LPIC%=-.),%0");
2113
}
2114
  [(set_attr "timings" "88")]
2115
)
2116
 
2117
;; Load pic register re-using existing stack space.
2118
(define_insn "mn10300_load_pic1"
2119
  [(set (match_operand:SI 0 "register_operand" "=a")
2120
        (unspec:SI [(const_int 0)] UNSPEC_GOT))
2121
   (clobber (mem:SI (reg:SI SP_REG)))
2122
   (clobber (reg:SI MDR_REG))
2123
   (clobber (reg:CC CC_REG))]
2124
  ""
2125
{
2126
  operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
2127
  return ("calls .LPIC%=\n"
2128
          ".LPIC%=:\;"
2129
          "mov (sp),%0\;"
2130
          "add %1-(.LPIC%=-.),%0");
2131
}
2132
  [(set_attr "timings" "66")]
2133
)
2134
 
2135
;; The mode on operand 3 has been deliberately omitted because it
2136
;; can be either SI (for arithmetic operations) or QI (for shifts).
2137
(define_insn "liw"
2138
  [(set (match_operand:SI             0 "register_operand" "=r")
2139
        (unspec:SI [(match_dup 0)
2140
                    (match_operand    2 "liw_operand"       "rO")
2141
                    (match_operand:SI 4 "const_int_operand" "")]
2142
                   UNSPEC_LIW))
2143
   (set (match_operand:SI             1 "register_operand" "=r")
2144
        (unspec:SI [(match_dup 1)
2145
                    (match_operand    3 "liw_operand"       "rO")
2146
                    (match_operand:SI 5 "const_int_operand" "")]
2147
                   UNSPEC_LIW))]
2148
  "TARGET_ALLOW_LIW"
2149
  "%W4_%W5 %2, %0, %3, %1"
2150
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2151
                                       (const_int 13) (const_int 12)))]
2152
)
2153
 
2154
;; The mode on operand 1 has been deliberately omitted because it
2155
;; can be either SI (for arithmetic operations) or QI (for shifts).
2156
(define_insn "cmp_liw"
2157
  [(set (reg:CC CC_REG)
2158
        (compare:CC (match_operand:SI 2 "register_operand" "r")
2159
                    (match_operand    3 "liw_operand"      "rO")))
2160
   (set (match_operand:SI             0 "register_operand" "=r")
2161
        (unspec:SI [(match_dup 0)
2162
                    (match_operand    1 "liw_operand"       "rO")
2163
                    (match_operand:SI 4 "const_int_operand" "")]
2164
                   UNSPEC_LIW))]
2165
  "TARGET_ALLOW_LIW"
2166
  "cmp_%W4 %3, %2, %1, %0"
2167
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2168
                                       (const_int 13) (const_int 12)))]
2169
)
2170
 
2171
(define_insn "liw_cmp"
2172
  [(set (match_operand:SI             0 "register_operand" "=r")
2173
        (unspec:SI [(match_dup 0)
2174
                    (match_operand    1 "liw_operand"      "rO")
2175
                    (match_operand:SI 4 "const_int_operand" "")]
2176
                   UNSPEC_LIW))
2177
   (set (reg:CC CC_REG)
2178
        (compare:CC (match_operand:SI 2 "register_operand" "r")
2179
                    (match_operand    3 "liw_operand"      "rO")))]
2180
  "TARGET_ALLOW_LIW"
2181
  "%W4_cmp %1, %0, %3, %2"
2182
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
2183
                                       (const_int 13) (const_int 12)))]
2184
)
2185
 
2186
;; Note - in theory the doloop patterns could be used here to express
2187
;; the SETLB and Lcc instructions.  In practice this does not work because
2188
;; the acceptable forms of the doloop patterns do not include UNSPECs
2189
;; and without them gcc's basic block reordering code can duplicate the
2190
;; doloop_end pattern, leading to bogus multiple decrements of the loop
2191
;; counter.
2192
 
2193
(define_insn "setlb"
2194
  [(unspec [(const_int 0)] UNSPEC_SETLB)]
2195
  "TARGET_AM33 && TARGET_ALLOW_SETLB"
2196
  "setlb"
2197
)
2198
 
2199
(define_insn "Lcc"
2200
  [(set (pc)
2201
        (if_then_else (match_operator 0 "comparison_operator"
2202
                      [(reg:CC CC_REG) (const_int 0)])
2203
                      (label_ref (match_operand 1 "" ""))
2204
                      (pc)))
2205
   (unspec [(const_int 1)] UNSPEC_SETLB)]
2206
  "TARGET_AM33 && TARGET_ALLOW_SETLB"
2207
  "L%b0 # loop back to: %1"
2208
)
2209
 
2210
(define_insn "FLcc"
2211
  [(set (pc)
2212
        (if_then_else (match_operator 0 "comparison_operator"
2213
                      [(reg:CC_FLOAT CC_REG) (const_int 0)])
2214
                      (label_ref (match_operand 1 "" ""))
2215
                      (pc)))
2216
   (unspec [(const_int 2)] UNSPEC_SETLB)]
2217
  "TARGET_AM33_2 && TARGET_ALLOW_SETLB"
2218
  "FL%b0 # loop back to: %1"
2219
  [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 44) (const_int 11)))]
2220
)

powered by: WebSVN 2.1.0

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