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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [xtensa/] [xtensa.md] - Blame information for rev 820

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

Line No. Rev Author Line
1 38 julius
;; GCC machine description for Tensilica's Xtensa architecture.
2
;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007
3
;  Free Software Foundation, Inc.
4
;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5
 
6
;; This file is part of GCC.
7
 
8
;; GCC is free software; you can redistribute it and/or modify it
9
;; under the terms of the GNU General Public License as published by
10
;; the Free Software Foundation; either version 3, or (at your option)
11
;; any later version.
12
 
13
;; GCC is distributed in the hope that it will be useful, but WITHOUT
14
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16
;; License for more details.
17
 
18
;; You should have received a copy of the GNU General Public License
19
;; along with GCC; see the file COPYING3.  If not see
20
;; .
21
 
22
 
23
(define_constants [
24
  (A0_REG               0)
25
  (A1_REG               1)
26
  (A7_REG               7)
27
  (A8_REG               8)
28
 
29
  (UNSPEC_NSAU          1)
30
  (UNSPEC_NOP           2)
31
  (UNSPEC_PLT           3)
32
  (UNSPEC_RET_ADDR      4)
33
  (UNSPECV_SET_FP       1)
34
  (UNSPECV_ENTRY        2)
35
])
36
 
37
 
38
;; Attributes.
39
 
40
(define_attr "type"
41
  "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fdiv,fsqrt,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr"
42
  (const_string "unknown"))
43
 
44
(define_attr "mode"
45
  "unknown,none,QI,HI,SI,DI,SF,DF,BL"
46
  (const_string "unknown"))
47
 
48
(define_attr "length" "" (const_int 1))
49
 
50
;; Describe a user's asm statement.
51
(define_asm_attributes
52
  [(set_attr "type" "multi")])
53
 
54
 
55
;; Pipeline model.
56
 
57
;; The Xtensa basically has simple 5-stage RISC pipeline.
58
;; Most instructions complete in 1 cycle, and it is OK to assume that
59
;; everything is fully pipelined.  The exceptions have special insn
60
;; reservations in the pipeline description below.  The Xtensa can
61
;; issue one instruction per cycle, so defining CPU units is unnecessary.
62
 
63
(define_insn_reservation "xtensa_any_insn" 1
64
                         (eq_attr "type" "!load,fload,rsr,mul16,mul32,fmadd,fconv")
65
                         "nothing")
66
 
67
(define_insn_reservation "xtensa_memory" 2
68
                         (eq_attr "type" "load,fload")
69
                         "nothing")
70
 
71
(define_insn_reservation "xtensa_sreg" 2
72
                         (eq_attr "type" "rsr")
73
                         "nothing")
74
 
75
(define_insn_reservation "xtensa_mul16" 2
76
                         (eq_attr "type" "mul16")
77
                         "nothing")
78
 
79
(define_insn_reservation "xtensa_mul32" 2
80
                         (eq_attr "type" "mul32")
81
                         "nothing")
82
 
83
(define_insn_reservation "xtensa_fmadd" 4
84
                         (eq_attr "type" "fmadd")
85
                         "nothing")
86
 
87
(define_insn_reservation "xtensa_fconv" 2
88
                         (eq_attr "type" "fconv")
89
                         "nothing")
90
 
91
;; Include predicate definitions
92
 
93
(include "predicates.md")
94
 
95
 
96
;; Addition.
97
 
98
(define_insn "addsi3"
99
  [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
100
        (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
101
                 (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
102
  ""
103
  "@
104
   add.n\t%0, %1, %2
105
   addi.n\t%0, %1, %d2
106
   add\t%0, %1, %2
107
   addi\t%0, %1, %d2
108
   addmi\t%0, %1, %x2"
109
  [(set_attr "type"     "arith,arith,arith,arith,arith")
110
   (set_attr "mode"     "SI")
111
   (set_attr "length"   "2,2,3,3,3")])
112
 
113
(define_insn "*addx2"
114
  [(set (match_operand:SI 0 "register_operand" "=a")
115
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
116
                          (const_int 2))
117
                 (match_operand:SI 2 "register_operand" "r")))]
118
  "TARGET_ADDX"
119
  "addx2\t%0, %1, %2"
120
  [(set_attr "type"     "arith")
121
   (set_attr "mode"     "SI")
122
   (set_attr "length"   "3")])
123
 
124
(define_insn "*addx4"
125
  [(set (match_operand:SI 0 "register_operand" "=a")
126
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
127
                          (const_int 4))
128
                 (match_operand:SI 2 "register_operand" "r")))]
129
  "TARGET_ADDX"
130
  "addx4\t%0, %1, %2"
131
  [(set_attr "type"     "arith")
132
   (set_attr "mode"     "SI")
133
   (set_attr "length"   "3")])
134
 
135
(define_insn "*addx8"
136
  [(set (match_operand:SI 0 "register_operand" "=a")
137
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
138
                          (const_int 8))
139
                 (match_operand:SI 2 "register_operand" "r")))]
140
  "TARGET_ADDX"
141
  "addx8\t%0, %1, %2"
142
  [(set_attr "type"     "arith")
143
   (set_attr "mode"     "SI")
144
   (set_attr "length"   "3")])
145
 
146
(define_insn "addsf3"
147
  [(set (match_operand:SF 0 "register_operand" "=f")
148
        (plus:SF (match_operand:SF 1 "register_operand" "%f")
149
                 (match_operand:SF 2 "register_operand" "f")))]
150
  "TARGET_HARD_FLOAT"
151
  "add.s\t%0, %1, %2"
152
  [(set_attr "type"     "fmadd")
153
   (set_attr "mode"     "SF")
154
   (set_attr "length"   "3")])
155
 
156
 
157
;; Subtraction.
158
 
159
(define_insn "subsi3"
160
  [(set (match_operand:SI 0 "register_operand" "=a")
161
        (minus:SI (match_operand:SI 1 "register_operand" "r")
162
                  (match_operand:SI 2 "register_operand" "r")))]
163
  ""
164
  "sub\t%0, %1, %2"
165
  [(set_attr "type"     "arith")
166
   (set_attr "mode"     "SI")
167
   (set_attr "length"   "3")])
168
 
169
(define_insn "*subx2"
170
  [(set (match_operand:SI 0 "register_operand" "=a")
171
        (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
172
                           (const_int 2))
173
                  (match_operand:SI 2 "register_operand" "r")))]
174
  "TARGET_ADDX"
175
  "subx2\t%0, %1, %2"
176
  [(set_attr "type"     "arith")
177
   (set_attr "mode"     "SI")
178
   (set_attr "length"   "3")])
179
 
180
(define_insn "*subx4"
181
  [(set (match_operand:SI 0 "register_operand" "=a")
182
        (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
183
                           (const_int 4))
184
                  (match_operand:SI 2 "register_operand" "r")))]
185
  "TARGET_ADDX"
186
  "subx4\t%0, %1, %2"
187
  [(set_attr "type"     "arith")
188
   (set_attr "mode"     "SI")
189
   (set_attr "length"   "3")])
190
 
191
(define_insn "*subx8"
192
  [(set (match_operand:SI 0 "register_operand" "=a")
193
        (minus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
194
                           (const_int 8))
195
                  (match_operand:SI 2 "register_operand" "r")))]
196
  "TARGET_ADDX"
197
  "subx8\t%0, %1, %2"
198
  [(set_attr "type"     "arith")
199
   (set_attr "mode"     "SI")
200
   (set_attr "length"   "3")])
201
 
202
(define_insn "subsf3"
203
  [(set (match_operand:SF 0 "register_operand" "=f")
204
        (minus:SF (match_operand:SF 1 "register_operand" "f")
205
                  (match_operand:SF 2 "register_operand" "f")))]
206
  "TARGET_HARD_FLOAT"
207
  "sub.s\t%0, %1, %2"
208
  [(set_attr "type"     "fmadd")
209
   (set_attr "mode"     "SF")
210
   (set_attr "length"   "3")])
211
 
212
 
213
;; Multiplication.
214
 
215
(define_insn "mulsi3"
216
  [(set (match_operand:SI 0 "register_operand" "=a")
217
        (mult:SI (match_operand:SI 1 "register_operand" "%r")
218
                 (match_operand:SI 2 "register_operand" "r")))]
219
  "TARGET_MUL32"
220
  "mull\t%0, %1, %2"
221
  [(set_attr "type"     "mul32")
222
   (set_attr "mode"     "SI")
223
   (set_attr "length"   "3")])
224
 
225
(define_insn "mulhisi3"
226
  [(set (match_operand:SI 0 "register_operand" "=C,A")
227
        (mult:SI (sign_extend:SI
228
                  (match_operand:HI 1 "register_operand" "%r,r"))
229
                 (sign_extend:SI
230
                  (match_operand:HI 2 "register_operand" "r,r"))))]
231
  "TARGET_MUL16 || TARGET_MAC16"
232
  "@
233
   mul16s\t%0, %1, %2
234
   mul.aa.ll\t%1, %2"
235
  [(set_attr "type"     "mul16,mac16")
236
   (set_attr "mode"     "SI")
237
   (set_attr "length"   "3,3")])
238
 
239
(define_insn "umulhisi3"
240
  [(set (match_operand:SI 0 "register_operand" "=C,A")
241
        (mult:SI (zero_extend:SI
242
                  (match_operand:HI 1 "register_operand" "%r,r"))
243
                 (zero_extend:SI
244
                  (match_operand:HI 2 "register_operand" "r,r"))))]
245
  "TARGET_MUL16 || TARGET_MAC16"
246
  "@
247
   mul16u\t%0, %1, %2
248
   umul.aa.ll\t%1, %2"
249
  [(set_attr "type"     "mul16,mac16")
250
   (set_attr "mode"     "SI")
251
   (set_attr "length"   "3,3")])
252
 
253
(define_insn "muladdhisi"
254
  [(set (match_operand:SI 0 "register_operand" "=A")
255
        (plus:SI (mult:SI (sign_extend:SI
256
                           (match_operand:HI 1 "register_operand" "%r"))
257
                          (sign_extend:SI
258
                           (match_operand:HI 2 "register_operand" "r")))
259
                 (match_operand:SI 3 "register_operand" "0")))]
260
  "TARGET_MAC16"
261
  "mula.aa.ll\t%1, %2"
262
  [(set_attr "type"     "mac16")
263
   (set_attr "mode"     "SI")
264
   (set_attr "length"   "3")])
265
 
266
(define_insn "mulsubhisi"
267
  [(set (match_operand:SI 0 "register_operand" "=A")
268
        (minus:SI (match_operand:SI 1 "register_operand" "0")
269
                  (mult:SI (sign_extend:SI
270
                            (match_operand:HI 2 "register_operand" "%r"))
271
                           (sign_extend:SI
272
                            (match_operand:HI 3 "register_operand" "r")))))]
273
  "TARGET_MAC16"
274
  "muls.aa.ll\t%2, %3"
275
  [(set_attr "type"     "mac16")
276
   (set_attr "mode"     "SI")
277
   (set_attr "length"   "3")])
278
 
279
(define_insn "mulsf3"
280
  [(set (match_operand:SF 0 "register_operand" "=f")
281
        (mult:SF (match_operand:SF 1 "register_operand" "%f")
282
                 (match_operand:SF 2 "register_operand" "f")))]
283
  "TARGET_HARD_FLOAT"
284
  "mul.s\t%0, %1, %2"
285
  [(set_attr "type"     "fmadd")
286
   (set_attr "mode"     "SF")
287
   (set_attr "length"   "3")])
288
 
289
(define_insn "muladdsf3"
290
  [(set (match_operand:SF 0 "register_operand" "=f")
291
        (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
292
                          (match_operand:SF 2 "register_operand" "f"))
293
                 (match_operand:SF 3 "register_operand" "0")))]
294
  "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
295
  "madd.s\t%0, %1, %2"
296
  [(set_attr "type"     "fmadd")
297
   (set_attr "mode"     "SF")
298
   (set_attr "length"   "3")])
299
 
300
(define_insn "mulsubsf3"
301
  [(set (match_operand:SF 0 "register_operand" "=f")
302
        (minus:SF (match_operand:SF 1 "register_operand" "0")
303
                  (mult:SF (match_operand:SF 2 "register_operand" "%f")
304
                           (match_operand:SF 3 "register_operand" "f"))))]
305
  "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
306
  "msub.s\t%0, %2, %3"
307
  [(set_attr "type"     "fmadd")
308
   (set_attr "mode"     "SF")
309
   (set_attr "length"   "3")])
310
 
311
 
312
;; Division.
313
 
314
(define_insn "divsi3"
315
  [(set (match_operand:SI 0 "register_operand" "=a")
316
        (div:SI (match_operand:SI 1 "register_operand" "r")
317
                (match_operand:SI 2 "register_operand" "r")))]
318
  "TARGET_DIV32"
319
  "quos\t%0, %1, %2"
320
  [(set_attr "type"     "div32")
321
   (set_attr "mode"     "SI")
322
   (set_attr "length"   "3")])
323
 
324
(define_insn "udivsi3"
325
  [(set (match_operand:SI 0 "register_operand" "=a")
326
        (udiv:SI (match_operand:SI 1 "register_operand" "r")
327
                 (match_operand:SI 2 "register_operand" "r")))]
328
  "TARGET_DIV32"
329
  "quou\t%0, %1, %2"
330
  [(set_attr "type"     "div32")
331
   (set_attr "mode"     "SI")
332
   (set_attr "length"   "3")])
333
 
334
(define_insn "divsf3"
335
  [(set (match_operand:SF 0 "register_operand" "=f")
336
        (div:SF (match_operand:SF 1 "register_operand" "f")
337
                (match_operand:SF 2 "register_operand" "f")))]
338
  "TARGET_HARD_FLOAT_DIV"
339
  "div.s\t%0, %1, %2"
340
  [(set_attr "type"     "fdiv")
341
   (set_attr "mode"     "SF")
342
   (set_attr "length"   "3")])
343
 
344
(define_insn "*recipsf2"
345
  [(set (match_operand:SF 0 "register_operand" "=f")
346
        (div:SF (match_operand:SF 1 "const_float_1_operand" "")
347
                (match_operand:SF 2 "register_operand" "f")))]
348
  "TARGET_HARD_FLOAT_RECIP && flag_unsafe_math_optimizations"
349
  "recip.s\t%0, %2"
350
  [(set_attr "type"     "fdiv")
351
   (set_attr "mode"     "SF")
352
   (set_attr "length"   "3")])
353
 
354
 
355
;; Remainders.
356
 
357
(define_insn "modsi3"
358
  [(set (match_operand:SI 0 "register_operand" "=a")
359
        (mod:SI (match_operand:SI 1 "register_operand" "r")
360
                (match_operand:SI 2 "register_operand" "r")))]
361
  "TARGET_DIV32"
362
  "rems\t%0, %1, %2"
363
  [(set_attr "type"     "div32")
364
   (set_attr "mode"     "SI")
365
   (set_attr "length"   "3")])
366
 
367
(define_insn "umodsi3"
368
  [(set (match_operand:SI 0 "register_operand" "=a")
369
        (umod:SI (match_operand:SI 1 "register_operand" "r")
370
                 (match_operand:SI 2 "register_operand" "r")))]
371
  "TARGET_DIV32"
372
  "remu\t%0, %1, %2"
373
  [(set_attr "type"     "div32")
374
   (set_attr "mode"     "SI")
375
   (set_attr "length"   "3")])
376
 
377
 
378
;; Square roots.
379
 
380
(define_insn "sqrtsf2"
381
  [(set (match_operand:SF 0 "register_operand" "=f")
382
        (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
383
  "TARGET_HARD_FLOAT_SQRT"
384
  "sqrt.s\t%0, %1"
385
  [(set_attr "type"     "fsqrt")
386
   (set_attr "mode"     "SF")
387
   (set_attr "length"   "3")])
388
 
389
(define_insn "*rsqrtsf2"
390
  [(set (match_operand:SF 0 "register_operand" "=f")
391
        (div:SF (match_operand:SF 1 "const_float_1_operand" "")
392
                (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
393
  "TARGET_HARD_FLOAT_RSQRT && flag_unsafe_math_optimizations"
394
  "rsqrt.s\t%0, %2"
395
  [(set_attr "type"     "fsqrt")
396
   (set_attr "mode"     "SF")
397
   (set_attr "length"   "3")])
398
 
399
 
400
;; Absolute value.
401
 
402
(define_insn "abssi2"
403
  [(set (match_operand:SI 0 "register_operand" "=a")
404
        (abs:SI (match_operand:SI 1 "register_operand" "r")))]
405
  "TARGET_ABS"
406
  "abs\t%0, %1"
407
  [(set_attr "type"     "arith")
408
   (set_attr "mode"     "SI")
409
   (set_attr "length"   "3")])
410
 
411
(define_insn "abssf2"
412
  [(set (match_operand:SF 0 "register_operand" "=f")
413
        (abs:SF (match_operand:SF 1 "register_operand" "f")))]
414
  "TARGET_HARD_FLOAT"
415
  "abs.s\t%0, %1"
416
  [(set_attr "type"     "farith")
417
   (set_attr "mode"     "SF")
418
   (set_attr "length"   "3")])
419
 
420
 
421
;; Min and max.
422
 
423
(define_insn "sminsi3"
424
  [(set (match_operand:SI 0 "register_operand" "=a")
425
        (smin:SI (match_operand:SI 1 "register_operand" "%r")
426
                 (match_operand:SI 2 "register_operand" "r")))]
427
  "TARGET_MINMAX"
428
  "min\t%0, %1, %2"
429
  [(set_attr "type"     "arith")
430
   (set_attr "mode"     "SI")
431
   (set_attr "length"   "3")])
432
 
433
(define_insn "uminsi3"
434
  [(set (match_operand:SI 0 "register_operand" "=a")
435
        (umin:SI (match_operand:SI 1 "register_operand" "%r")
436
                 (match_operand:SI 2 "register_operand" "r")))]
437
  "TARGET_MINMAX"
438
  "minu\t%0, %1, %2"
439
  [(set_attr "type"     "arith")
440
   (set_attr "mode"     "SI")
441
   (set_attr "length"   "3")])
442
 
443
(define_insn "smaxsi3"
444
  [(set (match_operand:SI 0 "register_operand" "=a")
445
        (smax:SI (match_operand:SI 1 "register_operand" "%r")
446
                 (match_operand:SI 2 "register_operand" "r")))]
447
  "TARGET_MINMAX"
448
  "max\t%0, %1, %2"
449
  [(set_attr "type"     "arith")
450
   (set_attr "mode"     "SI")
451
   (set_attr "length"   "3")])
452
 
453
(define_insn "umaxsi3"
454
  [(set (match_operand:SI 0 "register_operand" "=a")
455
        (umax:SI (match_operand:SI 1 "register_operand" "%r")
456
                 (match_operand:SI 2 "register_operand" "r")))]
457
  "TARGET_MINMAX"
458
  "maxu\t%0, %1, %2"
459
  [(set_attr "type"     "arith")
460
   (set_attr "mode"     "SI")
461
   (set_attr "length"   "3")])
462
 
463
 
464
;; Find first bit.
465
 
466
(define_expand "ffssi2"
467
  [(set (match_operand:SI 0 "register_operand" "")
468
        (ffs:SI (match_operand:SI 1 "register_operand" "")))]
469
  "TARGET_NSA"
470
{
471
  rtx temp = gen_reg_rtx (SImode);
472
  emit_insn (gen_negsi2 (temp, operands[1]));
473
  emit_insn (gen_andsi3 (temp, temp, operands[1]));
474
  emit_insn (gen_nsau (temp, temp));
475
  emit_insn (gen_negsi2 (temp, temp));
476
  emit_insn (gen_addsi3 (operands[0], temp, GEN_INT (32)));
477
  DONE;
478
})
479
 
480
;; There is no RTL operator corresponding to NSAU.
481
(define_insn "nsau"
482
  [(set (match_operand:SI 0 "register_operand" "=a")
483
        (unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_NSAU))]
484
  "TARGET_NSA"
485
  "nsau\t%0, %1"
486
  [(set_attr "type"     "arith")
487
   (set_attr "mode"     "SI")
488
   (set_attr "length"   "3")])
489
 
490
 
491
;; Negation and one's complement.
492
 
493
(define_insn "negsi2"
494
  [(set (match_operand:SI 0 "register_operand" "=a")
495
        (neg:SI (match_operand:SI 1 "register_operand" "r")))]
496
  ""
497
  "neg\t%0, %1"
498
  [(set_attr "type"     "arith")
499
   (set_attr "mode"     "SI")
500
   (set_attr "length"   "3")])
501
 
502
(define_expand "one_cmplsi2"
503
  [(set (match_operand:SI 0 "register_operand" "")
504
        (not:SI (match_operand:SI 1 "register_operand" "")))]
505
  ""
506
{
507
  rtx temp = gen_reg_rtx (SImode);
508
  emit_insn (gen_movsi (temp, constm1_rtx));
509
  emit_insn (gen_xorsi3 (operands[0], temp, operands[1]));
510
  DONE;
511
})
512
 
513
(define_insn "negsf2"
514
  [(set (match_operand:SF 0 "register_operand" "=f")
515
        (neg:SF (match_operand:SF 1 "register_operand" "f")))]
516
  "TARGET_HARD_FLOAT"
517
  "neg.s\t%0, %1"
518
  [(set_attr "type"     "farith")
519
   (set_attr "mode"     "SF")
520
   (set_attr "length"   "3")])
521
 
522
 
523
;; Logical instructions.
524
 
525
(define_insn "andsi3"
526
  [(set (match_operand:SI 0 "register_operand" "=a,a")
527
        (and:SI (match_operand:SI 1 "register_operand" "%r,r")
528
                (match_operand:SI 2 "mask_operand" "P,r")))]
529
  ""
530
  "@
531
   extui\t%0, %1, 0, %K2
532
   and\t%0, %1, %2"
533
  [(set_attr "type"     "arith,arith")
534
   (set_attr "mode"     "SI")
535
   (set_attr "length"   "3,3")])
536
 
537
(define_insn "iorsi3"
538
  [(set (match_operand:SI 0 "register_operand" "=a")
539
        (ior:SI (match_operand:SI 1 "register_operand" "%r")
540
                (match_operand:SI 2 "register_operand" "r")))]
541
  ""
542
  "or\t%0, %1, %2"
543
  [(set_attr "type"     "arith")
544
   (set_attr "mode"     "SI")
545
   (set_attr "length"   "3")])
546
 
547
(define_insn "xorsi3"
548
  [(set (match_operand:SI 0 "register_operand" "=a")
549
        (xor:SI (match_operand:SI 1 "register_operand" "%r")
550
                (match_operand:SI 2 "register_operand" "r")))]
551
  ""
552
  "xor\t%0, %1, %2"
553
  [(set_attr "type"     "arith")
554
   (set_attr "mode"     "SI")
555
   (set_attr "length"   "3")])
556
 
557
 
558
;; Zero-extend instructions.
559
 
560
(define_insn "zero_extendhisi2"
561
  [(set (match_operand:SI 0 "register_operand" "=a,a")
562
        (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
563
  ""
564
  "@
565
   extui\t%0, %1, 0, 16
566
   l16ui\t%0, %1"
567
  [(set_attr "type"     "arith,load")
568
   (set_attr "mode"     "SI")
569
   (set_attr "length"   "3,3")])
570
 
571
(define_insn "zero_extendqisi2"
572
  [(set (match_operand:SI 0 "register_operand" "=a,a")
573
        (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
574
  ""
575
  "@
576
   extui\t%0, %1, 0, 8
577
   l8ui\t%0, %1"
578
  [(set_attr "type"     "arith,load")
579
   (set_attr "mode"     "SI")
580
   (set_attr "length"   "3,3")])
581
 
582
 
583
;; Sign-extend instructions.
584
 
585
(define_expand "extendhisi2"
586
  [(set (match_operand:SI 0 "register_operand" "")
587
        (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
588
  ""
589
{
590
  if (sext_operand (operands[1], HImode))
591
    emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
592
  else
593
    xtensa_extend_reg (operands[0], operands[1]);
594
  DONE;
595
})
596
 
597
(define_insn "extendhisi2_internal"
598
  [(set (match_operand:SI 0 "register_operand" "=B,a")
599
        (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
600
  ""
601
  "@
602
   sext\t%0, %1, 15
603
   l16si\t%0, %1"
604
  [(set_attr "type"     "arith,load")
605
   (set_attr "mode"     "SI")
606
   (set_attr "length"   "3,3")])
607
 
608
(define_expand "extendqisi2"
609
  [(set (match_operand:SI 0 "register_operand" "")
610
        (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
611
  ""
612
{
613
  if (TARGET_SEXT)
614
    emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
615
  else
616
    xtensa_extend_reg (operands[0], operands[1]);
617
  DONE;
618
})
619
 
620
(define_insn "extendqisi2_internal"
621
  [(set (match_operand:SI 0 "register_operand" "=B")
622
        (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
623
  "TARGET_SEXT"
624
  "sext\t%0, %1, 7"
625
  [(set_attr "type"     "arith")
626
   (set_attr "mode"     "SI")
627
   (set_attr "length"   "3")])
628
 
629
 
630
;; Field extract instructions.
631
 
632
(define_expand "extv"
633
  [(set (match_operand:SI 0 "register_operand" "")
634
        (sign_extract:SI (match_operand:SI 1 "register_operand" "")
635
                         (match_operand:SI 2 "const_int_operand" "")
636
                         (match_operand:SI 3 "const_int_operand" "")))]
637
  "TARGET_SEXT"
638
{
639
  if (!sext_fldsz_operand (operands[2], SImode))
640
    FAIL;
641
 
642
  /* We could expand to a right shift followed by SEXT but that's
643
     no better than the standard left and right shift sequence.  */
644
  if (!lsbitnum_operand (operands[3], SImode))
645
    FAIL;
646
 
647
  emit_insn (gen_extv_internal (operands[0], operands[1],
648
                                operands[2], operands[3]));
649
  DONE;
650
})
651
 
652
(define_insn "extv_internal"
653
  [(set (match_operand:SI 0 "register_operand" "=a")
654
        (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
655
                         (match_operand:SI 2 "sext_fldsz_operand" "i")
656
                         (match_operand:SI 3 "lsbitnum_operand" "i")))]
657
  "TARGET_SEXT"
658
{
659
  int fldsz = INTVAL (operands[2]);
660
  operands[2] = GEN_INT (fldsz - 1);
661
  return "sext\t%0, %1, %2";
662
}
663
  [(set_attr "type"     "arith")
664
   (set_attr "mode"     "SI")
665
   (set_attr "length"   "3")])
666
 
667
(define_expand "extzv"
668
  [(set (match_operand:SI 0 "register_operand" "")
669
        (zero_extract:SI (match_operand:SI 1 "register_operand" "")
670
                         (match_operand:SI 2 "const_int_operand" "")
671
                         (match_operand:SI 3 "const_int_operand" "")))]
672
  ""
673
{
674
  if (!extui_fldsz_operand (operands[2], SImode))
675
    FAIL;
676
  emit_insn (gen_extzv_internal (operands[0], operands[1],
677
                                 operands[2], operands[3]));
678
  DONE;
679
})
680
 
681
(define_insn "extzv_internal"
682
  [(set (match_operand:SI 0 "register_operand" "=a")
683
        (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
684
                         (match_operand:SI 2 "extui_fldsz_operand" "i")
685
                         (match_operand:SI 3 "const_int_operand" "i")))]
686
  ""
687
{
688
  int shift;
689
  if (BITS_BIG_ENDIAN)
690
    shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
691
  else
692
    shift = INTVAL (operands[3]) & 0x1f;
693
  operands[3] = GEN_INT (shift);
694
  return "extui\t%0, %1, %3, %2";
695
}
696
  [(set_attr "type"     "arith")
697
   (set_attr "mode"     "SI")
698
   (set_attr "length"   "3")])
699
 
700
 
701
;; Conversions.
702
 
703
(define_insn "fix_truncsfsi2"
704
  [(set (match_operand:SI 0 "register_operand" "=a")
705
        (fix:SI (match_operand:SF 1 "register_operand" "f")))]
706
  "TARGET_HARD_FLOAT"
707
  "trunc.s\t%0, %1, 0"
708
  [(set_attr "type"     "fconv")
709
   (set_attr "mode"     "SF")
710
   (set_attr "length"   "3")])
711
 
712
(define_insn "fixuns_truncsfsi2"
713
  [(set (match_operand:SI 0 "register_operand" "=a")
714
        (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
715
  "TARGET_HARD_FLOAT"
716
  "utrunc.s\t%0, %1, 0"
717
  [(set_attr "type"     "fconv")
718
   (set_attr "mode"     "SF")
719
   (set_attr "length"   "3")])
720
 
721
(define_insn "floatsisf2"
722
  [(set (match_operand:SF 0 "register_operand" "=f")
723
        (float:SF (match_operand:SI 1 "register_operand" "a")))]
724
  "TARGET_HARD_FLOAT"
725
  "float.s\t%0, %1, 0"
726
  [(set_attr "type"     "fconv")
727
   (set_attr "mode"     "SF")
728
   (set_attr "length"   "3")])
729
 
730
(define_insn "floatunssisf2"
731
  [(set (match_operand:SF 0 "register_operand" "=f")
732
        (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
733
  "TARGET_HARD_FLOAT"
734
  "ufloat.s\t%0, %1, 0"
735
  [(set_attr "type"     "fconv")
736
   (set_attr "mode"     "SF")
737
   (set_attr "length"   "3")])
738
 
739
 
740
;; Data movement instructions.
741
 
742
;; 64-bit Integer moves
743
 
744
(define_expand "movdi"
745
  [(set (match_operand:DI 0 "nonimmed_operand" "")
746
        (match_operand:DI 1 "general_operand" ""))]
747
  ""
748
{
749
  if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
750
    operands[1] = force_const_mem (DImode, operands[1]);
751
 
752
  if (!register_operand (operands[0], DImode)
753
      && !register_operand (operands[1], DImode))
754
    operands[1] = force_reg (DImode, operands[1]);
755
 
756
  operands[1] = xtensa_copy_incoming_a7 (operands[1]);
757
})
758
 
759
(define_insn_and_split "movdi_internal"
760
  [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
761
        (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
762
  "register_operand (operands[0], DImode)
763
   || register_operand (operands[1], DImode)"
764
  "#"
765
  "reload_completed"
766
  [(set (match_dup 0) (match_dup 2))
767
   (set (match_dup 1) (match_dup 3))]
768
{
769
  xtensa_split_operand_pair (operands, SImode);
770
  if (reg_overlap_mentioned_p (operands[0], operands[3]))
771
    {
772
      rtx tmp;
773
      tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
774
      tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
775
    }
776
})
777
 
778
;; 32-bit Integer moves
779
 
780
(define_expand "movsi"
781
  [(set (match_operand:SI 0 "nonimmed_operand" "")
782
        (match_operand:SI 1 "general_operand" ""))]
783
  ""
784
{
785
  if (xtensa_emit_move_sequence (operands, SImode))
786
    DONE;
787
})
788
 
789
(define_insn "movsi_internal"
790
  [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,W,a,a,U,*a,*A")
791
        (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,i,T,U,r,*A,*r"))]
792
  "xtensa_valid_move (SImode, operands)"
793
  "@
794
   movi.n\t%0, %x1
795
   mov.n\t%0, %1
796
   mov.n\t%0, %1
797
   %v1l32i.n\t%0, %1
798
   %v0s32i.n\t%1, %0
799
   %v0s32i.n\t%1, %0
800
   mov\t%0, %1
801
   movsp\t%0, %1
802
   movi\t%0, %x1
803
   const16\t%0, %t1\;const16\t%0, %b1
804
   %v1l32r\t%0, %1
805
   %v1l32i\t%0, %1
806
   %v0s32i\t%1, %0
807
   rsr\t%0, ACCLO
808
   wsr\t%1, ACCLO"
809
  [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,load,load,store,rsr,wsr")
810
   (set_attr "mode"     "SI")
811
   (set_attr "length"   "2,2,2,2,2,2,3,3,3,6,3,3,3,3,3")])
812
 
813
;; 16-bit Integer moves
814
 
815
(define_expand "movhi"
816
  [(set (match_operand:HI 0 "nonimmed_operand" "")
817
        (match_operand:HI 1 "general_operand" ""))]
818
  ""
819
{
820
  if (xtensa_emit_move_sequence (operands, HImode))
821
    DONE;
822
})
823
 
824
(define_insn "movhi_internal"
825
  [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
826
        (match_operand:HI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
827
  "xtensa_valid_move (HImode, operands)"
828
  "@
829
   movi.n\t%0, %x1
830
   mov.n\t%0, %1
831
   mov\t%0, %1
832
   movi\t%0, %x1
833
   %v1l16ui\t%0, %1
834
   %v0s16i\t%1, %0
835
   rsr\t%0, ACCLO
836
   wsr\t%1, ACCLO"
837
  [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
838
   (set_attr "mode"     "HI")
839
   (set_attr "length"   "2,2,3,3,3,3,3,3")])
840
 
841
;; 8-bit Integer moves
842
 
843
(define_expand "movqi"
844
  [(set (match_operand:QI 0 "nonimmed_operand" "")
845
        (match_operand:QI 1 "general_operand" ""))]
846
  ""
847
{
848
  if (xtensa_emit_move_sequence (operands, QImode))
849
    DONE;
850
})
851
 
852
(define_insn "movqi_internal"
853
  [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
854
        (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
855
  "xtensa_valid_move (QImode, operands)"
856
  "@
857
   movi.n\t%0, %x1
858
   mov.n\t%0, %1
859
   mov\t%0, %1
860
   movi\t%0, %x1
861
   %v1l8ui\t%0, %1
862
   %v0s8i\t%1, %0
863
   rsr\t%0, ACCLO
864
   wsr\t%1, ACCLO"
865
  [(set_attr "type"     "move,move,move,move,load,store,rsr,wsr")
866
   (set_attr "mode"     "QI")
867
   (set_attr "length"   "2,2,3,3,3,3,3,3")])
868
 
869
;; 32-bit floating point moves
870
 
871
(define_expand "movsf"
872
  [(set (match_operand:SF 0 "nonimmed_operand" "")
873
        (match_operand:SF 1 "general_operand" ""))]
874
  ""
875
{
876
  if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
877
    operands[1] = force_const_mem (SFmode, operands[1]);
878
 
879
  if ((!register_operand (operands[0], SFmode)
880
       && !register_operand (operands[1], SFmode))
881
      || (FP_REG_P (xt_true_regnum (operands[0]))
882
          && !(reload_in_progress | reload_completed)
883
          && (constantpool_mem_p (operands[1])
884
              || CONSTANT_P (operands[1]))))
885
    operands[1] = force_reg (SFmode, operands[1]);
886
 
887
  operands[1] = xtensa_copy_incoming_a7 (operands[1]);
888
})
889
 
890
(define_insn "movsf_internal"
891
  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
892
        (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
893
  "((register_operand (operands[0], SFmode)
894
     || register_operand (operands[1], SFmode))
895
    && !(FP_REG_P (xt_true_regnum (operands[0]))
896
         && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
897
  "@
898
   mov.s\t%0, %1
899
   %v1lsi\t%0, %1
900
   %v0ssi\t%1, %0
901
   mov.n\t%0, %1
902
   %v1l32i.n\t%0, %1
903
   %v0s32i.n\t%1, %0
904
   mov\t%0, %1
905
   wfr\t%0, %1
906
   rfr\t%0, %1
907
   const16\t%0, %t1\;const16\t%0, %b1
908
   %v1l32r\t%0, %1
909
   %v1l32i\t%0, %1
910
   %v0s32i\t%1, %0"
911
  [(set_attr "type"     "farith,fload,fstore,move,load,store,move,farith,farith,move,load,load,store")
912
   (set_attr "mode"     "SF")
913
   (set_attr "length"   "3,3,3,2,2,2,3,3,3,6,3,3,3")])
914
 
915
(define_insn "*lsiu"
916
  [(set (match_operand:SF 0 "register_operand" "=f")
917
        (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
918
                         (match_operand:SI 2 "fpmem_offset_operand" "i"))))
919
   (set (match_dup 1)
920
        (plus:SI (match_dup 1) (match_dup 2)))]
921
  "TARGET_HARD_FLOAT"
922
{
923
  if (volatile_refs_p (PATTERN (insn)))
924
    output_asm_insn ("memw", operands);
925
  return "lsiu\t%0, %1, %2";
926
}
927
  [(set_attr "type"     "fload")
928
   (set_attr "mode"     "SF")
929
   (set_attr "length"   "3")])
930
 
931
(define_insn "*ssiu"
932
  [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
933
                         (match_operand:SI 1 "fpmem_offset_operand" "i")))
934
        (match_operand:SF 2 "register_operand" "f"))
935
   (set (match_dup 0)
936
        (plus:SI (match_dup 0) (match_dup 1)))]
937
  "TARGET_HARD_FLOAT"
938
{
939
  if (volatile_refs_p (PATTERN (insn)))
940
    output_asm_insn ("memw", operands);
941
  return "ssiu\t%2, %0, %1";
942
}
943
  [(set_attr "type"     "fstore")
944
   (set_attr "mode"     "SF")
945
   (set_attr "length"   "3")])
946
 
947
;; 64-bit floating point moves
948
 
949
(define_expand "movdf"
950
  [(set (match_operand:DF 0 "nonimmed_operand" "")
951
        (match_operand:DF 1 "general_operand" ""))]
952
  ""
953
{
954
  if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
955
    operands[1] = force_const_mem (DFmode, operands[1]);
956
 
957
  if (!register_operand (operands[0], DFmode)
958
      && !register_operand (operands[1], DFmode))
959
    operands[1] = force_reg (DFmode, operands[1]);
960
 
961
  operands[1] = xtensa_copy_incoming_a7 (operands[1]);
962
})
963
 
964
(define_insn_and_split "movdf_internal"
965
  [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
966
        (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
967
  "register_operand (operands[0], DFmode)
968
   || register_operand (operands[1], DFmode)"
969
  "#"
970
  "reload_completed"
971
  [(set (match_dup 0) (match_dup 2))
972
   (set (match_dup 1) (match_dup 3))]
973
{
974
  xtensa_split_operand_pair (operands, SFmode);
975
  if (reg_overlap_mentioned_p (operands[0], operands[3]))
976
    {
977
      rtx tmp;
978
      tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
979
      tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
980
    }
981
})
982
 
983
;; Block moves
984
 
985
(define_expand "movmemsi"
986
  [(parallel [(set (match_operand:BLK 0 "" "")
987
                   (match_operand:BLK 1 "" ""))
988
              (use (match_operand:SI 2 "arith_operand" ""))
989
              (use (match_operand:SI 3 "const_int_operand" ""))])]
990
  ""
991
{
992
  if (!xtensa_expand_block_move (operands))
993
    FAIL;
994
  DONE;
995
})
996
 
997
 
998
;; Shift instructions.
999
 
1000
(define_expand "ashlsi3"
1001
  [(set (match_operand:SI 0 "register_operand" "")
1002
        (ashift:SI (match_operand:SI 1 "register_operand" "")
1003
                   (match_operand:SI 2 "arith_operand" "")))]
1004
  ""
1005
{
1006
  operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1007
})
1008
 
1009
(define_insn "ashlsi3_internal"
1010
  [(set (match_operand:SI 0 "register_operand" "=a,a")
1011
        (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1012
                   (match_operand:SI 2 "arith_operand" "J,r")))]
1013
  ""
1014
  "@
1015
   slli\t%0, %1, %R2
1016
   ssl\t%2\;sll\t%0, %1"
1017
  [(set_attr "type"     "arith,arith")
1018
   (set_attr "mode"     "SI")
1019
   (set_attr "length"   "3,6")])
1020
 
1021
(define_insn "ashrsi3"
1022
  [(set (match_operand:SI 0 "register_operand" "=a,a")
1023
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1024
                     (match_operand:SI 2 "arith_operand" "J,r")))]
1025
  ""
1026
  "@
1027
   srai\t%0, %1, %R2
1028
   ssr\t%2\;sra\t%0, %1"
1029
  [(set_attr "type"     "arith,arith")
1030
   (set_attr "mode"     "SI")
1031
   (set_attr "length"   "3,6")])
1032
 
1033
(define_insn "lshrsi3"
1034
  [(set (match_operand:SI 0 "register_operand" "=a,a")
1035
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1036
                     (match_operand:SI 2 "arith_operand" "J,r")))]
1037
  ""
1038
{
1039
  if (which_alternative == 0)
1040
    {
1041
      if ((INTVAL (operands[2]) & 0x1f) < 16)
1042
        return "srli\t%0, %1, %R2";
1043
      else
1044
        return "extui\t%0, %1, %R2, %L2";
1045
    }
1046
  return "ssr\t%2\;srl\t%0, %1";
1047
}
1048
  [(set_attr "type"     "arith,arith")
1049
   (set_attr "mode"     "SI")
1050
   (set_attr "length"   "3,6")])
1051
 
1052
(define_insn "rotlsi3"
1053
  [(set (match_operand:SI 0 "register_operand" "=a,a")
1054
        (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1055
                     (match_operand:SI 2 "arith_operand" "J,r")))]
1056
  ""
1057
  "@
1058
   ssai\t%L2\;src\t%0, %1, %1
1059
   ssl\t%2\;src\t%0, %1, %1"
1060
  [(set_attr "type"     "multi,multi")
1061
   (set_attr "mode"     "SI")
1062
   (set_attr "length"   "6,6")])
1063
 
1064
(define_insn "rotrsi3"
1065
  [(set (match_operand:SI 0 "register_operand" "=a,a")
1066
        (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1067
                     (match_operand:SI 2 "arith_operand" "J,r")))]
1068
  ""
1069
  "@
1070
   ssai\t%R2\;src\t%0, %1, %1
1071
   ssr\t%2\;src\t%0, %1, %1"
1072
  [(set_attr "type"     "multi,multi")
1073
   (set_attr "mode"     "SI")
1074
   (set_attr "length"   "6,6")])
1075
 
1076
 
1077
;; Comparisons.
1078
 
1079
;; Handle comparisons by stashing away the operands and then using that
1080
;; information in the subsequent conditional branch.
1081
 
1082
(define_expand "cmpsi"
1083
  [(set (cc0)
1084
        (compare:CC (match_operand:SI 0 "register_operand" "")
1085
                    (match_operand:SI 1 "nonmemory_operand" "")))]
1086
  ""
1087
{
1088
  branch_cmp[0] = operands[0];
1089
  branch_cmp[1] = operands[1];
1090
  branch_type = CMP_SI;
1091
  DONE;
1092
})
1093
 
1094
(define_expand "tstsi"
1095
  [(set (cc0)
1096
        (match_operand:SI 0 "register_operand" ""))]
1097
  ""
1098
{
1099
  branch_cmp[0] = operands[0];
1100
  branch_cmp[1] = const0_rtx;
1101
  branch_type = CMP_SI;
1102
  DONE;
1103
})
1104
 
1105
(define_expand "cmpsf"
1106
  [(set (cc0)
1107
        (compare:CC (match_operand:SF 0 "register_operand" "")
1108
                    (match_operand:SF 1 "register_operand" "")))]
1109
  "TARGET_HARD_FLOAT"
1110
{
1111
  branch_cmp[0] = operands[0];
1112
  branch_cmp[1] = operands[1];
1113
  branch_type = CMP_SF;
1114
  DONE;
1115
})
1116
 
1117
 
1118
;; Conditional branches.
1119
 
1120
(define_expand "beq"
1121
  [(set (pc)
1122
        (if_then_else (eq (cc0) (const_int 0))
1123
                      (label_ref (match_operand 0 "" ""))
1124
                      (pc)))]
1125
  ""
1126
{
1127
  xtensa_expand_conditional_branch (operands, EQ);
1128
  DONE;
1129
})
1130
 
1131
(define_expand "bne"
1132
  [(set (pc)
1133
        (if_then_else (ne (cc0) (const_int 0))
1134
                      (label_ref (match_operand 0 "" ""))
1135
                      (pc)))]
1136
  ""
1137
{
1138
  xtensa_expand_conditional_branch (operands, NE);
1139
  DONE;
1140
})
1141
 
1142
(define_expand "bgt"
1143
  [(set (pc)
1144
        (if_then_else (gt (cc0) (const_int 0))
1145
                      (label_ref (match_operand 0 "" ""))
1146
                      (pc)))]
1147
  ""
1148
{
1149
  xtensa_expand_conditional_branch (operands, GT);
1150
  DONE;
1151
})
1152
 
1153
(define_expand "bge"
1154
  [(set (pc)
1155
        (if_then_else (ge (cc0) (const_int 0))
1156
                      (label_ref (match_operand 0 "" ""))
1157
                      (pc)))]
1158
  ""
1159
{
1160
  xtensa_expand_conditional_branch (operands, GE);
1161
  DONE;
1162
})
1163
 
1164
(define_expand "blt"
1165
  [(set (pc)
1166
        (if_then_else (lt (cc0) (const_int 0))
1167
                      (label_ref (match_operand 0 "" ""))
1168
                      (pc)))]
1169
  ""
1170
{
1171
  xtensa_expand_conditional_branch (operands, LT);
1172
  DONE;
1173
})
1174
 
1175
(define_expand "ble"
1176
  [(set (pc)
1177
        (if_then_else (le (cc0) (const_int 0))
1178
                      (label_ref (match_operand 0 "" ""))
1179
                      (pc)))]
1180
  ""
1181
{
1182
  xtensa_expand_conditional_branch (operands, LE);
1183
  DONE;
1184
})
1185
 
1186
(define_expand "bgtu"
1187
  [(set (pc)
1188
        (if_then_else (gtu (cc0) (const_int 0))
1189
                      (label_ref (match_operand 0 "" ""))
1190
                      (pc)))]
1191
  ""
1192
{
1193
  xtensa_expand_conditional_branch (operands, GTU);
1194
  DONE;
1195
})
1196
 
1197
(define_expand "bgeu"
1198
  [(set (pc)
1199
        (if_then_else (geu (cc0) (const_int 0))
1200
                      (label_ref (match_operand 0 "" ""))
1201
                      (pc)))]
1202
  ""
1203
{
1204
  xtensa_expand_conditional_branch (operands, GEU);
1205
  DONE;
1206
})
1207
 
1208
(define_expand "bltu"
1209
  [(set (pc)
1210
        (if_then_else (ltu (cc0) (const_int 0))
1211
                      (label_ref (match_operand 0 "" ""))
1212
                      (pc)))]
1213
  ""
1214
{
1215
  xtensa_expand_conditional_branch (operands, LTU);
1216
  DONE;
1217
})
1218
 
1219
(define_expand "bleu"
1220
  [(set (pc)
1221
        (if_then_else (leu (cc0) (const_int 0))
1222
                      (label_ref (match_operand 0 "" ""))
1223
                      (pc)))]
1224
  ""
1225
{
1226
  xtensa_expand_conditional_branch (operands, LEU);
1227
  DONE;
1228
})
1229
 
1230
;; Branch patterns for standard integer comparisons
1231
 
1232
(define_insn "*btrue"
1233
  [(set (pc)
1234
        (if_then_else (match_operator 3 "branch_operator"
1235
                         [(match_operand:SI 0 "register_operand" "r,r")
1236
                          (match_operand:SI 1 "branch_operand" "K,r")])
1237
                      (label_ref (match_operand 2 "" ""))
1238
                      (pc)))]
1239
  ""
1240
{
1241
  if (which_alternative == 1)
1242
    {
1243
      switch (GET_CODE (operands[3]))
1244
        {
1245
        case EQ:        return "beq\t%0, %1, %2";
1246
        case NE:        return "bne\t%0, %1, %2";
1247
        case LT:        return "blt\t%0, %1, %2";
1248
        case GE:        return "bge\t%0, %1, %2";
1249
        default:        gcc_unreachable ();
1250
        }
1251
    }
1252
  else if (INTVAL (operands[1]) == 0)
1253
    {
1254
      switch (GET_CODE (operands[3]))
1255
        {
1256
        case EQ:        return (TARGET_DENSITY
1257
                                ? "beqz.n\t%0, %2"
1258
                                : "beqz\t%0, %2");
1259
        case NE:        return (TARGET_DENSITY
1260
                                ? "bnez.n\t%0, %2"
1261
                                : "bnez\t%0, %2");
1262
        case LT:        return "bltz\t%0, %2";
1263
        case GE:        return "bgez\t%0, %2";
1264
        default:        gcc_unreachable ();
1265
        }
1266
    }
1267
  else
1268
    {
1269
      switch (GET_CODE (operands[3]))
1270
        {
1271
        case EQ:        return "beqi\t%0, %d1, %2";
1272
        case NE:        return "bnei\t%0, %d1, %2";
1273
        case LT:        return "blti\t%0, %d1, %2";
1274
        case GE:        return "bgei\t%0, %d1, %2";
1275
        default:        gcc_unreachable ();
1276
        }
1277
    }
1278
  gcc_unreachable ();
1279
}
1280
  [(set_attr "type"     "jump,jump")
1281
   (set_attr "mode"     "none")
1282
   (set_attr "length"   "3,3")])
1283
 
1284
(define_insn "*bfalse"
1285
  [(set (pc)
1286
        (if_then_else (match_operator 3 "branch_operator"
1287
                         [(match_operand:SI 0 "register_operand" "r,r")
1288
                          (match_operand:SI 1 "branch_operand" "K,r")])
1289
                      (pc)
1290
                      (label_ref (match_operand 2 "" ""))))]
1291
  ""
1292
{
1293
  if (which_alternative == 1)
1294
    {
1295
      switch (GET_CODE (operands[3]))
1296
        {
1297
        case EQ:        return "bne\t%0, %1, %2";
1298
        case NE:        return "beq\t%0, %1, %2";
1299
        case LT:        return "bge\t%0, %1, %2";
1300
        case GE:        return "blt\t%0, %1, %2";
1301
        default:        gcc_unreachable ();
1302
        }
1303
    }
1304
  else if (INTVAL (operands[1]) == 0)
1305
    {
1306
      switch (GET_CODE (operands[3]))
1307
        {
1308
        case EQ:        return (TARGET_DENSITY
1309
                                ? "bnez.n\t%0, %2"
1310
                                : "bnez\t%0, %2");
1311
        case NE:        return (TARGET_DENSITY
1312
                                ? "beqz.n\t%0, %2"
1313
                                : "beqz\t%0, %2");
1314
        case LT:        return "bgez\t%0, %2";
1315
        case GE:        return "bltz\t%0, %2";
1316
        default:        gcc_unreachable ();
1317
        }
1318
    }
1319
  else
1320
    {
1321
      switch (GET_CODE (operands[3]))
1322
        {
1323
        case EQ:        return "bnei\t%0, %d1, %2";
1324
        case NE:        return "beqi\t%0, %d1, %2";
1325
        case LT:        return "bgei\t%0, %d1, %2";
1326
        case GE:        return "blti\t%0, %d1, %2";
1327
        default:        gcc_unreachable ();
1328
        }
1329
    }
1330
  gcc_unreachable ();
1331
}
1332
  [(set_attr "type"     "jump,jump")
1333
   (set_attr "mode"     "none")
1334
   (set_attr "length"   "3,3")])
1335
 
1336
(define_insn "*ubtrue"
1337
  [(set (pc)
1338
        (if_then_else (match_operator 3 "ubranch_operator"
1339
                         [(match_operand:SI 0 "register_operand" "r,r")
1340
                          (match_operand:SI 1 "ubranch_operand" "L,r")])
1341
                      (label_ref (match_operand 2 "" ""))
1342
                      (pc)))]
1343
  ""
1344
{
1345
  if (which_alternative == 1)
1346
    {
1347
      switch (GET_CODE (operands[3]))
1348
        {
1349
        case LTU:       return "bltu\t%0, %1, %2";
1350
        case GEU:       return "bgeu\t%0, %1, %2";
1351
        default:        gcc_unreachable ();
1352
        }
1353
    }
1354
  else
1355
    {
1356
      switch (GET_CODE (operands[3]))
1357
        {
1358
        case LTU:       return "bltui\t%0, %d1, %2";
1359
        case GEU:       return "bgeui\t%0, %d1, %2";
1360
        default:        gcc_unreachable ();
1361
        }
1362
    }
1363
  gcc_unreachable ();
1364
}
1365
  [(set_attr "type"     "jump,jump")
1366
   (set_attr "mode"     "none")
1367
   (set_attr "length"   "3,3")])
1368
 
1369
(define_insn "*ubfalse"
1370
  [(set (pc)
1371
        (if_then_else (match_operator 3 "ubranch_operator"
1372
                         [(match_operand:SI 0 "register_operand" "r,r")
1373
                          (match_operand:SI 1 "ubranch_operand" "L,r")])
1374
                      (pc)
1375
                      (label_ref (match_operand 2 "" ""))))]
1376
  ""
1377
{
1378
  if (which_alternative == 1)
1379
    {
1380
      switch (GET_CODE (operands[3]))
1381
        {
1382
        case LTU:       return "bgeu\t%0, %1, %2";
1383
        case GEU:       return "bltu\t%0, %1, %2";
1384
        default:        gcc_unreachable ();
1385
        }
1386
    }
1387
  else
1388
    {
1389
      switch (GET_CODE (operands[3]))
1390
        {
1391
        case LTU:       return "bgeui\t%0, %d1, %2";
1392
        case GEU:       return "bltui\t%0, %d1, %2";
1393
        default:        gcc_unreachable ();
1394
        }
1395
    }
1396
  gcc_unreachable ();
1397
}
1398
  [(set_attr "type"     "jump,jump")
1399
   (set_attr "mode"     "none")
1400
   (set_attr "length"   "3,3")])
1401
 
1402
;; Branch patterns for bit testing
1403
 
1404
(define_insn "*bittrue"
1405
  [(set (pc)
1406
        (if_then_else (match_operator 3 "boolean_operator"
1407
                        [(zero_extract:SI
1408
                            (match_operand:SI 0 "register_operand" "r,r")
1409
                            (const_int 1)
1410
                            (match_operand:SI 1 "arith_operand" "J,r"))
1411
                         (const_int 0)])
1412
                      (label_ref (match_operand 2 "" ""))
1413
                      (pc)))]
1414
  ""
1415
{
1416
  if (which_alternative == 0)
1417
    {
1418
      unsigned bitnum = INTVAL(operands[1]) & 0x1f;
1419
      operands[1] = GEN_INT(bitnum);
1420
      switch (GET_CODE (operands[3]))
1421
        {
1422
        case EQ:        return "bbci\t%0, %d1, %2";
1423
        case NE:        return "bbsi\t%0, %d1, %2";
1424
        default:        gcc_unreachable ();
1425
        }
1426
    }
1427
  else
1428
    {
1429
      switch (GET_CODE (operands[3]))
1430
        {
1431
        case EQ:        return "bbc\t%0, %1, %2";
1432
        case NE:        return "bbs\t%0, %1, %2";
1433
        default:        gcc_unreachable ();
1434
        }
1435
    }
1436
  gcc_unreachable ();
1437
}
1438
  [(set_attr "type"     "jump")
1439
   (set_attr "mode"     "none")
1440
   (set_attr "length"   "3")])
1441
 
1442
(define_insn "*bitfalse"
1443
  [(set (pc)
1444
        (if_then_else (match_operator 3 "boolean_operator"
1445
                        [(zero_extract:SI
1446
                            (match_operand:SI 0 "register_operand" "r,r")
1447
                            (const_int 1)
1448
                            (match_operand:SI 1 "arith_operand" "J,r"))
1449
                         (const_int 0)])
1450
                      (pc)
1451
                      (label_ref (match_operand 2 "" ""))))]
1452
  ""
1453
{
1454
  if (which_alternative == 0)
1455
    {
1456
      unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1457
      operands[1] = GEN_INT (bitnum);
1458
      switch (GET_CODE (operands[3]))
1459
        {
1460
        case EQ:        return "bbsi\t%0, %d1, %2";
1461
        case NE:        return "bbci\t%0, %d1, %2";
1462
        default:        gcc_unreachable ();
1463
        }
1464
    }
1465
  else
1466
    {
1467
      switch (GET_CODE (operands[3]))
1468
        {
1469
        case EQ:        return "bbs\t%0, %1, %2";
1470
        case NE:        return "bbc\t%0, %1, %2";
1471
        default:        gcc_unreachable ();
1472
        }
1473
    }
1474
  gcc_unreachable ();
1475
}
1476
  [(set_attr "type"     "jump")
1477
   (set_attr "mode"     "none")
1478
   (set_attr "length"   "3")])
1479
 
1480
(define_insn "*masktrue"
1481
  [(set (pc)
1482
        (if_then_else (match_operator 3 "boolean_operator"
1483
                 [(and:SI (match_operand:SI 0 "register_operand" "r")
1484
                          (match_operand:SI 1 "register_operand" "r"))
1485
                  (const_int 0)])
1486
                      (label_ref (match_operand 2 "" ""))
1487
                      (pc)))]
1488
  ""
1489
{
1490
  switch (GET_CODE (operands[3]))
1491
    {
1492
    case EQ:            return "bnone\t%0, %1, %2";
1493
    case NE:            return "bany\t%0, %1, %2";
1494
    default:            gcc_unreachable ();
1495
    }
1496
}
1497
  [(set_attr "type"     "jump")
1498
   (set_attr "mode"     "none")
1499
   (set_attr "length"   "3")])
1500
 
1501
(define_insn "*maskfalse"
1502
  [(set (pc)
1503
        (if_then_else (match_operator 3 "boolean_operator"
1504
                 [(and:SI (match_operand:SI 0 "register_operand" "r")
1505
                          (match_operand:SI 1 "register_operand" "r"))
1506
                  (const_int 0)])
1507
                      (pc)
1508
                      (label_ref (match_operand 2 "" ""))))]
1509
  ""
1510
{
1511
  switch (GET_CODE (operands[3]))
1512
    {
1513
    case EQ:            return "bany\t%0, %1, %2";
1514
    case NE:            return "bnone\t%0, %1, %2";
1515
    default:            gcc_unreachable ();
1516
    }
1517
}
1518
  [(set_attr "type"     "jump")
1519
   (set_attr "mode"     "none")
1520
   (set_attr "length"   "3")])
1521
 
1522
 
1523
;; Define the loop insns used by bct optimization to represent the
1524
;; start and end of a zero-overhead loop (in loop.c).  This start
1525
;; template generates the loop insn; the end template doesn't generate
1526
;; any instructions since loop end is handled in hardware.
1527
 
1528
(define_insn "zero_cost_loop_start"
1529
  [(set (pc)
1530
        (if_then_else (eq (match_operand:SI 0 "register_operand" "a")
1531
                          (const_int 0))
1532
                      (label_ref (match_operand 1 "" ""))
1533
                      (pc)))
1534
   (set (reg:SI 19)
1535
        (plus:SI (match_dup 0) (const_int -1)))]
1536
  ""
1537
  "loopnez\t%0, %l1"
1538
  [(set_attr "type"     "jump")
1539
   (set_attr "mode"     "none")
1540
   (set_attr "length"   "3")])
1541
 
1542
(define_insn "zero_cost_loop_end"
1543
  [(set (pc)
1544
        (if_then_else (ne (reg:SI 19) (const_int 0))
1545
                      (label_ref (match_operand 0 "" ""))
1546
                      (pc)))
1547
   (set (reg:SI 19)
1548
        (plus:SI (reg:SI 19) (const_int -1)))]
1549
  ""
1550
{
1551
    xtensa_emit_loop_end (insn, operands);
1552
    return "";
1553
}
1554
  [(set_attr "type"     "jump")
1555
   (set_attr "mode"     "none")
1556
   (set_attr "length"   "0")])
1557
 
1558
 
1559
;; Setting a register from a comparison.
1560
 
1561
(define_expand "seq"
1562
  [(set (match_operand:SI 0 "register_operand" "")
1563
        (match_dup 1))]
1564
  ""
1565
{
1566
  operands[1] = gen_rtx_EQ (SImode, branch_cmp[0], branch_cmp[1]);
1567
  if (!xtensa_expand_scc (operands))
1568
    FAIL;
1569
  DONE;
1570
})
1571
 
1572
(define_expand "sne"
1573
  [(set (match_operand:SI 0 "register_operand" "")
1574
        (match_dup 1))]
1575
  ""
1576
{
1577
  operands[1] = gen_rtx_NE (SImode, branch_cmp[0], branch_cmp[1]);
1578
  if (!xtensa_expand_scc (operands))
1579
    FAIL;
1580
  DONE;
1581
})
1582
 
1583
(define_expand "sgt"
1584
  [(set (match_operand:SI 0 "register_operand" "")
1585
        (match_dup 1))]
1586
  ""
1587
{
1588
  operands[1] = gen_rtx_GT (SImode, branch_cmp[0], branch_cmp[1]);
1589
  if (!xtensa_expand_scc (operands))
1590
    FAIL;
1591
  DONE;
1592
})
1593
 
1594
(define_expand "sge"
1595
  [(set (match_operand:SI 0 "register_operand" "")
1596
        (match_dup 1))]
1597
  ""
1598
{
1599
  operands[1] = gen_rtx_GE (SImode, branch_cmp[0], branch_cmp[1]);
1600
  if (!xtensa_expand_scc (operands))
1601
    FAIL;
1602
  DONE;
1603
})
1604
 
1605
(define_expand "slt"
1606
  [(set (match_operand:SI 0 "register_operand" "")
1607
        (match_dup 1))]
1608
  ""
1609
{
1610
  operands[1] = gen_rtx_LT (SImode, branch_cmp[0], branch_cmp[1]);
1611
  if (!xtensa_expand_scc (operands))
1612
    FAIL;
1613
  DONE;
1614
})
1615
 
1616
(define_expand "sle"
1617
  [(set (match_operand:SI 0 "register_operand" "")
1618
        (match_dup 1))]
1619
  ""
1620
{
1621
  operands[1] = gen_rtx_LE (SImode, branch_cmp[0], branch_cmp[1]);
1622
  if (!xtensa_expand_scc (operands))
1623
    FAIL;
1624
  DONE;
1625
})
1626
 
1627
 
1628
;; Conditional moves.
1629
 
1630
(define_expand "movsicc"
1631
  [(set (match_operand:SI 0 "register_operand" "")
1632
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
1633
                         (match_operand:SI 2 "register_operand" "")
1634
                         (match_operand:SI 3 "register_operand" "")))]
1635
  ""
1636
{
1637
  if (!xtensa_expand_conditional_move (operands, 0))
1638
    FAIL;
1639
  DONE;
1640
})
1641
 
1642
(define_expand "movsfcc"
1643
  [(set (match_operand:SF 0 "register_operand" "")
1644
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
1645
                         (match_operand:SF 2 "register_operand" "")
1646
                         (match_operand:SF 3 "register_operand" "")))]
1647
  ""
1648
{
1649
  if (!xtensa_expand_conditional_move (operands, 1))
1650
    FAIL;
1651
  DONE;
1652
})
1653
 
1654
(define_insn "movsicc_internal0"
1655
  [(set (match_operand:SI 0 "register_operand" "=a,a")
1656
        (if_then_else:SI (match_operator 4 "branch_operator"
1657
                           [(match_operand:SI 1 "register_operand" "r,r")
1658
                            (const_int 0)])
1659
                         (match_operand:SI 2 "register_operand" "r,0")
1660
                         (match_operand:SI 3 "register_operand" "0,r")))]
1661
  ""
1662
{
1663
  if (which_alternative == 0)
1664
    {
1665
      switch (GET_CODE (operands[4]))
1666
        {
1667
        case EQ:        return "moveqz\t%0, %2, %1";
1668
        case NE:        return "movnez\t%0, %2, %1";
1669
        case LT:        return "movltz\t%0, %2, %1";
1670
        case GE:        return "movgez\t%0, %2, %1";
1671
        default:        gcc_unreachable ();
1672
        }
1673
    }
1674
  else
1675
    {
1676
      switch (GET_CODE (operands[4]))
1677
        {
1678
        case EQ:        return "movnez\t%0, %3, %1";
1679
        case NE:        return "moveqz\t%0, %3, %1";
1680
        case LT:        return "movgez\t%0, %3, %1";
1681
        case GE:        return "movltz\t%0, %3, %1";
1682
        default:        gcc_unreachable ();
1683
        }
1684
    }
1685
  gcc_unreachable ();
1686
}
1687
  [(set_attr "type"     "move,move")
1688
   (set_attr "mode"     "SI")
1689
   (set_attr "length"   "3,3")])
1690
 
1691
(define_insn "movsicc_internal1"
1692
  [(set (match_operand:SI 0 "register_operand" "=a,a")
1693
        (if_then_else:SI (match_operator 4 "boolean_operator"
1694
                           [(match_operand:CC 1 "register_operand" "b,b")
1695
                            (const_int 0)])
1696
                         (match_operand:SI 2 "register_operand" "r,0")
1697
                         (match_operand:SI 3 "register_operand" "0,r")))]
1698
  "TARGET_BOOLEANS"
1699
{
1700
  int isEq = (GET_CODE (operands[4]) == EQ);
1701
  switch (which_alternative)
1702
    {
1703
    case 0:
1704
      if (isEq) return "movf\t%0, %2, %1";
1705
      return "movt\t%0, %2, %1";
1706
    case 1:
1707
      if (isEq) return "movt\t%0, %3, %1";
1708
      return "movf\t%0, %3, %1";
1709
    default:
1710
      gcc_unreachable ();
1711
    }
1712
}
1713
  [(set_attr "type"     "move,move")
1714
   (set_attr "mode"     "SI")
1715
   (set_attr "length"   "3,3")])
1716
 
1717
(define_insn "movsfcc_internal0"
1718
  [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1719
        (if_then_else:SF (match_operator 4 "branch_operator"
1720
                           [(match_operand:SI 1 "register_operand" "r,r,r,r")
1721
                            (const_int 0)])
1722
                         (match_operand:SF 2 "register_operand" "r,0,f,0")
1723
                         (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1724
  ""
1725
{
1726
  switch (which_alternative)
1727
    {
1728
    case 0:
1729
      switch (GET_CODE (operands[4]))
1730
        {
1731
        case EQ:        return "moveqz\t%0, %2, %1";
1732
        case NE:        return "movnez\t%0, %2, %1";
1733
        case LT:        return "movltz\t%0, %2, %1";
1734
        case GE:        return "movgez\t%0, %2, %1";
1735
        default:        gcc_unreachable ();
1736
        }
1737
      break;
1738
    case 1:
1739
      switch (GET_CODE (operands[4]))
1740
        {
1741
        case EQ:        return "movnez\t%0, %3, %1";
1742
        case NE:        return "moveqz\t%0, %3, %1";
1743
        case LT:        return "movgez\t%0, %3, %1";
1744
        case GE:        return "movltz\t%0, %3, %1";
1745
        default:        gcc_unreachable ();
1746
        }
1747
      break;
1748
    case 2:
1749
      switch (GET_CODE (operands[4]))
1750
        {
1751
        case EQ:        return "moveqz.s %0, %2, %1";
1752
        case NE:        return "movnez.s %0, %2, %1";
1753
        case LT:        return "movltz.s %0, %2, %1";
1754
        case GE:        return "movgez.s %0, %2, %1";
1755
        default:        gcc_unreachable ();
1756
        }
1757
      break;
1758
    case 3:
1759
      switch (GET_CODE (operands[4]))
1760
        {
1761
        case EQ:        return "movnez.s %0, %3, %1";
1762
        case NE:        return "moveqz.s %0, %3, %1";
1763
        case LT:        return "movgez.s %0, %3, %1";
1764
        case GE:        return "movltz.s %0, %3, %1";
1765
        default:        gcc_unreachable ();
1766
        }
1767
      break;
1768
    default:
1769
      gcc_unreachable ();
1770
    }
1771
  gcc_unreachable ();
1772
}
1773
  [(set_attr "type"     "move,move,move,move")
1774
   (set_attr "mode"     "SF")
1775
   (set_attr "length"   "3,3,3,3")])
1776
 
1777
(define_insn "movsfcc_internal1"
1778
  [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
1779
        (if_then_else:SF (match_operator 4 "boolean_operator"
1780
                           [(match_operand:CC 1 "register_operand" "b,b,b,b")
1781
                            (const_int 0)])
1782
                         (match_operand:SF 2 "register_operand" "r,0,f,0")
1783
                         (match_operand:SF 3 "register_operand" "0,r,0,f")))]
1784
  "TARGET_BOOLEANS"
1785
{
1786
  int isEq = (GET_CODE (operands[4]) == EQ);
1787
  switch (which_alternative)
1788
    {
1789
    case 0:
1790
      if (isEq) return "movf\t%0, %2, %1";
1791
      return "movt\t%0, %2, %1";
1792
    case 1:
1793
      if (isEq) return "movt\t%0, %3, %1";
1794
      return "movf\t%0, %3, %1";
1795
    case 2:
1796
      if (isEq) return "movf.s\t%0, %2, %1";
1797
      return "movt.s\t%0, %2, %1";
1798
    case 3:
1799
      if (isEq) return "movt.s\t%0, %3, %1";
1800
      return "movf.s\t%0, %3, %1";
1801
    default:
1802
      gcc_unreachable ();
1803
    }
1804
}
1805
  [(set_attr "type"     "move,move,move,move")
1806
   (set_attr "mode"     "SF")
1807
   (set_attr "length"   "3,3,3,3")])
1808
 
1809
 
1810
;; Floating-point comparisons.
1811
 
1812
(define_insn "seq_sf"
1813
  [(set (match_operand:CC 0 "register_operand" "=b")
1814
        (eq:CC (match_operand:SF 1 "register_operand" "f")
1815
               (match_operand:SF 2 "register_operand" "f")))]
1816
  "TARGET_HARD_FLOAT"
1817
  "oeq.s\t%0, %1, %2"
1818
  [(set_attr "type"     "farith")
1819
   (set_attr "mode"     "BL")
1820
   (set_attr "length"   "3")])
1821
 
1822
(define_insn "slt_sf"
1823
  [(set (match_operand:CC 0 "register_operand" "=b")
1824
        (lt:CC (match_operand:SF 1 "register_operand" "f")
1825
               (match_operand:SF 2 "register_operand" "f")))]
1826
  "TARGET_HARD_FLOAT"
1827
  "olt.s\t%0, %1, %2"
1828
  [(set_attr "type"     "farith")
1829
   (set_attr "mode"     "BL")
1830
   (set_attr "length"   "3")])
1831
 
1832
(define_insn "sle_sf"
1833
  [(set (match_operand:CC 0 "register_operand" "=b")
1834
        (le:CC (match_operand:SF 1 "register_operand" "f")
1835
               (match_operand:SF 2 "register_operand" "f")))]
1836
  "TARGET_HARD_FLOAT"
1837
  "ole.s\t%0, %1, %2"
1838
  [(set_attr "type"     "farith")
1839
   (set_attr "mode"     "BL")
1840
   (set_attr "length"   "3")])
1841
 
1842
 
1843
;; Unconditional branches.
1844
 
1845
(define_insn "jump"
1846
  [(set (pc)
1847
        (label_ref (match_operand 0 "" "")))]
1848
  ""
1849
  "j\t%l0"
1850
  [(set_attr "type"     "jump")
1851
   (set_attr "mode"     "none")
1852
   (set_attr "length"   "3")])
1853
 
1854
(define_expand "indirect_jump"
1855
  [(set (pc)
1856
        (match_operand 0 "register_operand" ""))]
1857
  ""
1858
{
1859
  rtx dest = operands[0];
1860
  if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
1861
    operands[0] = copy_to_mode_reg (Pmode, dest);
1862
 
1863
  emit_jump_insn (gen_indirect_jump_internal (dest));
1864
  DONE;
1865
})
1866
 
1867
(define_insn "indirect_jump_internal"
1868
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1869
  ""
1870
  "jx\t%0"
1871
  [(set_attr "type"     "jump")
1872
   (set_attr "mode"     "none")
1873
   (set_attr "length"   "3")])
1874
 
1875
 
1876
(define_expand "tablejump"
1877
  [(use (match_operand:SI 0 "register_operand" ""))
1878
   (use (label_ref (match_operand 1 "" "")))]
1879
   ""
1880
{
1881
  rtx target = operands[0];
1882
  if (flag_pic)
1883
    {
1884
      /* For PIC, the table entry is relative to the start of the table.  */
1885
      rtx label = gen_reg_rtx (SImode);
1886
      target = gen_reg_rtx (SImode);
1887
      emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
1888
      emit_insn (gen_addsi3 (target, operands[0], label));
1889
    }
1890
  emit_jump_insn (gen_tablejump_internal (target, operands[1]));
1891
  DONE;
1892
})
1893
 
1894
(define_insn "tablejump_internal"
1895
  [(set (pc)
1896
        (match_operand:SI 0 "register_operand" "r"))
1897
   (use (label_ref (match_operand 1 "" "")))]
1898
  ""
1899
  "jx\t%0"
1900
  [(set_attr "type"     "jump")
1901
   (set_attr "mode"     "none")
1902
   (set_attr "length"   "3")])
1903
 
1904
 
1905
;; Function calls.
1906
 
1907
(define_expand "sym_PLT"
1908
  [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
1909
  ""
1910
  "")
1911
 
1912
(define_expand "call"
1913
  [(call (match_operand 0 "memory_operand" "")
1914
         (match_operand 1 "" ""))]
1915
  ""
1916
{
1917
  rtx addr = XEXP (operands[0], 0);
1918
  if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1919
      && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1920
    addr = gen_sym_PLT (addr);
1921
  if (!call_insn_operand (addr, VOIDmode))
1922
    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
1923
})
1924
 
1925
(define_insn "call_internal"
1926
  [(call (mem (match_operand:SI 0 "call_insn_operand" "n,i,r"))
1927
         (match_operand 1 "" "i,i,i"))]
1928
  ""
1929
{
1930
  return xtensa_emit_call (0, operands);
1931
}
1932
  [(set_attr "type"     "call")
1933
   (set_attr "mode"     "none")
1934
   (set_attr "length"   "3")])
1935
 
1936
(define_expand "call_value"
1937
  [(set (match_operand 0 "register_operand" "")
1938
        (call (match_operand 1 "memory_operand" "")
1939
              (match_operand 2 "" "")))]
1940
  ""
1941
{
1942
  rtx addr = XEXP (operands[1], 0);
1943
  if (flag_pic && GET_CODE (addr) == SYMBOL_REF
1944
      && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr)))
1945
    addr = gen_sym_PLT (addr);
1946
  if (!call_insn_operand (addr, VOIDmode))
1947
    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
1948
})
1949
 
1950
;; Cannot combine constraints for operand 0 into "afvb":
1951
;; reload.c:find_reloads seems to assume that grouped constraints somehow
1952
;; specify related register classes, and when they don't the constraints
1953
;; fail to match.  By not grouping the constraints, we get the correct
1954
;; behavior.
1955
(define_insn "call_value_internal"
1956
   [(set (match_operand 0 "register_operand" "=af,af,af,v,v,v,b,b,b")
1957
         (call (mem (match_operand:SI 1 "call_insn_operand"
1958
                                        "n,i,r,n,i,r,n,i,r"))
1959
               (match_operand 2 "" "i,i,i,i,i,i,i,i,i")))]
1960
  ""
1961
{
1962
  return xtensa_emit_call (1, operands);
1963
}
1964
  [(set_attr "type"     "call")
1965
   (set_attr "mode"     "none")
1966
   (set_attr "length"   "3")])
1967
 
1968
(define_insn "entry"
1969
  [(set (reg:SI A1_REG)
1970
        (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")
1971
                             (match_operand:SI 1 "const_int_operand" "i")]
1972
                            UNSPECV_ENTRY))]
1973
  ""
1974
{
1975
  if (frame_pointer_needed)
1976
    output_asm_insn (".frame\ta7, %0", operands);
1977
  else
1978
    output_asm_insn (".frame\tsp, %0", operands);
1979
  return "entry\tsp, %1";
1980
}
1981
  [(set_attr "type"     "move")
1982
   (set_attr "mode"     "SI")
1983
   (set_attr "length"   "3")])
1984
 
1985
(define_insn "return"
1986
  [(return)
1987
   (use (reg:SI A0_REG))]
1988
  "reload_completed"
1989
{
1990
  return (TARGET_DENSITY ? "retw.n" : "retw");
1991
}
1992
  [(set_attr "type"     "jump")
1993
   (set_attr "mode"     "none")
1994
   (set_attr "length"   "2")])
1995
 
1996
 
1997
;; Miscellaneous instructions.
1998
 
1999
(define_expand "prologue"
2000
  [(const_int 0)]
2001
  ""
2002
{
2003
  xtensa_expand_prologue ();
2004
  DONE;
2005
})
2006
 
2007
(define_expand "epilogue"
2008
  [(return)]
2009
  ""
2010
{
2011
  emit_jump_insn (gen_return ());
2012
  DONE;
2013
})
2014
 
2015
(define_insn "nop"
2016
  [(const_int 0)]
2017
  ""
2018
{
2019
  return (TARGET_DENSITY ? "nop.n" : "nop");
2020
}
2021
  [(set_attr "type"     "nop")
2022
   (set_attr "mode"     "none")
2023
   (set_attr "length"   "3")])
2024
 
2025
(define_expand "nonlocal_goto"
2026
  [(match_operand:SI 0 "general_operand" "")
2027
   (match_operand:SI 1 "general_operand" "")
2028
   (match_operand:SI 2 "general_operand" "")
2029
   (match_operand:SI 3 "" "")]
2030
  ""
2031
{
2032
  xtensa_expand_nonlocal_goto (operands);
2033
  DONE;
2034
})
2035
 
2036
;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2037
;; know if a frame pointer is required until the reload pass, and
2038
;; because there may be an incoming argument value in the hard frame
2039
;; pointer register (a7).  If there is an incoming argument in that
2040
;; register, the "set_frame_ptr" insn gets inserted immediately after
2041
;; the insn that copies the incoming argument to a pseudo or to the
2042
;; stack.  This serves several purposes here: (1) it keeps the
2043
;; optimizer from copy-propagating or scheduling the use of a7 as an
2044
;; incoming argument away from the beginning of the function; (2) we
2045
;; can use a post-reload splitter to expand away the insn if a frame
2046
;; pointer is not required, so that the post-reload scheduler can do
2047
;; the right thing; and (3) it makes it easy for the prologue expander
2048
;; to search for this insn to determine whether it should add a new insn
2049
;; to set up the frame pointer.
2050
 
2051
(define_insn "set_frame_ptr"
2052
  [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2053
  ""
2054
{
2055
  if (frame_pointer_needed)
2056
    return "mov\ta7, sp";
2057
  return "";
2058
}
2059
  [(set_attr "type"     "move")
2060
   (set_attr "mode"     "SI")
2061
   (set_attr "length"   "3")])
2062
 
2063
;; Post-reload splitter to remove fp assignment when it's not needed.
2064
(define_split
2065
  [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
2066
  "reload_completed && !frame_pointer_needed"
2067
  [(unspec [(const_int 0)] UNSPEC_NOP)]
2068
  "")
2069
 
2070
;; The preceding splitter needs something to split the insn into;
2071
;; things start breaking if the result is just a "use" so instead we
2072
;; generate the following insn.
2073
(define_insn "*unspec_nop"
2074
  [(unspec [(const_int 0)] UNSPEC_NOP)]
2075
  ""
2076
  ""
2077
  [(set_attr "type"     "nop")
2078
   (set_attr "mode"     "none")
2079
   (set_attr "length"   "0")])
2080
 
2081
;; The fix_return_addr pattern sets the high 2 bits of an address in a
2082
;; register to match the high bits of the current PC.
2083
(define_insn "fix_return_addr"
2084
  [(set (match_operand:SI 0 "register_operand" "=a")
2085
        (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
2086
                   UNSPEC_RET_ADDR))
2087
   (clobber (match_scratch:SI 2 "=r"))
2088
   (clobber (match_scratch:SI 3 "=r"))]
2089
  ""
2090
  "mov\t%2, a0\;call0\t0f\;.align\t4\;0:\;mov\t%3, a0\;mov\ta0, %2\;\
2091
srli\t%3, %3, 30\;slli\t%0, %1, 2\;ssai\t2\;src\t%0, %3, %0"
2092
  [(set_attr "type"     "multi")
2093
   (set_attr "mode"     "SI")
2094
   (set_attr "length"   "24")])
2095
 
2096
 
2097
;; Instructions for the Xtensa "boolean" option.
2098
 
2099
(define_insn "*booltrue"
2100
  [(set (pc)
2101
        (if_then_else (match_operator 2 "boolean_operator"
2102
                         [(match_operand:CC 0 "register_operand" "b")
2103
                          (const_int 0)])
2104
                      (label_ref (match_operand 1 "" ""))
2105
                      (pc)))]
2106
  "TARGET_BOOLEANS"
2107
{
2108
  if (GET_CODE (operands[2]) == EQ)
2109
    return "bf\t%0, %1";
2110
  else
2111
    return "bt\t%0, %1";
2112
}
2113
  [(set_attr "type"     "jump")
2114
   (set_attr "mode"     "none")
2115
   (set_attr "length"   "3")])
2116
 
2117
(define_insn "*boolfalse"
2118
  [(set (pc)
2119
        (if_then_else (match_operator 2 "boolean_operator"
2120
                         [(match_operand:CC 0 "register_operand" "b")
2121
                          (const_int 0)])
2122
                      (pc)
2123
                      (label_ref (match_operand 1 "" ""))))]
2124
  "TARGET_BOOLEANS"
2125
{
2126
  if (GET_CODE (operands[2]) == EQ)
2127
    return "bt\t%0, %1";
2128
  else
2129
    return "bf\t%0, %1";
2130
}
2131
  [(set_attr "type"     "jump")
2132
   (set_attr "mode"     "none")
2133
   (set_attr "length"   "3")])

powered by: WebSVN 2.1.0

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