]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/xtensa/xtensa.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / xtensa / xtensa.md
CommitLineData
03984308 1;; GCC machine description for Tensilica's Xtensa architecture.
a945c346 2;; Copyright (C) 2001-2024 Free Software Foundation, Inc.
03984308
BW
3;; Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
4
5;; This file is part of GCC.
6
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published by
2f83c7d6 9;; the Free Software Foundation; either version 3, or (at your option)
03984308
BW
10;; any later version.
11
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15;; License for more details.
16
17;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>.
03984308 20
03984308
BW
21
22(define_constants [
23 (A0_REG 0)
f42f5a1b 24 (A1_REG 1)
03984308 25 (A7_REG 7)
f42f5a1b 26 (A8_REG 8)
590e2636 27 (A9_REG 9)
b92f1c2d 28])
03984308 29
b92f1c2d
MF
30(define_c_enum "unspec" [
31 UNSPEC_NOP
32 UNSPEC_PLT
33 UNSPEC_RET_ADDR
34 UNSPEC_TPOFF
35 UNSPEC_DTPOFF
36 UNSPEC_TLS_FUNC
37 UNSPEC_TLS_ARG
38 UNSPEC_TLS_CALL
39 UNSPEC_TP
40 UNSPEC_MEMW
41 UNSPEC_LSETUP_START
42 UNSPEC_LSETUP_END
43 UNSPEC_FRAME_BLOCKAGE
44])
2a48b790 45
b92f1c2d
MF
46(define_c_enum "unspecv" [
47 UNSPECV_SET_FP
48 UNSPECV_ENTRY
49 UNSPECV_S32RI
50 UNSPECV_S32C1I
51 UNSPECV_EH_RETURN
52 UNSPECV_SET_TP
53 UNSPECV_BLOCKAGE
03984308
BW
54])
55
3abcb3a7 56;; This code iterator allows signed and unsigned widening multiplications
09fa8841 57;; to use the same template.
3abcb3a7 58(define_code_iterator any_extend [sign_extend zero_extend])
09fa8841
BW
59
60;; <u> expands to an empty string when doing a signed operation and
61;; "u" when doing an unsigned operation.
62(define_code_attr u [(sign_extend "") (zero_extend "u")])
63
64;; <su> is like <u>, but the signed form expands to "s" rather than "".
65(define_code_attr su [(sign_extend "s") (zero_extend "u")])
66
3abcb3a7 67;; This code iterator allows four integer min/max operations to be
036a2b7a 68;; generated from one template.
3abcb3a7 69(define_code_iterator any_minmax [smin umin smax umax])
036a2b7a
BW
70
71;; <minmax> expands to the opcode name for any_minmax operations.
72(define_code_attr minmax [(smin "min") (umin "minu")
73 (smax "max") (umax "maxu")])
74
3abcb3a7 75;; This code iterator is for floating-point comparisons.
ff779f98 76(define_code_iterator any_scc_sf [eq lt le uneq unlt unle unordered])
89d5982b 77(define_code_attr scc_sf [(eq "oeq") (lt "olt") (le "ole")
ff779f98
BW
78 (uneq "ueq") (unlt "ult") (unle "ule")
79 (unordered "un")])
036a2b7a 80
3abcb3a7
HPN
81;; This iterator and attribute allow to combine most atomic operations.
82(define_code_iterator ATOMIC [and ior xor plus minus mult])
89d5982b 83(define_code_attr atomic [(and "and") (ior "ior") (xor "xor")
2a48b790
BW
84 (plus "add") (minus "sub") (mult "nand")])
85
3abcb3a7 86;; This mode iterator allows the HI and QI patterns to be defined from
2a48b790 87;; the same template.
3abcb3a7 88(define_mode_iterator HQI [HI QI])
2a48b790 89
13fb3a61
BW
90\f
91;; Attributes.
03984308
BW
92
93(define_attr "type"
768b6664 94 "unknown,jump,call,load,store,move,arith,multi,nop,farith,fmadd,fconv,fload,fstore,mul16,mul32,div32,mac16,rsr,wsr,entry,trap"
03984308
BW
95 (const_string "unknown"))
96
97(define_attr "mode"
98 "unknown,none,QI,HI,SI,DI,SF,DF,BL"
99 (const_string "unknown"))
100
101(define_attr "length" "" (const_int 1))
102
103;; Describe a user's asm statement.
104(define_asm_attributes
ccd02e73
TJJS
105 [(set_attr "type" "multi")
106 (set_attr "mode" "none")
107 (set_attr "length" "3")]) ;; Should be the maximum possible length
108 ;; of a single machine instruction.
03984308 109
13fb3a61 110\f
3b1cce6a 111;; Pipeline model.
03984308 112
3b1cce6a
SB
113;; The Xtensa basically has simple 5-stage RISC pipeline.
114;; Most instructions complete in 1 cycle, and it is OK to assume that
115;; everything is fully pipelined. The exceptions have special insn
116;; reservations in the pipeline description below. The Xtensa can
117;; issue one instruction per cycle, so defining CPU units is unnecessary.
03984308 118
3b1cce6a
SB
119(define_insn_reservation "xtensa_any_insn" 1
120 (eq_attr "type" "!load,fload,rsr,mul16,mul32,fmadd,fconv")
121 "nothing")
03984308 122
3b1cce6a
SB
123(define_insn_reservation "xtensa_memory" 2
124 (eq_attr "type" "load,fload")
125 "nothing")
03984308 126
3b1cce6a
SB
127(define_insn_reservation "xtensa_sreg" 2
128 (eq_attr "type" "rsr")
129 "nothing")
03984308 130
3b1cce6a
SB
131(define_insn_reservation "xtensa_mul16" 2
132 (eq_attr "type" "mul16")
133 "nothing")
03984308 134
3b1cce6a
SB
135(define_insn_reservation "xtensa_mul32" 2
136 (eq_attr "type" "mul32")
137 "nothing")
03984308 138
3b1cce6a
SB
139(define_insn_reservation "xtensa_fmadd" 4
140 (eq_attr "type" "fmadd")
141 "nothing")
142
143(define_insn_reservation "xtensa_fconv" 2
144 (eq_attr "type" "fconv")
145 "nothing")
8eb1bc5c 146\f
887af464 147;; Include predicates and constraints.
8eb1bc5c
BW
148
149(include "predicates.md")
887af464 150(include "constraints.md")
8eb1bc5c 151
13fb3a61
BW
152\f
153;; Addition.
03984308
BW
154
155(define_insn "addsi3"
156 [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a")
157 (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r")
158 (match_operand:SI 2 "add_operand" "d,O,r,J,N")))]
159 ""
160 "@
13fb3a61
BW
161 add.n\t%0, %1, %2
162 addi.n\t%0, %1, %d2
163 add\t%0, %1, %2
164 addi\t%0, %1, %d2
165 addmi\t%0, %1, %x2"
03984308
BW
166 [(set_attr "type" "arith,arith,arith,arith,arith")
167 (set_attr "mode" "SI")
168 (set_attr "length" "2,2,3,3,3")])
169
8a20b4bc 170(define_insn "*addsubx"
03984308 171 [(set (match_operand:SI 0 "register_operand" "=a")
8a20b4bc
TJJS
172 (match_operator:SI 4 "addsub_operator"
173 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
06ff8708 174 (match_operand:SI 3 "addsubx_operand" "i"))
8a20b4bc 175 (match_operand:SI 2 "register_operand" "r")]))]
6c2e8d1c 176 "TARGET_ADDX"
06ff8708
MF
177{
178 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
8a20b4bc
TJJS
179 switch (GET_CODE (operands[4]))
180 {
181 case PLUS:
182 return "addx%3\t%0, %1, %2";
183 case MINUS:
184 return "subx%3\t%0, %1, %2";
185 default:
186 gcc_unreachable ();
187 }
06ff8708 188}
03984308
BW
189 [(set_attr "type" "arith")
190 (set_attr "mode" "SI")
191 (set_attr "length" "3")])
192
fe3ce086
TJJS
193(define_expand "adddi3"
194 [(set (match_operand:DI 0 "register_operand")
195 (plus:DI (match_operand:DI 1 "register_operand")
196 (match_operand:DI 2 "register_operand")))]
197 ""
198{
199 rtx lo_dest, hi_dest, lo_op0, hi_op0, lo_op1, hi_op1;
200 rtx_code_label *label;
201 if (rtx_equal_p (operands[0], operands[1])
202 || rtx_equal_p (operands[0], operands[2])
203 || ! REG_P (operands[1]) || ! REG_P (operands[2]))
204 FAIL;
205 lo_dest = gen_lowpart (SImode, operands[0]);
206 hi_dest = gen_highpart (SImode, operands[0]);
207 lo_op0 = gen_lowpart (SImode, operands[1]);
208 hi_op0 = gen_highpart (SImode, operands[1]);
209 lo_op1 = gen_lowpart (SImode, operands[2]);
210 hi_op1 = gen_highpart (SImode, operands[2]);
211 emit_insn (gen_addsi3 (hi_dest, hi_op0, hi_op1));
212 emit_insn (gen_addsi3 (lo_dest, lo_op0, lo_op1));
213 emit_cmp_and_jump_insns (lo_dest,
214 (REGNO (operands[1]) < REGNO (operands[2])
215 ? lo_op1 : lo_op0), GEU, const0_rtx,
216 SImode, true, label = gen_label_rtx ());
217 emit_insn (gen_addsi3 (hi_dest, hi_dest, const1_rtx));
218 emit_label (label);
219 DONE;
220})
221
03984308
BW
222(define_insn "addsf3"
223 [(set (match_operand:SF 0 "register_operand" "=f")
224 (plus:SF (match_operand:SF 1 "register_operand" "%f")
225 (match_operand:SF 2 "register_operand" "f")))]
226 "TARGET_HARD_FLOAT"
13fb3a61 227 "add.s\t%0, %1, %2"
03984308
BW
228 [(set_attr "type" "fmadd")
229 (set_attr "mode" "SF")
230 (set_attr "length" "3")])
231
13fb3a61
BW
232\f
233;; Subtraction.
03984308
BW
234
235(define_insn "subsi3"
236 [(set (match_operand:SI 0 "register_operand" "=a")
89d5982b 237 (minus:SI (match_operand:SI 1 "register_operand" "r")
03984308
BW
238 (match_operand:SI 2 "register_operand" "r")))]
239 ""
13fb3a61 240 "sub\t%0, %1, %2"
03984308
BW
241 [(set_attr "type" "arith")
242 (set_attr "mode" "SI")
243 (set_attr "length" "3")])
244
9b867c82
TJJS
245(define_insn_and_split "*subsi3_from_const"
246 [(set (match_operand:SI 0 "register_operand" "=a")
247 (minus:SI (match_operand:SI 1 "const_int_operand" "i")
248 (match_operand:SI 2 "register_operand" "r")))]
249 "xtensa_simm8 (-INTVAL (operands[1]))
250 || xtensa_simm8x256 (-INTVAL (operands[1]))"
251 "#"
252 "&& 1"
253 [(set (match_dup 0)
254 (plus:SI (match_dup 2)
255 (match_dup 1)))
256 (set (match_dup 0)
257 (neg:SI (match_dup 0)))]
258{
259 operands[1] = GEN_INT (-INTVAL (operands[1]));
260}
261 [(set_attr "type" "arith")
262 (set_attr "mode" "SI")
263 (set (attr "length")
264 (if_then_else (match_test "TARGET_DENSITY
265 && xtensa_m1_or_1_thru_15 (-INTVAL (operands[1]))")
266 (const_int 5)
267 (const_int 6)))])
268
fe3ce086
TJJS
269(define_expand "subdi3"
270 [(set (match_operand:DI 0 "register_operand")
271 (minus:DI (match_operand:DI 1 "register_operand")
272 (match_operand:DI 2 "register_operand")))]
273 ""
274{
275 rtx lo_dest, hi_dest, lo_op0, hi_op0, lo_op1, hi_op1;
276 rtx_code_label *label;
277 lo_dest = gen_lowpart (SImode, operands[0]);
278 hi_dest = gen_highpart (SImode, operands[0]);
279 lo_op0 = gen_lowpart (SImode, operands[1]);
280 hi_op0 = gen_highpart (SImode, operands[1]);
281 lo_op1 = gen_lowpart (SImode, operands[2]);
282 hi_op1 = gen_highpart (SImode, operands[2]);
283 emit_insn (gen_subsi3 (hi_dest, hi_op0, hi_op1));
284 emit_cmp_and_jump_insns (lo_op0, lo_op1, GEU, const0_rtx,
285 SImode, true, label = gen_label_rtx ());
286 emit_insn (gen_addsi3 (hi_dest, hi_dest, constm1_rtx));
287 emit_label (label);
288 emit_insn (gen_subsi3 (lo_dest, lo_op0, lo_op1));
289 DONE;
290})
291
03984308
BW
292(define_insn "subsf3"
293 [(set (match_operand:SF 0 "register_operand" "=f")
294 (minus:SF (match_operand:SF 1 "register_operand" "f")
295 (match_operand:SF 2 "register_operand" "f")))]
296 "TARGET_HARD_FLOAT"
13fb3a61 297 "sub.s\t%0, %1, %2"
03984308
BW
298 [(set_attr "type" "fmadd")
299 (set_attr "mode" "SF")
300 (set_attr "length" "3")])
301
13fb3a61
BW
302\f
303;; Multiplication.
03984308 304
9489a1ab 305(define_expand "mulsidi3"
09fa8841 306 [(set (match_operand:DI 0 "register_operand")
9489a1ab
TJJS
307 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"))
308 (sign_extend:DI (match_operand:SI 2 "register_operand"))))]
09fa8841
BW
309 "TARGET_MUL32_HIGH"
310{
1d29a58d
BW
311 rtx temp = gen_reg_rtx (SImode);
312 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
9489a1ab
TJJS
313 emit_insn (gen_mulsi3_highpart (gen_highpart (SImode, operands[0]),
314 operands[1], operands[2]));
1d29a58d 315 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp));
09fa8841
BW
316 DONE;
317})
318
9489a1ab
TJJS
319(define_expand "umulsidi3"
320 [(set (match_operand:DI 0 "register_operand")
321 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"))
322 (zero_extend:DI (match_operand:SI 2 "register_operand"))))]
323 ""
324{
325 if (TARGET_MUL32_HIGH)
326 {
327 rtx temp = gen_reg_rtx (SImode);
328 emit_insn (gen_mulsi3 (temp, operands[1], operands[2]));
329 emit_insn (gen_umulsi3_highpart (gen_highpart (SImode, operands[0]),
330 operands[1], operands[2]));
331 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), temp));
332 }
333 else
334 emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, "__umulsidi3"),
335 operands[0], LCT_NORMAL, DImode,
336 operands[1], SImode,
337 operands[2], SImode);
338 DONE;
339})
340
09fa8841
BW
341(define_insn "<u>mulsi3_highpart"
342 [(set (match_operand:SI 0 "register_operand" "=a")
343 (truncate:SI
344 (lshiftrt:DI
345 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "%r"))
346 (any_extend:DI (match_operand:SI 2 "register_operand" "r")))
347 (const_int 32))))]
348 "TARGET_MUL32_HIGH"
349 "mul<su>h\t%0, %1, %2"
350 [(set_attr "type" "mul32")
351 (set_attr "mode" "SI")
352 (set_attr "length" "3")])
353
03984308
BW
354(define_insn "mulsi3"
355 [(set (match_operand:SI 0 "register_operand" "=a")
356 (mult:SI (match_operand:SI 1 "register_operand" "%r")
357 (match_operand:SI 2 "register_operand" "r")))]
358 "TARGET_MUL32"
13fb3a61 359 "mull\t%0, %1, %2"
03984308
BW
360 [(set_attr "type" "mul32")
361 (set_attr "mode" "SI")
362 (set_attr "length" "3")])
363
9489a1ab 364(define_insn "<u>mulhisi3"
03984308 365 [(set (match_operand:SI 0 "register_operand" "=C,A")
9489a1ab 366 (mult:SI (any_extend:SI
03984308 367 (match_operand:HI 1 "register_operand" "%r,r"))
9489a1ab 368 (any_extend:SI
03984308
BW
369 (match_operand:HI 2 "register_operand" "r,r"))))]
370 "TARGET_MUL16 || TARGET_MAC16"
371 "@
9489a1ab
TJJS
372 mul16<su>\t%0, %1, %2
373 <u>mul.aa.ll\t%1, %2"
03984308
BW
374 [(set_attr "type" "mul16,mac16")
375 (set_attr "mode" "SI")
376 (set_attr "length" "3,3")])
377
378(define_insn "muladdhisi"
379 [(set (match_operand:SI 0 "register_operand" "=A")
380 (plus:SI (mult:SI (sign_extend:SI
381 (match_operand:HI 1 "register_operand" "%r"))
382 (sign_extend:SI
383 (match_operand:HI 2 "register_operand" "r")))
384 (match_operand:SI 3 "register_operand" "0")))]
385 "TARGET_MAC16"
13fb3a61 386 "mula.aa.ll\t%1, %2"
03984308
BW
387 [(set_attr "type" "mac16")
388 (set_attr "mode" "SI")
389 (set_attr "length" "3")])
390
391(define_insn "mulsubhisi"
392 [(set (match_operand:SI 0 "register_operand" "=A")
393 (minus:SI (match_operand:SI 1 "register_operand" "0")
394 (mult:SI (sign_extend:SI
395 (match_operand:HI 2 "register_operand" "%r"))
396 (sign_extend:SI
397 (match_operand:HI 3 "register_operand" "r")))))]
398 "TARGET_MAC16"
13fb3a61 399 "muls.aa.ll\t%2, %3"
03984308
BW
400 [(set_attr "type" "mac16")
401 (set_attr "mode" "SI")
402 (set_attr "length" "3")])
403
404(define_insn "mulsf3"
405 [(set (match_operand:SF 0 "register_operand" "=f")
406 (mult:SF (match_operand:SF 1 "register_operand" "%f")
407 (match_operand:SF 2 "register_operand" "f")))]
408 "TARGET_HARD_FLOAT"
13fb3a61 409 "mul.s\t%0, %1, %2"
03984308
BW
410 [(set_attr "type" "fmadd")
411 (set_attr "mode" "SF")
412 (set_attr "length" "3")])
413
47c21725 414(define_insn "fmasf4"
03984308 415 [(set (match_operand:SF 0 "register_operand" "=f")
47c21725
RH
416 (fma:SF (match_operand:SF 1 "register_operand" "f")
417 (match_operand:SF 2 "register_operand" "f")
418 (match_operand:SF 3 "register_operand" "0")))]
419 "TARGET_HARD_FLOAT"
13fb3a61 420 "madd.s\t%0, %1, %2"
03984308
BW
421 [(set_attr "type" "fmadd")
422 (set_attr "mode" "SF")
423 (set_attr "length" "3")])
424
47c21725
RH
425;; Note that (C - A*B) = (-A*B + C)
426(define_insn "fnmasf4"
03984308 427 [(set (match_operand:SF 0 "register_operand" "=f")
47c21725
RH
428 (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
429 (match_operand:SF 2 "register_operand" "f")
430 (match_operand:SF 3 "register_operand" "0")))]
431 "TARGET_HARD_FLOAT"
432 "msub.s\t%0, %1, %2"
03984308
BW
433 [(set_attr "type" "fmadd")
434 (set_attr "mode" "SF")
435 (set_attr "length" "3")])
436
13fb3a61
BW
437\f
438;; Division.
03984308
BW
439
440(define_insn "divsi3"
441 [(set (match_operand:SI 0 "register_operand" "=a")
442 (div:SI (match_operand:SI 1 "register_operand" "r")
443 (match_operand:SI 2 "register_operand" "r")))]
444 "TARGET_DIV32"
13fb3a61 445 "quos\t%0, %1, %2"
03984308
BW
446 [(set_attr "type" "div32")
447 (set_attr "mode" "SI")
448 (set_attr "length" "3")])
449
450(define_insn "udivsi3"
451 [(set (match_operand:SI 0 "register_operand" "=a")
452 (udiv:SI (match_operand:SI 1 "register_operand" "r")
453 (match_operand:SI 2 "register_operand" "r")))]
454 "TARGET_DIV32"
13fb3a61 455 "quou\t%0, %1, %2"
03984308
BW
456 [(set_attr "type" "div32")
457 (set_attr "mode" "SI")
458 (set_attr "length" "3")])
459
13fb3a61
BW
460\f
461;; Remainders.
03984308
BW
462
463(define_insn "modsi3"
464 [(set (match_operand:SI 0 "register_operand" "=a")
465 (mod:SI (match_operand:SI 1 "register_operand" "r")
466 (match_operand:SI 2 "register_operand" "r")))]
467 "TARGET_DIV32"
13fb3a61 468 "rems\t%0, %1, %2"
03984308
BW
469 [(set_attr "type" "div32")
470 (set_attr "mode" "SI")
471 (set_attr "length" "3")])
472
473(define_insn "umodsi3"
474 [(set (match_operand:SI 0 "register_operand" "=a")
475 (umod:SI (match_operand:SI 1 "register_operand" "r")
476 (match_operand:SI 2 "register_operand" "r")))]
477 "TARGET_DIV32"
13fb3a61 478 "remu\t%0, %1, %2"
03984308
BW
479 [(set_attr "type" "div32")
480 (set_attr "mode" "SI")
481 (set_attr "length" "3")])
03984308 482
13fb3a61
BW
483\f
484;; Absolute value.
03984308
BW
485
486(define_insn "abssi2"
487 [(set (match_operand:SI 0 "register_operand" "=a")
488 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
6c2e8d1c 489 "TARGET_ABS"
13fb3a61 490 "abs\t%0, %1"
03984308
BW
491 [(set_attr "type" "arith")
492 (set_attr "mode" "SI")
493 (set_attr "length" "3")])
494
495(define_insn "abssf2"
496 [(set (match_operand:SF 0 "register_operand" "=f")
497 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
498 "TARGET_HARD_FLOAT"
13fb3a61 499 "abs.s\t%0, %1"
03984308
BW
500 [(set_attr "type" "farith")
501 (set_attr "mode" "SF")
502 (set_attr "length" "3")])
503
13fb3a61
BW
504\f
505;; Min and max.
03984308 506
036a2b7a 507(define_insn "<code>si3"
03984308 508 [(set (match_operand:SI 0 "register_operand" "=a")
89d5982b 509 (any_minmax:SI (match_operand:SI 1 "register_operand" "%r")
036a2b7a 510 (match_operand:SI 2 "register_operand" "r")))]
03984308 511 "TARGET_MINMAX"
036a2b7a 512 "<minmax>\t%0, %1, %2"
03984308
BW
513 [(set_attr "type" "arith")
514 (set_attr "mode" "SI")
515 (set_attr "length" "3")])
516
ce83c3e4
TJJS
517\f
518;; Signed clamp.
519
520(define_insn_and_split "*xtensa_clamps"
521 [(set (match_operand:SI 0 "register_operand" "=a")
522 (smax:SI (smin:SI (match_operand:SI 1 "register_operand" "r")
523 (match_operand:SI 2 "const_int_operand" "i"))
524 (match_operand:SI 3 "const_int_operand" "i")))]
2f615b33 525 "TARGET_MINMAX && TARGET_CLAMPS
ce83c3e4
TJJS
526 && xtensa_match_CLAMPS_imms_p (operands[3], operands[2])"
527 "#"
528 "&& 1"
529 [(set (match_dup 0)
530 (smin:SI (smax:SI (match_dup 1)
531 (match_dup 3))
532 (match_dup 2)))]
533 ""
534 [(set_attr "type" "arith")
535 (set_attr "mode" "SI")
536 (set_attr "length" "3")])
537
538(define_insn "*xtensa_clamps"
539 [(set (match_operand:SI 0 "register_operand" "=a")
540 (smin:SI (smax:SI (match_operand:SI 1 "register_operand" "r")
541 (match_operand:SI 2 "const_int_operand" "i"))
542 (match_operand:SI 3 "const_int_operand" "i")))]
2f615b33 543 "TARGET_MINMAX && TARGET_CLAMPS
ce83c3e4
TJJS
544 && xtensa_match_CLAMPS_imms_p (operands[2], operands[3])"
545{
546 static char result[64];
547 sprintf (result, "clamps\t%%0, %%1, %d", floor_log2 (-INTVAL (operands[2])));
548 return result;
549}
550 [(set_attr "type" "arith")
551 (set_attr "mode" "SI")
552 (set_attr "length" "3")])
553
13fb3a61 554\f
29dc90a5
TJJS
555;; Count redundant leading sign bits and leading/trailing zeros,
556;; and find first bit.
557
558(define_insn "clrsbsi2"
559 [(set (match_operand:SI 0 "register_operand" "=a")
560 (clrsb:SI (match_operand:SI 1 "register_operand" "r")))]
561 "TARGET_NSA"
562 "nsa\t%0, %1"
563 [(set_attr "type" "arith")
564 (set_attr "mode" "SI")
565 (set_attr "length" "3")])
09fa8841
BW
566
567(define_insn "clzsi2"
568 [(set (match_operand:SI 0 "register_operand" "=a")
569 (clz:SI (match_operand:SI 1 "register_operand" "r")))]
570 "TARGET_NSA"
571 "nsau\t%0, %1"
572 [(set_attr "type" "arith")
573 (set_attr "mode" "SI")
574 (set_attr "length" "3")])
575
576(define_expand "ctzsi2"
577 [(set (match_operand:SI 0 "register_operand" "")
578 (ctz:SI (match_operand:SI 1 "register_operand" "")))]
579 "TARGET_NSA"
580{
581 rtx temp = gen_reg_rtx (SImode);
582 emit_insn (gen_negsi2 (temp, operands[1]));
583 emit_insn (gen_andsi3 (temp, temp, operands[1]));
584 emit_insn (gen_clzsi2 (temp, temp));
117be79b
TJJS
585 emit_move_insn (operands[0], GEN_INT (31));
586 emit_insn (gen_subsi3 (operands[0], operands[0], temp));
09fa8841
BW
587 DONE;
588})
03984308
BW
589
590(define_expand "ffssi2"
591 [(set (match_operand:SI 0 "register_operand" "")
592 (ffs:SI (match_operand:SI 1 "register_operand" "")))]
593 "TARGET_NSA"
03984308
BW
594{
595 rtx temp = gen_reg_rtx (SImode);
596 emit_insn (gen_negsi2 (temp, operands[1]));
597 emit_insn (gen_andsi3 (temp, temp, operands[1]));
09fa8841 598 emit_insn (gen_clzsi2 (temp, temp));
117be79b
TJJS
599 emit_move_insn (operands[0], GEN_INT (32));
600 emit_insn (gen_subsi3 (operands[0], operands[0], temp));
03984308 601 DONE;
13fb3a61 602})
03984308 603
18e86fae
MF
604\f
605;; Byte swap.
606
2fcc69d8
TJJS
607(define_insn "bswaphi2"
608 [(set (match_operand:HI 0 "register_operand" "=a")
609 (bswap:HI (match_operand:HI 1 "register_operand" "r")))
610 (clobber (match_scratch:HI 2 "=&a"))]
611 ""
612 "extui\t%2, %1, 8, 8\;slli\t%0, %1, 8\;or\t%0, %0, %2"
613 [(set_attr "type" "arith")
614 (set_attr "mode" "HI")
615 (set_attr "length" "9")])
616
9aad2b22
TJJS
617(define_expand "bswapsi2"
618 [(set (match_operand:SI 0 "register_operand" "")
89d5982b 619 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
9aad2b22
TJJS
620 "!optimize_debug && optimize > 1"
621{
622 /* GIMPLE manual byte-swapping recognition is now activated.
623 For both built-in and manual bswaps, emit corresponding library call
624 if optimizing for size, or a series of dedicated machine instructions
625 if otherwise. */
626 if (optimize_size)
627 emit_library_call_value (optab_libfunc (bswap_optab, SImode),
628 operands[0], LCT_NORMAL, SImode,
629 operands[1], SImode);
630 else
631 emit_insn (gen_bswapsi2_internal (operands[0], operands[1]));
632 DONE;
633})
18e86fae 634
9aad2b22
TJJS
635(define_insn "bswapsi2_internal"
636 [(set (match_operand:SI 0 "register_operand" "=a,&a")
637 (bswap:SI (match_operand:SI 1 "register_operand" "0,r")))
638 (clobber (match_scratch:SI 2 "=&a,X"))]
639 "!optimize_debug && optimize > 1 && !optimize_size"
640{
641 rtx_insn *prev_insn = prev_nonnote_nondebug_insn (insn);
642 const char *init = "ssai\t8\;";
ec532b47 643 static char result[128];
9aad2b22
TJJS
644 if (prev_insn && NONJUMP_INSN_P (prev_insn))
645 {
646 rtx x = PATTERN (prev_insn);
647 if (GET_CODE (x) == PARALLEL && XVECLEN (x, 0) == 2
648 && GET_CODE (XVECEXP (x, 0, 0)) == SET
649 && GET_CODE (XVECEXP (x, 0, 1)) == CLOBBER)
650 {
651 x = XEXP (XVECEXP (x, 0, 0), 1);
652 if (GET_CODE (x) == BSWAP && GET_MODE (x) == SImode)
653 init = "";
654 }
655 }
656 sprintf (result,
657 (which_alternative == 0)
658 ? "%s" "srli\t%%2, %%1, 16\;src\t%%2, %%2, %%1\;src\t%%2, %%2, %%2\;src\t%%0, %%1, %%2"
659 : "%s" "srli\t%%0, %%1, 16\;src\t%%0, %%0, %%1\;src\t%%0, %%0, %%0\;src\t%%0, %%1, %%0",
660 init);
661 return result;
662}
663 [(set_attr "type" "arith,arith")
664 (set_attr "mode" "SI")
665 (set_attr "length" "15,15")])
666
667(define_expand "bswapdi2"
668 [(set (match_operand:DI 0 "register_operand" "")
669 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
670 "!optimize_debug && optimize > 1 && optimize_size"
671{
672 /* Replace with a single DImode library call.
673 Without this, two SImode library calls are emitted. */
674 emit_library_call_value (optab_libfunc (bswap_optab, DImode),
675 operands[0], LCT_NORMAL, DImode,
676 operands[1], DImode);
677 DONE;
678})
18e86fae 679
13fb3a61
BW
680\f
681;; Negation and one's complement.
03984308
BW
682
683(define_insn "negsi2"
684 [(set (match_operand:SI 0 "register_operand" "=a")
685 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
686 ""
13fb3a61 687 "neg\t%0, %1"
03984308
BW
688 [(set_attr "type" "arith")
689 (set_attr "mode" "SI")
690 (set_attr "length" "3")])
691
9777d446
TJJS
692(define_insn_and_split "one_cmplsi2"
693 [(set (match_operand:SI 0 "register_operand" "=a")
694 (not:SI (match_operand:SI 1 "register_operand" "r")))]
03984308 695 ""
9777d446
TJJS
696 "#"
697 "&& can_create_pseudo_p ()"
698 [(set (match_dup 2)
699 (const_int -1))
700 (set (match_dup 0)
701 (xor:SI (match_dup 1)
702 (match_dup 2)))]
03984308 703{
9777d446
TJJS
704 operands[2] = gen_reg_rtx (SImode);
705}
706 [(set_attr "type" "arith")
707 (set_attr "mode" "SI")
708 (set (attr "length")
709 (if_then_else (match_test "TARGET_DENSITY")
710 (const_int 5)
711 (const_int 6)))])
03984308
BW
712
713(define_insn "negsf2"
714 [(set (match_operand:SF 0 "register_operand" "=f")
715 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
716 "TARGET_HARD_FLOAT"
13fb3a61 717 "neg.s\t%0, %1"
03984308
BW
718 [(set_attr "type" "farith")
719 (set_attr "mode" "SF")
720 (set_attr "length" "3")])
721
13fb3a61
BW
722\f
723;; Logical instructions.
03984308
BW
724
725(define_insn "andsi3"
726 [(set (match_operand:SI 0 "register_operand" "=a,a")
727 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
728 (match_operand:SI 2 "mask_operand" "P,r")))]
729 ""
730 "@
13fb3a61
BW
731 extui\t%0, %1, 0, %K2
732 and\t%0, %1, %2"
03984308
BW
733 [(set_attr "type" "arith,arith")
734 (set_attr "mode" "SI")
735 (set_attr "length" "3,3")])
736
e44e7fac
TJJS
737(define_insn_and_split "*andsi3_bitcmpl"
738 [(set (match_operand:SI 0 "register_operand" "=a")
739 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
740 (match_operand:SI 2 "register_operand" "r")))]
741 ""
742 "#"
743 "&& can_create_pseudo_p ()"
744 [(set (match_dup 3)
745 (and:SI (match_dup 1)
746 (match_dup 2)))
747 (set (match_dup 0)
748 (xor:SI (match_dup 3)
749 (match_dup 2)))]
750{
751 operands[3] = gen_reg_rtx (SImode);
752}
753 [(set_attr "type" "arith")
754 (set_attr "mode" "SI")
755 (set_attr "length" "6")])
756
07743893
TJJS
757(define_insn_and_split "*andsi3_const_pow2_minus_one"
758 [(set (match_operand:SI 0 "register_operand" "=a")
759 (and:SI (match_operand:SI 1 "register_operand" "r")
760 (match_operand:SI 2 "const_int_operand" "i")))]
761 "IN_RANGE (exact_log2 (INTVAL (operands[2]) + 1), 17, 31)"
762 "#"
763 "&& 1"
764 [(set (match_dup 0)
765 (ashift:SI (match_dup 1)
766 (match_dup 2)))
767 (set (match_dup 0)
768 (lshiftrt:SI (match_dup 0)
769 (match_dup 2)))]
770{
771 operands[2] = GEN_INT (32 - floor_log2 (INTVAL (operands[2]) + 1));
772}
773 [(set_attr "type" "arith")
774 (set_attr "mode" "SI")
775 (set (attr "length")
776 (if_then_else (match_test "TARGET_DENSITY
777 && INTVAL (operands[2]) == 0x7FFFFFFF")
778 (const_int 5)
779 (const_int 6)))])
780
781(define_insn_and_split "*andsi3_const_negative_pow2"
782 [(set (match_operand:SI 0 "register_operand" "=a")
783 (and:SI (match_operand:SI 1 "register_operand" "r")
784 (match_operand:SI 2 "const_int_operand" "i")))]
785 "IN_RANGE (exact_log2 (-INTVAL (operands[2])), 12, 31)"
786 "#"
787 "&& 1"
788 [(set (match_dup 0)
789 (lshiftrt:SI (match_dup 1)
790 (match_dup 2)))
791 (set (match_dup 0)
792 (ashift:SI (match_dup 0)
793 (match_dup 2)))]
794{
795 operands[2] = GEN_INT (floor_log2 (-INTVAL (operands[2])));
796}
797 [(set_attr "type" "arith")
798 (set_attr "mode" "SI")
799 (set_attr "length" "6")])
800
801(define_insn_and_split "*andsi3_const_shifted_mask"
802 [(set (match_operand:SI 0 "register_operand" "=a")
803 (and:SI (match_operand:SI 1 "register_operand" "r")
804 (match_operand:SI 2 "shifted_mask_operand" "i")))]
805 "! xtensa_simm12b (INTVAL (operands[2]))"
806 "#"
807 "&& 1"
808 [(set (match_dup 0)
809 (zero_extract:SI (match_dup 1)
810 (match_dup 3)
811 (match_dup 4)))
812 (set (match_dup 0)
813 (ashift:SI (match_dup 0)
814 (match_dup 2)))]
815{
816 HOST_WIDE_INT mask = INTVAL (operands[2]);
817 int shift = ctz_hwi (mask);
818 int mask_size = floor_log2 (((uint32_t)mask >> shift) + 1);
819 int mask_pos = shift;
820 if (BITS_BIG_ENDIAN)
821 mask_pos = (32 - (mask_size + shift)) & 0x1f;
822 operands[2] = GEN_INT (shift);
823 operands[3] = GEN_INT (mask_size);
824 operands[4] = GEN_INT (mask_pos);
825}
826 [(set_attr "type" "arith")
827 (set_attr "mode" "SI")
828 (set (attr "length")
829 (if_then_else (match_test "TARGET_DENSITY
830 && ctz_hwi (INTVAL (operands[2])) == 1")
831 (const_int 5)
832 (const_int 6)))])
833
03984308
BW
834(define_insn "iorsi3"
835 [(set (match_operand:SI 0 "register_operand" "=a")
836 (ior:SI (match_operand:SI 1 "register_operand" "%r")
837 (match_operand:SI 2 "register_operand" "r")))]
838 ""
13fb3a61 839 "or\t%0, %1, %2"
03984308
BW
840 [(set_attr "type" "arith")
841 (set_attr "mode" "SI")
842 (set_attr "length" "3")])
843
a4b05944
TJJS
844(define_expand "xorsi3"
845 [(set (match_operand:SI 0 "register_operand")
846 (xor:SI (match_operand:SI 1 "register_operand")
847 (match_operand:SI 2 "nonmemory_operand")))]
848 ""
849{
850 if (register_operand (operands[2], SImode))
851 emit_insn (gen_xorsi3_internal (operands[0], operands[1],
852 operands[2]));
853 else
854 {
855 rtx (*gen_op)(rtx, rtx, rtx);
856 if (TARGET_DENSITY
857 && CONST_INT_P (operands[2])
858 && INTVAL (operands[2]) == -2147483648L)
859 gen_op = gen_addsi3;
860 else
861 gen_op = gen_xorsi3_internal;
862 emit_insn (gen_op (operands[0], operands[1],
863 force_reg (SImode, operands[2])));
864 }
865 DONE;
866})
867
868(define_insn "xorsi3_internal"
03984308
BW
869 [(set (match_operand:SI 0 "register_operand" "=a")
870 (xor:SI (match_operand:SI 1 "register_operand" "%r")
871 (match_operand:SI 2 "register_operand" "r")))]
872 ""
13fb3a61 873 "xor\t%0, %1, %2"
03984308
BW
874 [(set_attr "type" "arith")
875 (set_attr "mode" "SI")
876 (set_attr "length" "3")])
877
e3a4bd0b
TJJS
878(define_insn_and_split "*splice_bits"
879 [(set (match_operand:SI 0 "register_operand" "=a")
880 (ior:SI (and:SI (match_operand:SI 1 "register_operand" "r")
881 (match_operand:SI 3 "const_int_operand" "i"))
882 (and:SI (match_operand:SI 2 "register_operand" "r")
883 (match_operand:SI 4 "const_int_operand" "i"))))]
884
885 "!optimize_debug && optimize
886 && INTVAL (operands[3]) + INTVAL (operands[4]) == -1
887 && (exact_log2 (INTVAL (operands[3]) + 1) > 16
888 || exact_log2 (INTVAL (operands[4]) + 1) > 16)"
889 "#"
890 "&& can_create_pseudo_p ()"
891 [(set (match_dup 5)
892 (ashift:SI (match_dup 1)
893 (match_dup 4)))
894 (set (match_dup 6)
895 (lshiftrt:SI (match_dup 2)
896 (match_dup 3)))
897 (set (match_dup 0)
898 (ior:SI (lshiftrt:SI (match_dup 5)
899 (match_dup 4))
900 (ashift:SI (match_dup 6)
901 (match_dup 3))))]
902{
903 int shift;
904 if (INTVAL (operands[3]) < 0)
905 {
906 rtx x;
907 x = operands[1], operands[1] = operands[2], operands[2] = x;
908 x = operands[3], operands[3] = operands[4], operands[4] = x;
909 }
910 shift = floor_log2 (INTVAL (operands[3]) + 1);
911 operands[3] = GEN_INT (shift);
912 operands[4] = GEN_INT (32 - shift);
913 operands[5] = gen_reg_rtx (SImode);
914 operands[6] = gen_reg_rtx (SImode);
915}
916 [(set_attr "type" "arith")
917 (set_attr "mode" "SI")
918 (set (attr "length")
919 (if_then_else (match_test "TARGET_DENSITY
920 && (INTVAL (operands[3]) == 0x7FFFFFFF
921 || INTVAL (operands[4]) == 0x7FFFFFFF)")
922 (const_int 11)
923 (const_int 12)))])
924
13fb3a61
BW
925\f
926;; Zero-extend instructions.
03984308
BW
927
928(define_insn "zero_extendhisi2"
929 [(set (match_operand:SI 0 "register_operand" "=a,a")
930 (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))]
931 ""
932 "@
13fb3a61 933 extui\t%0, %1, 0, 16
a288e202 934 %v1l16ui\t%0, %1"
03984308
BW
935 [(set_attr "type" "arith,load")
936 (set_attr "mode" "SI")
937 (set_attr "length" "3,3")])
938
939(define_insn "zero_extendqisi2"
940 [(set (match_operand:SI 0 "register_operand" "=a,a")
941 (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))]
942 ""
943 "@
13fb3a61 944 extui\t%0, %1, 0, 8
a288e202 945 %v1l8ui\t%0, %1"
03984308
BW
946 [(set_attr "type" "arith,load")
947 (set_attr "mode" "SI")
948 (set_attr "length" "3,3")])
949
13fb3a61
BW
950\f
951;; Sign-extend instructions.
03984308
BW
952
953(define_expand "extendhisi2"
954 [(set (match_operand:SI 0 "register_operand" "")
955 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
956 ""
03984308
BW
957{
958 if (sext_operand (operands[1], HImode))
959 emit_insn (gen_extendhisi2_internal (operands[0], operands[1]));
960 else
961 xtensa_extend_reg (operands[0], operands[1]);
962 DONE;
13fb3a61 963})
03984308
BW
964
965(define_insn "extendhisi2_internal"
966 [(set (match_operand:SI 0 "register_operand" "=B,a")
967 (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))]
968 ""
969 "@
13fb3a61 970 sext\t%0, %1, 15
a288e202 971 %v1l16si\t%0, %1"
03984308
BW
972 [(set_attr "type" "arith,load")
973 (set_attr "mode" "SI")
974 (set_attr "length" "3,3")])
975
976(define_expand "extendqisi2"
977 [(set (match_operand:SI 0 "register_operand" "")
978 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
979 ""
03984308
BW
980{
981 if (TARGET_SEXT)
13fb3a61
BW
982 emit_insn (gen_extendqisi2_internal (operands[0], operands[1]));
983 else
984 xtensa_extend_reg (operands[0], operands[1]);
03984308 985 DONE;
13fb3a61 986})
03984308
BW
987
988(define_insn "extendqisi2_internal"
989 [(set (match_operand:SI 0 "register_operand" "=B")
990 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
991 "TARGET_SEXT"
13fb3a61 992 "sext\t%0, %1, 7"
03984308
BW
993 [(set_attr "type" "arith")
994 (set_attr "mode" "SI")
995 (set_attr "length" "3")])
996
13fb3a61
BW
997\f
998;; Field extract instructions.
03984308 999
d543bac1 1000(define_expand "extvsi"
03984308
BW
1001 [(set (match_operand:SI 0 "register_operand" "")
1002 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
1003 (match_operand:SI 2 "const_int_operand" "")
1004 (match_operand:SI 3 "const_int_operand" "")))]
1005 "TARGET_SEXT"
03984308 1006{
13fb3a61
BW
1007 if (!sext_fldsz_operand (operands[2], SImode))
1008 FAIL;
1009
1010 /* We could expand to a right shift followed by SEXT but that's
1011 no better than the standard left and right shift sequence. */
1012 if (!lsbitnum_operand (operands[3], SImode))
1013 FAIL;
1014
d543bac1
TJJS
1015 emit_insn (gen_extvsi_internal (operands[0], operands[1],
1016 operands[2], operands[3]));
03984308 1017 DONE;
13fb3a61 1018})
03984308 1019
d543bac1 1020(define_insn "extvsi_internal"
03984308
BW
1021 [(set (match_operand:SI 0 "register_operand" "=a")
1022 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
1023 (match_operand:SI 2 "sext_fldsz_operand" "i")
1024 (match_operand:SI 3 "lsbitnum_operand" "i")))]
1025 "TARGET_SEXT"
03984308
BW
1026{
1027 int fldsz = INTVAL (operands[2]);
1028 operands[2] = GEN_INT (fldsz - 1);
13fb3a61
BW
1029 return "sext\t%0, %1, %2";
1030}
03984308
BW
1031 [(set_attr "type" "arith")
1032 (set_attr "mode" "SI")
1033 (set_attr "length" "3")])
1034
d543bac1 1035(define_expand "extzvsi"
03984308
BW
1036 [(set (match_operand:SI 0 "register_operand" "")
1037 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
1038 (match_operand:SI 2 "const_int_operand" "")
1039 (match_operand:SI 3 "const_int_operand" "")))]
1040 ""
03984308 1041{
13fb3a61
BW
1042 if (!extui_fldsz_operand (operands[2], SImode))
1043 FAIL;
d543bac1
TJJS
1044 emit_insn (gen_extzvsi_internal (operands[0], operands[1],
1045 operands[2], operands[3]));
03984308 1046 DONE;
13fb3a61 1047})
03984308 1048
d543bac1 1049(define_insn "extzvsi_internal"
03984308
BW
1050 [(set (match_operand:SI 0 "register_operand" "=a")
1051 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1052 (match_operand:SI 2 "extui_fldsz_operand" "i")
1053 (match_operand:SI 3 "const_int_operand" "i")))]
1054 ""
03984308
BW
1055{
1056 int shift;
1057 if (BITS_BIG_ENDIAN)
1058 shift = (32 - (INTVAL (operands[2]) + INTVAL (operands[3]))) & 0x1f;
1059 else
1060 shift = INTVAL (operands[3]) & 0x1f;
1061 operands[3] = GEN_INT (shift);
13fb3a61
BW
1062 return "extui\t%0, %1, %3, %2";
1063}
03984308
BW
1064 [(set_attr "type" "arith")
1065 (set_attr "mode" "SI")
1066 (set_attr "length" "3")])
1067
e33d2dcb
TJJS
1068(define_insn_and_split "*extzvsi-1bit_ashlsi3"
1069 [(set (match_operand:SI 0 "register_operand" "=a")
1070 (and:SI (match_operator:SI 4 "logical_shift_operator"
1071 [(match_operand:SI 1 "register_operand" "r")
1072 (match_operand:SI 2 "const_int_operand" "i")])
1073 (match_operand:SI 3 "const_int_operand" "i")))]
1074 "exact_log2 (INTVAL (operands[3])) > 0"
1075 "#"
1076 "&& 1"
1077 [(set (match_dup 0)
1078 (zero_extract:SI (match_dup 1)
1079 (const_int 1)
1080 (match_dup 2)))
1081 (set (match_dup 0)
1082 (ashift:SI (match_dup 0)
1083 (match_dup 3)))]
1084{
bf78e24a 1085 int pos = INTVAL (operands[2]), shift = floor_log2 (INTVAL (operands[3]));
e33d2dcb
TJJS
1086 switch (GET_CODE (operands[4]))
1087 {
1088 case ASHIFT:
1089 pos = shift - pos;
1090 break;
1091 case LSHIFTRT:
1092 pos = shift + pos;
1093 break;
1094 default:
1095 gcc_unreachable ();
1096 }
1097 if (BITS_BIG_ENDIAN)
1098 pos = (32 - (1 + pos)) & 0x1f;
1099 operands[2] = GEN_INT (pos);
1100 operands[3] = GEN_INT (shift);
1101}
1102 [(set_attr "type" "arith")
1103 (set_attr "mode" "SI")
bf78e24a
TJJS
1104 (set (attr "length")
1105 (if_then_else (match_test "TARGET_DENSITY && INTVAL (operands[3]) == 2")
1106 (const_int 5)
1107 (const_int 6)))])
e33d2dcb
TJJS
1108
1109(define_insn_and_split "*extzvsi-1bit_addsubx"
1110 [(set (match_operand:SI 0 "register_operand" "=a")
1111 (match_operator:SI 5 "addsub_operator"
1112 [(and:SI (match_operator:SI 6 "logical_shift_operator"
1113 [(match_operand:SI 1 "register_operand" "r")
1114 (match_operand:SI 3 "const_int_operand" "i")])
1115 (match_operand:SI 4 "const_int_operand" "i"))
1116 (match_operand:SI 2 "register_operand" "r")]))]
1117 "TARGET_ADDX
1118 && IN_RANGE (exact_log2 (INTVAL (operands[4])), 1, 3)"
1119 "#"
1120 "&& 1"
1121 [(set (match_dup 0)
1122 (zero_extract:SI (match_dup 1)
1123 (const_int 1)
1124 (match_dup 3)))
1125 (set (match_dup 0)
1126 (match_op_dup 5
1127 [(ashift:SI (match_dup 0)
1128 (match_dup 4))
1129 (match_dup 2)]))]
1130{
bf78e24a 1131 int pos = INTVAL (operands[3]), shift = floor_log2 (INTVAL (operands[4]));
e33d2dcb
TJJS
1132 switch (GET_CODE (operands[6]))
1133 {
1134 case ASHIFT:
1135 pos = shift - pos;
1136 break;
1137 case LSHIFTRT:
1138 pos = shift + pos;
1139 break;
1140 default:
1141 gcc_unreachable ();
1142 }
1143 if (BITS_BIG_ENDIAN)
1144 pos = (32 - (1 + pos)) & 0x1f;
1145 operands[3] = GEN_INT (pos);
1146 operands[4] = GEN_INT (shift);
1147}
1148 [(set_attr "type" "arith")
1149 (set_attr "mode" "SI")
1150 (set_attr "length" "6")])
1151
13fb3a61
BW
1152\f
1153;; Conversions.
03984308
BW
1154
1155(define_insn "fix_truncsfsi2"
1156 [(set (match_operand:SI 0 "register_operand" "=a")
1157 (fix:SI (match_operand:SF 1 "register_operand" "f")))]
1158 "TARGET_HARD_FLOAT"
13fb3a61 1159 "trunc.s\t%0, %1, 0"
03984308
BW
1160 [(set_attr "type" "fconv")
1161 (set_attr "mode" "SF")
1162 (set_attr "length" "3")])
1163
1164(define_insn "fixuns_truncsfsi2"
1165 [(set (match_operand:SI 0 "register_operand" "=a")
1166 (unsigned_fix:SI (match_operand:SF 1 "register_operand" "f")))]
1167 "TARGET_HARD_FLOAT"
13fb3a61 1168 "utrunc.s\t%0, %1, 0"
03984308
BW
1169 [(set_attr "type" "fconv")
1170 (set_attr "mode" "SF")
1171 (set_attr "length" "3")])
1172
1173(define_insn "floatsisf2"
1174 [(set (match_operand:SF 0 "register_operand" "=f")
1175 (float:SF (match_operand:SI 1 "register_operand" "a")))]
1176 "TARGET_HARD_FLOAT"
13fb3a61 1177 "float.s\t%0, %1, 0"
03984308
BW
1178 [(set_attr "type" "fconv")
1179 (set_attr "mode" "SF")
1180 (set_attr "length" "3")])
1181
1182(define_insn "floatunssisf2"
1183 [(set (match_operand:SF 0 "register_operand" "=f")
1184 (unsigned_float:SF (match_operand:SI 1 "register_operand" "a")))]
1185 "TARGET_HARD_FLOAT"
13fb3a61 1186 "ufloat.s\t%0, %1, 0"
03984308
BW
1187 [(set_attr "type" "fconv")
1188 (set_attr "mode" "SF")
1189 (set_attr "length" "3")])
1190
13fb3a61
BW
1191\f
1192;; Data movement instructions.
03984308
BW
1193
1194;; 64-bit Integer moves
1195
1196(define_expand "movdi"
1197 [(set (match_operand:DI 0 "nonimmed_operand" "")
1198 (match_operand:DI 1 "general_operand" ""))]
1199 ""
03984308 1200{
64a54505
TJJS
1201 if (CONSTANT_P (operands[1]))
1202 {
1203 /* Split in halves if 64-bit Const-to-Reg moves
1204 because of offering further optimization opportunities. */
1205 if (register_operand (operands[0], DImode))
1206 {
f896c134
TJJS
1207 rtx ops[4] = { operands[0], operands[1] };
1208 xtensa_split_DI_reg_imm (ops);
1209 emit_move_insn (ops[0], ops[1]);
1210 emit_move_insn (ops[2], ops[3]);
64a54505
TJJS
1211 DONE;
1212 }
1213
1214 if (!TARGET_CONST16)
1215 operands[1] = force_const_mem (DImode, operands[1]);
1216 }
03984308 1217
997b8b4d
BW
1218 if (!register_operand (operands[0], DImode)
1219 && !register_operand (operands[1], DImode))
1220 operands[1] = force_reg (DImode, operands[1]);
03984308 1221
997b8b4d 1222 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
13fb3a61 1223})
03984308 1224
633e4eb4
BW
1225(define_insn_and_split "movdi_internal"
1226 [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
1227 (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
03984308
BW
1228 "register_operand (operands[0], DImode)
1229 || register_operand (operands[1], DImode)"
633e4eb4 1230 "#"
2b5b8610 1231 "&& reload_completed"
633e4eb4
BW
1232 [(set (match_dup 0) (match_dup 2))
1233 (set (match_dup 1) (match_dup 3))]
03984308 1234{
633e4eb4
BW
1235 xtensa_split_operand_pair (operands, SImode);
1236 if (reg_overlap_mentioned_p (operands[0], operands[3]))
03984308 1237 {
633e4eb4
BW
1238 rtx tmp;
1239 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1240 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
03984308 1241 }
633e4eb4 1242})
03984308 1243
4f3f0296
TJJS
1244(define_split
1245 [(set (match_operand:DI 0 "register_operand")
1246 (match_operand:DI 1 "const_int_operand"))]
1247 "!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS
1248 && ! xtensa_split1_finished_p ()"
1249 [(set (match_dup 0)
1250 (match_dup 1))
1251 (set (match_dup 2)
1252 (match_dup 3))]
1253{
1254 xtensa_split_DI_reg_imm (operands);
1255})
1256
03984308
BW
1257;; 32-bit Integer moves
1258
1259(define_expand "movsi"
1260 [(set (match_operand:SI 0 "nonimmed_operand" "")
1261 (match_operand:SI 1 "general_operand" ""))]
1262 ""
03984308
BW
1263{
1264 if (xtensa_emit_move_sequence (operands, SImode))
1265 DONE;
13fb3a61 1266})
03984308
BW
1267
1268(define_insn "movsi_internal"
a024f514
MF
1269 [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
1270 (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
a8cacfd2 1271 "xtensa_valid_move (SImode, operands)"
03984308 1272 "@
13fb3a61
BW
1273 movi.n\t%0, %x1
1274 mov.n\t%0, %1
1275 mov.n\t%0, %1
1276 %v1l32i.n\t%0, %1
1277 %v0s32i.n\t%1, %0
1278 %v0s32i.n\t%1, %0
1279 mov\t%0, %1
1280 movsp\t%0, %1
1281 movi\t%0, %x1
a024f514 1282 movi\t%0, %1
13fb3a61
BW
1283 const16\t%0, %t1\;const16\t%0, %b1
1284 %v1l32r\t%0, %1
1285 %v1l32i\t%0, %1
1286 %v0s32i\t%1, %0
12a8ee33
BW
1287 rsr\t%0, ACCLO
1288 wsr\t%1, ACCLO"
89d5982b 1289 [(set_attr "type" "move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
03984308 1290 (set_attr "mode" "SI")
a024f514 1291 (set_attr "length" "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
03984308 1292
4f3f0296
TJJS
1293(define_split
1294 [(set (match_operand:SI 0 "register_operand")
1295 (match_operand:SI 1 "const_int_operand"))]
1296 "!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS
1297 && ! xtensa_split1_finished_p ()
1298 && ! xtensa_simm12b (INTVAL (operands[1]))"
1299 [(set (match_dup 0)
1300 (match_dup 1))]
1301{
1302 operands[1] = force_const_mem (SImode, operands[1]);
1303})
1304
cd02f15f
TJJS
1305(define_split
1306 [(set (match_operand:SI 0 "register_operand")
1307 (match_operand:SI 1 "constantpool_operand"))]
1308 "! optimize_debug && reload_completed"
1309 [(const_int 0)]
1310{
1311 rtx x = avoid_constant_pool_reference (operands[1]);
1312 if (! CONST_INT_P (x))
1313 FAIL;
1314 if (! xtensa_constantsynth (operands[0], INTVAL (x)))
1315 emit_move_insn (operands[0], x);
773dffc5 1316 DONE;
cd02f15f
TJJS
1317})
1318
03984308
BW
1319;; 16-bit Integer moves
1320
1321(define_expand "movhi"
1322 [(set (match_operand:HI 0 "nonimmed_operand" "")
1323 (match_operand:HI 1 "general_operand" ""))]
1324 ""
03984308
BW
1325{
1326 if (xtensa_emit_move_sequence (operands, HImode))
1327 DONE;
13fb3a61 1328})
03984308
BW
1329
1330(define_insn "movhi_internal"
a024f514
MF
1331 [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,U,*a,*A")
1332 (match_operand:HI 1 "move_operand" "M,d,r,I,Y,U,r,*A,*r"))]
a8cacfd2 1333 "xtensa_valid_move (HImode, operands)"
03984308 1334 "@
13fb3a61
BW
1335 movi.n\t%0, %x1
1336 mov.n\t%0, %1
1337 mov\t%0, %1
1338 movi\t%0, %x1
a024f514 1339 movi\t%0, %1
13fb3a61
BW
1340 %v1l16ui\t%0, %1
1341 %v0s16i\t%1, %0
12a8ee33
BW
1342 rsr\t%0, ACCLO
1343 wsr\t%1, ACCLO"
a024f514 1344 [(set_attr "type" "move,move,move,move,move,load,store,rsr,wsr")
03984308 1345 (set_attr "mode" "HI")
a024f514 1346 (set_attr "length" "2,2,3,3,3,3,3,3,3")])
03984308
BW
1347
1348;; 8-bit Integer moves
1349
1350(define_expand "movqi"
1351 [(set (match_operand:QI 0 "nonimmed_operand" "")
1352 (match_operand:QI 1 "general_operand" ""))]
1353 ""
03984308
BW
1354{
1355 if (xtensa_emit_move_sequence (operands, QImode))
1356 DONE;
13fb3a61 1357})
03984308
BW
1358
1359(define_insn "movqi_internal"
1360 [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A")
1361 (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))]
a8cacfd2 1362 "xtensa_valid_move (QImode, operands)"
03984308 1363 "@
13fb3a61
BW
1364 movi.n\t%0, %x1
1365 mov.n\t%0, %1
1366 mov\t%0, %1
1367 movi\t%0, %x1
1368 %v1l8ui\t%0, %1
1369 %v0s8i\t%1, %0
12a8ee33
BW
1370 rsr\t%0, ACCLO
1371 wsr\t%1, ACCLO"
03984308
BW
1372 [(set_attr "type" "move,move,move,move,load,store,rsr,wsr")
1373 (set_attr "mode" "QI")
1374 (set_attr "length" "2,2,3,3,3,3,3,3")])
1375
37fbe8a3
BW
1376;; Sub-word reloads from the constant pool.
1377
1378(define_expand "reload<mode>_literal"
1379 [(parallel [(match_operand:HQI 0 "register_operand" "=r")
1380 (match_operand:HQI 1 "constantpool_operand" "")
1381 (match_operand:SI 2 "register_operand" "=&r")])]
1382 ""
1383{
1384 rtx lit, scratch;
1385 unsigned word_off, byte_off;
1386
398857e4
BW
1387 if (MEM_P (operands[1]))
1388 {
1389 lit = operands[1];
1390 word_off = 0;
1391 byte_off = 0;
1392 }
1393 else
1394 {
1395 gcc_assert (GET_CODE (operands[1]) == SUBREG);
1396 lit = SUBREG_REG (operands[1]);
1397 word_off = SUBREG_BYTE (operands[1]) & ~(UNITS_PER_WORD - 1);
1398 byte_off = SUBREG_BYTE (operands[1]) - word_off;
1399 }
37fbe8a3
BW
1400
1401 lit = adjust_address (lit, SImode, word_off);
398857e4 1402 scratch = operands[2];
37fbe8a3
BW
1403 emit_insn (gen_movsi (scratch, lit));
1404 emit_insn (gen_mov<mode> (operands[0],
1405 gen_rtx_SUBREG (<MODE>mode, scratch, byte_off)));
1406
1407 DONE;
1408})
1409
03984308
BW
1410;; 32-bit floating point moves
1411
1412(define_expand "movsf"
1413 [(set (match_operand:SF 0 "nonimmed_operand" "")
1414 (match_operand:SF 1 "general_operand" ""))]
1415 ""
03984308 1416{
a024f514 1417 if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS && CONSTANT_P (operands[1]))
03984308
BW
1418 operands[1] = force_const_mem (SFmode, operands[1]);
1419
997b8b4d
BW
1420 if ((!register_operand (operands[0], SFmode)
1421 && !register_operand (operands[1], SFmode))
1422 || (FP_REG_P (xt_true_regnum (operands[0]))
1423 && !(reload_in_progress | reload_completed)
1424 && (constantpool_mem_p (operands[1])
1425 || CONSTANT_P (operands[1]))))
1426 operands[1] = force_reg (SFmode, operands[1]);
1427
1428 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
13fb3a61 1429})
03984308
BW
1430
1431(define_insn "movsf_internal"
a024f514
MF
1432 [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
1433 (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
03984308
BW
1434 "((register_operand (operands[0], SFmode)
1435 || register_operand (operands[1], SFmode))
f42f5a1b 1436 && !(FP_REG_P (xt_true_regnum (operands[0]))
89d5982b 1437 && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))"
03984308 1438 "@
13fb3a61
BW
1439 mov.s\t%0, %1
1440 %v1lsi\t%0, %1
1441 %v0ssi\t%1, %0
1442 mov.n\t%0, %1
1443 %v1l32i.n\t%0, %1
1444 %v0s32i.n\t%1, %0
1445 mov\t%0, %1
1446 wfr\t%0, %1
1447 rfr\t%0, %1
a024f514 1448 movi\t%0, %y1
13fb3a61
BW
1449 const16\t%0, %t1\;const16\t%0, %b1
1450 %v1l32r\t%0, %1
1451 %v1l32i\t%0, %1
1452 %v0s32i\t%1, %0"
a024f514 1453 [(set_attr "type" "farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
03984308 1454 (set_attr "mode" "SF")
a024f514 1455 (set_attr "length" "3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
03984308 1456
3219c65b
BW
1457(define_insn "*lsiu"
1458 [(set (match_operand:SF 0 "register_operand" "=f")
1459 (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "+a")
1460 (match_operand:SI 2 "fpmem_offset_operand" "i"))))
1461 (set (match_dup 1)
1462 (plus:SI (match_dup 1) (match_dup 2)))]
f211daa3 1463 "TARGET_HARD_FLOAT && !TARGET_HARD_FLOAT_POSTINC"
03984308 1464{
66e58b33 1465 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
13fb3a61
BW
1466 output_asm_insn ("memw", operands);
1467 return "lsiu\t%0, %1, %2";
1468}
03984308
BW
1469 [(set_attr "type" "fload")
1470 (set_attr "mode" "SF")
1471 (set_attr "length" "3")])
1472
3219c65b
BW
1473(define_insn "*ssiu"
1474 [(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "+a")
1475 (match_operand:SI 1 "fpmem_offset_operand" "i")))
1476 (match_operand:SF 2 "register_operand" "f"))
1477 (set (match_dup 0)
1478 (plus:SI (match_dup 0) (match_dup 1)))]
f211daa3 1479 "TARGET_HARD_FLOAT && !TARGET_HARD_FLOAT_POSTINC"
03984308 1480{
66e58b33 1481 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
13fb3a61
BW
1482 output_asm_insn ("memw", operands);
1483 return "ssiu\t%2, %0, %1";
1484}
03984308
BW
1485 [(set_attr "type" "fstore")
1486 (set_attr "mode" "SF")
1487 (set_attr "length" "3")])
1488
f211daa3
MF
1489(define_insn "*lsip"
1490 [(set (match_operand:SF 0 "register_operand" "=f")
1491 (mem:SF (match_operand:SI 1 "register_operand" "+a")))
1492 (set (match_dup 1)
1493 (plus:SI (match_dup 1)
1494 (match_operand:SI 2 "fpmem_offset_operand" "i")))]
1495 "TARGET_HARD_FLOAT && TARGET_HARD_FLOAT_POSTINC"
1496{
1497 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1498 output_asm_insn ("memw", operands);
1499 return "lsip\t%0, %1, %2";
1500}
1501 [(set_attr "type" "fload")
1502 (set_attr "mode" "SF")
1503 (set_attr "length" "3")])
1504
1505(define_insn "*ssip"
1506 [(set (mem:SF (match_operand:SI 0 "register_operand" "+a"))
1507 (match_operand:SF 1 "register_operand" "f"))
1508 (set (match_dup 0)
1509 (plus:SI (match_dup 0)
1510 (match_operand:SI 2 "fpmem_offset_operand" "i")))]
1511 "TARGET_HARD_FLOAT && TARGET_HARD_FLOAT_POSTINC"
1512{
1513 if (TARGET_SERIALIZE_VOLATILE && volatile_refs_p (PATTERN (insn)))
1514 output_asm_insn ("memw", operands);
1515 return "ssip\t%1, %0, %2";
1516}
1517 [(set_attr "type" "fstore")
1518 (set_attr "mode" "SF")
1519 (set_attr "length" "3")])
1520
cd02f15f
TJJS
1521(define_split
1522 [(set (match_operand:SF 0 "register_operand")
1523 (match_operand:SF 1 "constantpool_operand"))]
1524 "! optimize_debug && reload_completed"
1525 [(const_int 0)]
1526{
e85c94d1
TJJS
1527 rtx x = avoid_constant_pool_reference (operands[1]);
1528 long l;
1529 HOST_WIDE_INT value;
1530 if (! CONST_DOUBLE_P (x) || GET_MODE (x) != SFmode)
cd02f15f 1531 FAIL;
e85c94d1 1532 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
cd02f15f 1533 x = gen_rtx_REG (SImode, REGNO (operands[0]));
e85c94d1
TJJS
1534 value = (int32_t)l;
1535 if (! xtensa_constantsynth (x, value))
1536 emit_move_insn (x, GEN_INT (value));
773dffc5 1537 DONE;
cd02f15f
TJJS
1538})
1539
03984308
BW
1540;; 64-bit floating point moves
1541
1542(define_expand "movdf"
1543 [(set (match_operand:DF 0 "nonimmed_operand" "")
1544 (match_operand:DF 1 "general_operand" ""))]
1545 ""
03984308 1546{
a024f514 1547 if (CONSTANT_P (operands[1]) && !TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
633e4eb4 1548 operands[1] = force_const_mem (DFmode, operands[1]);
03984308 1549
997b8b4d
BW
1550 if (!register_operand (operands[0], DFmode)
1551 && !register_operand (operands[1], DFmode))
1552 operands[1] = force_reg (DFmode, operands[1]);
03984308 1553
997b8b4d 1554 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
13fb3a61 1555})
03984308 1556
633e4eb4 1557(define_insn_and_split "movdf_internal"
a024f514
MF
1558 [(set (match_operand:DF 0 "nonimmed_operand" "=a,a,W,a,a,U")
1559 (match_operand:DF 1 "move_operand" "r,Y,iF,T,U,r"))]
03984308
BW
1560 "register_operand (operands[0], DFmode)
1561 || register_operand (operands[1], DFmode)"
633e4eb4 1562 "#"
2b5b8610 1563 "&& reload_completed"
633e4eb4
BW
1564 [(set (match_dup 0) (match_dup 2))
1565 (set (match_dup 1) (match_dup 3))]
03984308 1566{
633e4eb4
BW
1567 xtensa_split_operand_pair (operands, SFmode);
1568 if (reg_overlap_mentioned_p (operands[0], operands[3]))
03984308 1569 {
633e4eb4
BW
1570 rtx tmp;
1571 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
1572 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
03984308 1573 }
633e4eb4 1574})
03984308
BW
1575
1576;; Block moves
1577
76715c32 1578(define_expand "cpymemsi"
03984308
BW
1579 [(parallel [(set (match_operand:BLK 0 "" "")
1580 (match_operand:BLK 1 "" ""))
1581 (use (match_operand:SI 2 "arith_operand" ""))
1582 (use (match_operand:SI 3 "const_int_operand" ""))])]
1583 ""
03984308 1584{
13fb3a61
BW
1585 if (!xtensa_expand_block_move (operands))
1586 FAIL;
03984308 1587 DONE;
13fb3a61 1588})
03984308 1589
6454b4a8
TJJS
1590;; Block sets
1591
1592(define_expand "setmemsi"
1593 [(match_operand:BLK 0 "memory_operand")
1594 (match_operand:SI 1 "")
1595 (match_operand:SI 2 "")
1596 (match_operand:SI 3 "const_int_operand")]
1597 "!optimize_debug && optimize"
1598{
78648c09 1599 if (xtensa_expand_block_set (operands))
6454b4a8
TJJS
1600 DONE;
1601 FAIL;
1602})
1603
13fb3a61
BW
1604\f
1605;; Shift instructions.
03984308 1606
997b8b4d
BW
1607(define_expand "ashlsi3"
1608 [(set (match_operand:SI 0 "register_operand" "")
1609 (ashift:SI (match_operand:SI 1 "register_operand" "")
1610 (match_operand:SI 2 "arith_operand" "")))]
1611 ""
1612{
1613 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1614})
1615
1616(define_insn "ashlsi3_internal"
03984308
BW
1617 [(set (match_operand:SI 0 "register_operand" "=a,a")
1618 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1619 (match_operand:SI 2 "arith_operand" "J,r")))]
89d5982b 1620 ""
03984308 1621 "@
13fb3a61
BW
1622 slli\t%0, %1, %R2
1623 ssl\t%2\;sll\t%0, %1"
03984308
BW
1624 [(set_attr "type" "arith,arith")
1625 (set_attr "mode" "SI")
1626 (set_attr "length" "3,6")])
1627
1c68ec1f
TJJS
1628(define_split
1629 [(set (match_operand:SI 0 "register_operand")
1630 (ashift:SI (match_operand:SI 1 "register_operand")
1631 (const_int 1)))]
1632 "TARGET_DENSITY"
1633 [(set (match_dup 0)
1634 (plus:SI (match_dup 1)
1635 (match_dup 1)))])
40bf68bb 1636
03984308
BW
1637(define_insn "ashrsi3"
1638 [(set (match_operand:SI 0 "register_operand" "=a,a")
1639 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1640 (match_operand:SI 2 "arith_operand" "J,r")))]
1641 ""
1642 "@
13fb3a61
BW
1643 srai\t%0, %1, %R2
1644 ssr\t%2\;sra\t%0, %1"
03984308
BW
1645 [(set_attr "type" "arith,arith")
1646 (set_attr "mode" "SI")
1647 (set_attr "length" "3,6")])
1648
1649(define_insn "lshrsi3"
1650 [(set (match_operand:SI 0 "register_operand" "=a,a")
1651 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1652 (match_operand:SI 2 "arith_operand" "J,r")))]
1653 ""
03984308
BW
1654{
1655 if (which_alternative == 0)
1656 {
1657 if ((INTVAL (operands[2]) & 0x1f) < 16)
1c68ec1f 1658 return "srli\t%0, %1, %R2";
03984308 1659 else
1c68ec1f 1660 return "extui\t%0, %1, %R2, %L2";
03984308 1661 }
13fb3a61
BW
1662 return "ssr\t%2\;srl\t%0, %1";
1663}
03984308
BW
1664 [(set_attr "type" "arith,arith")
1665 (set_attr "mode" "SI")
1666 (set_attr "length" "3,6")])
1667
1c68ec1f 1668(define_insn "*shift_per_byte"
40bf68bb 1669 [(set (match_operand:SI 0 "register_operand" "=a")
1c68ec1f
TJJS
1670 (match_operator:SI 3 "xtensa_shift_per_byte_operator"
1671 [(match_operand:SI 1 "register_operand" "r")
1672 (ashift:SI (match_operand:SI 2 "register_operand" "r")
1673 (const_int 3))]))]
1674 "!optimize_debug && optimize"
1675{
1676 switch (GET_CODE (operands[3]))
1677 {
1678 case ASHIFT: return "ssa8b\t%2\;sll\t%0, %1";
1679 case ASHIFTRT: return "ssa8l\t%2\;sra\t%0, %1";
1680 case LSHIFTRT: return "ssa8l\t%2\;srl\t%0, %1";
1681 default: gcc_unreachable ();
1682 }
1683}
1684 [(set_attr "type" "arith")
1685 (set_attr "mode" "SI")
1686 (set_attr "length" "6")])
1687
1688(define_insn_and_split "*shift_per_byte_omit_AND_0"
1689 [(set (match_operand:SI 0 "register_operand" "=a")
1690 (match_operator:SI 4 "xtensa_shift_per_byte_operator"
1691 [(match_operand:SI 1 "register_operand" "r")
1692 (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1693 (const_int 3))
1694 (match_operand:SI 3 "const_int_operand" "i"))]))]
1695 "!optimize_debug && optimize
1696 && (INTVAL (operands[3]) & 0x1f) == 3 << 3"
1697 "#"
1698 "&& 1"
1699 [(set (match_dup 0)
1700 (match_op_dup 4
1701 [(match_dup 1)
1702 (ashift:SI (match_dup 2)
1703 (const_int 3))]))]
1704 ""
1705 [(set_attr "type" "arith")
1706 (set_attr "mode" "SI")
1707 (set_attr "length" "6")])
1708
1709(define_insn_and_split "*shift_per_byte_omit_AND_1"
1710 [(set (match_operand:SI 0 "register_operand" "=a")
1711 (match_operator:SI 4 "xtensa_shift_per_byte_operator"
1712 [(match_operand:SI 1 "register_operand" "r")
1713 (neg:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1714 (const_int 3))
1715 (match_operand:SI 3 "const_int_operand" "i")))]))]
1716 "!optimize_debug && optimize
1717 && (INTVAL (operands[3]) & 0x1f) == 3 << 3"
1718 "#"
1719 "&& can_create_pseudo_p ()"
1720 [(set (match_dup 5)
1721 (neg:SI (match_dup 2)))
1722 (set (match_dup 0)
1723 (match_op_dup 4
1724 [(match_dup 1)
1725 (ashift:SI (match_dup 5)
1726 (const_int 3))]))]
1727{
1728 operands[5] = gen_reg_rtx (SImode);
1729}
1730 [(set_attr "type" "arith")
1731 (set_attr "mode" "SI")
1732 (set_attr "length" "9")])
1733
feae4e83 1734(define_insn "*shlrd_reg"
1c68ec1f 1735 [(set (match_operand:SI 0 "register_operand" "=a")
feae4e83
TJJS
1736 (match_operator:SI 6 "xtensa_bit_join_operator"
1737 [(match_operator:SI 4 "logical_shift_operator"
1c68ec1f 1738 [(match_operand:SI 1 "register_operand" "r")
feae4e83
TJJS
1739 (match_operand:SI 3 "register_operand" "r")])
1740 (match_operator:SI 5 "logical_shift_operator"
1741 [(match_operand:SI 2 "register_operand" "r")
1742 (neg:SI (match_dup 3))])]))]
1c68ec1f
TJJS
1743 "!optimize_debug && optimize
1744 && xtensa_shlrd_which_direction (operands[4], operands[5]) != UNKNOWN"
1745{
1746 switch (xtensa_shlrd_which_direction (operands[4], operands[5]))
1747 {
feae4e83
TJJS
1748 case ASHIFT: return "ssl\t%3\;src\t%0, %1, %2";
1749 case LSHIFTRT: return "ssr\t%3\;src\t%0, %2, %1";
1c68ec1f
TJJS
1750 default: gcc_unreachable ();
1751 }
1752}
1753 [(set_attr "type" "arith")
1754 (set_attr "mode" "SI")
1755 (set_attr "length" "6")])
1756
feae4e83
TJJS
1757(define_insn_and_split "*shlrd_reg"
1758 [(set (match_operand:SI 0 "register_operand" "=a")
1759 (match_operator:SI 6 "xtensa_bit_join_operator"
1760 [(match_operator:SI 4 "logical_shift_operator"
1761 [(match_operand:SI 1 "register_operand" "r")
1762 (neg:SI (match_operand:SI 3 "register_operand" "r"))])
1763 (match_operator:SI 5 "logical_shift_operator"
1764 [(match_operand:SI 2 "register_operand" "r")
1765 (match_dup 3)])]))]
1766 "!optimize_debug && optimize
1767 && xtensa_shlrd_which_direction (operands[5], operands[4]) != UNKNOWN"
1768 "#"
1769 "&& 1"
1770 [(set (match_dup 0)
1771 (match_op_dup 6
1772 [(match_op_dup 5
1773 [(match_dup 2)
1774 (match_dup 3)])
1775 (match_op_dup 4
1776 [(match_dup 1)
1777 (neg:SI (match_dup 3))])]))]
1778 ""
1779 [(set_attr "type" "arith")
1780 (set_attr "mode" "SI")
1781 (set_attr "length" "6")])
1782
1783
1784(define_insn "*shlrd_const"
1c68ec1f 1785 [(set (match_operand:SI 0 "register_operand" "=a")
feae4e83
TJJS
1786 (match_operator:SI 7 "xtensa_bit_join_operator"
1787 [(match_operator:SI 5 "logical_shift_operator"
1c68ec1f
TJJS
1788 [(match_operand:SI 1 "register_operand" "r")
1789 (match_operand:SI 3 "const_int_operand" "i")])
feae4e83 1790 (match_operator:SI 6 "logical_shift_operator"
1c68ec1f 1791 [(match_operand:SI 2 "register_operand" "r")
feae4e83 1792 (match_operand:SI 4 "const_int_operand" "i")])]))]
1c68ec1f
TJJS
1793 "!optimize_debug && optimize
1794 && xtensa_shlrd_which_direction (operands[5], operands[6]) != UNKNOWN
1795 && IN_RANGE (INTVAL (operands[3]), 1, 31)
1796 && IN_RANGE (INTVAL (operands[4]), 1, 31)
1797 && INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
1798{
1799 switch (xtensa_shlrd_which_direction (operands[5], operands[6]))
1800 {
1801 case ASHIFT: return "ssai\t%L3\;src\t%0, %1, %2";
1802 case LSHIFTRT: return "ssai\t%R3\;src\t%0, %2, %1";
1803 default: gcc_unreachable ();
1804 }
1805}
1806 [(set_attr "type" "arith")
1807 (set_attr "mode" "SI")
1808 (set_attr "length" "6")])
1809
feae4e83 1810(define_insn "*shlrd_per_byte"
1c68ec1f 1811 [(set (match_operand:SI 0 "register_operand" "=a")
feae4e83
TJJS
1812 (match_operator:SI 6 "xtensa_bit_join_operator"
1813 [(match_operator:SI 4 "logical_shift_operator"
1c68ec1f
TJJS
1814 [(match_operand:SI 1 "register_operand" "r")
1815 (ashift:SI (match_operand:SI 2 "register_operand" "r")
1816 (const_int 3))])
feae4e83 1817 (match_operator:SI 5 "logical_shift_operator"
1c68ec1f
TJJS
1818 [(match_operand:SI 3 "register_operand" "r")
1819 (neg:SI (ashift:SI (match_dup 2)
feae4e83 1820 (const_int 3)))])]))]
1c68ec1f
TJJS
1821 "!optimize_debug && optimize
1822 && xtensa_shlrd_which_direction (operands[4], operands[5]) != UNKNOWN"
1823{
1824 switch (xtensa_shlrd_which_direction (operands[4], operands[5]))
1825 {
1826 case ASHIFT: return "ssa8b\t%2\;src\t%0, %1, %3";
1827 case LSHIFTRT: return "ssa8l\t%2\;src\t%0, %3, %1";
1828 default: gcc_unreachable ();
1829 }
1830}
1831 [(set_attr "type" "arith")
1832 (set_attr "mode" "SI")
1833 (set_attr "length" "6")])
1834
feae4e83 1835(define_insn_and_split "*shlrd_per_byte_omit_AND"
1c68ec1f 1836 [(set (match_operand:SI 0 "register_operand" "=a")
feae4e83
TJJS
1837 (match_operator:SI 7 "xtensa_bit_join_operator"
1838 [(match_operator:SI 5 "logical_shift_operator"
1c68ec1f
TJJS
1839 [(match_operand:SI 1 "register_operand" "r")
1840 (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1841 (const_int 3))
1842 (match_operand:SI 4 "const_int_operand" "i"))])
feae4e83 1843 (match_operator:SI 6 "logical_shift_operator"
1c68ec1f
TJJS
1844 [(match_operand:SI 3 "register_operand" "r")
1845 (neg:SI (and:SI (ashift:SI (match_dup 2)
1846 (const_int 3))
feae4e83 1847 (match_dup 4)))])]))]
1c68ec1f
TJJS
1848 "!optimize_debug && optimize
1849 && xtensa_shlrd_which_direction (operands[5], operands[6]) != UNKNOWN
1850 && (INTVAL (operands[4]) & 0x1f) == 3 << 3"
1851 "#"
1852 "&& 1"
1853 [(set (match_dup 0)
feae4e83
TJJS
1854 (match_op_dup 7
1855 [(match_op_dup 5
1c68ec1f
TJJS
1856 [(match_dup 1)
1857 (ashift:SI (match_dup 2)
1858 (const_int 3))])
feae4e83 1859 (match_op_dup 6
1c68ec1f
TJJS
1860 [(match_dup 3)
1861 (neg:SI (ashift:SI (match_dup 2)
feae4e83 1862 (const_int 3)))])]))]
40bf68bb 1863 ""
40bf68bb
TJJS
1864 [(set_attr "type" "arith")
1865 (set_attr "mode" "SI")
1866 (set_attr "length" "6")])
1867
03984308
BW
1868(define_insn "rotlsi3"
1869 [(set (match_operand:SI 0 "register_operand" "=a,a")
1870 (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
1871 (match_operand:SI 2 "arith_operand" "J,r")))]
1872 ""
1873 "@
13fb3a61
BW
1874 ssai\t%L2\;src\t%0, %1, %1
1875 ssl\t%2\;src\t%0, %1, %1"
03984308
BW
1876 [(set_attr "type" "multi,multi")
1877 (set_attr "mode" "SI")
1878 (set_attr "length" "6,6")])
1879
1880(define_insn "rotrsi3"
1881 [(set (match_operand:SI 0 "register_operand" "=a,a")
1882 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
1883 (match_operand:SI 2 "arith_operand" "J,r")))]
1884 ""
1885 "@
13fb3a61
BW
1886 ssai\t%R2\;src\t%0, %1, %1
1887 ssr\t%2\;src\t%0, %1, %1"
03984308
BW
1888 [(set_attr "type" "multi,multi")
1889 (set_attr "mode" "SI")
1890 (set_attr "length" "6,6")])
1891
13fb3a61
BW
1892\f
1893;; Comparisons.
0c14a54d 1894
f90b7a5a 1895;; Conditional branches.
03984308 1896
f90b7a5a
PB
1897(define_expand "cbranchsi4"
1898 [(match_operator 0 "comparison_operator"
1899 [(match_operand:SI 1 "register_operand")
1900 (match_operand:SI 2 "nonmemory_operand")])
1901 (match_operand 3 "")]
03984308 1902 ""
03984308 1903{
f90b7a5a 1904 xtensa_expand_conditional_branch (operands, SImode);
03984308 1905 DONE;
13fb3a61 1906})
03984308 1907
f90b7a5a
PB
1908(define_expand "cbranchsf4"
1909 [(match_operator 0 "comparison_operator"
1910 [(match_operand:SF 1 "register_operand")
1911 (match_operand:SF 2 "register_operand")])
1912 (match_operand 3 "")]
03984308 1913 "TARGET_HARD_FLOAT"
03984308 1914{
f90b7a5a 1915 xtensa_expand_conditional_branch (operands, SFmode);
03984308 1916 DONE;
13fb3a61 1917})
03984308
BW
1918
1919;; Branch patterns for standard integer comparisons
1920
3219c65b 1921(define_insn "*btrue"
03984308
BW
1922 [(set (pc)
1923 (if_then_else (match_operator 3 "branch_operator"
e1b193c1 1924 [(match_operand:SI 0 "register_operand" "r,r")
bb65bd08 1925 (match_operand:SI 1 "branch_operand" "K,?r")])
03984308
BW
1926 (label_ref (match_operand 2 "" ""))
1927 (pc)))]
1928 ""
03984308 1929{
e1b193c1 1930 return xtensa_emit_branch (which_alternative == 0, operands);
13fb3a61 1931}
03984308
BW
1932 [(set_attr "type" "jump,jump")
1933 (set_attr "mode" "none")
bb65bd08
TJJS
1934 (set (attr "length")
1935 (if_then_else (match_test "TARGET_DENSITY
1936 && CONST_INT_P (operands[1])
1937 && INTVAL (operands[1]) == 0
1938 && (GET_CODE (operands[3]) == EQ
1939 || GET_CODE (operands[3]) == NE)")
1940 (const_int 2)
1941 (const_int 3)))])
03984308 1942
830d36b3
TJJS
1943(define_insn_and_split "*btrue_INT_MIN"
1944 [(set (pc)
1945 (if_then_else (match_operator 2 "boolean_operator"
1946 [(match_operand:SI 0 "register_operand" "r")
1947 (const_int -2147483648)])
1948 (label_ref (match_operand 1 ""))
1949 (pc)))]
1950 "TARGET_ABS"
1951 "#"
1952 "&& can_create_pseudo_p ()"
1953 [(set (match_dup 3)
1954 (abs:SI (match_dup 0)))
1955 (set (pc)
1956 (if_then_else (match_op_dup 2
1957 [(zero_extract:SI (match_dup 3)
1958 (const_int 1)
1959 (match_dup 4))
1960 (const_int 0)])
1961 (label_ref (match_dup 1))
1962 (pc)))]
1963{
1964 operands[3] = gen_reg_rtx (SImode);
1965 operands[4] = GEN_INT (BITS_BIG_ENDIAN ? 0 : 31);
1966 operands[2] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[2])),
1967 VOIDmode, XEXP (operands[2], 0),
1968 const0_rtx);
1969}
1970 [(set_attr "type" "jump")
1971 (set_attr "mode" "none")
1972 (set_attr "length" "6")])
1973
3219c65b 1974(define_insn "*ubtrue"
03984308
BW
1975 [(set (pc)
1976 (if_then_else (match_operator 3 "ubranch_operator"
e1b193c1
TJJS
1977 [(match_operand:SI 0 "register_operand" "r,r")
1978 (match_operand:SI 1 "ubranch_operand" "L,r")])
03984308
BW
1979 (label_ref (match_operand 2 "" ""))
1980 (pc)))]
1981 ""
03984308 1982{
e1b193c1 1983 return xtensa_emit_branch (which_alternative == 0, operands);
13fb3a61 1984}
03984308
BW
1985 [(set_attr "type" "jump,jump")
1986 (set_attr "mode" "none")
1987 (set_attr "length" "3,3")])
1988
1989;; Branch patterns for bit testing
1990
3219c65b 1991(define_insn "*bittrue"
03984308
BW
1992 [(set (pc)
1993 (if_then_else (match_operator 3 "boolean_operator"
e1b193c1
TJJS
1994 [(zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1995 (const_int 1)
1996 (match_operand:SI 1 "arith_operand" "J,r"))
03984308 1997 (const_int 0)])
03984308
BW
1998 (label_ref (match_operand 2 "" ""))
1999 (pc)))]
2000 ""
03984308 2001{
e1b193c1
TJJS
2002 static char result[64];
2003 char op;
03984308
BW
2004 switch (GET_CODE (operands[3]))
2005 {
e1b193c1
TJJS
2006 case EQ: op = 'c'; break;
2007 case NE: op = 's'; break;
2008 default: gcc_unreachable ();
03984308 2009 }
e1b193c1
TJJS
2010 if (which_alternative == 0)
2011 {
2012 operands[1] = GEN_INT (INTVAL (operands[1]) & 0x1f);
2013 sprintf (result, "bb%ci\t%%0, %%d1, %%2", op);
2014 }
2015 else
2016 sprintf (result, "bb%c\t%%0, %%1, %%2", op);
2017 return result;
13fb3a61 2018}
03984308
BW
2019 [(set_attr "type" "jump")
2020 (set_attr "mode" "none")
2021 (set_attr "length" "3")])
2022
e1b193c1 2023(define_insn "*masktrue"
03984308
BW
2024 [(set (pc)
2025 (if_then_else (match_operator 3 "boolean_operator"
e1b193c1
TJJS
2026 [(and:SI (match_operand:SI 0 "register_operand" "r")
2027 (match_operand:SI 1 "register_operand" "r"))
2028 (const_int 0)])
2029 (label_ref (match_operand 2 "" ""))
2030 (pc)))]
03984308 2031 ""
03984308
BW
2032{
2033 switch (GET_CODE (operands[3]))
2034 {
e1b193c1
TJJS
2035 case EQ: return "bnone\t%0, %1, %2";
2036 case NE: return "bany\t%0, %1, %2";
2037 default: gcc_unreachable ();
03984308 2038 }
13fb3a61 2039}
03984308
BW
2040 [(set_attr "type" "jump")
2041 (set_attr "mode" "none")
2042 (set_attr "length" "3")])
2043
70ce04ca
TJJS
2044(define_insn "*masktrue_bitcmpl"
2045 [(set (pc)
2046 (if_then_else (match_operator 3 "boolean_operator"
2047 [(and:SI (not:SI (match_operand:SI 0 "register_operand" "r"))
2048 (match_operand:SI 1 "register_operand" "r"))
2049 (const_int 0)])
2050 (label_ref (match_operand 2 "" ""))
2051 (pc)))]
2052 ""
2053{
2054 switch (GET_CODE (operands[3]))
2055 {
2056 case EQ: return "ball\t%0, %1, %2";
2057 case NE: return "bnall\t%0, %1, %2";
2058 default: gcc_unreachable ();
2059 }
2060}
2061 [(set_attr "type" "jump")
2062 (set_attr "mode" "none")
2063 (set_attr "length" "3")])
2064
64cb87b2
TJJS
2065(define_insn_and_split "*masktrue_const_bitcmpl"
2066 [(set (pc)
2067 (if_then_else (match_operator 3 "boolean_operator"
2068 [(and:SI (not:SI (match_operand:SI 0 "register_operand" "r"))
2069 (match_operand:SI 1 "const_int_operand" "i"))
2070 (const_int 0)])
2071 (label_ref (match_operand 2 "" ""))
2072 (pc)))]
2073 "exact_log2 (INTVAL (operands[1])) < 0"
2074 "#"
2075 "&& can_create_pseudo_p ()"
2076 [(set (match_dup 4)
2077 (match_dup 1))
2078 (set (pc)
2079 (if_then_else (match_op_dup 3
2080 [(and:SI (not:SI (match_dup 0))
2081 (match_dup 4))
2082 (const_int 0)])
2083 (label_ref (match_dup 2))
2084 (pc)))]
2085{
2086 operands[4] = gen_reg_rtx (SImode);
2087}
2088 [(set_attr "type" "jump")
2089 (set_attr "mode" "none")
2090 (set (attr "length")
2091 (if_then_else (match_test "TARGET_DENSITY
2092 && IN_RANGE (INTVAL (operands[1]), -32, 95)")
2093 (const_int 5)
2094 (if_then_else (match_test "xtensa_simm12b (INTVAL (operands[1]))")
2095 (const_int 6)
2096 (const_int 10))))])
2097
2098(define_split
2099 [(set (pc)
2100 (if_then_else (match_operator 2 "boolean_operator"
2101 [(subreg:HQI (not:SI (match_operand:SI 0 "register_operand")) 0)
2102 (const_int 0)])
2103 (label_ref (match_operand 1 ""))
2104 (pc)))]
2105 "!BYTES_BIG_ENDIAN"
2106 [(set (pc)
2107 (if_then_else (match_op_dup 2
2108 [(and:SI (not:SI (match_dup 0))
2109 (match_dup 3))
2110 (const_int 0)])
2111 (label_ref (match_dup 1))
2112 (pc)))]
2113{
2114 operands[3] = GEN_INT ((1 << GET_MODE_BITSIZE (<MODE>mode)) - 1);
2115})
2116
2117(define_split
2118 [(set (pc)
2119 (if_then_else (match_operator 2 "boolean_operator"
2120 [(subreg:HI (not:SI (match_operand:SI 0 "register_operand")) 2)
2121 (const_int 0)])
2122 (label_ref (match_operand 1 ""))
2123 (pc)))]
2124 "BYTES_BIG_ENDIAN"
2125 [(set (pc)
2126 (if_then_else (match_op_dup 2
2127 [(and:SI (not:SI (match_dup 0))
2128 (const_int 65535))
2129 (const_int 0)])
2130 (label_ref (match_dup 1))
2131 (pc)))])
2132
2133(define_split
2134 [(set (pc)
2135 (if_then_else (match_operator 2 "boolean_operator"
2136 [(subreg:QI (not:SI (match_operand:SI 0 "register_operand")) 3)
2137 (const_int 0)])
2138 (label_ref (match_operand 1 ""))
2139 (pc)))]
2140 "BYTES_BIG_ENDIAN"
2141 [(set (pc)
2142 (if_then_else (match_op_dup 2
2143 [(and:SI (not:SI (match_dup 0))
2144 (const_int 255))
2145 (const_int 0)])
2146 (label_ref (match_dup 1))
2147 (pc)))])
2148
07743893
TJJS
2149(define_insn_and_split "*masktrue_const_pow2_minus_one"
2150 [(set (pc)
d6d8e6a7 2151 (if_then_else (match_operator 4 "boolean_operator"
07743893
TJJS
2152 [(and:SI (match_operand:SI 0 "register_operand" "r")
2153 (match_operand:SI 1 "const_int_operand" "i"))
d6d8e6a7
TJJS
2154 (match_operand:SI 2 "const_int_operand" "i")])
2155 (label_ref (match_operand 3 "" ""))
07743893 2156 (pc)))]
d6d8e6a7
TJJS
2157 "IN_RANGE (exact_log2 (INTVAL (operands[1]) + 1), 17, 31)
2158 /* && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0 // can be omitted */
2159 && xtensa_b4const_or_zero (INTVAL (operands[2]) << (32 - floor_log2 (INTVAL (operands[1]) + 1)))"
07743893
TJJS
2160 "#"
2161 "&& can_create_pseudo_p ()"
d6d8e6a7 2162 [(set (match_dup 5)
07743893
TJJS
2163 (ashift:SI (match_dup 0)
2164 (match_dup 1)))
2165 (set (pc)
d6d8e6a7
TJJS
2166 (if_then_else (match_op_dup 4
2167 [(match_dup 5)
2168 (match_dup 2)])
2169 (label_ref (match_dup 3))
07743893
TJJS
2170 (pc)))]
2171{
d6d8e6a7
TJJS
2172 int shift = 32 - floor_log2 (INTVAL (operands[1]) + 1);
2173 operands[1] = GEN_INT (shift);
2174 operands[2] = GEN_INT (INTVAL (operands[2]) << shift);
2175 operands[5] = gen_reg_rtx (SImode);
07743893
TJJS
2176}
2177 [(set_attr "type" "jump")
2178 (set_attr "mode" "none")
2179 (set (attr "length")
d6d8e6a7
TJJS
2180 (if_then_else (match_test "(TARGET_DENSITY && INTVAL (operands[1]) == 0x7FFFFFFF)
2181 && INTVAL (operands[2]) == 0")
2182 (const_int 4)
2183 (if_then_else (match_test "TARGET_DENSITY
2184 && (INTVAL (operands[1]) == 0x7FFFFFFF
2185 || INTVAL (operands[2]) == 0)")
2186 (const_int 5)
2187 (const_int 6))))])
07743893
TJJS
2188
2189(define_insn_and_split "*masktrue_const_negative_pow2"
2190 [(set (pc)
d6d8e6a7 2191 (if_then_else (match_operator 4 "boolean_operator"
07743893
TJJS
2192 [(and:SI (match_operand:SI 0 "register_operand" "r")
2193 (match_operand:SI 1 "const_int_operand" "i"))
d6d8e6a7
TJJS
2194 (match_operand:SI 2 "const_int_operand" "i")])
2195 (label_ref (match_operand 3 "" ""))
07743893 2196 (pc)))]
d6d8e6a7
TJJS
2197 "IN_RANGE (exact_log2 (-INTVAL (operands[1])), 1, 30)
2198 /* && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0 // can be omitted */
2199 && xtensa_b4const_or_zero (INTVAL (operands[2]) >> floor_log2 (-INTVAL (operands[1])))"
07743893
TJJS
2200 "#"
2201 "&& can_create_pseudo_p ()"
d6d8e6a7 2202 [(set (match_dup 5)
07743893
TJJS
2203 (lshiftrt:SI (match_dup 0)
2204 (match_dup 1)))
2205 (set (pc)
d6d8e6a7
TJJS
2206 (if_then_else (match_op_dup 4
2207 [(match_dup 5)
2208 (match_dup 2)])
2209 (label_ref (match_dup 3))
07743893
TJJS
2210 (pc)))]
2211{
d6d8e6a7
TJJS
2212 int shift = floor_log2 (-INTVAL (operands[1]));
2213 operands[1] = GEN_INT (shift);
2214 operands[2] = GEN_INT (INTVAL (operands[2]) >> shift);
2215 operands[5] = gen_reg_rtx (SImode);
07743893
TJJS
2216}
2217 [(set_attr "type" "jump")
2218 (set_attr "mode" "none")
d6d8e6a7
TJJS
2219 (set (attr "length")
2220 (if_then_else (match_test "TARGET_DENSITY && INTVAL (operands[2]) == 0")
2221 (const_int 5)
2222 (const_int 6)))])
07743893
TJJS
2223
2224(define_insn_and_split "*masktrue_const_shifted_mask"
2225 [(set (pc)
2226 (if_then_else (match_operator 4 "boolean_operator"
2227 [(and:SI (match_operand:SI 0 "register_operand" "r")
2228 (match_operand:SI 1 "shifted_mask_operand" "i"))
2229 (match_operand:SI 2 "const_int_operand" "i")])
2230 (label_ref (match_operand 3 "" ""))
2231 (pc)))]
d6d8e6a7
TJJS
2232 "/* (INTVAL (operands[2]) & ((1 << ctz_hwi (INTVAL (operands[1]))) - 1)) == 0 // can be omitted
2233 && */ xtensa_b4const_or_zero ((uint32_t)INTVAL (operands[2]) >> ctz_hwi (INTVAL (operands[1])))"
07743893
TJJS
2234 "#"
2235 "&& can_create_pseudo_p ()"
2236 [(set (match_dup 6)
2237 (zero_extract:SI (match_dup 0)
2238 (match_dup 5)
2239 (match_dup 1)))
2240 (set (pc)
2241 (if_then_else (match_op_dup 4
2242 [(match_dup 6)
2243 (match_dup 2)])
2244 (label_ref (match_dup 3))
2245 (pc)))]
2246{
2247 HOST_WIDE_INT mask = INTVAL (operands[1]);
2248 int shift = ctz_hwi (mask);
2249 int mask_size = floor_log2 (((uint32_t)mask >> shift) + 1);
2250 int mask_pos = shift;
2251 if (BITS_BIG_ENDIAN)
2252 mask_pos = (32 - (mask_size + shift)) & 0x1f;
2253 operands[1] = GEN_INT (mask_pos);
2254 operands[2] = GEN_INT ((uint32_t)INTVAL (operands[2]) >> shift);
2255 operands[5] = GEN_INT (mask_size);
2256 operands[6] = gen_reg_rtx (SImode);
2257}
2258 [(set_attr "type" "jump")
2259 (set_attr "mode" "none")
2260 (set (attr "length")
2261 (if_then_else (match_test "TARGET_DENSITY
2262 && (uint32_t)INTVAL (operands[2]) >> ctz_hwi (INTVAL (operands[1])) == 0")
2263 (const_int 5)
2264 (const_int 6)))])
2265
03984308 2266
6383386a
FY
2267;; Zero-overhead looping support.
2268
13fb3a61 2269;; Define the loop insns used by bct optimization to represent the
6383386a
FY
2270;; start and end of a zero-overhead loop. This start template generates
2271;; the loop insn; the end template doesn't generate any instructions since
2272;; loop end is handled in hardware.
03984308
BW
2273
2274(define_insn "zero_cost_loop_start"
13fb3a61 2275 [(set (pc)
89d5982b
TJJS
2276 (if_then_else (ne (match_operand:SI 2 "register_operand" "0")
2277 (const_int 1))
2278 (label_ref (match_operand 1 "" ""))
2279 (pc)))
48c55a0a 2280 (set (match_operand:SI 0 "register_operand" "=a")
4f609c6f
TJJS
2281 (plus:SI (match_dup 0)
2282 (const_int -1)))
6383386a
FY
2283 (unspec [(const_int 0)] UNSPEC_LSETUP_START)]
2284 "TARGET_LOOPS && optimize"
2285 "loop\t%0, %l1_LEND"
03984308
BW
2286 [(set_attr "type" "jump")
2287 (set_attr "mode" "none")
2288 (set_attr "length" "3")])
2289
2290(define_insn "zero_cost_loop_end"
13fb3a61 2291 [(set (pc)
89d5982b
TJJS
2292 (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0")
2293 (const_int 1))
2294 (label_ref (match_operand 1 "" ""))
2295 (pc)))
48c55a0a 2296 (set (match_operand:SI 0 "nonimmediate_operand" "=a,m")
4f609c6f
TJJS
2297 (plus:SI (match_dup 0)
2298 (const_int -1)))
6383386a
FY
2299 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
2300 (clobber (match_scratch:SI 3 "=X,&r"))]
2301 "TARGET_LOOPS && optimize"
2302 "#"
2303 [(set_attr "type" "jump")
2304 (set_attr "mode" "none")
2305 (set_attr "length" "0")])
2306
2307(define_insn "loop_end"
2308 [(set (pc)
89d5982b
TJJS
2309 (if_then_else (ne (match_operand:SI 2 "register_operand" "0")
2310 (const_int 1))
2311 (label_ref (match_operand 1 "" ""))
2312 (pc)))
48c55a0a 2313 (set (match_operand:SI 0 "register_operand" "=a")
4f609c6f
TJJS
2314 (plus:SI (match_dup 0)
2315 (const_int -1)))
6383386a
FY
2316 (unspec [(const_int 0)] UNSPEC_LSETUP_END)]
2317 "TARGET_LOOPS && optimize"
13fb3a61 2318{
6383386a
FY
2319 xtensa_emit_loop_end (insn, operands);
2320 return "";
13fb3a61 2321}
03984308
BW
2322 [(set_attr "type" "jump")
2323 (set_attr "mode" "none")
2324 (set_attr "length" "0")])
2325
6383386a
FY
2326(define_split
2327 [(set (pc)
89d5982b
TJJS
2328 (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "")
2329 (const_int 1))
2330 (label_ref (match_operand 1 "" ""))
2331 (pc)))
6383386a 2332 (set (match_operand:SI 2 "nonimmediate_operand" "")
89d5982b
TJJS
2333 (plus:SI (match_dup 0)
2334 (const_int -1)))
6383386a
FY
2335 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
2336 (clobber (match_scratch 3))]
2337 "TARGET_LOOPS && optimize && reload_completed"
2338 [(const_int 0)]
2339{
2340 if (!REG_P (operands[0]))
2341 {
2342 rtx test;
2343
2344 /* Fallback into a normal conditional branch insn. */
2345 emit_move_insn (operands[3], operands[0]);
2346 emit_insn (gen_addsi3 (operands[3], operands[3], constm1_rtx));
2347 emit_move_insn (operands[0], operands[3]);
2348 test = gen_rtx_NE (VOIDmode, operands[3], const0_rtx);
2349 emit_jump_insn (gen_cbranchsi4 (test, operands[3],
89d5982b 2350 const0_rtx, operands[1]));
6383386a
FY
2351 }
2352 else
2353 {
2354 emit_jump_insn (gen_loop_end (operands[0], operands[1], operands[2]));
2355 }
2356
2357 DONE;
2358})
2359
2360; operand 0 is the loop count pseudo register
2361; operand 1 is the label to jump to at the top of the loop
2362(define_expand "doloop_end"
2363 [(parallel [(set (pc) (if_then_else
89d5982b
TJJS
2364 (ne (match_operand:SI 0 "" "")
2365 (const_int 1))
2366 (label_ref (match_operand 1 "" ""))
2367 (pc)))
2368 (set (match_dup 0)
2369 (plus:SI (match_dup 0)
2370 (const_int -1)))
2371 (unspec [(const_int 0)] UNSPEC_LSETUP_END)
2372 (clobber (match_dup 2))])] ; match_scratch
6383386a
FY
2373 "TARGET_LOOPS && optimize"
2374{
2375 /* The loop optimizer doesn't check the predicates... */
2376 if (GET_MODE (operands[0]) != SImode)
2377 FAIL;
2378 operands[2] = gen_rtx_SCRATCH (SImode);
2379})
2380
13fb3a61
BW
2381\f
2382;; Setting a register from a comparison.
03984308 2383
f90b7a5a
PB
2384(define_expand "cstoresi4"
2385 [(match_operand:SI 0 "register_operand")
2386 (match_operator 1 "xtensa_cstoresi_operator"
2387 [(match_operand:SI 2 "register_operand")
2388 (match_operand:SI 3 "nonmemory_operand")])]
03984308 2389 ""
03984308 2390{
f90b7a5a 2391 if (!xtensa_expand_scc (operands, SImode))
13fb3a61 2392 FAIL;
03984308 2393 DONE;
13fb3a61 2394})
03984308 2395
fd948fd8
MF
2396(define_insn "salt"
2397 [(set (match_operand:SI 0 "register_operand" "=a")
2398 (lt:SI (match_operand:SI 1 "register_operand" "r")
2399 (match_operand:SI 2 "register_operand" "r")))]
2400 "TARGET_SALT"
2401 "salt\t%0, %1, %2"
2402 [(set_attr "type" "arith")
2403 (set_attr "mode" "SI")
2404 (set_attr "length" "3")])
2405
2406(define_insn "saltu"
2407 [(set (match_operand:SI 0 "register_operand" "=a")
2408 (ltu:SI (match_operand:SI 1 "register_operand" "r")
2409 (match_operand:SI 2 "register_operand" "r")))]
2410 "TARGET_SALT"
2411 "saltu\t%0, %1, %2"
2412 [(set_attr "type" "arith")
2413 (set_attr "mode" "SI")
2414 (set_attr "length" "3")])
2415
f90b7a5a
PB
2416(define_expand "cstoresf4"
2417 [(match_operand:SI 0 "register_operand")
2418 (match_operator:SI 1 "comparison_operator"
2419 [(match_operand:SF 2 "register_operand")
2420 (match_operand:SF 3 "register_operand")])]
2421 "TARGET_HARD_FLOAT"
2422{
2423 if (!xtensa_expand_scc (operands, SFmode))
2424 FAIL;
2425 DONE;
2426})
2427
2428
13fb3a61
BW
2429\f
2430;; Conditional moves.
03984308
BW
2431
2432(define_expand "movsicc"
2433 [(set (match_operand:SI 0 "register_operand" "")
2434 (if_then_else:SI (match_operand 1 "comparison_operator" "")
2435 (match_operand:SI 2 "register_operand" "")
2436 (match_operand:SI 3 "register_operand" "")))]
2437 ""
03984308 2438{
13fb3a61
BW
2439 if (!xtensa_expand_conditional_move (operands, 0))
2440 FAIL;
03984308 2441 DONE;
13fb3a61 2442})
03984308
BW
2443
2444(define_expand "movsfcc"
2445 [(set (match_operand:SF 0 "register_operand" "")
2446 (if_then_else:SF (match_operand 1 "comparison_operator" "")
2447 (match_operand:SF 2 "register_operand" "")
2448 (match_operand:SF 3 "register_operand" "")))]
2449 ""
03984308 2450{
13fb3a61
BW
2451 if (!xtensa_expand_conditional_move (operands, 1))
2452 FAIL;
03984308 2453 DONE;
13fb3a61 2454})
03984308
BW
2455
2456(define_insn "movsicc_internal0"
2457 [(set (match_operand:SI 0 "register_operand" "=a,a")
2458 (if_then_else:SI (match_operator 4 "branch_operator"
2459 [(match_operand:SI 1 "register_operand" "r,r")
2460 (const_int 0)])
2461 (match_operand:SI 2 "register_operand" "r,0")
2462 (match_operand:SI 3 "register_operand" "0,r")))]
2463 ""
03984308 2464{
036a2b7a 2465 return xtensa_emit_movcc (which_alternative == 1, false, false, operands);
13fb3a61 2466}
03984308
BW
2467 [(set_attr "type" "move,move")
2468 (set_attr "mode" "SI")
2469 (set_attr "length" "3,3")])
2470
2471(define_insn "movsicc_internal1"
2472 [(set (match_operand:SI 0 "register_operand" "=a,a")
2473 (if_then_else:SI (match_operator 4 "boolean_operator"
2474 [(match_operand:CC 1 "register_operand" "b,b")
2475 (const_int 0)])
2476 (match_operand:SI 2 "register_operand" "r,0")
2477 (match_operand:SI 3 "register_operand" "0,r")))]
2478 "TARGET_BOOLEANS"
03984308 2479{
036a2b7a 2480 return xtensa_emit_movcc (which_alternative == 1, false, true, operands);
13fb3a61 2481}
03984308
BW
2482 [(set_attr "type" "move,move")
2483 (set_attr "mode" "SI")
2484 (set_attr "length" "3,3")])
2485
2486(define_insn "movsfcc_internal0"
2487 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2488 (if_then_else:SF (match_operator 4 "branch_operator"
2489 [(match_operand:SI 1 "register_operand" "r,r,r,r")
2490 (const_int 0)])
2491 (match_operand:SF 2 "register_operand" "r,0,f,0")
2492 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2493 ""
03984308 2494{
036a2b7a
BW
2495 return xtensa_emit_movcc ((which_alternative & 1) == 1,
2496 which_alternative >= 2, false, operands);
13fb3a61 2497}
03984308
BW
2498 [(set_attr "type" "move,move,move,move")
2499 (set_attr "mode" "SF")
2500 (set_attr "length" "3,3,3,3")])
2501
2502(define_insn "movsfcc_internal1"
2503 [(set (match_operand:SF 0 "register_operand" "=a,a,f,f")
2504 (if_then_else:SF (match_operator 4 "boolean_operator"
2505 [(match_operand:CC 1 "register_operand" "b,b,b,b")
2506 (const_int 0)])
2507 (match_operand:SF 2 "register_operand" "r,0,f,0")
2508 (match_operand:SF 3 "register_operand" "0,r,0,f")))]
2509 "TARGET_BOOLEANS"
03984308 2510{
036a2b7a
BW
2511 return xtensa_emit_movcc ((which_alternative & 1) == 1,
2512 which_alternative >= 2, true, operands);
13fb3a61 2513}
03984308
BW
2514 [(set_attr "type" "move,move,move,move")
2515 (set_attr "mode" "SF")
2516 (set_attr "length" "3,3,3,3")])
2517
13fb3a61
BW
2518\f
2519;; Floating-point comparisons.
03984308 2520
036a2b7a 2521(define_insn "s<code>_sf"
03984308 2522 [(set (match_operand:CC 0 "register_operand" "=b")
036a2b7a
BW
2523 (any_scc_sf:CC (match_operand:SF 1 "register_operand" "f")
2524 (match_operand:SF 2 "register_operand" "f")))]
03984308 2525 "TARGET_HARD_FLOAT"
ff779f98 2526 "<scc_sf>.s\t%0, %1, %2"
03984308
BW
2527 [(set_attr "type" "farith")
2528 (set_attr "mode" "BL")
2529 (set_attr "length" "3")])
2530
13fb3a61
BW
2531\f
2532;; Unconditional branches.
03984308
BW
2533
2534(define_insn "jump"
2535 [(set (pc)
2536 (label_ref (match_operand 0 "" "")))]
2537 ""
13fb3a61 2538 "j\t%l0"
03984308
BW
2539 [(set_attr "type" "jump")
2540 (set_attr "mode" "none")
2541 (set_attr "length" "3")])
2542
2543(define_expand "indirect_jump"
13fb3a61
BW
2544 [(set (pc)
2545 (match_operand 0 "register_operand" ""))]
03984308 2546 ""
03984308
BW
2547{
2548 rtx dest = operands[0];
2549 if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode)
2550 operands[0] = copy_to_mode_reg (Pmode, dest);
2551
2552 emit_jump_insn (gen_indirect_jump_internal (dest));
2553 DONE;
13fb3a61 2554})
03984308
BW
2555
2556(define_insn "indirect_jump_internal"
2557 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
2558 ""
13fb3a61 2559 "jx\t%0"
03984308
BW
2560 [(set_attr "type" "jump")
2561 (set_attr "mode" "none")
2562 (set_attr "length" "3")])
2563
2564
2565(define_expand "tablejump"
2566 [(use (match_operand:SI 0 "register_operand" ""))
2567 (use (label_ref (match_operand 1 "" "")))]
2568 ""
03984308
BW
2569{
2570 rtx target = operands[0];
2571 if (flag_pic)
2572 {
13fb3a61 2573 /* For PIC, the table entry is relative to the start of the table. */
03984308
BW
2574 rtx label = gen_reg_rtx (SImode);
2575 target = gen_reg_rtx (SImode);
2576 emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
2577 emit_insn (gen_addsi3 (target, operands[0], label));
2578 }
2579 emit_jump_insn (gen_tablejump_internal (target, operands[1]));
2580 DONE;
13fb3a61 2581})
03984308
BW
2582
2583(define_insn "tablejump_internal"
2584 [(set (pc)
2585 (match_operand:SI 0 "register_operand" "r"))
2586 (use (label_ref (match_operand 1 "" "")))]
2587 ""
13fb3a61 2588 "jx\t%0"
03984308
BW
2589 [(set_attr "type" "jump")
2590 (set_attr "mode" "none")
2591 (set_attr "length" "3")])
2592
13fb3a61
BW
2593\f
2594;; Function calls.
03984308
BW
2595
2596(define_expand "sym_PLT"
2597 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT))]
2598 ""
2599 "")
2600
2601(define_expand "call"
2602 [(call (match_operand 0 "memory_operand" "")
2603 (match_operand 1 "" ""))]
2604 ""
03984308 2605{
461d3c84
MF
2606 xtensa_expand_call (0, operands);
2607 DONE;
13fb3a61 2608})
03984308
BW
2609
2610(define_insn "call_internal"
887af464
BW
2611 [(call (mem (match_operand:SI 0 "call_insn_operand" "nir"))
2612 (match_operand 1 "" "i"))]
43b0c56f 2613 "!SIBLING_CALL_P (insn)"
13fb3a61
BW
2614{
2615 return xtensa_emit_call (0, operands);
2616}
03984308
BW
2617 [(set_attr "type" "call")
2618 (set_attr "mode" "none")
2619 (set_attr "length" "3")])
2620
2621(define_expand "call_value"
2622 [(set (match_operand 0 "register_operand" "")
2623 (call (match_operand 1 "memory_operand" "")
2624 (match_operand 2 "" "")))]
2625 ""
03984308 2626{
461d3c84
MF
2627 xtensa_expand_call (1, operands);
2628 DONE;
13fb3a61 2629})
03984308 2630
03984308 2631(define_insn "call_value_internal"
6a7a462c 2632 [(set (match_operand 0 "register_operand" "=a")
89d5982b
TJJS
2633 (call (mem (match_operand:SI 1 "call_insn_operand" "nir"))
2634 (match_operand 2 "" "i")))]
43b0c56f 2635 "!SIBLING_CALL_P (insn)"
13fb3a61
BW
2636{
2637 return xtensa_emit_call (1, operands);
2638}
03984308
BW
2639 [(set_attr "type" "call")
2640 (set_attr "mode" "none")
2641 (set_attr "length" "3")])
2642
43b0c56f 2643(define_expand "sibcall"
4c3191de
MF
2644 [(call (match_operand 0 "memory_operand" "")
2645 (match_operand 1 "" ""))]
43b0c56f
TJJS
2646 "!TARGET_WINDOWED_ABI"
2647{
461d3c84
MF
2648 xtensa_expand_call (0, operands);
2649 DONE;
43b0c56f
TJJS
2650})
2651
2652(define_insn "sibcall_internal"
8731aa98 2653 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "nic"))
4c3191de 2654 (match_operand 1 "" "i"))]
43b0c56f
TJJS
2655 "!TARGET_WINDOWED_ABI && SIBLING_CALL_P (insn)"
2656{
2657 return xtensa_emit_sibcall (0, operands);
2658}
2659 [(set_attr "type" "call")
2660 (set_attr "mode" "none")
2661 (set_attr "length" "3")])
2662
43b0c56f 2663(define_expand "sibcall_value"
4c3191de
MF
2664 [(set (match_operand 0 "register_operand" "")
2665 (call (match_operand 1 "memory_operand" "")
2666 (match_operand 2 "" "")))]
43b0c56f
TJJS
2667 "!TARGET_WINDOWED_ABI"
2668{
461d3c84
MF
2669 xtensa_expand_call (1, operands);
2670 DONE;
43b0c56f
TJJS
2671})
2672
2673(define_insn "sibcall_value_internal"
2674 [(set (match_operand 0 "register_operand" "=a")
8731aa98 2675 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "nic"))
4c3191de 2676 (match_operand 2 "" "i")))]
43b0c56f
TJJS
2677 "!TARGET_WINDOWED_ABI && SIBLING_CALL_P (insn)"
2678{
2679 return xtensa_emit_sibcall (1, operands);
2680}
2681 [(set_attr "type" "call")
2682 (set_attr "mode" "none")
2683 (set_attr "length" "3")])
2684
71cd6a04
MF
2685(define_expand "untyped_call"
2686 [(parallel [(call (match_operand 0 "")
2687 (const_int 0))
2688 (match_operand 1 "")
2689 (match_operand 2 "")])]
2690 ""
2691{
2692 int i;
2693
2694 emit_call_insn (gen_call (operands[0], const0_rtx));
2695
2696 for (i = 0; i < XVECLEN (operands[2], 0); i++)
2697 {
2698 rtx set = XVECEXP (operands[2], 0, i);
2699 emit_move_insn (SET_DEST (set), SET_SRC (set));
2700 }
2701
2702 emit_insn (gen_blockage ());
2703 DONE;
2704})
2705
f42f5a1b
BW
2706(define_insn "entry"
2707 [(set (reg:SI A1_REG)
35a3be48 2708 (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")]
f42f5a1b
BW
2709 UNSPECV_ENTRY))]
2710 ""
35a3be48
BW
2711 "entry\tsp, %0"
2712 [(set_attr "type" "entry")
f42f5a1b
BW
2713 (set_attr "mode" "SI")
2714 (set_attr "length" "3")])
2715
03984308
BW
2716(define_insn "return"
2717 [(return)
2718 (use (reg:SI A0_REG))]
ad89d820 2719 "xtensa_use_return_instruction_p ()"
03984308 2720{
590e2636
MF
2721 return TARGET_WINDOWED_ABI ?
2722 (TARGET_DENSITY ? "retw.n" : "retw") :
2723 (TARGET_DENSITY ? "ret.n" : "ret");
13fb3a61 2724}
03984308
BW
2725 [(set_attr "type" "jump")
2726 (set_attr "mode" "none")
ccd02e73
TJJS
2727 (set (attr "length")
2728 (if_then_else (match_test "TARGET_DENSITY")
2729 (const_int 2)
2730 (const_int 3)))])
03984308 2731
13fb3a61
BW
2732\f
2733;; Miscellaneous instructions.
03984308 2734
9a775e9d
MF
2735;; In windowed ABI stack pointer adjustment must happen before any access
2736;; to the space allocated on stack is allowed, otherwise register spill
2737;; area may be clobbered. That's what frame blockage is supposed to enforce.
2738
2739(define_expand "allocate_stack"
2740 [(set (match_operand 0 "nonimmed_operand")
89d5982b 2741 (minus (reg A1_REG) (match_operand 1 "add_operand")))
9a775e9d 2742 (set (reg A1_REG)
89d5982b 2743 (minus (reg A1_REG) (match_dup 1)))]
9a775e9d
MF
2744 "TARGET_WINDOWED_ABI"
2745{
2746 if (CONST_INT_P (operands[1]))
2747 {
2748 rtx neg_op0 = GEN_INT (-INTVAL (operands[1]));
2749 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, neg_op0));
2750 }
2751 else
2752 {
2753 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
2754 operands[1]));
2755 }
2756 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
2757 emit_insn (gen_frame_blockage ());
2758 DONE;
2759})
2760
f42f5a1b
BW
2761(define_expand "prologue"
2762 [(const_int 0)]
2763 ""
f42f5a1b
BW
2764{
2765 xtensa_expand_prologue ();
2766 DONE;
13fb3a61 2767})
f42f5a1b
BW
2768
2769(define_expand "epilogue"
2770 [(return)]
2771 ""
f42f5a1b 2772{
43b0c56f
TJJS
2773 xtensa_expand_epilogue (false);
2774 DONE;
2775})
2776
2777(define_expand "sibcall_epilogue"
2778 [(return)]
2779 "!TARGET_WINDOWED_ABI"
2780{
2781 xtensa_expand_epilogue (true);
f42f5a1b 2782 DONE;
13fb3a61 2783})
f42f5a1b 2784
03984308
BW
2785(define_insn "nop"
2786 [(const_int 0)]
2787 ""
03984308 2788{
13fb3a61
BW
2789 return (TARGET_DENSITY ? "nop.n" : "nop");
2790}
03984308
BW
2791 [(set_attr "type" "nop")
2792 (set_attr "mode" "none")
ccd02e73
TJJS
2793 (set (attr "length")
2794 (if_then_else (match_test "TARGET_DENSITY")
2795 (const_int 2)
2796 (const_int 3)))])
03984308
BW
2797
2798(define_expand "nonlocal_goto"
2799 [(match_operand:SI 0 "general_operand" "")
2800 (match_operand:SI 1 "general_operand" "")
2801 (match_operand:SI 2 "general_operand" "")
2802 (match_operand:SI 3 "" "")]
590e2636 2803 "TARGET_WINDOWED_ABI"
03984308
BW
2804{
2805 xtensa_expand_nonlocal_goto (operands);
2806 DONE;
13fb3a61 2807})
03984308 2808
6eb065e6
SA
2809;; Stuff an address into the return address register along with the window
2810;; size in the high bits. Because we don't have the window size of the
2811;; previous frame, assume the function called out with a CALL8 since that
2812;; is what compilers always use. Note: __builtin_frob_return_addr has
2813;; already been applied to the handler, but the generic version doesn't
2814;; allow us to frob it quite enough, so we just frob here.
2815
590e2636
MF
2816(define_expand "eh_return"
2817 [(use (match_operand 0 "general_operand"))]
2818 ""
2819{
2820 if (TARGET_WINDOWED_ABI)
2821 emit_insn (gen_eh_set_a0_windowed (operands[0]));
2822 else
2823 emit_insn (gen_eh_set_a0_call0 (operands[0]));
2824 DONE;
2825})
2826
2827(define_insn_and_split "eh_set_a0_windowed"
6eb065e6
SA
2828 [(set (reg:SI A0_REG)
2829 (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
2830 UNSPECV_EH_RETURN))
2831 (clobber (match_scratch:SI 1 "=r"))]
2832 ""
2833 "#"
2834 "reload_completed"
2835 [(set (match_dup 1) (ashift:SI (match_dup 0) (const_int 2)))
2836 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
2837 (set (reg:SI A0_REG) (rotatert:SI (match_dup 1) (const_int 2)))]
2838 "")
2839
590e2636
MF
2840(define_insn_and_split "eh_set_a0_call0"
2841 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
2842 UNSPECV_EH_RETURN)
2843 (clobber (match_scratch:SI 1 "=r"))]
2844 ""
2845 "#"
2846 "reload_completed"
2847 [(const_int 0)]
2848{
2849 xtensa_set_return_address (operands[0], operands[1]);
2850 DONE;
2851})
2852
2853;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2854;; all of memory. This blocks insns from being moved across this point.
2855
2856(define_insn "blockage"
2857 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
2858 ""
2859 ""
ccd02e73
TJJS
2860 [(set_attr "type" "nop")
2861 (set_attr "mode" "none")
2862 (set_attr "length" "0")])
590e2636 2863
9a775e9d
MF
2864;; Do not schedule instructions accessing memory before this point.
2865
2866(define_expand "frame_blockage"
2867 [(set (match_dup 0)
89d5982b 2868 (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
9a775e9d
MF
2869 ""
2870{
2871 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2872 MEM_VOLATILE_P (operands[0]) = 1;
2873 operands[1] = stack_pointer_rtx;
2874})
2875
2876(define_insn "*frame_blockage"
2877 [(set (match_operand:BLK 0 "" "")
89d5982b 2878 (unspec:BLK [(match_operand:SI 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
9a775e9d
MF
2879 ""
2880 ""
ccd02e73
TJJS
2881 [(set_attr "type" "nop")
2882 (set_attr "mode" "none")
2883 (set_attr "length" "0")])
9a775e9d 2884
768b6664
MF
2885(define_insn "trap"
2886 [(trap_if (const_int 1) (const_int 0))]
2887 ""
2888{
2889 if (TARGET_DEBUG)
2890 return "break\t1, 15";
2891 else
2892 return (TARGET_DENSITY ? "ill.n" : "ill");
2893}
2894 [(set_attr "type" "trap")
2895 (set_attr "mode" "none")
ccd02e73
TJJS
2896 (set (attr "length")
2897 (if_then_else (match_test "!TARGET_DEBUG && TARGET_DENSITY")
2898 (const_int 2)
2899 (const_int 3)))])
768b6664 2900
03984308
BW
2901;; Setting up a frame pointer is tricky for Xtensa because GCC doesn't
2902;; know if a frame pointer is required until the reload pass, and
2903;; because there may be an incoming argument value in the hard frame
13fb3a61 2904;; pointer register (a7). If there is an incoming argument in that
03984308
BW
2905;; register, the "set_frame_ptr" insn gets inserted immediately after
2906;; the insn that copies the incoming argument to a pseudo or to the
2907;; stack. This serves several purposes here: (1) it keeps the
2908;; optimizer from copy-propagating or scheduling the use of a7 as an
2909;; incoming argument away from the beginning of the function; (2) we
2910;; can use a post-reload splitter to expand away the insn if a frame
2911;; pointer is not required, so that the post-reload scheduler can do
13fb3a61
BW
2912;; the right thing; and (3) it makes it easy for the prologue expander
2913;; to search for this insn to determine whether it should add a new insn
03984308
BW
2914;; to set up the frame pointer.
2915
2916(define_insn "set_frame_ptr"
f42f5a1b 2917 [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
03984308 2918 ""
03984308
BW
2919{
2920 if (frame_pointer_needed)
48a0e822 2921 return (TARGET_DENSITY ? "mov.n\ta7, sp" : "mov\ta7, sp");
13fb3a61
BW
2922 return "";
2923}
03984308
BW
2924 [(set_attr "type" "move")
2925 (set_attr "mode" "SI")
48a0e822
TJJS
2926 (set (attr "length")
2927 (if_then_else (match_test "TARGET_DENSITY")
2928 (const_int 2)
2929 (const_int 3)))])
03984308
BW
2930
2931;; Post-reload splitter to remove fp assignment when it's not needed.
2932(define_split
f42f5a1b 2933 [(set (reg:SI A7_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_SET_FP))]
03984308
BW
2934 "reload_completed && !frame_pointer_needed"
2935 [(unspec [(const_int 0)] UNSPEC_NOP)]
2936 "")
2937
2938;; The preceding splitter needs something to split the insn into;
2939;; things start breaking if the result is just a "use" so instead we
2940;; generate the following insn.
3219c65b 2941(define_insn "*unspec_nop"
03984308
BW
2942 [(unspec [(const_int 0)] UNSPEC_NOP)]
2943 ""
2944 ""
2945 [(set_attr "type" "nop")
2946 (set_attr "mode" "none")
2947 (set_attr "length" "0")])
2948
6a7a462c
BW
2949\f
2950;; TLS support
2951
2952(define_expand "sym_TPOFF"
2953 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_TPOFF))]
2954 ""
2955 "")
2956
2957(define_expand "sym_DTPOFF"
2958 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_DTPOFF))]
2959 ""
2960 "")
2961
f959607b 2962(define_insn "get_thread_pointersi"
6a7a462c
BW
2963 [(set (match_operand:SI 0 "register_operand" "=a")
2964 (unspec:SI [(const_int 0)] UNSPEC_TP))]
2965 "TARGET_THREADPTR"
2966 "rur\t%0, THREADPTR"
2967 [(set_attr "type" "rsr")
2968 (set_attr "mode" "SI")
2969 (set_attr "length" "3")])
2970
f959607b 2971(define_insn "set_thread_pointersi"
6a7a462c
BW
2972 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
2973 UNSPECV_SET_TP)]
2974 "TARGET_THREADPTR"
2975 "wur\t%0, THREADPTR"
2976 [(set_attr "type" "wsr")
2977 (set_attr "mode" "SI")
2978 (set_attr "length" "3")])
2979
2980(define_insn "tls_func"
2981 [(set (match_operand:SI 0 "register_operand" "=a")
2982 (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
2983 UNSPEC_TLS_FUNC))]
2984 "TARGET_THREADPTR && HAVE_AS_TLS"
2985 "movi\t%0, %1@TLSFUNC"
2986 [(set_attr "type" "load")
2987 (set_attr "mode" "SI")
2988 (set_attr "length" "3")])
2989
2990(define_insn "tls_arg"
2991 [(set (match_operand:SI 0 "register_operand" "=a")
2992 (unspec:SI [(match_operand:SI 1 "tls_symbol_operand" "")]
2993 UNSPEC_TLS_ARG))]
2994 "TARGET_THREADPTR && HAVE_AS_TLS"
2995 "movi\t%0, %1@TLSARG"
2996 [(set_attr "type" "load")
2997 (set_attr "mode" "SI")
2998 (set_attr "length" "3")])
2999
3000(define_insn "tls_call"
3001 [(set (match_operand:SI 0 "register_operand" "=a")
3002 (call (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3003 (match_operand:SI 2 "tls_symbol_operand" "")]
3004 UNSPEC_TLS_CALL))
3005 (match_operand 3 "" "i")))]
3006 "TARGET_THREADPTR && HAVE_AS_TLS"
e1b8828b
MF
3007{
3008 if (TARGET_WINDOWED_ABI)
3009 return "callx8.tls %1, %2@TLSCALL";
3010 else
3011 return "callx0.tls %1, %2@TLSCALL";
3012}
6a7a462c
BW
3013 [(set_attr "type" "call")
3014 (set_attr "mode" "none")
3015 (set_attr "length" "3")])
3016
13fb3a61
BW
3017\f
3018;; Instructions for the Xtensa "boolean" option.
03984308 3019
3219c65b 3020(define_insn "*booltrue"
03984308
BW
3021 [(set (pc)
3022 (if_then_else (match_operator 2 "boolean_operator"
3023 [(match_operand:CC 0 "register_operand" "b")
3024 (const_int 0)])
3025 (label_ref (match_operand 1 "" ""))
3026 (pc)))]
3027 "TARGET_BOOLEANS"
03984308
BW
3028{
3029 if (GET_CODE (operands[2]) == EQ)
13fb3a61 3030 return "bf\t%0, %1";
03984308 3031 else
13fb3a61
BW
3032 return "bt\t%0, %1";
3033}
03984308
BW
3034 [(set_attr "type" "jump")
3035 (set_attr "mode" "none")
3036 (set_attr "length" "3")])
3037
3219c65b 3038(define_insn "*boolfalse"
03984308
BW
3039 [(set (pc)
3040 (if_then_else (match_operator 2 "boolean_operator"
3041 [(match_operand:CC 0 "register_operand" "b")
3042 (const_int 0)])
3043 (pc)
3044 (label_ref (match_operand 1 "" ""))))]
3045 "TARGET_BOOLEANS"
03984308
BW
3046{
3047 if (GET_CODE (operands[2]) == EQ)
13fb3a61 3048 return "bt\t%0, %1";
03984308 3049 else
13fb3a61
BW
3050 return "bf\t%0, %1";
3051}
03984308
BW
3052 [(set_attr "type" "jump")
3053 (set_attr "mode" "none")
3054 (set_attr "length" "3")])
2a48b790
BW
3055
3056\f
3057;; Atomic operations
3058
3059(define_expand "memory_barrier"
1a8c13b3
UB
3060 [(set (match_dup 0)
3061 (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))]
2a48b790
BW
3062 ""
3063{
1a8c13b3 3064 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
2a48b790
BW
3065 MEM_VOLATILE_P (operands[0]) = 1;
3066})
3067
3068(define_insn "*memory_barrier"
3069 [(set (match_operand:BLK 0 "" "")
1a8c13b3 3070 (unspec:BLK [(match_dup 0)] UNSPEC_MEMW))]
2a48b790
BW
3071 ""
3072 "memw"
3073 [(set_attr "type" "unknown")
3074 (set_attr "mode" "none")
3075 (set_attr "length" "3")])
3076
3077;; sync_lock_release is only implemented for SImode.
3078;; For other modes, just use the default of a store with a memory_barrier.
3079(define_insn "sync_lock_releasesi"
3080 [(set (match_operand:SI 0 "mem_operand" "=U")
3081 (unspec_volatile:SI
3082 [(match_operand:SI 1 "register_operand" "r")]
3083 UNSPECV_S32RI))]
3084 "TARGET_RELEASE_SYNC"
3085 "s32ri\t%1, %0"
3086 [(set_attr "type" "store")
3087 (set_attr "mode" "SI")
3088 (set_attr "length" "3")])
3089
3090(define_insn "sync_compare_and_swapsi"
3091 [(parallel
3092 [(set (match_operand:SI 0 "register_operand" "=a")
3093 (match_operand:SI 1 "mem_operand" "+U"))
3094 (set (match_dup 1)
3095 (unspec_volatile:SI
3096 [(match_dup 1)
3097 (match_operand:SI 2 "register_operand" "r")
3098 (match_operand:SI 3 "register_operand" "0")]
3099 UNSPECV_S32C1I))])]
3100 "TARGET_S32C1I"
3101 "wsr\t%2, SCOMPARE1\;s32c1i\t%3, %1"
3102 [(set_attr "type" "multi")
3103 (set_attr "mode" "SI")
3104 (set_attr "length" "6")])
3105
3106(define_expand "sync_compare_and_swap<mode>"
3107 [(parallel
3108 [(set (match_operand:HQI 0 "register_operand" "")
3109 (match_operand:HQI 1 "mem_operand" ""))
3110 (set (match_dup 1)
3111 (unspec_volatile:HQI
3112 [(match_dup 1)
3113 (match_operand:HQI 2 "register_operand" "")
3114 (match_operand:HQI 3 "register_operand" "")]
3115 UNSPECV_S32C1I))])]
3116 "TARGET_S32C1I"
3117{
3118 xtensa_expand_compare_and_swap (operands[0], operands[1],
3119 operands[2], operands[3]);
3120 DONE;
3121})
3122
3123(define_expand "sync_lock_test_and_set<mode>"
3124 [(match_operand:HQI 0 "register_operand")
3125 (match_operand:HQI 1 "memory_operand")
3126 (match_operand:HQI 2 "register_operand")]
3127 "TARGET_S32C1I"
3128{
3129 xtensa_expand_atomic (SET, operands[0], operands[1], operands[2], false);
3130 DONE;
3131})
3132
3133(define_expand "sync_<atomic><mode>"
3134 [(set (match_operand:HQI 0 "memory_operand")
3135 (ATOMIC:HQI (match_dup 0)
3136 (match_operand:HQI 1 "register_operand")))]
3137 "TARGET_S32C1I"
3138{
3139 xtensa_expand_atomic (<CODE>, NULL_RTX, operands[0], operands[1], false);
3140 DONE;
3141})
3142
3143(define_expand "sync_old_<atomic><mode>"
3144 [(set (match_operand:HQI 0 "register_operand")
3145 (match_operand:HQI 1 "memory_operand"))
3146 (set (match_dup 1)
3147 (ATOMIC:HQI (match_dup 1)
3148 (match_operand:HQI 2 "register_operand")))]
3149 "TARGET_S32C1I"
3150{
3151 xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], false);
3152 DONE;
3153})
3154
3155(define_expand "sync_new_<atomic><mode>"
3156 [(set (match_operand:HQI 0 "register_operand")
3157 (ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
89d5982b 3158 (match_operand:HQI 2 "register_operand")))
2a48b790
BW
3159 (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
3160 "TARGET_S32C1I"
3161{
3162 xtensa_expand_atomic (<CODE>, operands[0], operands[1], operands[2], true);
3163 DONE;
3164})
c95e307e
TJJS
3165
3166(define_insn_and_split "*round_up_to_even"
3167 [(set (match_operand:SI 0 "register_operand" "=a")
3168 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
3169 (const_int 1))
3170 (const_int -2)))]
3171 ""
3172 "#"
3173 "can_create_pseudo_p ()"
3174 [(set (match_dup 2)
3175 (and:SI (match_dup 1)
3176 (const_int 1)))
3177 (set (match_dup 0)
3178 (plus:SI (match_dup 2)
3179 (match_dup 1)))]
3180{
3181 operands[2] = gen_reg_rtx (SImode);
3182}
3183 [(set_attr "type" "arith")
3184 (set_attr "mode" "SI")
3185 (set (attr "length")
3186 (if_then_else (match_test "TARGET_DENSITY")
3187 (const_int 5)
3188 (const_int 6)))])
3189
3190(define_insn_and_split "*signed_ge_zero"
3191 [(set (match_operand:SI 0 "register_operand" "=a")
3192 (ge:SI (match_operand:SI 1 "register_operand" "r")
3193 (const_int 0)))]
3194 ""
3195 "#"
3196 ""
3197 [(set (match_dup 0)
3198 (ashiftrt:SI (match_dup 1)
3199 (const_int 31)))
3200 (set (match_dup 0)
3201 (plus:SI (match_dup 0)
3202 (const_int 1)))]
3203 ""
3204 [(set_attr "type" "arith")
3205 (set_attr "mode" "SI")
3206 (set (attr "length")
3207 (if_then_else (match_test "TARGET_DENSITY")
3208 (const_int 5)
3209 (const_int 6)))])
cfad4856 3210
1d17d58c
TJJS
3211(define_insn_and_split "eq_zero_NSA"
3212 [(set (match_operand:SI 0 "register_operand" "=a")
3213 (eq:SI (match_operand:SI 1 "register_operand" "r")
3214 (const_int 0)))]
3215 "TARGET_NSA"
3216 "#"
3217 "&& 1"
3218 [(set (match_dup 0)
3219 (clz:SI (match_dup 1)))
3220 (set (match_dup 0)
3221 (lshiftrt:SI (match_dup 0)
3222 (const_int 5)))]
3223 ""
3224 [(set_attr "type" "move")
3225 (set_attr "mode" "SI")
3226 (set_attr "length" "6")])
3227
3228(define_insn_and_split "eqne_zero"
3229 [(set (match_operand:SI 0 "register_operand" "=a,&a")
3230 (match_operator:SI 2 "boolean_operator"
3231 [(match_operand:SI 1 "register_operand" "0,r")
3232 (const_int 0)]))
3233 (clobber (match_scratch:SI 3 "=&a,X"))]
3234 ""
3235 "#"
3236 "&& reload_completed"
3237 [(const_int 0)]
3238{
3239 enum rtx_code code = GET_CODE (operands[2]);
3240 int same_p = REGNO (operands[0]) == REGNO (operands[1]);
3241 emit_move_insn (same_p ? operands[3] : operands[0],
3242 code == EQ ? constm1_rtx : const1_rtx);
3243 emit_insn (gen_movsicc_internal0 (operands[0], operands[1],
3244 same_p ? operands[3] : operands[1],
3245 operands[0],
3246 gen_rtx_fmt_ee (same_p ? NE : EQ,
3247 VOIDmode,
3248 operands[1],
3249 const0_rtx)));
3250 if (code == EQ)
3251 emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
3252 DONE;
3253}
3254 [(set_attr "type" "move")
3255 (set_attr "mode" "SI")
3256 (set (attr "length")
3257 (if_then_else (match_test "GET_CODE (operands[2]) == EQ")
3258 (if_then_else (match_test "TARGET_DENSITY")
3259 (const_int 7)
3260 (const_int 9))
3261 (if_then_else (match_test "TARGET_DENSITY")
3262 (const_int 5)
3263 (const_int 6))))])
3264
3265(define_insn_and_split "*eqne_zero_masked_bits"
3266 [(set (match_operand:SI 0 "register_operand" "=a")
3267 (match_operator 3 "boolean_operator"
3268 [(and:SI (match_operand:SI 1 "register_operand" "r")
3269 (match_operand:SI 2 "const_int_operand" "i"))
3270 (const_int 0)]))]
3271 "IN_RANGE (exact_log2 (INTVAL (operands[2]) + 1), 17, 31)
3272 || IN_RANGE (exact_log2 (-INTVAL (operands[2])), 1, 30)"
3273 "#"
3274 "&& 1"
3275 [(const_int 0)]
3276{
3277 HOST_WIDE_INT mask = INTVAL (operands[2]);
3278 int n;
3279 enum rtx_code code = GET_CODE (operands[3]);
3280 if (IN_RANGE (n = exact_log2 (mask + 1), 17, 31))
3281 emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (32 - n)));
3282 else
3283 emit_insn (gen_lshrsi3 (operands[0], operands[1],
3284 GEN_INT (floor_log2 (-mask))));
3285 if (TARGET_NSA && code == EQ)
3286 emit_insn (gen_eq_zero_NSA (operands[0], operands[0]));
3287 else
3288 emit_insn (gen_eqne_zero (operands[0], operands[0],
3289 gen_rtx_fmt_ee (code, VOIDmode,
3290 operands[0], const0_rtx)));
3291 DONE;
3292})
3293
3294(define_insn_and_split "*eqne_INT_MIN"
3295 [(set (match_operand:SI 0 "register_operand" "=a")
3296 (match_operator:SI 2 "boolean_operator"
3297 [(match_operand:SI 1 "register_operand" "r")
3298 (const_int -2147483648)]))]
3299 "TARGET_ABS"
3300 "#"
3301 "&& 1"
3302 [(const_int 0)]
3303{
3304 emit_insn (gen_abssi2 (operands[0], operands[1]));
3305 if (GET_CODE (operands[2]) == EQ)
3306 emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
3307 else
3308 {
3309 emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (31)));
3310 emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
3311 }
3312 DONE;
3313}
3314 [(set_attr "type" "move")
3315 (set_attr "mode" "SI")
3316 (set (attr "length")
3317 (if_then_else (match_test "GET_CODE (operands[2]) == EQ")
3318 (const_int 6)
3319 (if_then_else (match_test "TARGET_DENSITY")
3320 (const_int 8)
3321 (const_int 9))))])
3322
cfad4856
TJJS
3323(define_peephole2
3324 [(set (match_operand:SI 0 "register_operand")
3325 (match_operand:SI 6 "reload_operand"))
3326 (set (match_operand:SI 1 "register_operand")
3327 (match_operand:SI 7 "reload_operand"))
3328 (set (match_operand:SF 2 "register_operand")
3329 (match_operand:SF 4 "register_operand"))
3330 (set (match_operand:SF 3 "register_operand")
3331 (match_operand:SF 5 "register_operand"))]
3332 "REGNO (operands[0]) == REGNO (operands[4])
3333 && REGNO (operands[1]) == REGNO (operands[5])
3334 && peep2_reg_dead_p (4, operands[0])
3335 && peep2_reg_dead_p (4, operands[1])"
3336 [(set (match_dup 2)
3337 (match_dup 6))
3338 (set (match_dup 3)
3339 (match_dup 7))]
3340{
cd22b977 3341 HARD_REG_SET regs;
cfad4856 3342 int i;
cd22b977 3343 CLEAR_HARD_REG_SET (regs);
cfad4856 3344 for (i = 0; i <= 3; ++i)
cd22b977
TJJS
3345 if (TEST_HARD_REG_BIT (regs, REGNO (operands[i])))
3346 FAIL;
3347 else
3348 SET_HARD_REG_BIT (regs, REGNO (operands[i]));
cfad4856
TJJS
3349 operands[6] = gen_rtx_MEM (SFmode, XEXP (operands[6], 0));
3350 operands[7] = gen_rtx_MEM (SFmode, XEXP (operands[7], 0));
3351})
ce3867d4
TJJS
3352
3353(define_split
89afb2e8
TJJS
3354 [(clobber (match_operand 0 "register_operand"))]
3355 "HARD_REGISTER_P (operands[0])
3356 && COMPLEX_MODE_P (GET_MODE (operands[0]))"
ce3867d4
TJJS
3357 [(const_int 0)]
3358{
89afb2e8 3359 auto_sbitmap bmp (FIRST_PSEUDO_REGISTER);
ce3867d4 3360 rtx_insn *insn;
1c407dc0
TJJS
3361 rtx reg = gen_rtx_REG (SImode, 0), dest;
3362 unsigned int regno;
3363 sbitmap_iterator iter;
89afb2e8
TJJS
3364 bitmap_set_range (bmp, REGNO (operands[0]), REG_NREGS (operands[0]));
3365 for (insn = next_nonnote_nondebug_insn_bb (curr_insn);
3366 insn; insn = next_nonnote_nondebug_insn_bb (insn))
1c407dc0
TJJS
3367 if (NONJUMP_INSN_P (insn))
3368 {
89afb2e8 3369 EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
1c407dc0
TJJS
3370 {
3371 set_regno_raw (reg, regno, REG_NREGS (reg));
3372 if (reg_referenced_p (reg, PATTERN (insn)))
3373 goto ABORT;
3374 }
3375 if (GET_CODE (PATTERN (insn)) == SET
3376 || GET_CODE (PATTERN (insn)) == CLOBBER)
3377 {
3378 dest = SET_DEST (PATTERN (insn));
3379 if (REG_P (dest) && HARD_REGISTER_P (dest))
3380 bitmap_clear_range (bmp, REGNO (dest), REG_NREGS (dest));
3381 else if (SUBREG_P (dest)
3382 && HARD_REGISTER_P (SUBREG_REG (dest)))
3383 {
3384 struct subreg_info info;
3385 subreg_get_info (regno = REGNO (SUBREG_REG (dest)),
3386 GET_MODE (SUBREG_REG (dest)),
3387 SUBREG_BYTE (dest), GET_MODE (dest),
3388 &info);
3389 if (!info.representable_p)
3390 break;
3391 bitmap_clear_range (bmp, regno + info.offset, info.nregs);
3392 }
3393 }
3394 if (bitmap_empty_p (bmp))
3395 goto FALLTHRU;
3396 }
3397 else if (CALL_P (insn))
3398 EXECUTE_IF_SET_IN_BITMAP (bmp, 2, regno, iter)
3399 if (call_used_or_fixed_reg_p (regno))
3400 goto ABORT;
3401ABORT:
89afb2e8
TJJS
3402 FAIL;
3403FALLTHRU:;
ce3867d4 3404})
773dffc5
TJJS
3405
3406(define_peephole2
3407 [(set (match_operand:SI 0 "register_operand")
3408 (match_operand:SI 1 "const_int_operand"))
3409 (set (match_dup 0)
3410 (plus:SI (match_dup 0)
3411 (match_operand:SI 2 "const_int_operand")))
3412 (set (match_operand:SI 3 "register_operand")
3413 (plus:SI (match_operand:SI 4 "register_operand")
3414 (match_dup 0)))]
3415 "IN_RANGE (INTVAL (operands[1]) + INTVAL (operands[2]),
3416 (-128 - 32768), (127 + 32512))
3417 && REGNO (operands[0]) != REGNO (operands[3])
3418 && REGNO (operands[0]) != REGNO (operands[4])
3419 && peep2_reg_dead_p (3, operands[0])"
3420 [(set (match_dup 3)
3421 (plus:SI (match_dup 4)
3422 (match_dup 1)))
3423 (set (match_dup 3)
3424 (plus:SI (match_dup 3)
3425 (match_dup 2)))]
3426{
3427 HOST_WIDE_INT value = INTVAL (operands[1]) + INTVAL (operands[2]);
3428 int imm0, imm1;
3429 value += 128;
3430 if (value > 32512)
3431 imm1 = 32512;
3432 else
3433 imm1 = value & ~255;
3434 imm0 = value - imm1 - 128;
3435 operands[1] = GEN_INT (imm0);
3436 operands[2] = GEN_INT (imm1);
3437})
f83e76c3
TJJS
3438
3439(define_peephole2
3440 [(set (match_operand 0 "register_operand")
3441 (match_operand 1 "register_operand"))]
3442 "REG_NREGS (operands[0]) == 1 && GP_REG_P (REGNO (operands[0]))
3443 && REG_NREGS (operands[1]) == 1 && GP_REG_P (REGNO (operands[1]))
3444 && peep2_reg_dead_p (1, operands[1])"
3445 [(const_int 0)]
3446{
3447 basic_block bb = BLOCK_FOR_INSN (curr_insn);
3448 rtx_insn *head = BB_HEAD (bb), *insn;
3449 rtx dest = operands[0], src = operands[1], pattern, t_dest, dest_orig;
3450 for (insn = PREV_INSN (curr_insn);
3451 insn && insn != head;
3452 insn = PREV_INSN (insn))
3453 if (CALL_P (insn))
3454 break;
3455 else if (INSN_P (insn))
3456 {
3457 if (GET_CODE (pattern = PATTERN (insn)) == SET
3458 && REG_P (t_dest = SET_DEST (pattern))
3459 && REG_NREGS (t_dest) == 1
3460 && REGNO (t_dest) == REGNO (src))
3461 {
3462 dest_orig = SET_DEST (pattern);
3463 SET_DEST (pattern) = gen_rtx_REG (GET_MODE (t_dest),
3464 REGNO (dest));
3465 extract_insn (insn);
3466 if (!constrain_operands (true, get_enabled_alternatives (insn)))
3467 {
3468 SET_DEST (pattern) = dest_orig;
3469 goto ABORT;
3470 }
3471 df_insn_rescan (insn);
3472 goto FALLTHRU;
3473 }
3474 if (reg_overlap_mentioned_p (dest, pattern)
3475 || reg_overlap_mentioned_p (src, pattern)
3476 || set_of (dest, insn)
3477 || set_of (src, insn))
3478 break;
3479 }
3480ABORT:
3481 FAIL;
3482FALLTHRU:;
3483})