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