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

Subversion Repositories openrisc_me

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc1/] [gcc/] [config/] [rx/] [rx.md] - Blame information for rev 282

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

Line No. Rev Author Line
1 282 jeremybenn
;;  Machine Description for Renesas RX processors
2
;;  Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
3
;;  Contributed by Red Hat.
4
 
5
;; This file is part of GCC.
6
 
7
;; GCC is free software; you can redistribute it and/or modify
8
;; it under the terms of the GNU General Public License as published by
9
;; the Free Software Foundation; either version 3, or (at your option)
10
;; any later version.
11
 
12
;; GCC is distributed in the hope that it will be useful,
13
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
;; GNU General Public License for more details.
16
 
17
;; You should have received a copy of the GNU General Public License
18
;; along with GCC; see the file COPYING3.  If not see
19
;; .
20
 
21
 
22
;; This code iterator allows all branch instructions to
23
;; be generated from a single define_expand template.
24
(define_code_iterator most_cond [eq ne gt ge lt le gtu geu ltu leu
25
                                 unordered ordered ])
26
 
27
;; This code iterator is used for sign- and zero- extensions.
28
(define_mode_iterator small_int_modes [(HI "") (QI "")])
29
 
30
;; We do not handle DFmode here because it is either
31
;; the same as SFmode, or if -m64bit-doubles is active
32
;; then all operations on doubles have to be handled by
33
;; library functions.
34
(define_mode_iterator register_modes
35
  [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")])
36
 
37
 
38
;; Used to map RX condition names to GCC
39
;; condition names for builtin instructions.
40
(define_code_iterator gcc_conds [eq ne gt ge lt le gtu geu ltu leu
41
                                unge unlt uneq ltgt])
42
(define_code_attr rx_conds [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt")
43
                            (le "le") (gtu "gtu") (geu "geu") (ltu "ltu")
44
                            (leu "leu") (unge "pz") (unlt "n") (uneq "o")
45
                            (ltgt "no")])
46
 
47
(define_constants
48
  [
49
   (SP_REG 0)
50
   (CC_REG                 16)
51
 
52
   (UNSPEC_LOW_REG         0)
53
   (UNSPEC_HIGH_REG        1)
54
 
55
   (UNSPEC_RTE             10)
56
   (UNSPEC_RTFI            11)
57
   (UNSPEC_NAKED           12)
58
 
59
   (UNSPEC_MOVSTR          20)
60
   (UNSPEC_MOVMEM          21)
61
   (UNSPEC_SETMEM          22)
62
   (UNSPEC_STRLEN          23)
63
   (UNSPEC_CMPSTRN         24)
64
 
65
   (UNSPEC_BUILTIN_BRK     30)
66
   (UNSPEC_BUILTIN_CLRPSW  31)
67
   (UNSPEC_BUILTIN_INT     32)
68
   (UNSPEC_BUILTIN_MACHI   33)
69
   (UNSPEC_BUILTIN_MACLO   34)
70
   (UNSPEC_BUILTIN_MULHI   35)
71
   (UNSPEC_BUILTIN_MULLO   36)
72
   (UNSPEC_BUILTIN_MVFACHI 37)
73
   (UNSPEC_BUILTIN_MVFACMI 38)
74
   (UNSPEC_BUILTIN_MVFC    39)
75
   (UNSPEC_BUILTIN_MVFCP   40)
76
   (UNSPEC_BUILTIN_MVTACHI 41)
77
   (UNSPEC_BUILTIN_MVTACLO 42)
78
   (UNSPEC_BUILTIN_MVTC    43)
79
   (UNSPEC_BUILTIN_MVTIPL  44)
80
   (UNSPEC_BUILTIN_RACW    45)
81
   (UNSPEC_BUILTIN_REVW    46)
82
   (UNSPEC_BUILTIN_RMPA    47)
83
   (UNSPEC_BUILTIN_ROUND   48)
84
   (UNSPEC_BUILTIN_SAT     49)
85
   (UNSPEC_BUILTIN_SETPSW  50)
86
   (UNSPEC_BUILTIN_WAIT    51)
87
  ]
88
)
89
 
90
(define_attr "length" "" (const_int 8))
91
 
92
(include "predicates.md")
93
(include "constraints.md")
94
 
95
;; Pipeline description.
96
 
97
;; The RX only has a single pipeline.  It has five stages (fetch,
98
;; decode, execute, memory access, writeback) each of which normally
99
;; takes a single CPU clock cycle.
100
 
101
;; The timings attribute consists of two numbers, the first is the
102
;; throughput, which is the number of cycles the instruction takes
103
;; to execute and generate a result.  The second is the latency
104
;; which is the effective number of cycles the instruction takes to
105
;; execute if its result is used by the following instruction.  The
106
;; latency is always greater than or equal to the throughput.
107
;; These values were taken from tables 2.13 and 2.14 in section 2.8
108
;; of the RX610 Group Hardware Manual v0.11
109
 
110
;; Note - it would be nice to use strings rather than integers for
111
;; the possible values of this attribute, so that we can have the
112
;; gcc build mechanism check for values that are not supported by
113
;; the reservations below.  But this will not work because the code
114
;; in rx_adjust_sched_cost() needs integers not strings.
115
 
116
(define_attr "timings" "" (const_int 11))
117
 
118
(define_automaton "pipelining")
119
(define_cpu_unit "throughput" "pipelining")
120
 
121
(define_insn_reservation "throughput__1_latency__1"  1
122
  (eq_attr "timings" "11") "throughput")
123
(define_insn_reservation "throughput__1_latency__2"  2
124
  (eq_attr "timings" "12") "throughput,nothing")
125
(define_insn_reservation "throughput__2_latency__2"  1
126
  (eq_attr "timings" "22") "throughput*2")
127
(define_insn_reservation "throughput__3_latency__3"  1
128
  (eq_attr "timings" "33") "throughput*3")
129
(define_insn_reservation "throughput__3_latency__4"  2
130
  (eq_attr "timings" "34") "throughput*3,nothing")
131
(define_insn_reservation "throughput__4_latency__4"  1
132
  (eq_attr "timings" "44") "throughput*4")
133
(define_insn_reservation "throughput__4_latency__5"  2
134
  (eq_attr "timings" "45") "throughput*4,nothing")
135
(define_insn_reservation "throughput__5_latency__5"  1
136
  (eq_attr "timings" "55") "throughput*5")
137
(define_insn_reservation "throughput__5_latency__6"  2
138
  (eq_attr "timings" "56") "throughput*5,nothing")
139
(define_insn_reservation "throughput__6_latency__6"  1
140
  (eq_attr "timings" "66") "throughput*6")
141
(define_insn_reservation "throughput_10_latency_10"  1
142
  (eq_attr "timings" "1010") "throughput*10")
143
(define_insn_reservation "throughput_11_latency_11"  1
144
  (eq_attr "timings" "1111") "throughput*11")
145
(define_insn_reservation "throughput_16_latency_16"  1
146
  (eq_attr "timings" "1616") "throughput*16")
147
(define_insn_reservation "throughput_18_latency_18"  1
148
  (eq_attr "timings" "1818") "throughput*18")
149
 
150
;; Comparisons
151
 
152
;; Note - we do not specify the two instructions necessary to perform
153
;; a compare-and-branch in the cbranchsi4 pattern because that would
154
;; allow the comparison to be moved away from the jump before the reload
155
;; pass has completed.  That would be problematical because reload can
156
;; generate ADDSI3 instructions which would corrupt the PSW flags.
157
 
158
(define_expand "cbranchsi4"
159
  [(set (pc)
160
        (if_then_else (match_operator:SI 0 "comparison_operator"
161
                                         [(match_operand:SI 1 "register_operand")
162
                                          (match_operand:SI 2 "rx_source_operand")])
163
                      (label_ref (match_operand 3 ""))
164
                      (pc)))
165
   ]
166
  ""
167
  ""
168
)
169
 
170
(define_insn_and_split "*cbranchsi4_"
171
  [(set (pc)
172
        (if_then_else (most_cond:SI (match_operand:SI  0 "register_operand"  "r")
173
                                    (match_operand:SI  1 "rx_source_operand" "riQ"))
174
                      (label_ref (match_operand        2 "" ""))
175
                      (pc)))
176
   ]
177
  ""
178
  "#"
179
  "reload_completed"
180
  [(const_int 0)]
181
  "
182
  /* We contstruct the split by hand as otherwise the JUMP_LABEL
183
     attribute is not set correctly on the jump insn.  */
184
  emit_insn (gen_cmpsi (operands[0], operands[1]));
185
 
186
  emit_jump_insn (gen_conditional_branch (operands[2],
187
                 gen_rtx_fmt_ee (, CCmode,
188
                                 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
189
  "
190
)
191
 
192
(define_expand "cbranchsf4"
193
  [(set (pc)
194
        (if_then_else (match_operator:SF 0 "comparison_operator"
195
                                         [(match_operand:SF 1 "register_operand")
196
                                          (match_operand:SF 2 "rx_source_operand")])
197
                      (label_ref (match_operand 3 ""))
198
                      (pc)))
199
   ]
200
  "ALLOW_RX_FPU_INSNS"
201
  ""
202
)
203
 
204
(define_insn_and_split "*cbranchsf4_"
205
  [(set (pc)
206
        (if_then_else (most_cond:SF (match_operand:SF  0 "register_operand"  "r")
207
                                    (match_operand:SF  1 "rx_source_operand" "rFiQ"))
208
                      (label_ref (match_operand        2 "" ""))
209
                      (pc)))
210
   ]
211
  "ALLOW_RX_FPU_INSNS"
212
  "#"
213
  "&& reload_completed"
214
  [(const_int 0)]
215
  "
216
  /* We contstruct the split by hand as otherwise the JUMP_LABEL
217
     attribute is not set correctly on the jump insn.  */
218
  emit_insn (gen_cmpsf (operands[0], operands[1]));
219
 
220
  emit_jump_insn (gen_conditional_branch (operands[2],
221
                 gen_rtx_fmt_ee (, CCmode,
222
                                 gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
223
  "
224
)
225
 
226
(define_insn "tstsi"
227
  [(set (reg:CC_ZS CC_REG)
228
        (compare:CC_ZS (and:SI (match_operand:SI 0 "register_operand"  "r,r,r")
229
                               (match_operand:SI 1 "rx_source_operand" "r,i,Q"))
230
                       (const_int 0)))]
231
  ""
232
  {
233
    rx_float_compare_mode = false;
234
    return "tst\t%Q1, %0";
235
  }
236
  [(set_attr "timings" "11,11,33")
237
   (set_attr "length"   "3,7,6")]
238
)
239
 
240
(define_insn "cmpsi"
241
  [(set (reg:CC CC_REG)
242
        (compare:CC (match_operand:SI 0 "register_operand"  "r,r,r,r,r,r,r")
243
                    (match_operand:SI 1 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")))]
244
  ""
245
  {
246
    rx_float_compare_mode = false;
247
    if (rx_compare_redundant (insn))
248
      return "; Compare Eliminated: cmp %Q1, %0";
249
    return "cmp\t%Q1, %0";
250
  }
251
  [(set_attr "timings" "11,11,11,11,11,11,33")
252
   (set_attr "length"  "2,2,3,4,5,6,5")]
253
)
254
 
255
;; This pattern is disabled when -fnon-call-exceptions is active because
256
;; it could generate a floating point exception, which would introduce an
257
;; edge into the flow graph between this insn and the conditional branch
258
;; insn to follow, thus breaking the cc0 relationship.  Run the g++ test
259
;; g++.dg/eh/080514-1.C to see this happen.
260
(define_insn "cmpsf"
261
  [(set (reg:CC_ZSO CC_REG)
262
        (compare:CC_ZSO (match_operand:SF 0 "register_operand"  "r,r,r")
263
                        (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
264
  "ALLOW_RX_FPU_INSNS"
265
  {
266
    rx_float_compare_mode = true;
267
    return "fcmp\t%1, %0";
268
  }
269
  [(set_attr "timings" "11,11,33")
270
   (set_attr "length" "3,7,5")]
271
)
272
 
273
;; Flow Control Instructions:
274
 
275
(define_expand "b"
276
  [(set (pc)
277
        (if_then_else (most_cond (reg:CC CC_REG) (const_int 0))
278
                      (label_ref (match_operand 0))
279
                      (pc)))]
280
  ""
281
  ""
282
)
283
 
284
(define_insn "conditional_branch"
285
  [(set (pc)
286
        (if_then_else (match_operator           1 "comparison_operator"
287
                                                [(reg:CC CC_REG) (const_int 0)])
288
                      (label_ref (match_operand 0 "" ""))
289
                      (pc)))]
290
  ""
291
  {
292
    return rx_gen_cond_branch_template (operands[1], false);
293
  }
294
  [(set_attr "length" "8")    ;; This length is wrong, but it is
295
                              ;; too hard to compute statically.
296
   (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
297
)
298
 
299
(define_insn "*reveresed_conditional_branch"
300
  [(set (pc)
301
        (if_then_else (match_operator 1 "comparison_operator"
302
                                      [(reg:CC CC_REG) (const_int 0)])
303
                      (pc)
304
                      (label_ref (match_operand 0 "" ""))))]
305
  ""
306
  {
307
    return rx_gen_cond_branch_template (operands[1], true);
308
  }
309
  [(set_attr "length" "8")    ;; This length is wrong, but it is
310
                              ;; too hard to compute statically.
311
   (set_attr "timings" "33")] ;; The timing assumes that the branch is taken.
312
)
313
 
314
(define_insn "jump"
315
  [(set (pc)
316
        (label_ref (match_operand 0 "" "")))]
317
  ""
318
  "bra\t%0"
319
  [(set_attr "length" "4")
320
   (set_attr "timings" "33")]
321
)
322
 
323
(define_insn "indirect_jump"
324
  [(set (pc)
325
        (match_operand:SI 0 "register_operand" "r"))]
326
  ""
327
  "jmp\t%0"
328
  [(set_attr "length" "2")
329
   (set_attr "timings" "33")]
330
)
331
 
332
(define_insn "tablejump"
333
  [(set (pc)
334
        (match_operand:SI          0 "register_operand" "r"))
335
   (use (label_ref (match_operand  1 "" "")))]
336
  ""
337
  { return flag_pic ? (TARGET_AS100_SYNTAX ? "\n?:\tbra\t%0"
338
                                           : "\n1:\tbra\t%0")
339
                                           : "jmp\t%0";
340
  }
341
  [(set_attr "timings" "33")
342
   (set_attr "length" "2")]
343
)
344
 
345
(define_insn "simple_return"
346
  [(return)]
347
  ""
348
  "rts"
349
  [(set_attr "length" "1")
350
   (set_attr "timings" "55")]
351
)
352
 
353
(define_insn "deallocate_and_return"
354
  [(set (reg:SI SP_REG)
355
        (plus:SI (reg:SI SP_REG)
356
                 (match_operand:SI 0 "immediate_operand" "i")))
357
   (return)]
358
  ""
359
  "rtsd\t%0"
360
  [(set_attr "length" "2")
361
   (set_attr "timings" "55")]
362
)
363
 
364
(define_insn "pop_and_return"
365
  [(match_parallel 1 "rx_rtsd_vector"
366
                   [(set:SI (reg:SI SP_REG)
367
                            (plus:SI (reg:SI SP_REG)
368
                                     (match_operand:SI 0 "const_int_operand" "n")))])]
369
  "reload_completed"
370
  {
371
    rx_emit_stack_popm (operands, false);
372
    return "";
373
  }
374
  [(set_attr "length" "3")
375
   (set_attr "timings" "56")]
376
)
377
 
378
(define_insn "fast_interrupt_return"
379
  [(unspec_volatile [(return)] UNSPEC_RTFI) ]
380
  ""
381
  "rtfi"
382
  [(set_attr "length" "2")
383
   (set_attr "timings" "33")]
384
)
385
 
386
(define_insn "exception_return"
387
  [(unspec_volatile [(return)] UNSPEC_RTE) ]
388
  ""
389
  "rte"
390
  [(set_attr "length" "2")
391
   (set_attr "timings" "66")]
392
)
393
 
394
(define_insn "naked_return"
395
  [(unspec_volatile [(return)] UNSPEC_NAKED) ]
396
  ""
397
  "; Naked function: epilogue provided by programmer."
398
)
399
 
400
 
401
;; Note - the following set of patterns do not use the "memory_operand"
402
;; predicate or an "m" constraint because we do not allow symbol_refs
403
;; or label_refs as legitmate memory addresses.  This matches the
404
;; behaviour of most of the RX instructions.  Only the call/branch
405
;; instructions are allowed to refer to symbols/labels directly.
406
;; The call operands are in QImode because that is the value of
407
;; FUNCTION_MODE
408
 
409
(define_expand "call"
410
  [(call (match_operand:QI 0 "general_operand")
411
         (match_operand:SI 1 "general_operand"))]
412
  ""
413
  {
414
    rtx dest = XEXP (operands[0], 0);
415
 
416
    if (! rx_call_operand (dest, Pmode))
417
      dest = force_reg (Pmode, dest);
418
    emit_call_insn (gen_call_internal (dest, operands[1]));
419
    DONE;
420
  }
421
)
422
 
423
(define_insn "call_internal"
424
  [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol"))
425
         (match_operand:SI         1 "general_operand" "g,g"))
426
   (clobber (reg:CC CC_REG))]
427
  ""
428
  "@
429
  jsr\t%0
430
  bsr\t%A0"
431
  [(set_attr "length" "2,4")
432
   (set_attr "timings" "33")]
433
)
434
 
435
(define_expand "call_value"
436
  [(set (match_operand          0 "register_operand")
437
        (call (match_operand:QI 1 "general_operand")
438
              (match_operand:SI 2 "general_operand")))]
439
  ""
440
  {
441
    rtx dest = XEXP (operands[1], 0);
442
 
443
    if (! rx_call_operand (dest, Pmode))
444
      dest = force_reg (Pmode, dest);
445
    emit_call_insn (gen_call_value_internal (operands[0], dest, operands[2]));
446
    DONE;
447
  }
448
)
449
 
450
(define_insn "call_value_internal"
451
  [(set (match_operand                  0 "register_operand" "=r,r")
452
        (call (mem:QI (match_operand:SI 1 "rx_call_operand"   "r,Symbol"))
453
              (match_operand:SI         2 "general_operand"   "g,g")))
454
   (clobber (reg:CC CC_REG))]
455
  ""
456
  "@
457
  jsr\t%1
458
  bsr\t%A1"
459
  [(set_attr "length" "2,4")
460
   (set_attr "timings" "33")]
461
)
462
 
463
;; Note - we do not allow indirect sibcalls (with the address
464
;; held in a register) because we cannot guarantee that the register
465
;; chosen will be a call-used one.  If it is a call-saved register,
466
;; then the epilogue code will corrupt it by popping the saved value
467
;; off of the stack.
468
(define_expand "sibcall"
469
  [(parallel
470
    [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
471
           (match_operand:SI         1 "general_operand"))
472
     (return)])]
473
  ""
474
  {
475
    if (MEM_P (operands[0]))
476
      operands[0] = XEXP (operands[0], 0);
477
  }
478
)
479
 
480
(define_insn "sibcall_internal"
481
  [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
482
         (match_operand:SI         1 "general_operand"          "g"))
483
   (return)]
484
  ""
485
  "bra\t%A0"
486
  [(set_attr "length"  "4")
487
   (set_attr "timings" "33")]
488
)
489
 
490
(define_expand "sibcall_value"
491
 [(parallel
492
   [(set (match_operand                  0 "register_operand")
493
         (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
494
               (match_operand:SI         2 "general_operand")))
495
    (return)])]
496
  ""
497
  {
498
    if (MEM_P (operands[1]))
499
      operands[1] = XEXP (operands[1], 0);
500
  }
501
)
502
 
503
(define_insn "sibcall_value_internal"
504
 [(set (match_operand                  0 "register_operand"         "=r")
505
       (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
506
             (match_operand:SI         2 "general_operand"          "g")))
507
  (return)]
508
  ""
509
  "bra\t%A1"
510
  [(set_attr "length"  "4")
511
   (set_attr "timings" "33")]
512
)
513
 
514
;; Function Prologue/Epilogue Instructions
515
 
516
(define_expand "prologue"
517
  [(const_int 0)]
518
  ""
519
  "rx_expand_prologue (); DONE;"
520
)
521
 
522
(define_expand "epilogue"
523
  [(return)]
524
  ""
525
  "rx_expand_epilogue (false); DONE;"
526
)
527
 
528
(define_expand "sibcall_epilogue"
529
  [(return)]
530
  ""
531
  "rx_expand_epilogue (true); DONE;"
532
)
533
 
534
;; Move Instructions
535
 
536
;; Note - we do not allow memory to memory moves, even though the ISA
537
;; supports them.  The reason is that the conditions on such moves are
538
;; too restrictive, specifically the source addressing mode is limited
539
;; by the destination addressing mode and vice versa.  (For example it
540
;; is not possible to use indexed register indirect addressing for one
541
;; of the operands if the other operand is anything other than a register,
542
;; but it is possible to use register relative addressing when the other
543
;; operand also uses register relative or register indirect addressing).
544
;;
545
;; GCC does not support computing legitimate addresses based on the
546
;; nature of other operands involved in the instruction, and reload is
547
;; not smart enough to cope with a whole variety of different memory
548
;; addressing constraints, so it is simpler and safer to just refuse
549
;; to support memory to memory moves.
550
 
551
(define_expand "mov"
552
  [(set (match_operand:register_modes 0 "general_operand")
553
        (match_operand:register_modes 1 "general_operand"))]
554
  ""
555
  {
556
    if (MEM_P (operand0) && MEM_P (operand1))
557
      operands[1] = copy_to_mode_reg (mode, operand1);
558
  }
559
)
560
 
561
(define_insn "*mov_internal"
562
  [(set (match_operand:register_modes
563
 
564
        (match_operand:register_modes
565
         1 "general_operand" "Int08,Sint16,Sint24,i,r,m,r,Int08,Sint16,Sint24,i"))]
566
  ""
567
  { return rx_gen_move_template (operands, false); }
568
  [(set_attr "length" "3,4,5,6,2,4,6,5,6,7,8")
569
   (set_attr "timings" "11,11,11,11,11,12,11,11,11,11,11")]
570
)
571
 
572
(define_insn "extendsi2"
573
  [(set (match_operand:SI 0 "register_operand"    "=r,r")
574
        (sign_extend:SI (match_operand:small_int_modes
575
                          1 "nonimmediate_operand" "r,m")))]
576
  ""
577
  { return rx_gen_move_template (operands, false); }
578
  [(set_attr "length" "2,6")
579
   (set_attr "timings" "11,12")]
580
)
581
 
582
(define_insn "zero_extendsi2"
583
  [(set (match_operand:SI 0 "register_operand"     "=r,r")
584
        (zero_extend:SI (match_operand:small_int_modes
585
                          1 "nonimmediate_operand"  "r,m")))]
586
  ""
587
  { return rx_gen_move_template (operands, true); }
588
  [(set_attr "length" "2,4")
589
   (set_attr "timings" "11,12")]
590
)
591
 
592
(define_insn "stack_push"
593
  [(set:SI (reg:SI SP_REG)
594
           (minus:SI (reg:SI SP_REG)
595
                     (const_int 4)))
596
   (set:SI (mem:SI (reg:SI SP_REG))
597
           (match_operand:SI 0 "register_operand" "r"))]
598
  ""
599
  "push.l\t%0"
600
  [(set_attr "length" "2")]
601
)
602
 
603
(define_insn "stack_pushm"
604
  [(match_parallel 1 "rx_store_multiple_vector"
605
                   [(set:SI (reg:SI SP_REG)
606
                            (minus:SI (reg:SI SP_REG)
607
                                      (match_operand:SI 0 "const_int_operand" "n")))])]
608
  "reload_completed"
609
  {
610
    rx_emit_stack_pushm (operands);
611
    return "";
612
  }
613
  [(set_attr "length" "2")
614
   (set_attr "timings" "44")] ;; The timing is a guesstimate average timing.
615
)
616
 
617
(define_insn "stack_pop"
618
  [(set:SI (match_operand:SI 0 "register_operand" "=r")
619
           (mem:SI (reg:SI SP_REG)))
620
   (set:SI (reg:SI SP_REG)
621
           (plus:SI (reg:SI SP_REG)
622
                    (const_int 4)))]
623
  ""
624
  "pop\t%0"
625
  [(set_attr "length" "2")
626
   (set_attr "timings" "12")]
627
)
628
 
629
(define_insn "stack_popm"
630
  [(match_parallel 1 "rx_load_multiple_vector"
631
                   [(set:SI (reg:SI SP_REG)
632
                            (plus:SI (reg:SI SP_REG)
633
                                     (match_operand:SI 0 "const_int_operand" "n")))])]
634
  "reload_completed"
635
  {
636
    rx_emit_stack_popm (operands, true);
637
    return "";
638
  }
639
  [(set_attr "length" "2")
640
   (set_attr "timings" "45")] ;; The timing is a guesstimate average timing.
641
)
642
 
643
;; FIXME: Add memory destination options ?
644
(define_insn "cstoresi4"
645
  [(set (match_operand:SI   0 "register_operand" "=r,r,r,r,r,r,r")
646
        (match_operator:SI  1 "comparison_operator"
647
         [(match_operand:SI 2 "register_operand"  "r,r,r,r,r,r,r")
648
          (match_operand:SI 3 "rx_source_operand" "r,Uint04,Int08,Sint16,Sint24,i,Q")]))
649
   (clobber (reg:CC CC_REG))] ;; Because the cc flags are set based on comparing ops 2 & 3 not the value in op 0.
650
  ""
651
  {
652
    rx_float_compare_mode = false;
653
    return "cmp\t%Q3, %Q2\n\tsc%B1.L\t%0";
654
  }
655
  [(set_attr "timings" "22,22,22,22,22,22,44")
656
   (set_attr "length"  "5,5,6,7,8,9,8")]
657
)
658
 
659
(define_expand "movsicc"
660
  [(parallel
661
    [(set (match_operand:SI                  0 "register_operand")
662
          (if_then_else:SI (match_operand:SI 1 "comparison_operator")
663
                           (match_operand:SI 2 "nonmemory_operand")
664
                           (match_operand:SI 3 "immediate_operand")))
665
     (clobber (reg:CC CC_REG))])] ;; See cstoresi4
666
  ""
667
  {
668
    if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
669
      FAIL;
670
    if (! CONST_INT_P (operands[3]))
671
      FAIL;
672
  }
673
)
674
 
675
(define_insn "*movsieq"
676
  [(set (match_operand:SI                      0 "register_operand" "=r,r,r")
677
        (if_then_else:SI (eq (match_operand:SI 3 "register_operand"  "r,r,r")
678
                             (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
679
                         (match_operand:SI     1 "nonmemory_operand" "0,i,r")
680
                         (match_operand:SI     2 "immediate_operand" "i,i,i")))
681
   (clobber (reg:CC CC_REG))] ;; See cstoresi4
682
  ""
683
  "@
684
  cmp\t%Q4, %Q3\n\tstnz\t%2, %0
685
  cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstz\t%1, %0
686
  cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstnz\t%2, %0"
687
  [(set_attr "length"  "13,19,15")
688
   (set_attr "timings" "22,33,33")]
689
)
690
 
691
(define_insn "*movsine"
692
  [(set (match_operand:SI                      0 "register_operand" "=r,r,r")
693
        (if_then_else:SI (ne (match_operand:SI 3 "register_operand"  "r,r,r")
694
                             (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ"))
695
                         (match_operand:SI     1 "nonmemory_operand" "0,i,r")
696
                         (match_operand:SI     2 "immediate_operand" "i,i,i")))
697
   (clobber (reg:CC CC_REG))] ;; See cstoresi4
698
  ""
699
  "@
700
  cmp\t%Q4, %Q3\n\tstz\t%2, %0
701
  cmp\t%Q4, %Q3\n\tmov.l\t%2, %0\n\tstnz\t%1, %0
702
  cmp\t%Q4, %Q3\n\tmov.l\t%1, %0\n\tstz\t%2, %0"
703
  [(set_attr "length"  "13,19,15")
704
   (set_attr "timings" "22,33,33")]
705
)
706
 
707
;; Arithmetic Instructions
708
 
709
(define_insn "abssi2"
710
  [(set (match_operand:SI         0 "register_operand" "=r,r")
711
        (abs:SI (match_operand:SI 1 "register_operand"  "0,r")))
712
   (set (reg:CC_ZSO CC_REG)
713
        (compare:CC_ZSO (abs:SI (match_dup 1))
714
                        (const_int 0)))]
715
  ""
716
  "@
717
  abs\t%0
718
  abs\t%1, %0"
719
  [(set_attr "length" "2,3")]
720
)
721
 
722
(define_insn "addsi3"
723
  [(set (match_operand:SI          0 "register_operand"  "=r,r,r,r,r,r,r,r,r,r,r,r,r,r")
724
        (plus:SI (match_operand:SI 1 "register_operand"  "%0,0,0,0,0,0,0,r,r,r,r,r,r,0")
725
                 (match_operand:SI 2 "rx_source_operand" "r,Uint04,NEGint4,Sint08,Sint16,Sint24,i,0,r,Sint08,Sint16,Sint24,i,Q")))
726
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
727
        (compare:CC_ZSC (plus:SI (match_dup 1) (match_dup 2))
728
                        (const_int 0)))]
729
  ""
730
  "@
731
  add\t%2, %0
732
  add\t%2, %0
733
  sub\t%N2, %0
734
  add\t%2, %0
735
  add\t%2, %0
736
  add\t%2, %0
737
  add\t%2, %0
738
  add\t%1, %0
739
  add\t%2, %1, %0
740
  add\t%2, %1, %0
741
  add\t%2, %1, %0
742
  add\t%2, %1, %0
743
  add\t%2, %1, %0
744
  add\t%Q2, %0"
745
  [(set_attr "timings" "11,11,11,11,11,11,11,11,11,11,11,11,11,33")
746
   (set_attr "length"   "2,2,2,3,4,5,6,2,3,3,4,5,6,5")]
747
)
748
 
749
(define_insn "adddi3"
750
  [(set (match_operand:DI          0 "register_operand" "=r,r,r,r,r,r")
751
        (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0,0,0,0")
752
                 (match_operand:DI 2 "rx_source_operand"
753
                                   "r,Sint08,Sint16,Sint24,i,Q")))
754
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
755
        (compare:CC_ZSC (plus:DI (match_dup 1) (match_dup 2))
756
                        (const_int 0)))]
757
  ""
758
  "add\t%L2, %L0\n\tadc\t%H2, %H0"
759
  [(set_attr "timings" "22,22,22,22,22,44")
760
   (set_attr "length" "5,7,9,11,13,11")]
761
)
762
 
763
(define_insn "andsi3"
764
  [(set (match_operand:SI         0 "register_operand"  "=r,r,r,r,r,r,r,r,r")
765
        (and:SI (match_operand:SI 1 "register_operand"  "%0,0,0,0,0,0,r,r,0")
766
                (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
767
   (set (reg:CC_ZS CC_REG)
768
        (compare:CC_ZS (and:SI (match_dup 1) (match_dup 2))
769
                       (const_int 0)))]
770
  ""
771
  "@
772
  and\t%2, %0
773
  and\t%2, %0
774
  and\t%2, %0
775
  and\t%2, %0
776
  and\t%2, %0
777
  and\t%2, %0
778
  and\t%1, %0
779
  and\t%2, %1, %0
780
  and\t%Q2, %0"
781
  [(set_attr "timings" "11,11,11,11,11,11,11,33,33")
782
   (set_attr "length" "2,2,3,4,5,6,2,5,5")]
783
)
784
 
785
;; Byte swap (single 32-bit value).
786
(define_insn "bswapsi2"
787
  [(set (match_operand:SI           0 "register_operand" "+r")
788
        (bswap:SI (match_operand:SI 1 "register_operand"  "r")))]
789
  ""
790
  "revl\t%1, %0"
791
  [(set_attr "length" "3")]
792
)
793
 
794
;; Byte swap (single 16-bit value).  Note - we ignore the swapping of the high 16-bits.
795
(define_insn "bswaphi2"
796
  [(set (match_operand:HI           0 "register_operand" "+r")
797
        (bswap:HI (match_operand:HI 1 "register_operand"  "r")))]
798
  ""
799
  "revw\t%1, %0"
800
  [(set_attr "length" "3")]
801
)
802
 
803
(define_insn "divsi3"
804
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r")
805
        (div:SI (match_operand:SI 1 "register_operand"  "0,0,0,0,0,0")
806
                (match_operand:SI 2 "rx_source_operand" "r,Sint08,Sint16,Sint24,i,Q")))
807
   (clobber (reg:CC CC_REG))]
808
  ""
809
  "div\t%Q2, %0"
810
  [(set_attr "timings" "1111") ;; Strictly speaking the timing should be
811
                               ;; 2222, but that is a worst case sceanario.
812
   (set_attr "length" "3,4,5,6,7,6")]
813
)
814
 
815
(define_insn "udivsi3"
816
  [(set (match_operand:SI          0 "register_operand"  "=r,r,r,r,r,r")
817
        (udiv:SI (match_operand:SI 1 "register_operand"   "0,0,0,0,0,0")
818
                 (match_operand:SI 2 "rx_source_operand"  "r,Sint08,Sint16,Sint24,i,Q")))
819
   (clobber (reg:CC CC_REG))]
820
  ""
821
  "divu\t%Q2, %0"
822
  [(set_attr "timings" "1010") ;; Strictly speaking the timing should be
823
                               ;; 2020, but that is a worst case sceanario.
824
   (set_attr "length" "3,4,5,6,7,6")]
825
)
826
 
827
;; Note - these patterns are suppressed in big-endian mode because they
828
;; generate a little endian result.  ie the most significant word of the
829
;; result is placed in the higher numbered register of the destination
830
;; register pair.
831
 
832
(define_insn "mulsidi3"
833
  [(set (match_operand:DI          0 "register_operand"  "=r,r,r,r,r,r")
834
        (mult:DI (sign_extend:DI (match_operand:SI
835
                                  1 "register_operand"  "%0,0,0,0,0,0"))
836
                 (sign_extend:DI (match_operand:SI
837
                                  2 "rx_source_operand"
838
                                  "r,Sint08,Sint16,Sint24,i,Q"))))]
839
  "! TARGET_BIG_ENDIAN_DATA"
840
  "emul\t%Q2, %0"
841
  [(set_attr "length" "3,4,5,6,7,6")
842
   (set_attr "timings" "22,22,22,22,22,44")]
843
)
844
 
845
;; See comment for mulsidi3.
846
;; Note - the zero_extends are to distinguish this pattern from the
847
;; mulsidi3 pattern.  Immediate mode addressing is not supported
848
;; because gcc cannot handle the expression: (zero_extend (const_int)).
849
(define_insn "umulsidi3"
850
  [(set (match_operand:DI                          0 "register_operand"  "=r,r")
851
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "%0,0"))
852
                 (zero_extend:DI (match_operand:SI 2 "rx_compare_operand" "r,Q"))))]
853
  "! TARGET_BIG_ENDIAN_DATA"
854
  "emulu\t%Q2, %0"
855
  [(set_attr "length" "3,6")
856
   (set_attr "timings" "22,44")]
857
)
858
 
859
(define_insn "smaxsi3"
860
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
861
        (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
862
                 (match_operand:SI 2 "rx_source_operand"
863
                                   "r,Sint08,Sint16,Sint24,i,Q")))]
864
  ""
865
  "max\t%Q2, %0"
866
  [(set_attr "length" "3,4,5,6,7,6")
867
   (set_attr "timings" "11,11,11,11,11,33")]
868
)
869
 
870
(define_insn "sminsi3"
871
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
872
        (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
873
                 (match_operand:SI 2 "rx_source_operand"
874
                                   "r,Sint08,Sint16,Sint24,i,Q")))]
875
  ""
876
  "min\t%Q2, %0"
877
  [(set_attr "length"  "3,4,5,6,7,6")
878
   (set_attr "timings" "11,11,11,11,11,33")]
879
)
880
 
881
(define_insn "mulsi3"
882
  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r,r,r,r")
883
        (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r")
884
                 (match_operand:SI 2 "rx_source_operand"
885
                                   "r,Uint04,Sint08,Sint16,Sint24,i,Q,0,r")))]
886
  ""
887
  "@
888
  mul\t%2, %0
889
  mul\t%2, %0
890
  mul\t%2, %0
891
  mul\t%2, %0
892
  mul\t%2, %0
893
  mul\t%Q2, %0
894
  mul\t%Q2, %0
895
  mul\t%1, %0
896
  mul\t%2, %1, %0"
897
  [(set_attr "length"  "2,2,3,4,5,6,5,2,3")
898
   (set_attr "timings" "11,11,11,11,11,11,33,11,11")]
899
)
900
 
901
(define_insn "negsi2"
902
  [(set (match_operand:SI         0 "register_operand" "=r,r")
903
        (neg:SI (match_operand:SI 1 "register_operand"  "0,r")))
904
   (set (reg:CC CC_REG)
905
        (compare:CC (neg:SI (match_dup 1))
906
                    (const_int 0)))]
907
  ;; The NEG instruction does not comply with -fwrapv semantics.
908
  ;; See gcc.c-torture/execute/pr22493-1.c for an example of this.
909
  "! flag_wrapv"
910
  "@
911
  neg\t%0
912
  neg\t%1, %0"
913
  [(set_attr "length" "2,3")]
914
)
915
 
916
(define_insn "one_cmplsi2"
917
  [(set (match_operand:SI         0 "register_operand" "=r,r")
918
        (not:SI (match_operand:SI 1 "register_operand"  "0,r")))
919
   (set (reg:CC_ZS CC_REG)
920
        (compare:CC_ZS (not:SI (match_dup 1))
921
                       (const_int 0)))]
922
  ""
923
  "@
924
  not\t%0
925
  not\t%1, %0"
926
  [(set_attr "length" "2,3")]
927
)
928
 
929
(define_insn "iorsi3"
930
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r,r,r,r")
931
        (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0")
932
                (match_operand:SI 2 "rx_source_operand" "r,Uint04,Sint08,Sint16,Sint24,i,0,r,Q")))
933
   (set (reg:CC_ZS CC_REG)
934
        (compare:CC_ZS (ior:SI (match_dup 1) (match_dup 2))
935
                       (const_int 0)))]
936
  ""
937
  "@
938
  or\t%2, %0
939
  or\t%2, %0
940
  or\t%2, %0
941
  or\t%2, %0
942
  or\t%2, %0
943
  or\t%Q2, %0
944
  or\t%1, %0
945
  or\t%2, %1, %0
946
  or\t%Q2, %0"
947
  [(set_attr "timings" "11,11,11,11,11,11,11,11,33")
948
   (set_attr "length"  "2,2,3,4,5,6,2,3,5")]
949
)
950
 
951
(define_insn "rotlsi3"
952
  [(set (match_operand:SI            0 "register_operand" "=r")
953
        (rotate:SI (match_operand:SI 1 "register_operand"  "0")
954
                   (match_operand:SI 2 "rx_shift_operand" "rn")))
955
   (set (reg:CC_ZS CC_REG)
956
        (compare:CC_ZS (rotate:SI (match_dup 1) (match_dup 2))
957
                       (const_int 0)))]
958
  ""
959
  "rotl\t%2, %0"
960
  [(set_attr "length" "3")]
961
)
962
 
963
(define_insn "rotrsi3"
964
  [(set (match_operand:SI              0 "register_operand" "=r")
965
        (rotatert:SI (match_operand:SI 1 "register_operand"  "0")
966
                     (match_operand:SI 2 "rx_shift_operand" "rn")))
967
   (set (reg:CC_ZS CC_REG)
968
        (compare:CC_ZS (rotatert:SI (match_dup 1) (match_dup 2))
969
                       (const_int 0)))]
970
  ""
971
  "rotr\t%2, %0"
972
  [(set_attr "length" "3")]
973
)
974
 
975
(define_insn "ashrsi3"
976
  [(set (match_operand:SI              0 "register_operand" "=r,r,r")
977
        (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r")
978
                     (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
979
   (set (reg:CC_ZS CC_REG)
980
        (compare:CC_ZS (ashiftrt:SI (match_dup 1) (match_dup 2))
981
                       (const_int 0)))]
982
  ""
983
  "@
984
  shar\t%2, %0
985
  shar\t%2, %0
986
  shar\t%2, %1, %0"
987
  [(set_attr "length" "3,2,3")]
988
)
989
 
990
(define_insn "lshrsi3"
991
  [(set (match_operand:SI              0 "register_operand" "=r,r,r")
992
        (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r")
993
                     (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
994
   (set (reg:CC_ZS CC_REG)
995
        (compare:CC_ZS (lshiftrt:SI (match_dup 1) (match_dup 2))
996
                       (const_int 0)))]
997
  ""
998
  "@
999
  shlr\t%2, %0
1000
  shlr\t%2, %0
1001
  shlr\t%2, %1, %0"
1002
  [(set_attr "length" "3,2,3")]
1003
)
1004
 
1005
(define_insn "ashlsi3"
1006
  [(set (match_operand:SI            0 "register_operand" "=r,r,r")
1007
        (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r")
1008
                   (match_operand:SI 2 "rx_shift_operand"  "r,n,n")))
1009
   (set (reg:CC_ZS CC_REG)
1010
        (compare:CC_ZS (ashift:SI (match_dup 1) (match_dup 2))
1011
                       (const_int 0)))]
1012
  ""
1013
  "@
1014
  shll\t%2, %0
1015
  shll\t%2, %0
1016
  shll\t%2, %1, %0"
1017
  [(set_attr "length" "3,2,3")]
1018
)
1019
 
1020
(define_insn "subsi3"
1021
  [(set (match_operand:SI           0 "register_operand" "=r,r,r,r,r")
1022
        (minus:SI (match_operand:SI 1 "register_operand"  "0,0,0,r,0")
1023
                  (match_operand:SI 2 "rx_source_operand" "r,Uint04,n,r,Q")))
1024
   (set (reg:CC_ZSC CC_REG)
1025
        ;; Note - we do not acknowledge that the SUB instruction sets the Overflow
1026
        ;; flag because its interpretation is different from comparing the result
1027
        ;; against zero.  Compile and run gcc.c-torture/execute/cmpsi-1.c to see this.
1028
        (compare:CC_ZSC (minus:SI (match_dup 1) (match_dup 2))
1029
                        (const_int 0)))]
1030
  ""
1031
  "@
1032
  sub\t%2, %0
1033
  sub\t%2, %0
1034
  add\t%N2, %0
1035
  sub\t%2, %1, %0
1036
  sub\t%Q2, %0"
1037
  [(set_attr "timings" "11,11,11,11,33")
1038
   (set_attr "length" "2,2,6,3,5")]
1039
)
1040
 
1041
(define_insn "subdi3"
1042
  [(set (match_operand:DI           0 "register_operand" "=r,r")
1043
        (minus:DI (match_operand:DI 1 "register_operand"  "0,0")
1044
                  (match_operand:DI 2 "rx_source_operand" "r,Q")))
1045
   (set (reg:CC_ZSC CC_REG) ;; See subsi3
1046
        (compare:CC_ZSC (minus:DI (match_dup 1) (match_dup 2))
1047
                        (const_int 0)))]
1048
  ""
1049
  "sub\t%L2, %L0\n\tsbb\t%H2, %H0"
1050
  [(set_attr "timings" "22,44")
1051
   (set_attr "length" "5,11")]
1052
)
1053
 
1054
(define_insn "xorsi3"
1055
  [(set (match_operand:SI         0 "register_operand" "=r,r,r,r,r,r")
1056
        (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
1057
                (match_operand:SI 2 "rx_source_operand"
1058
                                  "r,Sint08,Sint16,Sint24,i,Q")))
1059
   (set (reg:CC_ZS CC_REG)
1060
        (compare:CC_ZS (xor:SI (match_dup 1) (match_dup 2))
1061
                       (const_int 0)))]
1062
  ""
1063
  "xor\t%Q2, %0"
1064
  [(set_attr "timings" "11,11,11,11,11,33")
1065
   (set_attr "length" "3,4,5,6,7,6")]
1066
)
1067
 
1068
;; Floating Point Instructions
1069
 
1070
(define_insn "addsf3"
1071
  [(set (match_operand:SF          0 "register_operand"  "=r,r,r")
1072
        (plus:SF (match_operand:SF 1 "register_operand"  "%0,0,0")
1073
                 (match_operand:SF 2 "rx_source_operand"  "r,F,Q")))
1074
   (set (reg:CC_ZS CC_REG)
1075
        (compare:CC_ZS (plus:SF (match_dup 1) (match_dup 2))
1076
                        (const_int 0)))]
1077
  "ALLOW_RX_FPU_INSNS"
1078
  "fadd\t%2, %0"
1079
  [(set_attr "timings" "44,44,66")
1080
   (set_attr "length" "3,7,5")]
1081
)
1082
 
1083
(define_insn "divsf3"
1084
  [(set (match_operand:SF         0 "register_operand" "=r,r,r")
1085
        (div:SF (match_operand:SF 1 "register_operand"  "0,0,0")
1086
                (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1087
   (set (reg:CC_ZS CC_REG)
1088
        (compare:CC_ZS (div:SF (match_dup 1) (match_dup 2))
1089
                        (const_int 0)))]
1090
  "ALLOW_RX_FPU_INSNS"
1091
  "fdiv\t%2, %0"
1092
  [(set_attr "timings" "1616,1616,1818")
1093
   (set_attr "length" "3,7,5")]
1094
)
1095
 
1096
(define_insn "mulsf3"
1097
  [(set (match_operand:SF          0 "register_operand" "=r,r,r")
1098
        (mult:SF (match_operand:SF 1 "register_operand" "%0,0,0")
1099
                (match_operand:SF  2 "rx_source_operand" "r,F,Q")))
1100
   (set (reg:CC_ZS CC_REG)
1101
        (compare:CC_ZS (mult:SF (match_dup 1) (match_dup 2))
1102
                        (const_int 0)))]
1103
  "ALLOW_RX_FPU_INSNS"
1104
  "fmul\t%2, %0"
1105
  [(set_attr "timings" "33,33,55")
1106
   (set_attr "length"  "3,7,5")]
1107
)
1108
 
1109
(define_insn "subsf3"
1110
  [(set (match_operand:SF           0 "register_operand" "=r,r,r")
1111
        (minus:SF (match_operand:SF 1 "register_operand"  "0,0,0")
1112
                  (match_operand:SF 2 "rx_source_operand" "r,F,Q")))
1113
   (set (reg:CC_ZS CC_REG)
1114
        (compare:CC_ZS (minus:SF (match_dup 1) (match_dup 2))
1115
                       (const_int 0)))]
1116
  "ALLOW_RX_FPU_INSNS"
1117
  "fsub\t%Q2, %0"
1118
  [(set_attr "timings" "44,44,66")
1119
   (set_attr "length" "3,7,5")]
1120
)
1121
 
1122
(define_insn "fix_truncsfsi2"
1123
  [(set (match_operand:SI         0 "register_operand"  "=r,r")
1124
        (fix:SI (match_operand:SF 1 "rx_compare_operand" "r,Q")))
1125
   (set (reg:CC_ZS CC_REG)
1126
        (compare:CC_ZS (fix:SI (match_dup 1))
1127
                       (const_int 0)))]
1128
  "ALLOW_RX_FPU_INSNS"
1129
  "ftoi\t%Q1, %0"
1130
  [(set_attr "timings" "22,44")
1131
   (set_attr "length" "3,5")]
1132
)
1133
 
1134
(define_insn "floatsisf2"
1135
  [(set (match_operand:SF           0 "register_operand"  "=r,r")
1136
        (float:SF (match_operand:SI 1 "rx_compare_operand" "r,Q")))
1137
   (set (reg:CC_ZS CC_REG)
1138
        (compare:CC_ZS (float:SF (match_dup 1))
1139
                        (const_int 0)))]
1140
  "ALLOW_RX_FPU_INSNS"
1141
  "itof\t%Q1, %0"
1142
  [(set_attr "timings" "22,44")
1143
   (set_attr "length" "3,6")]
1144
)
1145
 
1146
;; Bit manipulation instructions.
1147
;; Note - there are two versions of each pattern because the memory
1148
;; accessing versions use QImode whilst the register accessing
1149
;; versions use SImode.
1150
;; The peephole are here because the combiner only looks at a maximum
1151
;; of three instructions at a time.
1152
 
1153
(define_insn "bitset"
1154
  [(set:SI (match_operand:SI                    0 "register_operand" "=r")
1155
           (ior:SI (match_operand:SI            1 "register_operand" "0")
1156
                   (ashift:SI (const_int 1)
1157
                              (match_operand:SI 2 "nonmemory_operand" "ri"))))]
1158
  ""
1159
  "bset\t%2, %0"
1160
  [(set_attr "length" "3")]
1161
)
1162
 
1163
(define_insn "bitset_in_memory"
1164
  [(set:QI (match_operand:QI                    0 "memory_operand" "=m")
1165
           (ior:QI (match_operand:QI            1 "memory_operand" "0")
1166
                   (ashift:QI (const_int 1)
1167
                              (match_operand:QI 2 "nonmemory_operand" "ri"))))]
1168
  ""
1169
  "bset\t%2, %0.B"
1170
  [(set_attr "length" "3")
1171
   (set_attr "timings" "34")]
1172
)
1173
 
1174
;; (set (reg A) (const_int 1))
1175
;; (set (reg A) (ashift (reg A) (reg B)))
1176
;; (set (reg C) (ior (reg A) (reg C)))
1177
(define_peephole2
1178
  [(set:SI (match_operand:SI 0 "register_operand" "")
1179
           (const_int 1))
1180
   (set:SI (match_dup 0)
1181
           (ashift:SI (match_dup 0)
1182
                      (match_operand:SI 1 "register_operand" "")))
1183
   (set:SI (match_operand:SI 2 "register_operand" "")
1184
           (ior:SI (match_dup 0)
1185
                   (match_dup 2)))]
1186
  "dead_or_set_p (insn, operands[0])"
1187
  [(set:SI (match_dup 2)
1188
           (ior:SI (match_dup 2)
1189
                   (ashift:SI (const_int 1)
1190
                              (match_dup 1))))]
1191
)
1192
 
1193
;; (set (reg A) (const_int 1))
1194
;; (set (reg A) (ashift (reg A) (reg B)))
1195
;; (set (reg A) (ior (reg A) (reg C)))
1196
;; (set (reg C) (reg A)
1197
(define_peephole2
1198
  [(set:SI (match_operand:SI 0 "register_operand" "")
1199
           (const_int 1))
1200
   (set:SI (match_dup 0)
1201
           (ashift:SI (match_dup 0)
1202
                      (match_operand:SI 1 "register_operand" "")))
1203
   (set:SI (match_dup 0)
1204
           (ior:SI (match_dup 0)
1205
                   (match_operand:SI 2 "register_operand" "")))
1206
   (set:SI (match_dup 2) (match_dup 0))]
1207
  "dead_or_set_p (insn, operands[0])"
1208
  [(set:SI (match_dup 2)
1209
           (ior:SI (match_dup 2)
1210
                   (ashift:SI (const_int 1)
1211
                              (match_dup 1))))]
1212
)
1213
 
1214
(define_insn "bitinvert"
1215
  [(set:SI (match_operand:SI 0 "register_operand" "+r")
1216
           (xor:SI (match_operand:SI 1 "register_operand" "0")
1217
                   (ashift:SI (const_int 1)
1218
                              (match_operand:SI 2 "nonmemory_operand" "ri"))))]
1219
  ""
1220
  "bnot\t%2, %0"
1221
  [(set_attr "length" "3")]
1222
)
1223
 
1224
(define_insn "bitinvert_in_memory"
1225
  [(set:QI (match_operand:QI 0 "memory_operand" "+m")
1226
           (xor:QI (match_operand:QI 1 "register_operand" "0")
1227
                   (ashift:QI (const_int 1)
1228
                              (match_operand:QI 2 "nonmemory_operand" "ri"))))]
1229
  ""
1230
  "bnot\t%2, %0.B"
1231
  [(set_attr "length" "5")
1232
   (set_attr "timings" "33")]
1233
)
1234
 
1235
;; (set (reg A) (const_int 1))
1236
;; (set (reg A) (ashift (reg A) (reg B)))
1237
;; (set (reg C) (xor (reg A) (reg C)))
1238
(define_peephole2
1239
  [(set:SI (match_operand:SI 0 "register_operand" "")
1240
           (const_int 1))
1241
   (set:SI (match_dup 0)
1242
           (ashift:SI (match_dup 0)
1243
                      (match_operand:SI 1 "register_operand" "")))
1244
   (set:SI (match_operand:SI 2 "register_operand" "")
1245
           (xor:SI (match_dup 0)
1246
                   (match_dup 2)))]
1247
  "dead_or_set_p (insn, operands[0])"
1248
  [(set:SI (match_dup 2)
1249
           (xor:SI (match_dup 2)
1250
                   (ashift:SI (const_int 1)
1251
                              (match_dup 1))))]
1252
  ""
1253
)
1254
 
1255
;; (set (reg A) (const_int 1))
1256
;; (set (reg A) (ashift (reg A) (reg B)))
1257
;; (set (reg A) (xor (reg A) (reg C)))
1258
;; (set (reg C) (reg A))
1259
(define_peephole2
1260
  [(set:SI (match_operand:SI 0 "register_operand" "")
1261
           (const_int 1))
1262
   (set:SI (match_dup 0)
1263
           (ashift:SI (match_dup 0)
1264
                      (match_operand:SI 1 "register_operand" "")))
1265
   (set:SI (match_dup 0)
1266
           (xor:SI (match_dup 0)
1267
                   (match_operand:SI 2 "register_operand" "")))
1268
   (set:SI (match_dup 2) (match_dup 0))]
1269
  "dead_or_set_p (insn, operands[0])"
1270
  [(set:SI (match_dup 2)
1271
           (xor:SI (match_dup 2)
1272
                   (ashift:SI (const_int 1)
1273
                              (match_dup 1))))]
1274
  ""
1275
)
1276
 
1277
(define_insn "bitclr"
1278
  [(set:SI (match_operand:SI 0 "register_operand" "+r")
1279
           (and:SI (match_operand:SI 1 "register_operand" "0")
1280
                   (not:SI (ashift:SI (const_int 1)
1281
                                      (match_operand:SI 2 "nonmemory_operand" "ri")))))]
1282
  ""
1283
  "bclr\t%2, %0"
1284
  [(set_attr "length" "3")]
1285
)
1286
 
1287
(define_insn "bitclr_in_memory"
1288
  [(set:QI (match_operand:QI 0 "memory_operand" "+m")
1289
           (and:QI (match_operand:QI 1 "memory_operand" "0")
1290
                   (not:QI (ashift:QI (const_int 1)
1291
                                      (match_operand:QI 2 "nonmemory_operand" "ri")))))]
1292
  ""
1293
  "bclr\t%2, %0.B"
1294
  [(set_attr "length" "3")
1295
   (set_attr "timings" "34")]
1296
)
1297
 
1298
;; (set (reg A) (const_int -2))
1299
;; (set (reg A) (rotate (reg A) (reg B)))
1300
;; (set (reg C) (and (reg A) (reg C)))
1301
(define_peephole2
1302
  [(set:SI (match_operand:SI 0 "register_operand" "")
1303
           (const_int -2))
1304
   (set:SI (match_dup 0)
1305
           (rotate:SI (match_dup 0)
1306
                      (match_operand:SI 1 "register_operand" "")))
1307
   (set:SI (match_operand:SI 2 "register_operand" "")
1308
           (and:SI (match_dup 0)
1309
                   (match_dup 2)))]
1310
  "dead_or_set_p (insn, operands[0])"
1311
  [(set:SI (match_dup 2)
1312
           (and:SI (match_dup 2)
1313
                   (not:SI (ashift:SI (const_int 1)
1314
                                      (match_dup 1)))))]
1315
)
1316
 
1317
;; (set (reg A) (const_int -2))
1318
;; (set (reg A) (rotate (reg A) (reg B)))
1319
;; (set (reg A) (and (reg A) (reg C)))
1320
;; (set (reg C) (reg A)
1321
(define_peephole2
1322
  [(set:SI (match_operand:SI 0 "register_operand" "")
1323
           (const_int -2))
1324
   (set:SI (match_dup 0)
1325
           (rotate:SI (match_dup 0)
1326
                      (match_operand:SI 1 "register_operand" "")))
1327
   (set:SI (match_dup 0)
1328
           (and:SI (match_dup 0)
1329
                   (match_operand:SI 2 "register_operand" "")))
1330
   (set:SI (match_dup 2) (match_dup 0))]
1331
  "dead_or_set_p (insn, operands[0])"
1332
  [(set:SI (match_dup 2)
1333
           (and:SI (match_dup 2)
1334
                   (not:SI (ashift:SI (const_int 1)
1335
                                      (match_dup 1)))))]
1336
)
1337
 
1338
(define_expand "insv"
1339
  [(set:SI (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand") ;; Destination
1340
                            (match_operand    1 "immediate_operand")    ;; # of bits to set
1341
                            (match_operand    2 "immediate_operand"))   ;; Starting bit
1342
           (match_operand                     3 "immediate_operand"))]  ;; Bits to insert
1343
  ""
1344
  {
1345
    if (rx_expand_insv (operands))
1346
      DONE;
1347
    FAIL;
1348
  }
1349
)
1350
 
1351
;; Atomic exchange operation.
1352
 
1353
(define_insn "sync_lock_test_and_setsi"
1354
  [(set:SI (match_operand:SI 0 "register_operand"   "=r,r")
1355
           (match_operand:SI 1 "rx_compare_operand" "=r,Q"))
1356
   (set:SI (match_dup 1)
1357
           (match_operand:SI 2 "register_operand"    "0,0"))]
1358
  ""
1359
  "xchg\t%1, %0"
1360
  [(set_attr "length" "3,6")
1361
   (set_attr "timings" "22")]
1362
)
1363
 
1364
;; Block move functions.
1365
 
1366
(define_expand "movstr"
1367
  [(set:SI (match_operand:BLK 1 "memory_operand")    ;; Dest
1368
           (match_operand:BLK 2 "memory_operand"))   ;; Source
1369
   (use (match_operand:SI     0 "register_operand")) ;; Updated Dest
1370
  ]
1371
  ""
1372
  {
1373
    rtx addr1 = gen_rtx_REG (SImode, 1);
1374
    rtx addr2 = gen_rtx_REG (SImode, 2);
1375
    rtx len   = gen_rtx_REG (SImode, 3);
1376
    rtx dest_copy = gen_reg_rtx (SImode);
1377
 
1378
    emit_move_insn (len, GEN_INT (-1));
1379
    emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
1380
    emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
1381
    operands[1] = replace_equiv_address_nv (operands[1], addr1);
1382
    operands[2] = replace_equiv_address_nv (operands[2], addr2);
1383
    emit_move_insn (dest_copy, addr1);
1384
    emit_insn (gen_rx_movstr ());
1385
    emit_move_insn (len, GEN_INT (-1));
1386
    emit_insn (gen_rx_strend (operands[0], dest_copy));
1387
    DONE;
1388
  }
1389
)
1390
 
1391
(define_insn "rx_movstr"
1392
  [(set:SI (mem:BLK (reg:SI 1))
1393
           (mem:BLK (reg:SI 2)))
1394
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVSTR)
1395
   (clobber (reg:SI 1))
1396
   (clobber (reg:SI 2))
1397
   (clobber (reg:SI 3))]
1398
  ""
1399
  "smovu"
1400
  [(set_attr "length" "2")
1401
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1402
)
1403
 
1404
(define_insn "rx_strend"
1405
  [(set:SI (match_operand:SI                      0 "register_operand" "=r")
1406
           (unspec_volatile:SI [(match_operand:SI 1 "register_operand"  "r")
1407
                                (reg:SI 3)] UNSPEC_STRLEN))
1408
   (clobber (reg:SI 1))
1409
   (clobber (reg:SI 2))
1410
   (clobber (reg:SI 3))
1411
   (clobber (reg:CC CC_REG))
1412
   ]
1413
  ""
1414
  "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0"
1415
  [(set_attr "length" "10")
1416
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1417
)
1418
 
1419
(define_expand "movmemsi"
1420
  [(parallel
1421
    [(set (match_operand:BLK 0 "memory_operand")    ;; Dest
1422
          (match_operand:BLK 1 "memory_operand"))   ;; Source
1423
     (use (match_operand:SI  2 "register_operand")) ;; Length in bytes
1424
     (match_operand          3 "immediate_operand") ;; Align
1425
     (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)]
1426
    )]
1427
  ""
1428
  {
1429
    rtx addr1 = gen_rtx_REG (SImode, 1);
1430
    rtx addr2 = gen_rtx_REG (SImode, 2);
1431
    rtx len   = gen_rtx_REG (SImode, 3);
1432
 
1433
    if (REG_P (operands[0]) && (REGNO (operands[0]) == 2
1434
                                      || REGNO (operands[0]) == 3))
1435
      FAIL;
1436
    if (REG_P (operands[1]) && (REGNO (operands[1]) == 1
1437
                                      || REGNO (operands[1]) == 3))
1438
      FAIL;
1439
    if (REG_P (operands[2]) && (REGNO (operands[2]) == 1
1440
                                      || REGNO (operands[2]) == 2))
1441
      FAIL;
1442
    emit_move_insn (addr1, force_operand (XEXP (operands[0], 0), NULL_RTX));
1443
    emit_move_insn (addr2, force_operand (XEXP (operands[1], 0), NULL_RTX));
1444
    emit_move_insn (len, force_operand (operands[2], NULL_RTX));
1445
    operands[0] = replace_equiv_address_nv (operands[0], addr1);
1446
    operands[1] = replace_equiv_address_nv (operands[1], addr2);
1447
    emit_insn (gen_rx_movmem ());
1448
    DONE;
1449
  }
1450
)
1451
 
1452
(define_insn "rx_movmem"
1453
  [(set (mem:BLK (reg:SI 1))
1454
        (mem:BLK (reg:SI 2)))
1455
   (use (reg:SI 3))
1456
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)
1457
   (clobber (reg:SI 1))
1458
   (clobber (reg:SI 2))
1459
   (clobber (reg:SI 3))]
1460
  ""
1461
  "smovf"
1462
  [(set_attr "length" "2")
1463
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1464
)
1465
 
1466
(define_expand "setmemsi"
1467
  [(set (match_operand:BLK 0 "memory_operand")     ;; Dest
1468
        (match_operand:QI  2 "nonmemory_operand")) ;; Value
1469
   (use (match_operand:SI  1 "nonmemory_operand")) ;; Length
1470
   (match_operand          3 "immediate_operand")  ;; Align
1471
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)]
1472
  ""
1473
  {
1474
    rtx addr = gen_rtx_REG (SImode, 1);
1475
    rtx val  = gen_rtx_REG (QImode, 2);
1476
    rtx len  = gen_rtx_REG (SImode, 3);
1477
 
1478
    emit_move_insn (addr, force_operand (XEXP (operands[0], 0), NULL_RTX));
1479
    emit_move_insn (len, force_operand (operands[1], NULL_RTX));
1480
    emit_move_insn (val, operands[2]);
1481
    emit_insn (gen_rx_setmem ());
1482
    DONE;
1483
  }
1484
)
1485
 
1486
(define_insn "rx_setmem"
1487
  [(set:BLK (mem:BLK (reg:SI 1)) (reg 2))
1488
   (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_SETMEM)
1489
   (clobber (reg:SI 1))
1490
   (clobber (reg:SI 3))]
1491
  ""
1492
  "sstr.b"
1493
  [(set_attr "length" "2")
1494
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1495
)
1496
 
1497
(define_expand "cmpstrnsi"
1498
  [(set (match_operand:SI                       0 "register_operand")   ;; Result
1499
        (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand")     ;; String1
1500
                             (match_operand:BLK 2 "memory_operand")]    ;; String2
1501
                            UNSPEC_CMPSTRN))
1502
   (use (match_operand:SI                       3 "register_operand"))  ;; Max Length
1503
   (match_operand:SI                            4 "immediate_operand")] ;; Known Align
1504
  ""
1505
  {
1506
    rtx str1 = gen_rtx_REG (SImode, 1);
1507
    rtx str2 = gen_rtx_REG (SImode, 2);
1508
    rtx len  = gen_rtx_REG (SImode, 3);
1509
 
1510
    emit_move_insn (str1, force_operand (XEXP (operands[1], 0), NULL_RTX));
1511
    emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX));
1512
    emit_move_insn (len, force_operand (operands[3], NULL_RTX));
1513
 
1514
    emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
1515
    DONE;
1516
  }
1517
)
1518
 
1519
(define_expand "cmpstrsi"
1520
  [(set (match_operand:SI                       0 "register_operand")   ;; Result
1521
        (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand")     ;; String1
1522
                             (match_operand:BLK 2 "memory_operand")]    ;; String2
1523
                            UNSPEC_CMPSTRN))
1524
   (match_operand:SI                            3 "immediate_operand")] ;; Known Align
1525
  ""
1526
  {
1527
    rtx str1 = gen_rtx_REG (SImode, 1);
1528
    rtx str2 = gen_rtx_REG (SImode, 2);
1529
    rtx len  = gen_rtx_REG (SImode, 3);
1530
 
1531
    emit_move_insn (str1, force_reg (SImode, XEXP (operands[1], 0)));
1532
    emit_move_insn (str2, force_reg (SImode, XEXP (operands[2], 0)));
1533
    emit_move_insn (len, GEN_INT (-1));
1534
 
1535
    emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
1536
    DONE;
1537
  }
1538
)
1539
 
1540
(define_insn "rx_cmpstrn"
1541
  [(set:SI (match_operand:SI 0 "register_operand" "=r")
1542
           (unspec_volatile:SI [(reg:SI 1) (reg:SI 2) (reg:SI 3)]
1543
                               UNSPEC_CMPSTRN))
1544
   (use (match_operand:BLK   1 "memory_operand" "m"))
1545
   (use (match_operand:BLK   2 "memory_operand" "m"))
1546
   (clobber (reg:SI 1))
1547
   (clobber (reg:SI 2))
1548
   (clobber (reg:SI 3))
1549
   (clobber (reg:CC CC_REG))]
1550
  ""
1551
  "scmpu                ; Perform the string comparison
1552
   mov     #-1, %0      ; Set up -1 result (which cannot be created
1553
                        ; by the SC insn)
1554
   bnc     ?+           ; If Carry is not set skip over
1555
   scne.L  %0           ; Set result based on Z flag
1556
?:
1557
"
1558
  [(set_attr "length" "9")
1559
   (set_attr "timings" "1111")] ;; The timing is a guesstimate.
1560
)
1561
 
1562
;;   Builtin Functions
1563
;;
1564
;; GCC does not have the ability to generate the following instructions
1565
;; on its own so they are provided as builtins instead.  To use them from
1566
;; a program for example invoke them as __builtin_rx_.  For
1567
;; example:
1568
;;
1569
;;    int short_byte_swap (int arg) { return __builtin_rx_revw (arg); }
1570
 
1571
;;---------- Accumulator Support ------------------------
1572
 
1573
;; Multiply & Accumulate (high)
1574
(define_insn "machi"
1575
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1576
               (match_operand:SI 1 "register_operand" "r")]
1577
              UNSPEC_BUILTIN_MACHI)]
1578
  ""
1579
  "machi\t%0, %1"
1580
  [(set_attr "length" "3")]
1581
)
1582
 
1583
;; Multiply & Accumulate (low)
1584
(define_insn "maclo"
1585
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1586
               (match_operand:SI 1 "register_operand" "r")]
1587
              UNSPEC_BUILTIN_MACLO)]
1588
  ""
1589
  "maclo\t%0, %1"
1590
  [(set_attr "length" "3")]
1591
)
1592
 
1593
;; Multiply (high)
1594
(define_insn "mulhi"
1595
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1596
               (match_operand:SI 1 "register_operand" "r")]
1597
              UNSPEC_BUILTIN_MULHI)]
1598
  ""
1599
  "mulhi\t%0, %1"
1600
  [(set_attr "length" "3")]
1601
)
1602
 
1603
;; Multiply (low)
1604
(define_insn "mullo"
1605
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
1606
               (match_operand:SI 1 "register_operand" "r")]
1607
              UNSPEC_BUILTIN_MULLO)]
1608
  ""
1609
  "mullo\t%0, %1"
1610
  [(set_attr "length" "3")]
1611
)
1612
 
1613
;; Move from Accumulator (high)
1614
(define_insn "mvfachi"
1615
  [(set (match_operand:SI 0 "register_operand" "=r")
1616
        (unspec:SI [(const_int 0)]
1617
                   UNSPEC_BUILTIN_MVFACHI))]
1618
  ""
1619
  "mvfachi\t%0"
1620
  [(set_attr "length" "3")]
1621
)
1622
 
1623
;; Move from Accumulator (middle)
1624
(define_insn "mvfacmi"
1625
  [(set (match_operand:SI 0 "register_operand" "=r")
1626
        (unspec:SI [(const_int 0)]
1627
                   UNSPEC_BUILTIN_MVFACMI))]
1628
  ""
1629
  "mvfacmi\t%0"
1630
  [(set_attr "length" "3")]
1631
)
1632
 
1633
;; Move to Accumulator (high)
1634
(define_insn "mvtachi"
1635
  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1636
                       UNSPEC_BUILTIN_MVTACHI)]
1637
  ""
1638
  "mvtachi\t%0"
1639
  [(set_attr "length" "3")]
1640
)
1641
 
1642
;; Move to Accumulator (low)
1643
(define_insn "mvtaclo"
1644
  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
1645
                       UNSPEC_BUILTIN_MVTACLO)]
1646
  ""
1647
  "mvtaclo\t%0"
1648
  [(set_attr "length" "3")]
1649
)
1650
 
1651
;; Round Accumulator
1652
(define_insn "racw"
1653
  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
1654
                       UNSPEC_BUILTIN_RACW)]
1655
  ""
1656
  "racw\t%0"
1657
  [(set_attr "length" "3")]
1658
)
1659
 
1660
;; Repeat multiply and accumulate
1661
(define_insn "rmpa"
1662
  [(unspec:SI [(const_int 0) (reg:SI 1) (reg:SI 2) (reg:SI 3)
1663
               (reg:SI 4) (reg:SI 5) (reg:SI 6)]
1664
              UNSPEC_BUILTIN_RMPA)
1665
  (clobber (reg:SI 1))
1666
  (clobber (reg:SI 2))
1667
  (clobber (reg:SI 3))]
1668
  ""
1669
  "rmpa"
1670
  [(set_attr "length" "2")
1671
   (set_attr "timings" "1010")]
1672
)
1673
 
1674
;;---------- Arithmetic ------------------------
1675
 
1676
;; Byte swap (two 16-bit values).
1677
(define_insn "revw"
1678
  [(set (match_operand:SI             0 "register_operand" "+r")
1679
        (unspec:SI [(match_operand:SI 1 "register_operand"  "r")]
1680
                   UNSPEC_BUILTIN_REVW))]
1681
  ""
1682
  "revw\t%1, %0"
1683
  [(set_attr "length" "3")]
1684
)
1685
 
1686
;; Round to integer.
1687
(define_insn "lrintsf2"
1688
  [(set (match_operand:SI             0 "register_operand"  "=r,r")
1689
        (unspec:SI [(match_operand:SF 1 "rx_compare_operand" "r,Q")]
1690
                   UNSPEC_BUILTIN_ROUND))
1691
   (clobber (reg:CC CC_REG))]
1692
  ""
1693
  "round\t%1, %0"
1694
  [(set_attr "timings" "22,44")
1695
   (set_attr "length" "3,5")]
1696
)
1697
 
1698
;; Saturate to 32-bits
1699
(define_insn "sat"
1700
  [(set (match_operand:SI             0 "register_operand" "=r")
1701
        (unspec:SI [(match_operand:SI 1 "register_operand"  "0")]
1702
                   UNSPEC_BUILTIN_SAT))]
1703
  ""
1704
  "sat\t%0"
1705
  [(set_attr "length" "2")]
1706
)
1707
 
1708
;;---------- Control Registers ------------------------
1709
 
1710
;; Clear Processor Status Word
1711
(define_insn "clrpsw"
1712
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
1713
              UNSPEC_BUILTIN_CLRPSW)
1714
   (clobber (reg:CC CC_REG))]
1715
  ""
1716
  "clrpsw\t%F0"
1717
  [(set_attr "length" "2")]
1718
)
1719
 
1720
;; Set Processor Status Word
1721
(define_insn "setpsw"
1722
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
1723
              UNSPEC_BUILTIN_SETPSW)
1724
   (clobber (reg:CC CC_REG))]
1725
  ""
1726
  "setpsw\t%F0"
1727
  [(set_attr "length" "2")]
1728
)
1729
 
1730
;; Move from control register
1731
(define_insn "mvfc"
1732
  [(set (match_operand:SI             0 "register_operand" "=r")
1733
        (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")]
1734
                   UNSPEC_BUILTIN_MVFC))]
1735
  ""
1736
  "mvfc\t%C1, %0"
1737
  [(set_attr "length" "3")]
1738
)
1739
 
1740
;; Move to control register
1741
(define_insn "mvtc"
1742
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i")
1743
               (match_operand:SI 1 "nonmemory_operand" "r,i")]
1744
              UNSPEC_BUILTIN_MVTC)]
1745
  ""
1746
  "mvtc\t%1, %C0"
1747
  [(set_attr "length" "3,7")]
1748
  ;; Ignore possible clobbering of the comparison flags in the
1749
  ;; PSW register.  This is a cc0 target so any cc0 setting
1750
  ;; instruction will always be paired with a cc0 user, without
1751
  ;; the possibility of this instruction being placed in between
1752
  ;; them.
1753
)
1754
 
1755
;; Move to interrupt priority level
1756
(define_insn "mvtipl"
1757
  [(unspec:SI [(match_operand:SI 0 "immediate_operand" "Uint04")]
1758
              UNSPEC_BUILTIN_MVTIPL)]
1759
  ""
1760
  "mvtipl\t%0"
1761
  [(set_attr "length" "3")]
1762
)
1763
 
1764
;;---------- Interrupts ------------------------
1765
 
1766
;; Break
1767
(define_insn "brk"
1768
  [(unspec_volatile [(const_int 0)]
1769
                    UNSPEC_BUILTIN_BRK)]
1770
  ""
1771
  "brk"
1772
  [(set_attr "length" "1")
1773
   (set_attr "timings" "66")]
1774
)
1775
 
1776
;; Interrupt
1777
(define_insn "int"
1778
  [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
1779
                       UNSPEC_BUILTIN_INT)]
1780
  ""
1781
  "int\t%0"
1782
  [(set_attr "length" "3")]
1783
)
1784
 
1785
;; Wait
1786
(define_insn "wait"
1787
  [(unspec_volatile [(const_int 0)]
1788
                    UNSPEC_BUILTIN_WAIT)]
1789
  ""
1790
  "wait"
1791
  [(set_attr "length" "2")]
1792
)
1793
 
1794
;;---------- CoProcessor Support ------------------------
1795
 
1796
;; FIXME: The instructions are currently commented out because
1797
;; the bit patterns have not been finalized, so the assembler
1798
;; does not support them.  Once they are decided and the assembler
1799
;; supports them, enable the instructions here.
1800
 
1801
;; Move from co-processor register
1802
(define_insn "mvfcp"
1803
  [(set (match_operand:SI             0 "register_operand" "=r")
1804
        (unspec:SI [(match_operand:SI 1 "immediate_operand" "i")
1805
                    (match_operand:SI 2 "immediate_operand" "i")]
1806
                   UNSPEC_BUILTIN_MVFCP))]
1807
  ""
1808
  "; mvfcp\t%1, %0, %2"
1809
  [(set_attr "length" "5")]
1810
)
1811
 
1812
;;---------- Misc ------------------------
1813
 
1814
;; Required by cfglayout.c...
1815
(define_insn "nop"
1816
  [(const_int 0)]
1817
  ""
1818
  "nop"
1819
  [(set_attr "length" "1")]
1820
)

powered by: WebSVN 2.1.0

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