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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [xtensa/] [xtensa.md] - Blame information for rev 298

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

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

powered by: WebSVN 2.1.0

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