OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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

powered by: WebSVN 2.1.0

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