]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nds32/nds32.md
PR c++/85214 - ICE with alias, generic lambda, constexpr if.
[thirdparty/gcc.git] / gcc / config / nds32 / nds32.md
CommitLineData
9304f876 1;; Machine description of Andes NDS32 cpu for GNU compiler
85ec4feb 2;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
9304f876
CJW
3;; Contributed by Andes Technology Corporation.
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
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) 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
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>.
20
21;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23;; Include predicates definition.
24(include "predicates.md")
25
26;; Include constraints definition.
27(include "constraints.md")
28
29;; Include iterators definition.
30(include "iterators.md")
31
32;; Include pipelines definition.
33(include "pipelines.md")
34
35
36;; Include constants definition.
37(include "constants.md")
38
39
40;; Include intrinsic functions definition.
41(include "nds32-intrinsic.md")
42
43;; Include block move for nds32 multiple load/store behavior.
44(include "nds32-multiple.md")
45
46;; Include DImode/DFmode operations.
47(include "nds32-doubleword.md")
48
e2286268
MC
49;; Include floating-point patterns.
50(include "nds32-fpu.md")
51
9304f876
CJW
52;; Include peephole patterns.
53(include "nds32-peephole2.md")
54
55
56;; Insn type, it is used to default other attribute values.
57(define_attr "type"
e2286268
MC
58 "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,call,misc,\
59 falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore"
9304f876
CJW
60 (const_string "unknown"))
61
0aa683b3
CJW
62;; Insn sub-type
63(define_attr "subtype"
64 "simple,shift"
65 (const_string "simple"))
66
9304f876
CJW
67;; Length, in bytes, default is 4-bytes.
68(define_attr "length" "" (const_int 4))
69
264159d2
KC
70;; Indicate the amount of micro instructions.
71(define_attr "combo"
72 "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25"
73 (const_string "1"))
9304f876 74
9be6885b
KC
75;; Insn in which feature set, it is used to enable/disable insn alternatives.
76;; v1 : Baseline Instructions
77;; v2 : Baseline Version 2 Instructions
78;; v3m : Baseline Version 3m Instructions
79;; v3 : Baseline Version 3 Instructions
80;; pe1 : Performance Extension Instructions
81;; pe2 : Performance Extension Version 2 Instructions
82;; se : String Extension instructions
83(define_attr "feature"
e2286268 84 "v1,v2,v3m,v3,pe1,pe2,se,fpu"
9be6885b
KC
85 (const_string "v1"))
86
9304f876
CJW
87;; Enabled, which is used to enable/disable insn alternatives.
88;; Note that we use length and TARGET_16_BIT here as criteria.
9be6885b
KC
89;; If the instruction pattern already check TARGET_16_BIT to determine
90;; the length by itself, its enabled attribute should be customized to
91;; avoid the conflict between length attribute and this default setting.
30feb954 92(define_attr "enabled" "no,yes"
9be6885b
KC
93 (if_then_else
94 (and (eq_attr "length" "2")
95 (match_test "!TARGET_16_BIT"))
96 (const_string "no")
97 (cond [(eq_attr "feature" "v1") (const_string "yes")
98 (eq_attr "feature" "v2") (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M")
99 (const_string "yes")
100 (const_string "no"))
101 (eq_attr "feature" "v3") (if_then_else (match_test "TARGET_ISA_V3")
102 (const_string "yes")
103 (const_string "no"))
104 (eq_attr "feature" "v3m") (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M")
105 (const_string "yes")
106 (const_string "no"))
107 (eq_attr "feature" "pe1") (if_then_else (match_test "TARGET_EXT_PERF")
108 (const_string "yes")
109 (const_string "no"))
110 (eq_attr "feature" "pe2") (if_then_else (match_test "TARGET_EXT_PERF2")
111 (const_string "yes")
112 (const_string "no"))
113 (eq_attr "feature" "se") (if_then_else (match_test "TARGET_EXT_STRING")
e2286268
MC
114 (const_string "yes")
115 (const_string "no"))
116 (eq_attr "feature" "fpu") (if_then_else (match_test "TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE")
9be6885b
KC
117 (const_string "yes")
118 (const_string "no"))]
119 (const_string "yes"))))
9304f876
CJW
120
121
122;; ----------------------------------------------------------------------------
123
124
125;; Move instructions.
126
127;; For QImode and HImode, the immediate value can be fit in imm20s.
128;; So there is no need to split rtx for QI and HI patterns.
129
76dc9cb5
CJW
130(define_expand "mov<mode>"
131 [(set (match_operand:QIHI 0 "general_operand" "")
132 (match_operand:QIHI 1 "general_operand" ""))]
9304f876
CJW
133 ""
134{
135 /* Need to force register if mem <- !reg. */
136 if (MEM_P (operands[0]) && !REG_P (operands[1]))
76dc9cb5 137 operands[1] = force_reg (<MODE>mode, operands[1]);
9304f876 138
76dc9cb5
CJW
139 if (MEM_P (operands[1]) && optimize > 0)
140 {
141 rtx reg = gen_reg_rtx (SImode);
142
143 emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
144 operands[1] = gen_lowpart (<MODE>mode, reg);
145 }
9304f876
CJW
146})
147
2cf09a99
KC
148(define_expand "movmisalign<mode>"
149 [(set (match_operand:SIDI 0 "general_operand" "")
150 (match_operand:SIDI 1 "general_operand" ""))]
151 ""
152{
153 rtx addr;
154 if (MEM_P (operands[0]) && !REG_P (operands[1]))
155 operands[1] = force_reg (<MODE>mode, operands[1]);
156
157 if (MEM_P (operands[0]))
158 {
159 addr = force_reg (Pmode, XEXP (operands[0], 0));
160 emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
161 }
162 else
163 {
164 addr = force_reg (Pmode, XEXP (operands[1], 0));
165 emit_insn (gen_unaligned_load<mode> (operands[0], addr));
166 }
167 DONE;
168})
76dc9cb5 169
9304f876
CJW
170(define_expand "movsi"
171 [(set (match_operand:SI 0 "general_operand" "")
172 (match_operand:SI 1 "general_operand" ""))]
173 ""
174{
175 /* Need to force register if mem <- !reg. */
176 if (MEM_P (operands[0]) && !REG_P (operands[1]))
177 operands[1] = force_reg (SImode, operands[1]);
178
179 /* If operands[1] is a large constant and cannot be performed
180 by a single instruction, we need to split it. */
181 if (CONST_INT_P (operands[1])
182 && !satisfies_constraint_Is20 (operands[1])
183 && !satisfies_constraint_Ihig (operands[1]))
184 {
185 rtx high20_rtx;
186 HOST_WIDE_INT low12_int;
187 rtx tmp_rtx;
188
189 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
190
191 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
192 low12_int = INTVAL (operands[1]) & 0xfff;
193
194 emit_move_insn (tmp_rtx, high20_rtx);
195 emit_move_insn (operands[0], plus_constant (SImode,
196 tmp_rtx,
197 low12_int));
198 DONE;
199 }
200})
201
202(define_insn "*mov<mode>"
e2286268
MC
203 [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r,U45,U33,U37,U45, m, l, l, l, d, d, r, d, r, r, r, *f, *f, r, *f, Q")
204 (match_operand:QIHISI 1 "nds32_move_operand" " r, r, l, l, l, d, r,U45,U33,U37,U45,Ufe, m,Ip05, Is05, Is20, Ihig, *f, r, *f, Q, *f"))]
b4350271
KC
205 "register_operand(operands[0], <MODE>mode)
206 || register_operand(operands[1], <MODE>mode)"
9304f876
CJW
207{
208 switch (which_alternative)
209 {
210 case 0:
211 return "mov55\t%0, %1";
212 case 1:
213 return "ori\t%0, %1, 0";
214 case 2:
215 case 3:
216 case 4:
217 case 5:
218 return nds32_output_16bit_store (operands, <byte>);
219 case 6:
220 return nds32_output_32bit_store (operands, <byte>);
221 case 7:
222 case 8:
223 case 9:
224 case 10:
9304f876 225 case 11:
8656bbcf 226 return nds32_output_16bit_load (operands, <byte>);
9304f876 227 case 12:
8656bbcf 228 return nds32_output_32bit_load (operands, <byte>);
9304f876 229 case 13:
8656bbcf 230 return "movpi45\t%0, %1";
9304f876 231 case 14:
8656bbcf 232 return "movi55\t%0, %1";
9304f876 233 case 15:
8656bbcf
SC
234 return "movi\t%0, %1";
235 case 16:
9304f876 236 return "sethi\t%0, hi20(%1)";
e2286268
MC
237 case 17:
238 if (TARGET_FPU_SINGLE)
239 return "fcpyss\t%0, %1, %1";
240 else
241 return "#";
242 case 18:
243 return "fmtsr\t%1, %0";
244 case 19:
245 return "fmfsr\t%0, %1";
246 case 20:
247 return nds32_output_float_load (operands);
248 case 21:
249 return nds32_output_float_store (operands);
9304f876
CJW
250 default:
251 gcc_unreachable ();
252 }
253}
e2286268
MC
254 [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,load,alu,alu,alu,alu,fcpy,fmtsr,fmfsr,fload,fstore")
255 (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4")
256 (set_attr "feature" " v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v1, v3m, v1, v1, v1, v1, v1, fpu, fpu, fpu, fpu, fpu")])
9304f876
CJW
257
258
259;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
260;; are able to match such instruction template.
c4d8d050 261(define_insn "move_addr"
9304f876
CJW
262 [(set (match_operand:SI 0 "register_operand" "=l, r")
263 (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
264 ""
265 "la\t%0, %1"
5ba6d585 266 [(set_attr "type" "alu")
9304f876
CJW
267 (set_attr "length" "8")])
268
269
c4d8d050 270(define_insn "sethi"
9304f876
CJW
271 [(set (match_operand:SI 0 "register_operand" "=r")
272 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
273 ""
274 "sethi\t%0, hi20(%1)"
275 [(set_attr "type" "alu")
276 (set_attr "length" "4")])
277
278
c4d8d050 279(define_insn "lo_sum"
9304f876
CJW
280 [(set (match_operand:SI 0 "register_operand" "=r")
281 (lo_sum:SI (match_operand:SI 1 "register_operand" " r")
282 (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
283 ""
284 "ori\t%0, %1, lo12(%2)"
285 [(set_attr "type" "alu")
286 (set_attr "length" "4")])
287
288
289;; ----------------------------------------------------------------------------
290
291;; Zero extension instructions.
292
293(define_insn "zero_extend<mode>si2"
294 [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r")
295 (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))]
296 ""
297{
298 switch (which_alternative)
299 {
300 case 0:
301 return "ze<size>33\t%0, %1";
302 case 1:
303 return "ze<size>\t%0, %1";
304 case 2:
305 return nds32_output_16bit_load (operands, <byte>);
306 case 3:
307 return nds32_output_32bit_load (operands, <byte>);
308
309 default:
310 gcc_unreachable ();
311 }
312}
313 [(set_attr "type" "alu,alu,load,load")
314 (set_attr "length" " 2, 4, 2, 4")])
315
316
317;; Sign extension instructions.
318
319(define_insn "extend<mode>si2"
320 [(set (match_operand:SI 0 "register_operand" "=l, r, r")
321 (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
322 ""
323{
324 switch (which_alternative)
325 {
326 case 0:
327 return "se<size>33\t%0, %1";
328 case 1:
329 return "se<size>\t%0, %1";
330 case 2:
331 return nds32_output_32bit_load_s (operands, <byte>);
332
333 default:
334 gcc_unreachable ();
335 }
336}
337 [(set_attr "type" "alu,alu,load")
338 (set_attr "length" " 2, 4, 4")])
339
340
341;; ----------------------------------------------------------------------------
342
343;; Arithmetic instructions.
344
5c36be57
CJW
345(define_insn "addsi3"
346 [(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
347 (plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
a3b13564 348 (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,Iu06, Is15, r")))]
9304f876
CJW
349 ""
350{
351 switch (which_alternative)
352 {
353 case 0:
354 /* addi Rt4,Rt4,-x ==> subi45 Rt4,x
8a498f99 355 where 0 <= x <= 31 */
9304f876
CJW
356 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
357 return "subi45\t%0, %2";
358 case 1:
359 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
8a498f99 360 where 0 <= x <= 7 */
9304f876
CJW
361 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
362 return "subi333\t%0, %1, %2";
363 case 2:
364 return "addi45\t%0, %2";
365 case 3:
366 return "addi333\t%0, %1, %2";
367 case 4:
368 return "add45\t%0, %2";
369 case 5:
370 return "add333\t%0, %1, %2";
371 case 6:
372 return "addi10.sp\t%2";
373 case 7:
374 return "addri36.sp\t%0, %2";
375 case 8:
376 return "addi\t%0, %1, %2";
377 case 9:
378 return "add\t%0, %1, %2";
379
380 default:
381 gcc_unreachable ();
382 }
383}
9be6885b
KC
384 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
385 (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")
386 (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")])
9304f876 387
5c36be57
CJW
388(define_insn "subsi3"
389 [(set (match_operand:SI 0 "register_operand" "=d, l, r, r")
390 (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
391 (match_operand:SI 2 "register_operand" " r, l, r, r")))]
9304f876
CJW
392 ""
393 "@
9c1a4c0f
CJW
394 sub45\t%0, %2
395 sub333\t%0, %1, %2
396 subri\t%0, %2, %1
397 sub\t%0, %1, %2"
9304f876
CJW
398 [(set_attr "type" "alu,alu,alu,alu")
399 (set_attr "length" " 2, 2, 4, 4")])
400
401
402;; GCC intends to simplify (plus (ashift ...) (reg))
403;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
404;; and needs to ensure it is exact_log2 value.
405(define_insn "*add_slli"
406 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99 407 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
9304f876
CJW
408 (match_operand:SI 2 "immediate_operand" " i"))
409 (match_operand:SI 3 "register_operand" " r")))]
b9774a97 410 "TARGET_ISA_V3 && optimize_size
9304f876
CJW
411 && (exact_log2 (INTVAL (operands[2])) != -1)
412 && (exact_log2 (INTVAL (operands[2])) <= 31)"
413{
414 /* Get floor_log2 of the immediate value
415 so that we can generate 'add_slli' instruction. */
416 operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
417
418 return "add_slli\t%0, %3, %1, %2";
419}
5ba6d585
KC
420 [(set_attr "type" "alu_shift")
421 (set_attr "combo" "2")
422 (set_attr "length" "4")])
9304f876
CJW
423
424(define_insn "*add_srli"
a3b13564
KC
425 [(set (match_operand:SI 0 "register_operand" "= r")
426 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
427 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
428 (match_operand:SI 3 "register_operand" " r")))]
b9774a97 429 "TARGET_ISA_V3 && optimize_size"
9304f876 430 "add_srli\t%0, %3, %1, %2"
5ba6d585
KC
431 [(set_attr "type" "alu_shift")
432 (set_attr "combo" "2")
433 (set_attr "length" "4")])
9304f876
CJW
434
435
436;; GCC intends to simplify (minus (reg) (ashift ...))
437;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
438;; and needs to ensure it is exact_log2 value.
439(define_insn "*sub_slli"
440 [(set (match_operand:SI 0 "register_operand" "=r")
441 (minus:SI (match_operand:SI 1 "register_operand" " r")
442 (mult:SI (match_operand:SI 2 "register_operand" " r")
443 (match_operand:SI 3 "immediate_operand" " i"))))]
b9774a97 444 "TARGET_ISA_V3 && optimize_size
9304f876
CJW
445 && (exact_log2 (INTVAL (operands[3])) != -1)
446 && (exact_log2 (INTVAL (operands[3])) <= 31)"
447{
448 /* Get floor_log2 of the immediate value
449 so that we can generate 'sub_slli' instruction. */
450 operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
451
452 return "sub_slli\t%0, %1, %2, %3";
453}
5ba6d585
KC
454 [(set_attr "type" "alu_shift")
455 (set_attr "combo" "2")
456 (set_attr "length" "4")])
9304f876
CJW
457
458(define_insn "*sub_srli"
77827557
CJW
459 [(set (match_operand:SI 0 "register_operand" "= r")
460 (minus:SI (match_operand:SI 1 "register_operand" " r")
461 (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
462 (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))]
b9774a97 463 "TARGET_ISA_V3 && optimize_size"
9304f876 464 "sub_srli\t%0, %1, %2, %3"
5ba6d585
KC
465 [(set_attr "type" "alu_shift")
466 (set_attr "combo" "2")
467 (set_attr "length" "4")])
9304f876
CJW
468
469
470;; Multiplication instructions.
471
472(define_insn "mulsi3"
73f793e3
RS
473 [(set (match_operand:SI 0 "register_operand" "=w, r")
474 (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
475 (match_operand:SI 2 "register_operand" " w, r")))]
9304f876
CJW
476 ""
477 "@
9c1a4c0f
CJW
478 mul33\t%0, %2
479 mul\t%0, %1, %2"
5ba6d585 480 [(set_attr "type" "mul,mul")
9be6885b
KC
481 (set_attr "length" " 2, 4")
482 (set_attr "feature" "v3m, v1")])
9304f876
CJW
483
484(define_insn "mulsidi3"
485 [(set (match_operand:DI 0 "register_operand" "=r")
486 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
487 (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
488 "TARGET_ISA_V2 || TARGET_ISA_V3"
489 "mulsr64\t%0, %1, %2"
5ba6d585 490 [(set_attr "type" "mul")
9304f876
CJW
491 (set_attr "length" "4")])
492
493(define_insn "umulsidi3"
494 [(set (match_operand:DI 0 "register_operand" "=r")
495 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
496 (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
497 "TARGET_ISA_V2 || TARGET_ISA_V3"
498 "mulr64\t%0, %1, %2"
5ba6d585 499 [(set_attr "type" "mul")
9304f876
CJW
500 (set_attr "length" "4")])
501
502
503;; Multiply-accumulate instructions.
504
505(define_insn "*maddr32_0"
506 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
507 (plus:SI (match_operand:SI 3 "register_operand" " 0")
508 (mult:SI (match_operand:SI 1 "register_operand" " r")
509 (match_operand:SI 2 "register_operand" " r"))))]
9304f876
CJW
510 ""
511 "maddr32\t%0, %1, %2"
5ba6d585 512 [(set_attr "type" "mac")
9304f876
CJW
513 (set_attr "length" "4")])
514
515(define_insn "*maddr32_1"
516 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
517 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
518 (match_operand:SI 2 "register_operand" " r"))
519 (match_operand:SI 3 "register_operand" " 0")))]
9304f876
CJW
520 ""
521 "maddr32\t%0, %1, %2"
5ba6d585 522 [(set_attr "type" "mac")
9304f876
CJW
523 (set_attr "length" "4")])
524
525(define_insn "*msubr32"
526 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
527 (minus:SI (match_operand:SI 3 "register_operand" " 0")
528 (mult:SI (match_operand:SI 1 "register_operand" " r")
529 (match_operand:SI 2 "register_operand" " r"))))]
9304f876
CJW
530 ""
531 "msubr32\t%0, %1, %2"
5ba6d585 532 [(set_attr "type" "mac")
9304f876
CJW
533 (set_attr "length" "4")])
534
535
536;; Div Instructions.
537
538(define_insn "divmodsi4"
539 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
540 (div:SI (match_operand:SI 1 "register_operand" " r")
541 (match_operand:SI 2 "register_operand" " r")))
9304f876 542 (set (match_operand:SI 3 "register_operand" "=r")
8a498f99 543 (mod:SI (match_dup 1) (match_dup 2)))]
9304f876
CJW
544 ""
545 "divsr\t%0, %3, %1, %2"
5ba6d585 546 [(set_attr "type" "div")
9304f876
CJW
547 (set_attr "length" "4")])
548
549(define_insn "udivmodsi4"
550 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
551 (udiv:SI (match_operand:SI 1 "register_operand" " r")
552 (match_operand:SI 2 "register_operand" " r")))
9304f876 553 (set (match_operand:SI 3 "register_operand" "=r")
8a498f99 554 (umod:SI (match_dup 1) (match_dup 2)))]
9304f876
CJW
555 ""
556 "divr\t%0, %3, %1, %2"
5ba6d585 557 [(set_attr "type" "div")
9304f876
CJW
558 (set_attr "length" "4")])
559
50ea1e4a
CJW
560;; divsr/divr will keep quotient only when quotient and remainder is the same
561;; register in our ISA spec, it's can reduce 1 register presure if we don't
562;; want remainder.
563(define_insn "divsi4"
564 [(set (match_operand:SI 0 "register_operand" "=r")
565 (div:SI (match_operand:SI 1 "register_operand" " r")
566 (match_operand:SI 2 "register_operand" " r")))]
567 ""
568 "divsr\t%0, %0, %1, %2"
569 [(set_attr "type" "div")
570 (set_attr "length" "4")])
571
572(define_insn "udivsi4"
573 [(set (match_operand:SI 0 "register_operand" "=r")
574 (udiv:SI (match_operand:SI 1 "register_operand" " r")
575 (match_operand:SI 2 "register_operand" " r")))]
576 ""
577 "divr\t%0, %0, %1, %2"
578 [(set_attr "type" "div")
579 (set_attr "length" "4")])
9304f876
CJW
580
581;; ----------------------------------------------------------------------------
582
583;; Boolean instructions.
584;; Note: We define the DImode versions in nds32-doubleword.md.
585
586;; ----------------------------------------------------------------------------
587;; 'AND' operation
588;; ----------------------------------------------------------------------------
589
590(define_insn "bitc"
591 [(set (match_operand:SI 0 "register_operand" "=r")
592 (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
593 (match_operand:SI 2 "register_operand" " r")))]
594 "TARGET_ISA_V3"
595 "bitc\t%0, %2, %1"
596 [(set_attr "type" "alu")
597 (set_attr "length" "4")]
598)
599
a3b13564
KC
600(define_expand "andsi3"
601 [(set (match_operand:SI 0 "register_operand" "")
602 (and:SI (match_operand:SI 1 "register_operand" "")
603 (match_operand:SI 2 "nds32_reg_constant_operand" "")))]
604 ""
605{
606 if (CONST_INT_P (operands[2])
607 && !nds32_and_operand (operands[2], SImode))
608 {
609 nds32_expand_constant (SImode, INTVAL (operands[2]),
610 operands[0], operands[1]);
611 DONE;
612 }
613})
614
615(define_insn "*andsi3"
616 [(set (match_operand:SI 0 "register_operand" "=l, r, l, l, l, l, l, l, r, r, r, r, r")
617 (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r")
618 (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
9304f876
CJW
619 ""
620{
621 HOST_WIDE_INT mask = INTVAL (operands[2]);
9304f876
CJW
622
623 /* 16-bit andi instructions:
624 andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3
625 andi Rt3,Ra3,0xffff -> zeh33 Rt3,Ra3
626 andi Rt3,Ra3,0x01 -> xlsb33 Rt3,Ra3
627 andi Rt3,Ra3,0x7ff -> x11b33 Rt3,Ra3
628 andi Rt3,Rt3,2^imm3u -> bmski33 Rt3,imm3u
629 andi Rt3,Rt3,(2^(imm3u+1))-1 -> fexti33 Rt3,imm3u. */
630
631 switch (which_alternative)
632 {
633 case 0:
634 return "and33\t%0, %2";
635 case 1:
636 return "and\t%0, %1, %2";
637 case 2:
638 return "zeb33\t%0, %1";
639 case 3:
640 return "zeh33\t%0, %1";
641 case 4:
642 return "xlsb33\t%0, %1";
643 case 5:
644 return "x11b33\t%0, %1";
645 case 6:
a3b13564 646 return "bmski33\t%0, %B2";
9304f876
CJW
647 case 7:
648 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
649 return "fexti33\t%0, %2";
650 case 8:
651 return "zeb\t%0, %1";
652 case 9:
653 return "zeh\t%0, %1";
654 case 10:
655 return "andi\t%0, %1, %2";
656 case 11:
657 operands[2] = GEN_INT (~mask);
658 return "bitci\t%0, %1, %2";
659 case 12:
a3b13564 660 return "bclr\t%0, %1, %b2";
9304f876
CJW
661
662 default:
663 gcc_unreachable ();
664 }
665}
9be6885b
KC
666 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
667 (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")
668 (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")])
9304f876
CJW
669
670(define_insn "*and_slli"
77827557
CJW
671 [(set (match_operand:SI 0 "register_operand" "= r")
672 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
673 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
674 (match_operand:SI 3 "register_operand" " r")))]
b9774a97 675 "TARGET_ISA_V3 && optimize_size"
9304f876 676 "and_slli\t%0, %3, %1, %2"
5ba6d585
KC
677 [(set_attr "type" "alu_shift")
678 (set_attr "length" "4")])
9304f876
CJW
679
680(define_insn "*and_srli"
77827557
CJW
681 [(set (match_operand:SI 0 "register_operand" "= r")
682 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
683 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
684 (match_operand:SI 3 "register_operand" " r")))]
b9774a97 685 "TARGET_ISA_V3 && optimize_size"
9304f876 686 "and_srli\t%0, %3, %1, %2"
5ba6d585
KC
687 [(set_attr "type" "alu_shift")
688 (set_attr "length" "4")])
9304f876
CJW
689
690
691;; ----------------------------------------------------------------------------
692;; 'OR' operation
693;; ----------------------------------------------------------------------------
694
695;; For V3/V3M ISA, we have 'or33' instruction.
696;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
a3b13564
KC
697
698(define_expand "iorsi3"
699 [(set (match_operand:SI 0 "register_operand" "")
700 (ior:SI (match_operand:SI 1 "register_operand" "")
701 (match_operand:SI 2 "general_operand" "")))]
9304f876
CJW
702 ""
703{
a3b13564
KC
704 if (!nds32_ior_operand (operands[2], SImode))
705 operands[2] = force_reg (SImode, operands[2]);
706})
9304f876 707
a3b13564
KC
708(define_insn "*iorsi3"
709 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
710 (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
711 (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))]
712 ""
713 "@
714 or33\t%0, %2
715 or\t%0, %1, %2
716 ori\t%0, %1, %2
717 bset\t%0, %1, %B2"
718 [(set_attr "type" "alu,alu,alu,alu")
719 (set_attr "length" " 2, 4, 4, 4")
720 (set_attr "feature" "v3m, v1, v1,pe1")])
9304f876
CJW
721
722(define_insn "*or_slli"
a3b13564
KC
723 [(set (match_operand:SI 0 "register_operand" "= r")
724 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
725 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
726 (match_operand:SI 3 "register_operand" " r")))]
b9774a97 727 "TARGET_ISA_V3 && optimize_size"
9304f876 728 "or_slli\t%0, %3, %1, %2"
5ba6d585
KC
729 [(set_attr "type" "alu_shift")
730 (set_attr "length" "4")])
9304f876
CJW
731
732(define_insn "*or_srli"
a3b13564
KC
733 [(set (match_operand:SI 0 "register_operand" "= r")
734 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
735 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
736 (match_operand:SI 3 "register_operand" " r")))]
b9774a97 737 "TARGET_ISA_V3 && optimize_size"
9304f876 738 "or_srli\t%0, %3, %1, %2"
5ba6d585
KC
739 [(set_attr "type" "alu_shift")
740 (set_attr "length" "4")])
9304f876
CJW
741
742
743;; ----------------------------------------------------------------------------
744;; 'XOR' operation
745;; ----------------------------------------------------------------------------
746
747;; For V3/V3M ISA, we have 'xor33' instruction.
748;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
a3b13564
KC
749
750(define_expand "xorsi3"
751 [(set (match_operand:SI 0 "register_operand" "")
752 (xor:SI (match_operand:SI 1 "register_operand" "")
753 (match_operand:SI 2 "general_operand" "")))]
9304f876
CJW
754 ""
755{
a3b13564
KC
756 if (!nds32_xor_operand (operands[2], SImode))
757 operands[2] = force_reg (SImode, operands[2]);
758})
9304f876 759
a3b13564
KC
760(define_insn "*xorsi3"
761 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
762 (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
763 (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))]
764 ""
765 "@
766 xor33\t%0, %2
767 xor\t%0, %1, %2
768 xori\t%0, %1, %2
769 btgl\t%0, %1, %B2"
9be6885b
KC
770 [(set_attr "type" "alu,alu,alu,alu")
771 (set_attr "length" " 2, 4, 4, 4")
772 (set_attr "feature" "v3m, v1, v1,pe1")])
9304f876
CJW
773
774(define_insn "*xor_slli"
775 [(set (match_operand:SI 0 "register_operand" "= r")
776 (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
a3b13564 777 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
9304f876 778 (match_operand:SI 3 "register_operand" " r")))]
b9774a97 779 "TARGET_ISA_V3 && optimize_size"
9304f876 780 "xor_slli\t%0, %3, %1, %2"
5ba6d585
KC
781 [(set_attr "type" "alu_shift")
782 (set_attr "length" "4")])
9304f876
CJW
783
784(define_insn "*xor_srli"
a3b13564
KC
785 [(set (match_operand:SI 0 "register_operand" "= r")
786 (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
787 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
788 (match_operand:SI 3 "register_operand" " r")))]
b9774a97 789 "TARGET_ISA_V3 && optimize_size"
9304f876 790 "xor_srli\t%0, %3, %1, %2"
5ba6d585
KC
791 [(set_attr "type" "alu_shift")
792 (set_attr "length" "4")])
9304f876
CJW
793
794;; Rotate Right Instructions.
795
a3b13564
KC
796(define_insn "*rotrsi3"
797 [(set (match_operand:SI 0 "register_operand" "= r, r")
798 (rotatert:SI (match_operand:SI 1 "register_operand" " r, r")
799 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
9304f876
CJW
800 ""
801 "@
9c1a4c0f
CJW
802 rotri\t%0, %1, %2
803 rotr\t%0, %1, %2"
5ba6d585 804 [(set_attr "type" " alu, alu")
0aa683b3 805 (set_attr "subtype" "shift,shift")
5ba6d585 806 (set_attr "length" " 4, 4")])
9304f876
CJW
807
808
809;; ----------------------------------------------------------------------------
810;; 'NEG' operation
811;; ----------------------------------------------------------------------------
812
813;; For V3/V3M ISA, we have 'neg33' instruction.
814;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
815;; And for V2 ISA, there is NO 'neg33' instruction.
816;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
817(define_insn "negsi2"
3fbbd9e5
CJW
818 [(set (match_operand:SI 0 "register_operand" "=l, r")
819 (neg:SI (match_operand:SI 1 "register_operand" " l, r")))]
9304f876
CJW
820 ""
821 "@
822 neg33\t%0, %1
823 subri\t%0, %1, 0"
3fbbd9e5
CJW
824 [(set_attr "type" "alu,alu")
825 (set_attr "length" " 2, 4")
826 (set_attr "feature" "v3m, v1")])
9304f876 827
e2286268
MC
828(define_expand "negsf2"
829 [(set (match_operand:SF 0 "register_operand" "")
830 (neg:SF (match_operand:SF 1 "register_operand" "")))]
831 ""
832{
833 if (!TARGET_FPU_SINGLE && !TARGET_EXT_PERF)
834 {
835 rtx new_dst = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
836 rtx new_src = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
837
838 emit_insn (gen_xorsi3 (new_dst,
839 new_src,
840 gen_int_mode (0x80000000, SImode)));
841
842 DONE;
843 }
844})
845
846(define_expand "negdf2"
847 [(set (match_operand:DF 0 "register_operand" "")
848 (neg:DF (match_operand:DF 1 "register_operand" "")))]
849 ""
850{
851})
852
853(define_insn_and_split "soft_negdf2"
854 [(set (match_operand:DF 0 "register_operand" "")
855 (neg:DF (match_operand:DF 1 "register_operand" "")))]
856 "!TARGET_FPU_DOUBLE"
857 "#"
858 "!TARGET_FPU_DOUBLE"
859 [(const_int 1)]
860{
861 rtx src = operands[1];
862 rtx dst = operands[0];
863 rtx ori_dst = operands[0];
864
865 bool need_extra_move_for_dst_p;
866 /* FPU register can't change mode to SI directly, so we need create a
867 tmp register to handle it, and FPU register can't do `xor` or btgl. */
868 if (HARD_REGISTER_P (src)
869 && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (src)))
870 {
871 rtx tmp = gen_reg_rtx (DFmode);
872 emit_move_insn (tmp, src);
873 src = tmp;
874 }
875
876 if (HARD_REGISTER_P (dst)
877 && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (dst)))
878 {
879 need_extra_move_for_dst_p = true;
880 rtx tmp = gen_reg_rtx (DFmode);
881 dst = tmp;
882 }
883
884 rtx dst_high_part = simplify_gen_subreg (
885 SImode, dst,
886 DFmode, subreg_highpart_offset (SImode, DFmode));
887 rtx dst_low_part = simplify_gen_subreg (
888 SImode, dst,
889 DFmode, subreg_lowpart_offset (SImode, DFmode));
890 rtx src_high_part = simplify_gen_subreg (
891 SImode, src,
892 DFmode, subreg_highpart_offset (SImode, DFmode));
893 rtx src_low_part = simplify_gen_subreg (
894 SImode, src,
895 DFmode, subreg_lowpart_offset (SImode, DFmode));
896
897 emit_insn (gen_xorsi3 (dst_high_part,
898 src_high_part,
899 gen_int_mode (0x80000000, SImode)));
900 emit_move_insn (dst_low_part, src_low_part);
901
902 if (need_extra_move_for_dst_p)
903 emit_move_insn (ori_dst, dst);
904
905 DONE;
906})
907
908
9304f876
CJW
909;; ----------------------------------------------------------------------------
910;; 'ONE_COMPLIMENT' operation
911;; ----------------------------------------------------------------------------
912
913;; For V3/V3M ISA, we have 'not33' instruction.
914;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
915(define_insn "one_cmplsi2"
916 [(set (match_operand:SI 0 "register_operand" "=w, r")
917 (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
918 ""
919 "@
920 not33\t%0, %1
921 nor\t%0, %1, %1"
9be6885b
KC
922 [(set_attr "type" "alu,alu")
923 (set_attr "length" " 2, 4")
924 (set_attr "feature" "v3m, v1")])
9304f876
CJW
925
926
927;; ----------------------------------------------------------------------------
928
929;; Shift instructions.
930
a3b13564
KC
931(define_expand "<shift>si3"
932 [(set (match_operand:SI 0 "register_operand" "")
933 (shift_rotate:SI (match_operand:SI 1 "register_operand" "")
934 (match_operand:SI 2 "nds32_rimm5u_operand" "")))]
935 ""
936{
937 if (operands[2] == const0_rtx)
938 {
939 emit_move_insn (operands[0], operands[1]);
940 DONE;
941 }
942})
943
944(define_insn "*ashlsi3"
945 [(set (match_operand:SI 0 "register_operand" "= l, r, r")
946 (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r")
947 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))]
9304f876
CJW
948 ""
949 "@
9c1a4c0f
CJW
950 slli333\t%0, %1, %2
951 slli\t%0, %1, %2
952 sll\t%0, %1, %2"
0aa683b3
CJW
953 [(set_attr "type" " alu, alu, alu")
954 (set_attr "subtype" "shift,shift,shift")
955 (set_attr "length" " 2, 4, 4")])
a3b13564
KC
956
957(define_insn "*ashrsi3"
958 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
959 (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
960 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
9304f876
CJW
961 ""
962 "@
9c1a4c0f
CJW
963 srai45\t%0, %2
964 srai\t%0, %1, %2
965 sra\t%0, %1, %2"
0aa683b3
CJW
966 [(set_attr "type" " alu, alu, alu")
967 (set_attr "subtype" "shift,shift,shift")
968 (set_attr "length" " 2, 4, 4")])
9304f876 969
a3b13564
KC
970(define_insn "*lshrsi3"
971 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
972 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
973 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
9304f876
CJW
974 ""
975 "@
9c1a4c0f
CJW
976 srli45\t%0, %2
977 srli\t%0, %1, %2
978 srl\t%0, %1, %2"
0aa683b3
CJW
979 [(set_attr "type" " alu, alu, alu")
980 (set_attr "subtype" "shift,shift,shift")
981 (set_attr "length" " 2, 4, 4")])
9304f876
CJW
982
983
984;; ----------------------------------------------------------------------------
985
986;; ----------------------------------------------------------------------------
987;; Conditional Move patterns
988;; ----------------------------------------------------------------------------
989
6e9ca932
CJW
990(define_expand "mov<mode>cc"
991 [(set (match_operand:QIHISI 0 "register_operand" "")
992 (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
993 (match_operand:QIHISI 2 "register_operand" "")
994 (match_operand:QIHISI 3 "register_operand" "")))]
995 "TARGET_CMOV && !optimize_size"
9304f876 996{
6e9ca932
CJW
997 enum nds32_expand_result_type result = nds32_expand_movcc (operands);
998 switch (result)
9304f876 999 {
6e9ca932
CJW
1000 case EXPAND_DONE:
1001 DONE;
1002 break;
1003 case EXPAND_FAIL:
1004 FAIL;
1005 break;
1006 case EXPAND_CREATE_TEMPLATE:
1007 break;
1008 default:
1009 gcc_unreachable ();
9304f876 1010 }
9304f876
CJW
1011})
1012
6e9ca932
CJW
1013(define_insn "cmovz<mode>"
1014 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
1015 (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
9304f876 1016 (const_int 0))
6e9ca932
CJW
1017 (match_operand:QIHISI 2 "register_operand" " r, 0")
1018 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
9304f876
CJW
1019 "TARGET_CMOV"
1020 "@
1021 cmovz\t%0, %2, %1
1022 cmovn\t%0, %3, %1"
5ba6d585 1023 [(set_attr "type" "alu")
9304f876
CJW
1024 (set_attr "length" "4")])
1025
6e9ca932
CJW
1026(define_insn "cmovn<mode>"
1027 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
1028 (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
9304f876 1029 (const_int 0))
6e9ca932
CJW
1030 (match_operand:QIHISI 2 "register_operand" " r, 0")
1031 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
9304f876
CJW
1032 "TARGET_CMOV"
1033 "@
1034 cmovn\t%0, %2, %1
1035 cmovz\t%0, %3, %1"
5ba6d585 1036 [(set_attr "type" "alu")
9304f876
CJW
1037 (set_attr "length" "4")])
1038
6e9ca932
CJW
1039;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
1040;; It should be removed once after we change the expansion form of the cmovn.
1041(define_insn "*cmovn_simplified_<mode>"
1042 [(set (match_operand:QIHISI 0 "register_operand" "=r")
1043 (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
1044 (match_operand:QIHISI 2 "register_operand" "r")
1045 (match_operand:QIHISI 3 "register_operand" "0")))]
1046 ""
1047 "cmovn\t%0, %2, %1"
1048 [(set_attr "type" "alu")])
9304f876
CJW
1049
1050;; ----------------------------------------------------------------------------
1051;; Conditional Branch patterns
1052;; ----------------------------------------------------------------------------
1053
1054(define_expand "cbranchsi4"
1055 [(set (pc)
1056 (if_then_else (match_operator 0 "comparison_operator"
1057 [(match_operand:SI 1 "register_operand" "")
1058 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
1059 (label_ref (match_operand 3 "" ""))
1060 (pc)))]
1061 ""
1062{
6e9ca932
CJW
1063 enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
1064 switch (result)
9304f876 1065 {
6e9ca932 1066 case EXPAND_DONE:
9304f876 1067 DONE;
6e9ca932
CJW
1068 break;
1069 case EXPAND_FAIL:
9304f876 1070 FAIL;
6e9ca932
CJW
1071 break;
1072 case EXPAND_CREATE_TEMPLATE:
1073 break;
1074 default:
1075 gcc_unreachable ();
9304f876 1076 }
9304f876
CJW
1077})
1078
1079
6e9ca932 1080(define_insn "cbranchsi4_equality_zero"
9304f876
CJW
1081 [(set (pc)
1082 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
6e9ca932 1083 [(match_operand:SI 1 "register_operand" "t,l, r")
9304f876
CJW
1084 (const_int 0)])
1085 (label_ref (match_operand 2 "" ""))
1086 (pc)))]
1087 ""
1088{
6e9ca932 1089 return nds32_output_cbranchsi4_equality_zero (insn, operands);
9304f876
CJW
1090}
1091 [(set_attr "type" "branch")
6e9ca932
CJW
1092 (set_attr_alternative "enabled"
1093 [
1094 ;; Alternative 0
1095 (if_then_else (match_test "TARGET_16_BIT")
1096 (const_string "yes")
1097 (const_string "no"))
1098 ;; Alternative 1
1099 (if_then_else (match_test "TARGET_16_BIT")
1100 (const_string "yes")
1101 (const_string "no"))
1102 ;; Alternative 2
1103 (const_string "yes")
1104 ])
9304f876
CJW
1105 (set_attr_alternative "length"
1106 [
1107 ;; Alternative 0
6e9ca932
CJW
1108 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1109 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1110 (le (minus (match_dup 2) (pc)) (const_int 250)))
9304f876 1111 (if_then_else (match_test "TARGET_16_BIT")
6e9ca932
CJW
1112 (const_int 2)
1113 (const_int 4))
1114 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1115 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1116 (const_int 4)
1117 (if_then_else (match_test "TARGET_16_BIT")
1118 (const_int 8)
1119 (const_int 10))))
1120 (const_int 10))
9304f876 1121 ;; Alternative 1
6e9ca932
CJW
1122 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1123 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1124 (le (minus (match_dup 2) (pc)) (const_int 250)))
1125 (if_then_else (match_test "TARGET_16_BIT")
1126 (const_int 2)
1127 (const_int 4))
1128 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1129 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1130 (const_int 4)
1131 (if_then_else (match_test "TARGET_16_BIT")
1132 (const_int 8)
1133 (const_int 10))))
1134 (const_int 10))
1135 ;; Alternative 2
1136 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
9304f876
CJW
1137 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1138 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1139 (const_int 4)
6e9ca932
CJW
1140 (const_int 10))
1141 (const_int 10))
9304f876
CJW
1142 ])])
1143
1144
1145;; This pattern is dedicated to V2 ISA,
1146;; because V2 DOES NOT HAVE beqc/bnec instruction.
6e9ca932 1147(define_insn "cbranchsi4_equality_reg"
9304f876
CJW
1148 [(set (pc)
1149 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
6e9ca932
CJW
1150 [(match_operand:SI 1 "register_operand" "v, r")
1151 (match_operand:SI 2 "register_operand" "l, r")])
9304f876
CJW
1152 (label_ref (match_operand 3 "" ""))
1153 (pc)))]
1154 "TARGET_ISA_V2"
1155{
6e9ca932 1156 return nds32_output_cbranchsi4_equality_reg (insn, operands);
9304f876
CJW
1157}
1158 [(set_attr "type" "branch")
6e9ca932
CJW
1159 (set_attr_alternative "enabled"
1160 [
1161 ;; Alternative 0
1162 (if_then_else (match_test "TARGET_16_BIT")
1163 (const_string "yes")
1164 (const_string "no"))
1165 ;; Alternative 1
1166 (const_string "yes")
1167 ])
1168 (set_attr_alternative "length"
1169 [
1170 ;; Alternative 0
1171 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1172 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1173 (le (minus (match_dup 3) (pc)) (const_int 250)))
1174 (const_int 2)
1175 (if_then_else (and (ge (minus (match_dup 3) (pc))
1176 (const_int -16350))
1177 (le (minus (match_dup 3) (pc))
1178 (const_int 16350)))
1179 (const_int 4)
1180 (const_int 8)))
1181 (const_int 8))
1182 ;; Alternative 1
1183 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1184 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1185 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1186 (const_int 4)
1187 (const_int 10))
1188 (const_int 10))
1189 ])])
9304f876
CJW
1190
1191
1192;; This pattern is dedicated to V3/V3M,
1193;; because V3/V3M DO HAVE beqc/bnec instruction.
6e9ca932 1194(define_insn "cbranchsi4_equality_reg_or_const_int"
9304f876
CJW
1195 [(set (pc)
1196 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
6e9ca932
CJW
1197 [(match_operand:SI 1 "register_operand" "v, r, r")
1198 (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
9304f876
CJW
1199 (label_ref (match_operand 3 "" ""))
1200 (pc)))]
1201 "TARGET_ISA_V3 || TARGET_ISA_V3M"
1202{
6e9ca932 1203 return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
9304f876
CJW
1204}
1205 [(set_attr "type" "branch")
6e9ca932
CJW
1206 (set_attr_alternative "enabled"
1207 [
1208 ;; Alternative 0
1209 (if_then_else (match_test "TARGET_16_BIT")
1210 (const_string "yes")
1211 (const_string "no"))
1212 ;; Alternative 1
1213 (const_string "yes")
1214 ;; Alternative 2
1215 (const_string "yes")
1216 ])
9304f876
CJW
1217 (set_attr_alternative "length"
1218 [
1219 ;; Alternative 0
6e9ca932
CJW
1220 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1221 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1222 (le (minus (match_dup 3) (pc)) (const_int 250)))
1223 (const_int 2)
1224 (if_then_else (and (ge (minus (match_dup 3) (pc))
1225 (const_int -16350))
1226 (le (minus (match_dup 3) (pc))
1227 (const_int 16350)))
1228 (const_int 4)
1229 (const_int 8)))
1230 (const_int 8))
9304f876 1231 ;; Alternative 1
6e9ca932
CJW
1232 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1233 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1234 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1235 (const_int 4)
1236 (const_int 10))
1237 (const_int 10))
1238 ;; Alternative 2
1239 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1240 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1241 (le (minus (match_dup 3) (pc)) (const_int 250)))
1242 (const_int 4)
1243 (const_int 10))
1244 (const_int 10))
9304f876
CJW
1245 ])])
1246
1247
1248(define_insn "*cbranchsi4_greater_less_zero"
1249 [(set (pc)
1250 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1251 [(match_operand:SI 1 "register_operand" "r")
1252 (const_int 0)])
1253 (label_ref (match_operand 2 "" ""))
1254 (pc)))]
1255 ""
1256{
6e9ca932 1257 return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
9304f876
CJW
1258}
1259 [(set_attr "type" "branch")
1260 (set (attr "length")
6e9ca932
CJW
1261 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1262 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1263 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1264 (const_int 4)
1265 (const_int 10))
1266 (const_int 10)))])
9304f876
CJW
1267
1268
1269(define_expand "cstoresi4"
1270 [(set (match_operand:SI 0 "register_operand" "")
1271 (match_operator:SI 1 "comparison_operator"
1272 [(match_operand:SI 2 "register_operand" "")
1273 (match_operand:SI 3 "nonmemory_operand" "")]))]
1274 ""
1275{
6e9ca932
CJW
1276 enum nds32_expand_result_type result = nds32_expand_cstore (operands);
1277 switch (result)
9304f876 1278 {
6e9ca932 1279 case EXPAND_DONE:
9304f876 1280 DONE;
6e9ca932
CJW
1281 break;
1282 case EXPAND_FAIL:
1283 FAIL;
1284 break;
1285 case EXPAND_CREATE_TEMPLATE:
1286 break;
9304f876
CJW
1287 default:
1288 gcc_unreachable ();
1289 }
1290})
1291
1292
6e9ca932
CJW
1293(define_expand "slts_compare"
1294 [(set (match_operand:SI 0 "register_operand" "")
1295 (lt:SI (match_operand:SI 1 "general_operand" "")
1296 (match_operand:SI 2 "general_operand" "")))]
1297 ""
1298{
1299 if (!REG_P (operands[1]))
1300 operands[1] = force_reg (SImode, operands[1]);
1301
1302 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1303 operands[2] = force_reg (SImode, operands[2]);
1304})
1305
1306(define_insn "slts_compare_impl"
1307 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1308 (lt:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1309 (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
9304f876
CJW
1310 ""
1311 "@
1312 slts45\t%1, %2
1313 sltsi45\t%1, %2
1314 slts\t%0, %1, %2
1315 sltsi\t%0, %1, %2"
6e9ca932
CJW
1316 [(set_attr "type" "alu, alu, alu, alu")
1317 (set_attr "length" " 2, 2, 4, 4")])
1318
1319(define_insn "slt_eq0"
1320 [(set (match_operand:SI 0 "register_operand" "=t, r")
1321 (eq:SI (match_operand:SI 1 "register_operand" " d, r")
1322 (const_int 0)))]
1323 ""
1324 "@
1325 slti45\t%1, 1
1326 slti\t%0, %1, 1"
1327 [(set_attr "type" "alu, alu")
1328 (set_attr "length" " 2, 4")])
1329
1330(define_expand "slt_compare"
1331 [(set (match_operand:SI 0 "register_operand" "")
1332 (ltu:SI (match_operand:SI 1 "general_operand" "")
1333 (match_operand:SI 2 "general_operand" "")))]
1334 ""
1335{
1336 if (!REG_P (operands[1]))
1337 operands[1] = force_reg (SImode, operands[1]);
1338
1339 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1340 operands[2] = force_reg (SImode, operands[2]);
1341})
9304f876 1342
6e9ca932
CJW
1343(define_insn "slt_compare_impl"
1344 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1345 (ltu:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1346 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
9304f876
CJW
1347 ""
1348 "@
1349 slt45\t%1, %2
1350 slti45\t%1, %2
1351 slt\t%0, %1, %2
1352 slti\t%0, %1, %2"
5ba6d585
KC
1353 [(set_attr "type" "alu, alu, alu, alu")
1354 (set_attr "length" " 2, 2, 4, 4")])
9304f876
CJW
1355
1356
1357;; ----------------------------------------------------------------------------
1358
1359;; Unconditional and other jump instructions.
1360
1361(define_insn "jump"
1362 [(set (pc) (label_ref (match_operand 0 "" "")))]
1363 ""
1364{
1365 /* This unconditional jump has two forms:
1366 32-bit instruction => j imm24s << 1
1367 16-bit instruction => j8 imm8s << 1
1368
1369 For 32-bit case,
1370 we assume it is always reachable.
1371 For 16-bit case,
1372 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1373 However, since the $pc for nds32 is at the beginning of the instruction,
1374 we should leave some length space for current insn.
1375 So we use range -250 ~ 250. */
1376 switch (get_attr_length (insn))
1377 {
1378 case 2:
1379 return "j8\t%0";
1380 case 4:
1381 return "j\t%0";
1382 default:
1383 gcc_unreachable ();
1384 }
1385}
1386 [(set_attr "type" "branch")
30feb954 1387 (set_attr "enabled" "yes")
9304f876 1388 (set (attr "length")
6e9ca932
CJW
1389 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1390 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1391 (le (minus (match_dup 0) (pc)) (const_int 250)))
1392 (if_then_else (match_test "TARGET_16_BIT")
1393 (const_int 2)
1394 (const_int 4))
9304f876
CJW
1395 (const_int 4))
1396 (const_int 4)))])
1397
1398(define_insn "indirect_jump"
1399 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1400 ""
1401 "@
9c1a4c0f
CJW
1402 jr5\t%0
1403 jr\t%0"
9304f876
CJW
1404 [(set_attr "type" "branch,branch")
1405 (set_attr "length" " 2, 4")])
1406
1407;; Subroutine call instruction returning no value.
1408;; operands[0]: It should be a mem RTX whose address is
026c3cfd 1409;; the address of the function.
9304f876
CJW
1410;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
1411;; operands[2]: It is the number of registers used as operands.
1412
1413(define_expand "call"
1414 [(parallel [(call (match_operand 0 "memory_operand" "")
1415 (match_operand 1))
1f7b8028
CJW
1416 (clobber (reg:SI LP_REGNUM))
1417 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1418 ""
1419 ""
1420)
1421
1422(define_insn "*call_register"
1423 [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
1424 (match_operand 1))
1f7b8028
CJW
1425 (clobber (reg:SI LP_REGNUM))
1426 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1427 ""
1428 "@
1429 jral5\t%0
1430 jral\t%0"
1431 [(set_attr "type" "branch,branch")
1432 (set_attr "length" " 2, 4")])
1433
1434(define_insn "*call_immediate"
1435 [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
1436 (match_operand 1))
1f7b8028
CJW
1437 (clobber (reg:SI LP_REGNUM))
1438 (clobber (reg:SI TA_REGNUM))])]
9304f876 1439 ""
1f7b8028
CJW
1440{
1441 if (TARGET_CMODEL_LARGE)
1442 return "bal\t%0";
1443 else
1444 return "jal\t%0";
1445}
9304f876 1446 [(set_attr "type" "branch")
1f7b8028
CJW
1447 (set (attr "length")
1448 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1449 (const_int 12)
1450 (const_int 4)))])
9304f876
CJW
1451
1452
1453;; Subroutine call instruction returning a value.
1454;; operands[0]: It is the hard regiser in which the value is returned.
1455;; The rest three operands are the same as the
1456;; three operands of the 'call' instruction.
1457;; (but with numbers increased by one)
1458
1459(define_expand "call_value"
1460 [(parallel [(set (match_operand 0)
1461 (call (match_operand 1 "memory_operand" "")
1462 (match_operand 2)))
1f7b8028
CJW
1463 (clobber (reg:SI LP_REGNUM))
1464 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1465 ""
1466 ""
1467)
1468
1469(define_insn "*call_value_register"
1470 [(parallel [(set (match_operand 0)
1471 (call (mem (match_operand:SI 1 "register_operand" "r, r"))
1472 (match_operand 2)))
1f7b8028
CJW
1473 (clobber (reg:SI LP_REGNUM))
1474 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1475 ""
1476 "@
1477 jral5\t%1
1478 jral\t%1"
1479 [(set_attr "type" "branch,branch")
1480 (set_attr "length" " 2, 4")])
1481
1482(define_insn "*call_value_immediate"
1483 [(parallel [(set (match_operand 0)
1484 (call (mem (match_operand:SI 1 "immediate_operand" "i"))
1485 (match_operand 2)))
1f7b8028
CJW
1486 (clobber (reg:SI LP_REGNUM))
1487 (clobber (reg:SI TA_REGNUM))])]
9304f876 1488 ""
1f7b8028
CJW
1489{
1490 if (TARGET_CMODEL_LARGE)
1491 return "bal\t%1";
1492 else
1493 return "jal\t%1";
1494}
9304f876 1495 [(set_attr "type" "branch")
1f7b8028
CJW
1496 (set (attr "length")
1497 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1498 (const_int 12)
1499 (const_int 4)))])
9304f876
CJW
1500
1501
d6529176
CJW
1502;; ----------------------------------------------------------------------------
1503
1504;; The sibcall patterns.
1505
1506;; sibcall
cc48a87f 1507;; sibcall_internal
d6529176
CJW
1508
1509(define_expand "sibcall"
1510 [(parallel [(call (match_operand 0 "memory_operand" "")
1511 (const_int 0))
1512 (clobber (reg:SI TA_REGNUM))
1513 (return)])]
cc48a87f 1514 "")
d6529176 1515
cc48a87f
CJW
1516(define_insn "sibcall_internal"
1517 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
d6529176
CJW
1518 (match_operand 1))
1519 (clobber (reg:SI TA_REGNUM))
1520 (return)])]
1521 ""
1522{
cc48a87f
CJW
1523 switch (which_alternative)
1524 {
1525 case 0:
1526 if (TARGET_16_BIT)
1527 return "jr5\t%0";
1528 else
1529 return "jr\t%0";
1530 case 1:
1531 if (nds32_long_call_p (operands[0]))
1532 return "b\t%0";
1533 else
1534 return "j\t%0";
1535 default:
1536 gcc_unreachable ();
1537 }
d6529176 1538}
30feb954 1539 [(set_attr "enabled" "yes")
cc48a87f
CJW
1540 (set_attr "type" "branch")
1541 (set_attr_alternative "length"
1542 [
1543 ;; Alternative 0
1544 (if_then_else (match_test "TARGET_16_BIT")
1545 (const_int 2)
1546 (const_int 4))
1547 ;; Alternative 1
1548 (if_then_else (match_test "nds32_long_call_p (operands[0])")
1549 (const_int 12)
1550 (const_int 4))
1551 ])]
1552)
d6529176
CJW
1553
1554;; sibcall_value
cc48a87f 1555;; sibcall_value_internal
d6529176
CJW
1556;; sibcall_value_immediate
1557
1558(define_expand "sibcall_value"
1559 [(parallel [(set (match_operand 0)
1560 (call (match_operand 1 "memory_operand" "")
1561 (const_int 0)))
1562 (clobber (reg:SI TA_REGNUM))
1563 (return)])]
cc48a87f 1564 "")
d6529176 1565
cc48a87f 1566(define_insn "sibcall_value_internal"
d6529176 1567 [(parallel [(set (match_operand 0)
cc48a87f 1568 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
d6529176
CJW
1569 (match_operand 2)))
1570 (clobber (reg:SI TA_REGNUM))
1571 (return)])]
1572 ""
1573{
cc48a87f
CJW
1574 switch (which_alternative)
1575 {
1576 case 0:
1577 if (TARGET_16_BIT)
1578 return "jr5\t%1";
1579 else
1580 return "jr\t%1";
1581 case 1:
1582 if (nds32_long_call_p (operands[1]))
1583 return "b\t%1";
1584 else
1585 return "j\t%1";
1586 default:
1587 gcc_unreachable ();
1588 }
d6529176 1589}
30feb954 1590 [(set_attr "enabled" "yes")
cc48a87f
CJW
1591 (set_attr "type" "branch")
1592 (set_attr_alternative "length"
1593 [
1594 ;; Alternative 0
1595 (if_then_else (match_test "TARGET_16_BIT")
1596 (const_int 2)
1597 (const_int 4))
1598 ;; Alternative 1
1599 (if_then_else (match_test "nds32_long_call_p (operands[1])")
1600 (const_int 12)
1601 (const_int 4))
1602 ])]
1603)
d6529176
CJW
1604
1605;; ----------------------------------------------------------------------------
1606
9304f876
CJW
1607;; prologue and epilogue.
1608
1609(define_expand "prologue" [(const_int 0)]
1610 ""
1611{
2da1e7c0 1612 /* Note that only under V3/V3M ISA, we could use v3push prologue.
a6c7e777
MC
1613 In addition, we need to check if v3push is indeed available. */
1614 if (NDS32_V3PUSH_AVAILABLE_P)
9304f876
CJW
1615 nds32_expand_prologue_v3push ();
1616 else
1617 nds32_expand_prologue ();
1618 DONE;
1619})
1620
1621(define_expand "epilogue" [(const_int 0)]
1622 ""
1623{
2da1e7c0 1624 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
a6c7e777
MC
1625 In addition, we need to check if v3push is indeed available. */
1626 if (NDS32_V3PUSH_AVAILABLE_P)
d6529176
CJW
1627 nds32_expand_epilogue_v3pop (false);
1628 else
1629 nds32_expand_epilogue (false);
1630 DONE;
1631})
1632
1633(define_expand "sibcall_epilogue" [(const_int 0)]
1634 ""
1635{
1636 /* Pass true to indicate that this is sibcall epilogue and
1637 exit from a function without the final branch back to the
1638 calling function. */
a6c7e777 1639 nds32_expand_epilogue (true);
d6529176 1640
9304f876
CJW
1641 DONE;
1642})
1643
1644
1645;; nop instruction.
1646
1647(define_insn "nop"
1648 [(const_int 0)]
1649 ""
1650{
1651 if (TARGET_16_BIT)
1652 return "nop16";
1653 else
1654 return "nop";
1655}
1656 [(set_attr "type" "misc")
30feb954 1657 (set_attr "enabled" "yes")
9304f876
CJW
1658 (set (attr "length")
1659 (if_then_else (match_test "TARGET_16_BIT")
1660 (const_int 2)
1661 (const_int 4)))])
1662
1663
1664;; ----------------------------------------------------------------------------
1665;; Stack push/pop operations
1666;; ----------------------------------------------------------------------------
1667
1668;; The pattern for stack push.
1669;; Both stack_push_multiple and stack_v3push use the following pattern.
1670;; So we need to use TARGET_V3PUSH to determine the instruction length.
1671(define_insn "*stack_push"
1672 [(match_parallel 0 "nds32_stack_push_operation"
1673 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1674 (match_operand:SI 1 "const_int_operand" "")))
1675 (match_operand:SI 2 "register_operand" ""))
1676 ])]
1677 ""
1678{
6f3d3f9c 1679 return nds32_output_stack_push (operands[0]);
9304f876 1680}
264159d2
KC
1681 [(set_attr "type" "store_multiple")
1682 (set_attr "combo" "12")
30feb954 1683 (set_attr "enabled" "yes")
9304f876 1684 (set (attr "length")
9865d240 1685 (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
9304f876
CJW
1686 (const_int 2)
1687 (const_int 4)))])
1688
1689
1690;; The pattern for stack pop.
1691;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1692;; So we need to use TARGET_V3PUSH to determine the instruction length.
1693(define_insn "*stack_pop"
1694 [(match_parallel 0 "nds32_stack_pop_operation"
1695 [(set (match_operand:SI 1 "register_operand" "")
1696 (mem:SI (reg:SI SP_REGNUM)))
1697 ])]
1698 ""
1699{
6f3d3f9c 1700 return nds32_output_stack_pop (operands[0]);
9304f876 1701}
264159d2
KC
1702 [(set_attr "type" "load_multiple")
1703 (set_attr "combo" "12")
30feb954 1704 (set_attr "enabled" "yes")
9304f876 1705 (set (attr "length")
9865d240 1706 (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
9304f876
CJW
1707 (const_int 2)
1708 (const_int 4)))])
1709
1710
1711;; ----------------------------------------------------------------------------
03390cda 1712;; Return operation patterns
9304f876
CJW
1713;; ----------------------------------------------------------------------------
1714
03390cda
CJW
1715;; Use this pattern to expand a return instruction
1716;; with simple_return rtx if no epilogue is required.
1717(define_expand "return"
1718 [(simple_return)]
1719 "nds32_can_use_return_insn ()"
1720 ""
1721)
9304f876 1722
03390cda
CJW
1723;; This pattern is expanded only by the shrink-wrapping optimization
1724;; on paths where the function prologue has not been executed.
1725(define_expand "simple_return"
1726 [(simple_return)]
1727 ""
1728 ""
1729)
1730
1731(define_insn "return_internal"
1732 [(simple_return)]
9304f876
CJW
1733 ""
1734{
1735 if (TARGET_16_BIT)
1736 return "ret5";
1737 else
1738 return "ret";
1739}
03390cda 1740 [(set_attr "type" "branch")
30feb954 1741 (set_attr "enabled" "yes")
9304f876
CJW
1742 (set (attr "length")
1743 (if_then_else (match_test "TARGET_16_BIT")
1744 (const_int 2)
1745 (const_int 4)))])
1746
1747
1748;; ----------------------------------------------------------------------------
1749;; Jump Table patterns
1750;; ----------------------------------------------------------------------------
1751;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
1752;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
1753;;
1754;; operands[0]: The index to dispatch on.
1755;; operands[1]: The lower bound for indices in the table.
1756;; operands[2]: The total range of indices int the table.
1757;; i.e. The largest index minus the smallest one.
1758;; operands[3]: A label that precedes the table itself.
1759;; operands[4]: A label to jump to if the index has a value outside the bounds.
1760;;
1761;; We need to create following sequences for jump table code generation:
1762;; A) k <-- (plus (operands[0]) (-operands[1]))
1763;; B) if (gtu k operands[2]) then goto operands[4]
1764;; C) t <-- operands[3]
1765;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
1766;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
1767;; F) jump to target with register t or z
1768;;
1769;; The steps C, D, E, and F are performed by casesi_internal pattern.
1770(define_expand "casesi"
1771 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
1772 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
1773 (match_operand:SI 2 "immediate_operand" "i") ; total range
1774 (match_operand:SI 3 "" "") ; table label
1775 (match_operand:SI 4 "" "")] ; Out of range label
1776 ""
1777{
1778 rtx add_tmp;
1779 rtx reg, test;
1780
1781 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
1782 if (operands[1] != const0_rtx)
1783 {
1784 reg = gen_reg_rtx (SImode);
1785 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
1786
1787 /* If the integer value is not in the range of imm15s,
8a498f99
CJW
1788 we need to force register first because our addsi3 pattern
1789 only accept nds32_rimm15s_operand predicate. */
9304f876
CJW
1790 add_tmp = force_reg (SImode, add_tmp);
1791
1792 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
1793 operands[0] = reg;
1794 }
1795
1796 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
1797 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
1798 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
1799 operands[4]));
1800
9759608c
SB
1801 /* Step C, D, E, and F, using another temporary register. */
1802 rtx tmp = gen_reg_rtx (SImode);
1803 emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
9304f876
CJW
1804 DONE;
1805})
1806
1807;; We are receiving operands from casesi pattern:
1808;;
1809;; operands[0]: The index that have been substracted with lower bound.
1810;; operands[1]: A label that precedes the table itself.
1811;; operands[2]: A temporary register to retrieve value in table.
1812;;
1813;; We need to perform steps C, D, E, and F:
1814;;
1815;; C) t <-- operands[1]
1816;; D) z <-- (mem (plus (operands[0] << m) t))
1817;; m is 2 for normal jump table.
1818;; m is 0, 1, or 2 for pc relative jump table based on diff size.
1819;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
1820;; F) Jump to target with register t or z.
1821;;
1822;; The USE in this pattern is needed to tell flow analysis that this is
1823;; a CASESI insn. It has no other purpose.
1824(define_insn "casesi_internal"
1825 [(parallel [(set (pc)
1826 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1827 (const_int 4))
1828 (label_ref (match_operand 1 "" "")))))
1829 (use (label_ref (match_dup 1)))
24f036fb 1830 (clobber (match_operand:SI 2 "register_operand" "=r"))
9304f876
CJW
1831 (clobber (reg:SI TA_REGNUM))])]
1832 ""
1833{
1834 if (CASE_VECTOR_PC_RELATIVE)
1835 return nds32_output_casesi_pc_relative (operands);
1836 else
1837 return nds32_output_casesi (operands);
1838}
1839 [(set_attr "length" "20")
5ba6d585 1840 (set_attr "type" "branch")])
9304f876
CJW
1841
1842;; ----------------------------------------------------------------------------
1843
1844;; Performance Extension
1845
1846(define_insn "clzsi2"
1847 [(set (match_operand:SI 0 "register_operand" "=r")
1848 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
aa4b851c 1849 "TARGET_EXT_PERF"
9304f876
CJW
1850 "clz\t%0, %1"
1851 [(set_attr "type" "alu")
1852 (set_attr "length" "4")])
1853
1854(define_insn "smaxsi3"
1855 [(set (match_operand:SI 0 "register_operand" "=r")
1856 (smax:SI (match_operand:SI 1 "register_operand" " r")
1857 (match_operand:SI 2 "register_operand" " r")))]
aa4b851c 1858 "TARGET_EXT_PERF"
9304f876
CJW
1859 "max\t%0, %1, %2"
1860 [(set_attr "type" "alu")
1861 (set_attr "length" "4")])
1862
1863(define_insn "sminsi3"
1864 [(set (match_operand:SI 0 "register_operand" "=r")
1865 (smin:SI (match_operand:SI 1 "register_operand" " r")
1866 (match_operand:SI 2 "register_operand" " r")))]
aa4b851c 1867 "TARGET_EXT_PERF"
9304f876
CJW
1868 "min\t%0, %1, %2"
1869 [(set_attr "type" "alu")
1870 (set_attr "length" "4")])
1871
1872(define_insn "*btst"
1873 [(set (match_operand:SI 0 "register_operand" "= r")
1874 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
1875 (const_int 1)
1876 (match_operand:SI 2 "immediate_operand" " Iu05")))]
aa4b851c 1877 "TARGET_EXT_PERF"
9304f876
CJW
1878 "btst\t%0, %1, %2"
1879 [(set_attr "type" "alu")
1880 (set_attr "length" "4")])
1881
1882;; ----------------------------------------------------------------------------
aa2642ef
CJW
1883
1884;; Pseudo NOPs
1885
c4d8d050
CJW
1886(define_insn "relax_group"
1887 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
1888 ""
1889 ".relax_hint %0"
1890 [(set_attr "length" "0")]
1891)
1892
aa2642ef
CJW
1893(define_insn "pop25return"
1894 [(return)
1895 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
1896 ""
1897 "! return for pop 25"
1898 [(set_attr "length" "0")]
1899)
1900
1901;; ----------------------------------------------------------------------------