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

Subversion Repositories openrisc

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

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

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

powered by: WebSVN 2.1.0

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