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