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