1 ;; Machine description of Andes NDS32 cpu for GNU compiler
2 ;; Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 ;; Contributed by Andes Technology Corporation.
5 ;; This file is part of GCC.
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.
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.
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/>.
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 ;; Include predicates definition.
24 (include "predicates.md")
26 ;; Include constraints definition.
27 (include "constraints.md")
29 ;; Include iterators definition.
30 (include "iterators.md")
32 ;; Include pipelines definition.
33 (include "pipelines.md")
36 ;; Include constants definition.
37 (include "constants.md")
40 ;; Include intrinsic functions definition.
41 (include "nds32-intrinsic.md")
43 ;; Include block move for nds32 multiple load/store behavior.
44 (include "nds32-multiple.md")
46 ;; Include DImode/DFmode operations.
47 (include "nds32-doubleword.md")
49 ;; Include peephole patterns.
50 (include "nds32-peephole2.md")
53 ;; Insn type, it is used to default other attribute values.
55 "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,call,misc"
56 (const_string "unknown"))
59 (define_attr "subtype"
61 (const_string "simple"))
63 ;; Length, in bytes, default is 4-bytes.
64 (define_attr "length" "" (const_int 4))
66 ;; Indicate the amount of micro instructions.
68 "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"
71 ;; Insn in which feature set, it is used to enable/disable insn alternatives.
72 ;; v1 : Baseline Instructions
73 ;; v2 : Baseline Version 2 Instructions
74 ;; v3m : Baseline Version 3m Instructions
75 ;; v3 : Baseline Version 3 Instructions
76 ;; pe1 : Performance Extension Instructions
77 ;; pe2 : Performance Extension Version 2 Instructions
78 ;; se : String Extension instructions
79 (define_attr "feature"
80 "v1,v2,v3m,v3,pe1,pe2,se"
83 ;; Enabled, which is used to enable/disable insn alternatives.
84 ;; Note that we use length and TARGET_16_BIT here as criteria.
85 ;; If the instruction pattern already check TARGET_16_BIT to determine
86 ;; the length by itself, its enabled attribute should be customized to
87 ;; avoid the conflict between length attribute and this default setting.
88 (define_attr "enabled" "no,yes"
90 (and (eq_attr "length" "2")
91 (match_test "!TARGET_16_BIT"))
93 (cond [(eq_attr "feature" "v1") (const_string "yes")
94 (eq_attr "feature" "v2") (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M")
97 (eq_attr "feature" "v3") (if_then_else (match_test "TARGET_ISA_V3")
100 (eq_attr "feature" "v3m") (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M")
103 (eq_attr "feature" "pe1") (if_then_else (match_test "TARGET_EXT_PERF")
106 (eq_attr "feature" "pe2") (if_then_else (match_test "TARGET_EXT_PERF2")
109 (eq_attr "feature" "se") (if_then_else (match_test "TARGET_EXT_STRING")
111 (const_string "no"))]
112 (const_string "yes"))))
115 ;; ----------------------------------------------------------------------------
118 ;; Move instructions.
120 ;; For QImode and HImode, the immediate value can be fit in imm20s.
121 ;; So there is no need to split rtx for QI and HI patterns.
123 (define_expand "mov<mode>"
124 [(set (match_operand:QIHI 0 "general_operand" "")
125 (match_operand:QIHI 1 "general_operand" ""))]
128 /* Need to force register if mem <- !reg. */
129 if (MEM_P (operands[0]) && !REG_P (operands[1]))
130 operands[1] = force_reg (<MODE>mode, operands[1]);
132 if (MEM_P (operands[1]) && optimize > 0)
134 rtx reg = gen_reg_rtx (SImode);
136 emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
137 operands[1] = gen_lowpart (<MODE>mode, reg);
141 (define_expand "movmisalign<mode>"
142 [(set (match_operand:SIDI 0 "general_operand" "")
143 (match_operand:SIDI 1 "general_operand" ""))]
147 if (MEM_P (operands[0]) && !REG_P (operands[1]))
148 operands[1] = force_reg (<MODE>mode, operands[1]);
150 if (MEM_P (operands[0]))
152 addr = force_reg (Pmode, XEXP (operands[0], 0));
153 emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
157 addr = force_reg (Pmode, XEXP (operands[1], 0));
158 emit_insn (gen_unaligned_load<mode> (operands[0], addr));
163 (define_expand "movsi"
164 [(set (match_operand:SI 0 "general_operand" "")
165 (match_operand:SI 1 "general_operand" ""))]
168 /* Need to force register if mem <- !reg. */
169 if (MEM_P (operands[0]) && !REG_P (operands[1]))
170 operands[1] = force_reg (SImode, operands[1]);
172 /* If operands[1] is a large constant and cannot be performed
173 by a single instruction, we need to split it. */
174 if (CONST_INT_P (operands[1])
175 && !satisfies_constraint_Is20 (operands[1])
176 && !satisfies_constraint_Ihig (operands[1]))
179 HOST_WIDE_INT low12_int;
182 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
184 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
185 low12_int = INTVAL (operands[1]) & 0xfff;
187 emit_move_insn (tmp_rtx, high20_rtx);
188 emit_move_insn (operands[0], plus_constant (SImode,
195 (define_insn "*mov<mode>"
196 [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r, U45, U33, U37, U45, m, l, l, l, d, r, d, r, r, r")
197 (match_operand:QIHISI 1 "nds32_move_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45, m, Ip05, Is05, Is20, Ihig"))]
198 "register_operand(operands[0], <MODE>mode)
199 || register_operand(operands[1], <MODE>mode)"
201 switch (which_alternative)
204 return "mov55\t%0, %1";
206 return "ori\t%0, %1, 0";
211 return nds32_output_16bit_store (operands, <byte>);
213 return nds32_output_32bit_store (operands, <byte>);
218 return nds32_output_16bit_load (operands, <byte>);
220 return nds32_output_32bit_load (operands, <byte>);
222 return "movpi45\t%0, %1";
224 return "movi55\t%0, %1";
226 return "movi\t%0, %1";
228 return "sethi\t%0, hi20(%1)";
233 [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,alu,alu,alu,alu")
234 (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 4, 4")])
237 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
238 ;; are able to match such instruction template.
239 (define_insn "move_addr"
240 [(set (match_operand:SI 0 "register_operand" "=l, r")
241 (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
244 [(set_attr "type" "alu")
245 (set_attr "length" "8")])
249 [(set (match_operand:SI 0 "register_operand" "=r")
250 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
252 "sethi\t%0, hi20(%1)"
253 [(set_attr "type" "alu")
254 (set_attr "length" "4")])
257 (define_insn "lo_sum"
258 [(set (match_operand:SI 0 "register_operand" "=r")
259 (lo_sum:SI (match_operand:SI 1 "register_operand" " r")
260 (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
262 "ori\t%0, %1, lo12(%2)"
263 [(set_attr "type" "alu")
264 (set_attr "length" "4")])
267 ;; ----------------------------------------------------------------------------
269 ;; Zero extension instructions.
271 (define_insn "zero_extend<mode>si2"
272 [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r")
273 (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))]
276 switch (which_alternative)
279 return "ze<size>33\t%0, %1";
281 return "ze<size>\t%0, %1";
283 return nds32_output_16bit_load (operands, <byte>);
285 return nds32_output_32bit_load (operands, <byte>);
291 [(set_attr "type" "alu,alu,load,load")
292 (set_attr "length" " 2, 4, 2, 4")])
295 ;; Sign extension instructions.
297 (define_insn "extend<mode>si2"
298 [(set (match_operand:SI 0 "register_operand" "=l, r, r")
299 (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
302 switch (which_alternative)
305 return "se<size>33\t%0, %1";
307 return "se<size>\t%0, %1";
309 return nds32_output_32bit_load_s (operands, <byte>);
315 [(set_attr "type" "alu,alu,load")
316 (set_attr "length" " 2, 4, 4")])
319 ;; ----------------------------------------------------------------------------
321 ;; Arithmetic instructions.
323 (define_insn "addsi3"
324 [(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
325 (plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
326 (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,Iu06, Is15, r")))]
329 switch (which_alternative)
332 /* addi Rt4,Rt4,-x ==> subi45 Rt4,x
333 where 0 <= x <= 31 */
334 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
335 return "subi45\t%0, %2";
337 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
339 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
340 return "subi333\t%0, %1, %2";
342 return "addi45\t%0, %2";
344 return "addi333\t%0, %1, %2";
346 return "add45\t%0, %2";
348 return "add333\t%0, %1, %2";
350 return "addi10.sp\t%2";
352 return "addri36.sp\t%0, %2";
354 return "addi\t%0, %1, %2";
356 return "add\t%0, %1, %2";
362 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
363 (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")
364 (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")])
366 (define_insn "subsi3"
367 [(set (match_operand:SI 0 "register_operand" "=d, l, r, r")
368 (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
369 (match_operand:SI 2 "register_operand" " r, l, r, r")))]
376 [(set_attr "type" "alu,alu,alu,alu")
377 (set_attr "length" " 2, 2, 4, 4")])
380 ;; GCC intends to simplify (plus (ashift ...) (reg))
381 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
382 ;; and needs to ensure it is exact_log2 value.
383 (define_insn "*add_slli"
384 [(set (match_operand:SI 0 "register_operand" "=r")
385 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
386 (match_operand:SI 2 "immediate_operand" " i"))
387 (match_operand:SI 3 "register_operand" " r")))]
389 && (exact_log2 (INTVAL (operands[2])) != -1)
390 && (exact_log2 (INTVAL (operands[2])) <= 31)"
392 /* Get floor_log2 of the immediate value
393 so that we can generate 'add_slli' instruction. */
394 operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
396 return "add_slli\t%0, %3, %1, %2";
398 [(set_attr "type" "alu_shift")
399 (set_attr "combo" "2")
400 (set_attr "length" "4")])
402 (define_insn "*add_srli"
403 [(set (match_operand:SI 0 "register_operand" "= r")
404 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
405 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
406 (match_operand:SI 3 "register_operand" " r")))]
408 "add_srli\t%0, %3, %1, %2"
409 [(set_attr "type" "alu_shift")
410 (set_attr "combo" "2")
411 (set_attr "length" "4")])
414 ;; GCC intends to simplify (minus (reg) (ashift ...))
415 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
416 ;; and needs to ensure it is exact_log2 value.
417 (define_insn "*sub_slli"
418 [(set (match_operand:SI 0 "register_operand" "=r")
419 (minus:SI (match_operand:SI 1 "register_operand" " r")
420 (mult:SI (match_operand:SI 2 "register_operand" " r")
421 (match_operand:SI 3 "immediate_operand" " i"))))]
423 && (exact_log2 (INTVAL (operands[3])) != -1)
424 && (exact_log2 (INTVAL (operands[3])) <= 31)"
426 /* Get floor_log2 of the immediate value
427 so that we can generate 'sub_slli' instruction. */
428 operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
430 return "sub_slli\t%0, %1, %2, %3";
432 [(set_attr "type" "alu_shift")
433 (set_attr "combo" "2")
434 (set_attr "length" "4")])
436 (define_insn "*sub_srli"
437 [(set (match_operand:SI 0 "register_operand" "= r")
438 (minus:SI (match_operand:SI 1 "register_operand" " r")
439 (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
440 (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))]
442 "sub_srli\t%0, %1, %2, %3"
443 [(set_attr "type" "alu_shift")
444 (set_attr "combo" "2")
445 (set_attr "length" "4")])
448 ;; Multiplication instructions.
450 (define_insn "mulsi3"
451 [(set (match_operand:SI 0 "register_operand" "=w, r")
452 (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
453 (match_operand:SI 2 "register_operand" " w, r")))]
458 [(set_attr "type" "mul,mul")
459 (set_attr "length" " 2, 4")
460 (set_attr "feature" "v3m, v1")])
462 (define_insn "mulsidi3"
463 [(set (match_operand:DI 0 "register_operand" "=r")
464 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
465 (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
466 "TARGET_ISA_V2 || TARGET_ISA_V3"
467 "mulsr64\t%0, %1, %2"
468 [(set_attr "type" "mul")
469 (set_attr "length" "4")])
471 (define_insn "umulsidi3"
472 [(set (match_operand:DI 0 "register_operand" "=r")
473 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
474 (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
475 "TARGET_ISA_V2 || TARGET_ISA_V3"
477 [(set_attr "type" "mul")
478 (set_attr "length" "4")])
481 ;; Multiply-accumulate instructions.
483 (define_insn "*maddr32_0"
484 [(set (match_operand:SI 0 "register_operand" "=r")
485 (plus:SI (match_operand:SI 3 "register_operand" " 0")
486 (mult:SI (match_operand:SI 1 "register_operand" " r")
487 (match_operand:SI 2 "register_operand" " r"))))]
489 "maddr32\t%0, %1, %2"
490 [(set_attr "type" "mac")
491 (set_attr "length" "4")])
493 (define_insn "*maddr32_1"
494 [(set (match_operand:SI 0 "register_operand" "=r")
495 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
496 (match_operand:SI 2 "register_operand" " r"))
497 (match_operand:SI 3 "register_operand" " 0")))]
499 "maddr32\t%0, %1, %2"
500 [(set_attr "type" "mac")
501 (set_attr "length" "4")])
503 (define_insn "*msubr32"
504 [(set (match_operand:SI 0 "register_operand" "=r")
505 (minus:SI (match_operand:SI 3 "register_operand" " 0")
506 (mult:SI (match_operand:SI 1 "register_operand" " r")
507 (match_operand:SI 2 "register_operand" " r"))))]
509 "msubr32\t%0, %1, %2"
510 [(set_attr "type" "mac")
511 (set_attr "length" "4")])
516 (define_insn "divmodsi4"
517 [(set (match_operand:SI 0 "register_operand" "=r")
518 (div:SI (match_operand:SI 1 "register_operand" " r")
519 (match_operand:SI 2 "register_operand" " r")))
520 (set (match_operand:SI 3 "register_operand" "=r")
521 (mod:SI (match_dup 1) (match_dup 2)))]
523 "divsr\t%0, %3, %1, %2"
524 [(set_attr "type" "div")
525 (set_attr "length" "4")])
527 (define_insn "udivmodsi4"
528 [(set (match_operand:SI 0 "register_operand" "=r")
529 (udiv:SI (match_operand:SI 1 "register_operand" " r")
530 (match_operand:SI 2 "register_operand" " r")))
531 (set (match_operand:SI 3 "register_operand" "=r")
532 (umod:SI (match_dup 1) (match_dup 2)))]
534 "divr\t%0, %3, %1, %2"
535 [(set_attr "type" "div")
536 (set_attr "length" "4")])
538 ;; divsr/divr will keep quotient only when quotient and remainder is the same
539 ;; register in our ISA spec, it's can reduce 1 register presure if we don't
541 (define_insn "divsi4"
542 [(set (match_operand:SI 0 "register_operand" "=r")
543 (div:SI (match_operand:SI 1 "register_operand" " r")
544 (match_operand:SI 2 "register_operand" " r")))]
546 "divsr\t%0, %0, %1, %2"
547 [(set_attr "type" "div")
548 (set_attr "length" "4")])
550 (define_insn "udivsi4"
551 [(set (match_operand:SI 0 "register_operand" "=r")
552 (udiv:SI (match_operand:SI 1 "register_operand" " r")
553 (match_operand:SI 2 "register_operand" " r")))]
555 "divr\t%0, %0, %1, %2"
556 [(set_attr "type" "div")
557 (set_attr "length" "4")])
559 ;; ----------------------------------------------------------------------------
561 ;; Boolean instructions.
562 ;; Note: We define the DImode versions in nds32-doubleword.md.
564 ;; ----------------------------------------------------------------------------
566 ;; ----------------------------------------------------------------------------
569 [(set (match_operand:SI 0 "register_operand" "=r")
570 (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
571 (match_operand:SI 2 "register_operand" " r")))]
574 [(set_attr "type" "alu")
575 (set_attr "length" "4")]
578 (define_expand "andsi3"
579 [(set (match_operand:SI 0 "register_operand" "")
580 (and:SI (match_operand:SI 1 "register_operand" "")
581 (match_operand:SI 2 "nds32_reg_constant_operand" "")))]
584 if (CONST_INT_P (operands[2])
585 && !nds32_and_operand (operands[2], SImode))
587 nds32_expand_constant (SImode, INTVAL (operands[2]),
588 operands[0], operands[1]);
593 (define_insn "*andsi3"
594 [(set (match_operand:SI 0 "register_operand" "=l, r, l, l, l, l, l, l, r, r, r, r, r")
595 (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r")
596 (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
599 HOST_WIDE_INT mask = INTVAL (operands[2]);
601 /* 16-bit andi instructions:
602 andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3
603 andi Rt3,Ra3,0xffff -> zeh33 Rt3,Ra3
604 andi Rt3,Ra3,0x01 -> xlsb33 Rt3,Ra3
605 andi Rt3,Ra3,0x7ff -> x11b33 Rt3,Ra3
606 andi Rt3,Rt3,2^imm3u -> bmski33 Rt3,imm3u
607 andi Rt3,Rt3,(2^(imm3u+1))-1 -> fexti33 Rt3,imm3u. */
609 switch (which_alternative)
612 return "and33\t%0, %2";
614 return "and\t%0, %1, %2";
616 return "zeb33\t%0, %1";
618 return "zeh33\t%0, %1";
620 return "xlsb33\t%0, %1";
622 return "x11b33\t%0, %1";
624 return "bmski33\t%0, %B2";
626 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
627 return "fexti33\t%0, %2";
629 return "zeb\t%0, %1";
631 return "zeh\t%0, %1";
633 return "andi\t%0, %1, %2";
635 operands[2] = GEN_INT (~mask);
636 return "bitci\t%0, %1, %2";
638 return "bclr\t%0, %1, %b2";
644 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
645 (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")
646 (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")])
648 (define_insn "*and_slli"
649 [(set (match_operand:SI 0 "register_operand" "= r")
650 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
651 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
652 (match_operand:SI 3 "register_operand" " r")))]
654 "and_slli\t%0, %3, %1, %2"
655 [(set_attr "type" "alu_shift")
656 (set_attr "length" "4")])
658 (define_insn "*and_srli"
659 [(set (match_operand:SI 0 "register_operand" "= r")
660 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
661 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
662 (match_operand:SI 3 "register_operand" " r")))]
664 "and_srli\t%0, %3, %1, %2"
665 [(set_attr "type" "alu_shift")
666 (set_attr "length" "4")])
669 ;; ----------------------------------------------------------------------------
671 ;; ----------------------------------------------------------------------------
673 ;; For V3/V3M ISA, we have 'or33' instruction.
674 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
676 (define_expand "iorsi3"
677 [(set (match_operand:SI 0 "register_operand" "")
678 (ior:SI (match_operand:SI 1 "register_operand" "")
679 (match_operand:SI 2 "general_operand" "")))]
682 if (!nds32_ior_operand (operands[2], SImode))
683 operands[2] = force_reg (SImode, operands[2]);
686 (define_insn "*iorsi3"
687 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
688 (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
689 (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))]
696 [(set_attr "type" "alu,alu,alu,alu")
697 (set_attr "length" " 2, 4, 4, 4")
698 (set_attr "feature" "v3m, v1, v1,pe1")])
700 (define_insn "*or_slli"
701 [(set (match_operand:SI 0 "register_operand" "= r")
702 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
703 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
704 (match_operand:SI 3 "register_operand" " r")))]
706 "or_slli\t%0, %3, %1, %2"
707 [(set_attr "type" "alu_shift")
708 (set_attr "length" "4")])
710 (define_insn "*or_srli"
711 [(set (match_operand:SI 0 "register_operand" "= r")
712 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
713 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
714 (match_operand:SI 3 "register_operand" " r")))]
716 "or_srli\t%0, %3, %1, %2"
717 [(set_attr "type" "alu_shift")
718 (set_attr "length" "4")])
721 ;; ----------------------------------------------------------------------------
723 ;; ----------------------------------------------------------------------------
725 ;; For V3/V3M ISA, we have 'xor33' instruction.
726 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
728 (define_expand "xorsi3"
729 [(set (match_operand:SI 0 "register_operand" "")
730 (xor:SI (match_operand:SI 1 "register_operand" "")
731 (match_operand:SI 2 "general_operand" "")))]
734 if (!nds32_xor_operand (operands[2], SImode))
735 operands[2] = force_reg (SImode, operands[2]);
738 (define_insn "*xorsi3"
739 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
740 (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
741 (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))]
748 [(set_attr "type" "alu,alu,alu,alu")
749 (set_attr "length" " 2, 4, 4, 4")
750 (set_attr "feature" "v3m, v1, v1,pe1")])
752 (define_insn "*xor_slli"
753 [(set (match_operand:SI 0 "register_operand" "= r")
754 (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
755 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
756 (match_operand:SI 3 "register_operand" " r")))]
758 "xor_slli\t%0, %3, %1, %2"
759 [(set_attr "type" "alu_shift")
760 (set_attr "length" "4")])
762 (define_insn "*xor_srli"
763 [(set (match_operand:SI 0 "register_operand" "= r")
764 (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
765 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
766 (match_operand:SI 3 "register_operand" " r")))]
768 "xor_srli\t%0, %3, %1, %2"
769 [(set_attr "type" "alu_shift")
770 (set_attr "length" "4")])
772 ;; Rotate Right Instructions.
774 (define_insn "*rotrsi3"
775 [(set (match_operand:SI 0 "register_operand" "= r, r")
776 (rotatert:SI (match_operand:SI 1 "register_operand" " r, r")
777 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
782 [(set_attr "type" " alu, alu")
783 (set_attr "subtype" "shift,shift")
784 (set_attr "length" " 4, 4")])
787 ;; ----------------------------------------------------------------------------
789 ;; ----------------------------------------------------------------------------
791 ;; For V3/V3M ISA, we have 'neg33' instruction.
792 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
793 ;; And for V2 ISA, there is NO 'neg33' instruction.
794 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
795 (define_insn "negsi2"
796 [(set (match_operand:SI 0 "register_operand" "=l, r")
797 (neg:SI (match_operand:SI 1 "register_operand" " l, r")))]
802 [(set_attr "type" "alu,alu")
803 (set_attr "length" " 2, 4")
804 (set_attr "feature" "v3m, v1")])
806 ;; ----------------------------------------------------------------------------
807 ;; 'ONE_COMPLIMENT' operation
808 ;; ----------------------------------------------------------------------------
810 ;; For V3/V3M ISA, we have 'not33' instruction.
811 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
812 (define_insn "one_cmplsi2"
813 [(set (match_operand:SI 0 "register_operand" "=w, r")
814 (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
819 [(set_attr "type" "alu,alu")
820 (set_attr "length" " 2, 4")
821 (set_attr "feature" "v3m, v1")])
824 ;; ----------------------------------------------------------------------------
826 ;; Shift instructions.
828 (define_expand "<shift>si3"
829 [(set (match_operand:SI 0 "register_operand" "")
830 (shift_rotate:SI (match_operand:SI 1 "register_operand" "")
831 (match_operand:SI 2 "nds32_rimm5u_operand" "")))]
834 if (operands[2] == const0_rtx)
836 emit_move_insn (operands[0], operands[1]);
841 (define_insn "*ashlsi3"
842 [(set (match_operand:SI 0 "register_operand" "= l, r, r")
843 (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r")
844 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))]
850 [(set_attr "type" " alu, alu, alu")
851 (set_attr "subtype" "shift,shift,shift")
852 (set_attr "length" " 2, 4, 4")])
854 (define_insn "*ashrsi3"
855 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
856 (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
857 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
863 [(set_attr "type" " alu, alu, alu")
864 (set_attr "subtype" "shift,shift,shift")
865 (set_attr "length" " 2, 4, 4")])
867 (define_insn "*lshrsi3"
868 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
869 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
870 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
876 [(set_attr "type" " alu, alu, alu")
877 (set_attr "subtype" "shift,shift,shift")
878 (set_attr "length" " 2, 4, 4")])
881 ;; ----------------------------------------------------------------------------
883 ;; ----------------------------------------------------------------------------
884 ;; Conditional Move patterns
885 ;; ----------------------------------------------------------------------------
887 (define_expand "mov<mode>cc"
888 [(set (match_operand:QIHISI 0 "register_operand" "")
889 (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
890 (match_operand:QIHISI 2 "register_operand" "")
891 (match_operand:QIHISI 3 "register_operand" "")))]
892 "TARGET_CMOV && !optimize_size"
894 enum nds32_expand_result_type result = nds32_expand_movcc (operands);
903 case EXPAND_CREATE_TEMPLATE:
910 (define_insn "cmovz<mode>"
911 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
912 (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
914 (match_operand:QIHISI 2 "register_operand" " r, 0")
915 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
920 [(set_attr "type" "alu")
921 (set_attr "length" "4")])
923 (define_insn "cmovn<mode>"
924 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
925 (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
927 (match_operand:QIHISI 2 "register_operand" " r, 0")
928 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
933 [(set_attr "type" "alu")
934 (set_attr "length" "4")])
936 ;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
937 ;; It should be removed once after we change the expansion form of the cmovn.
938 (define_insn "*cmovn_simplified_<mode>"
939 [(set (match_operand:QIHISI 0 "register_operand" "=r")
940 (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
941 (match_operand:QIHISI 2 "register_operand" "r")
942 (match_operand:QIHISI 3 "register_operand" "0")))]
945 [(set_attr "type" "alu")])
947 ;; ----------------------------------------------------------------------------
948 ;; Conditional Branch patterns
949 ;; ----------------------------------------------------------------------------
951 (define_expand "cbranchsi4"
953 (if_then_else (match_operator 0 "comparison_operator"
954 [(match_operand:SI 1 "register_operand" "")
955 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
956 (label_ref (match_operand 3 "" ""))
960 enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
969 case EXPAND_CREATE_TEMPLATE:
977 (define_insn "cbranchsi4_equality_zero"
979 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
980 [(match_operand:SI 1 "register_operand" "t,l, r")
982 (label_ref (match_operand 2 "" ""))
986 return nds32_output_cbranchsi4_equality_zero (insn, operands);
988 [(set_attr "type" "branch")
989 (set_attr_alternative "enabled"
992 (if_then_else (match_test "TARGET_16_BIT")
996 (if_then_else (match_test "TARGET_16_BIT")
1000 (const_string "yes")
1002 (set_attr_alternative "length"
1005 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1006 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1007 (le (minus (match_dup 2) (pc)) (const_int 250)))
1008 (if_then_else (match_test "TARGET_16_BIT")
1011 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1012 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1014 (if_then_else (match_test "TARGET_16_BIT")
1019 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1020 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1021 (le (minus (match_dup 2) (pc)) (const_int 250)))
1022 (if_then_else (match_test "TARGET_16_BIT")
1025 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1026 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1028 (if_then_else (match_test "TARGET_16_BIT")
1033 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1034 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1035 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1042 ;; This pattern is dedicated to V2 ISA,
1043 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
1044 (define_insn "cbranchsi4_equality_reg"
1046 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1047 [(match_operand:SI 1 "register_operand" "v, r")
1048 (match_operand:SI 2 "register_operand" "l, r")])
1049 (label_ref (match_operand 3 "" ""))
1053 return nds32_output_cbranchsi4_equality_reg (insn, operands);
1055 [(set_attr "type" "branch")
1056 (set_attr_alternative "enabled"
1059 (if_then_else (match_test "TARGET_16_BIT")
1060 (const_string "yes")
1061 (const_string "no"))
1063 (const_string "yes")
1065 (set_attr_alternative "length"
1068 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1069 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1070 (le (minus (match_dup 3) (pc)) (const_int 250)))
1072 (if_then_else (and (ge (minus (match_dup 3) (pc))
1074 (le (minus (match_dup 3) (pc))
1080 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1081 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1082 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1089 ;; This pattern is dedicated to V3/V3M,
1090 ;; because V3/V3M DO HAVE beqc/bnec instruction.
1091 (define_insn "cbranchsi4_equality_reg_or_const_int"
1093 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1094 [(match_operand:SI 1 "register_operand" "v, r, r")
1095 (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
1096 (label_ref (match_operand 3 "" ""))
1098 "TARGET_ISA_V3 || TARGET_ISA_V3M"
1100 return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
1102 [(set_attr "type" "branch")
1103 (set_attr_alternative "enabled"
1106 (if_then_else (match_test "TARGET_16_BIT")
1107 (const_string "yes")
1108 (const_string "no"))
1110 (const_string "yes")
1112 (const_string "yes")
1114 (set_attr_alternative "length"
1117 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1118 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1119 (le (minus (match_dup 3) (pc)) (const_int 250)))
1121 (if_then_else (and (ge (minus (match_dup 3) (pc))
1123 (le (minus (match_dup 3) (pc))
1129 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1130 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1131 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1136 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1137 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1138 (le (minus (match_dup 3) (pc)) (const_int 250)))
1145 (define_insn "*cbranchsi4_greater_less_zero"
1147 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1148 [(match_operand:SI 1 "register_operand" "r")
1150 (label_ref (match_operand 2 "" ""))
1154 return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
1156 [(set_attr "type" "branch")
1157 (set (attr "length")
1158 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1159 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1160 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1166 (define_expand "cstoresi4"
1167 [(set (match_operand:SI 0 "register_operand" "")
1168 (match_operator:SI 1 "comparison_operator"
1169 [(match_operand:SI 2 "register_operand" "")
1170 (match_operand:SI 3 "nonmemory_operand" "")]))]
1173 enum nds32_expand_result_type result = nds32_expand_cstore (operands);
1182 case EXPAND_CREATE_TEMPLATE:
1190 (define_expand "slts_compare"
1191 [(set (match_operand:SI 0 "register_operand" "")
1192 (lt:SI (match_operand:SI 1 "general_operand" "")
1193 (match_operand:SI 2 "general_operand" "")))]
1196 if (!REG_P (operands[1]))
1197 operands[1] = force_reg (SImode, operands[1]);
1199 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1200 operands[2] = force_reg (SImode, operands[2]);
1203 (define_insn "slts_compare_impl"
1204 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1205 (lt:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1206 (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
1213 [(set_attr "type" "alu, alu, alu, alu")
1214 (set_attr "length" " 2, 2, 4, 4")])
1216 (define_insn "slt_eq0"
1217 [(set (match_operand:SI 0 "register_operand" "=t, r")
1218 (eq:SI (match_operand:SI 1 "register_operand" " d, r")
1224 [(set_attr "type" "alu, alu")
1225 (set_attr "length" " 2, 4")])
1227 (define_expand "slt_compare"
1228 [(set (match_operand:SI 0 "register_operand" "")
1229 (ltu:SI (match_operand:SI 1 "general_operand" "")
1230 (match_operand:SI 2 "general_operand" "")))]
1233 if (!REG_P (operands[1]))
1234 operands[1] = force_reg (SImode, operands[1]);
1236 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1237 operands[2] = force_reg (SImode, operands[2]);
1240 (define_insn "slt_compare_impl"
1241 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1242 (ltu:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1243 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
1250 [(set_attr "type" "alu, alu, alu, alu")
1251 (set_attr "length" " 2, 2, 4, 4")])
1254 ;; ----------------------------------------------------------------------------
1256 ;; Unconditional and other jump instructions.
1259 [(set (pc) (label_ref (match_operand 0 "" "")))]
1262 /* This unconditional jump has two forms:
1263 32-bit instruction => j imm24s << 1
1264 16-bit instruction => j8 imm8s << 1
1267 we assume it is always reachable.
1269 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1270 However, since the $pc for nds32 is at the beginning of the instruction,
1271 we should leave some length space for current insn.
1272 So we use range -250 ~ 250. */
1273 switch (get_attr_length (insn))
1283 [(set_attr "type" "branch")
1284 (set_attr "enabled" "yes")
1285 (set (attr "length")
1286 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1287 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1288 (le (minus (match_dup 0) (pc)) (const_int 250)))
1289 (if_then_else (match_test "TARGET_16_BIT")
1295 (define_insn "indirect_jump"
1296 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1301 [(set_attr "type" "branch,branch")
1302 (set_attr "length" " 2, 4")])
1304 ;; Subroutine call instruction returning no value.
1305 ;; operands[0]: It should be a mem RTX whose address is
1306 ;; the address of the function.
1307 ;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
1308 ;; operands[2]: It is the number of registers used as operands.
1310 (define_expand "call"
1311 [(parallel [(call (match_operand 0 "memory_operand" "")
1313 (clobber (reg:SI LP_REGNUM))
1314 (clobber (reg:SI TA_REGNUM))])]
1319 (define_insn "*call_register"
1320 [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
1322 (clobber (reg:SI LP_REGNUM))
1323 (clobber (reg:SI TA_REGNUM))])]
1328 [(set_attr "type" "branch,branch")
1329 (set_attr "length" " 2, 4")])
1331 (define_insn "*call_immediate"
1332 [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
1334 (clobber (reg:SI LP_REGNUM))
1335 (clobber (reg:SI TA_REGNUM))])]
1338 if (TARGET_CMODEL_LARGE)
1343 [(set_attr "type" "branch")
1344 (set (attr "length")
1345 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1350 ;; Subroutine call instruction returning a value.
1351 ;; operands[0]: It is the hard regiser in which the value is returned.
1352 ;; The rest three operands are the same as the
1353 ;; three operands of the 'call' instruction.
1354 ;; (but with numbers increased by one)
1356 (define_expand "call_value"
1357 [(parallel [(set (match_operand 0)
1358 (call (match_operand 1 "memory_operand" "")
1360 (clobber (reg:SI LP_REGNUM))
1361 (clobber (reg:SI TA_REGNUM))])]
1366 (define_insn "*call_value_register"
1367 [(parallel [(set (match_operand 0)
1368 (call (mem (match_operand:SI 1 "register_operand" "r, r"))
1370 (clobber (reg:SI LP_REGNUM))
1371 (clobber (reg:SI TA_REGNUM))])]
1376 [(set_attr "type" "branch,branch")
1377 (set_attr "length" " 2, 4")])
1379 (define_insn "*call_value_immediate"
1380 [(parallel [(set (match_operand 0)
1381 (call (mem (match_operand:SI 1 "immediate_operand" "i"))
1383 (clobber (reg:SI LP_REGNUM))
1384 (clobber (reg:SI TA_REGNUM))])]
1387 if (TARGET_CMODEL_LARGE)
1392 [(set_attr "type" "branch")
1393 (set (attr "length")
1394 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1399 ;; ----------------------------------------------------------------------------
1401 ;; The sibcall patterns.
1406 (define_expand "sibcall"
1407 [(parallel [(call (match_operand 0 "memory_operand" "")
1409 (clobber (reg:SI TA_REGNUM))
1413 (define_insn "sibcall_internal"
1414 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
1416 (clobber (reg:SI TA_REGNUM))
1420 switch (which_alternative)
1428 if (nds32_long_call_p (operands[0]))
1436 [(set_attr "enabled" "yes")
1437 (set_attr "type" "branch")
1438 (set_attr_alternative "length"
1441 (if_then_else (match_test "TARGET_16_BIT")
1445 (if_then_else (match_test "nds32_long_call_p (operands[0])")
1452 ;; sibcall_value_internal
1453 ;; sibcall_value_immediate
1455 (define_expand "sibcall_value"
1456 [(parallel [(set (match_operand 0)
1457 (call (match_operand 1 "memory_operand" "")
1459 (clobber (reg:SI TA_REGNUM))
1463 (define_insn "sibcall_value_internal"
1464 [(parallel [(set (match_operand 0)
1465 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
1467 (clobber (reg:SI TA_REGNUM))
1471 switch (which_alternative)
1479 if (nds32_long_call_p (operands[1]))
1487 [(set_attr "enabled" "yes")
1488 (set_attr "type" "branch")
1489 (set_attr_alternative "length"
1492 (if_then_else (match_test "TARGET_16_BIT")
1496 (if_then_else (match_test "nds32_long_call_p (operands[1])")
1502 ;; ----------------------------------------------------------------------------
1504 ;; prologue and epilogue.
1506 (define_expand "prologue" [(const_int 0)]
1509 /* Note that only under V3/V3M ISA, we could use v3push prologue.
1510 In addition, we need to check if v3push is indeed available. */
1511 if (NDS32_V3PUSH_AVAILABLE_P)
1512 nds32_expand_prologue_v3push ();
1514 nds32_expand_prologue ();
1518 (define_expand "epilogue" [(const_int 0)]
1521 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
1522 In addition, we need to check if v3push is indeed available. */
1523 if (NDS32_V3PUSH_AVAILABLE_P)
1524 nds32_expand_epilogue_v3pop (false);
1526 nds32_expand_epilogue (false);
1530 (define_expand "sibcall_epilogue" [(const_int 0)]
1533 /* Pass true to indicate that this is sibcall epilogue and
1534 exit from a function without the final branch back to the
1535 calling function. */
1536 nds32_expand_epilogue (true);
1553 [(set_attr "type" "misc")
1554 (set_attr "enabled" "yes")
1555 (set (attr "length")
1556 (if_then_else (match_test "TARGET_16_BIT")
1561 ;; ----------------------------------------------------------------------------
1562 ;; Stack push/pop operations
1563 ;; ----------------------------------------------------------------------------
1565 ;; The pattern for stack push.
1566 ;; Both stack_push_multiple and stack_v3push use the following pattern.
1567 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1568 (define_insn "*stack_push"
1569 [(match_parallel 0 "nds32_stack_push_operation"
1570 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1571 (match_operand:SI 1 "const_int_operand" "")))
1572 (match_operand:SI 2 "register_operand" ""))
1576 return nds32_output_stack_push (operands[0]);
1578 [(set_attr "type" "store_multiple")
1579 (set_attr "combo" "12")
1580 (set_attr "enabled" "yes")
1581 (set (attr "length")
1582 (if_then_else (match_test "TARGET_V3PUSH
1583 && !nds32_isr_function_p (cfun->decl)
1584 && (cfun->machine->va_args_size == 0)")
1589 ;; The pattern for stack pop.
1590 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1591 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1592 (define_insn "*stack_pop"
1593 [(match_parallel 0 "nds32_stack_pop_operation"
1594 [(set (match_operand:SI 1 "register_operand" "")
1595 (mem:SI (reg:SI SP_REGNUM)))
1599 return nds32_output_stack_pop (operands[0]);
1601 [(set_attr "type" "load_multiple")
1602 (set_attr "combo" "12")
1603 (set_attr "enabled" "yes")
1604 (set (attr "length")
1605 (if_then_else (match_test "TARGET_V3PUSH
1606 && !nds32_isr_function_p (cfun->decl)
1607 && (cfun->machine->va_args_size == 0)")
1612 ;; ----------------------------------------------------------------------------
1613 ;; Return operation patterns
1614 ;; ----------------------------------------------------------------------------
1616 ;; Use this pattern to expand a return instruction
1617 ;; with simple_return rtx if no epilogue is required.
1618 (define_expand "return"
1620 "nds32_can_use_return_insn ()"
1624 ;; This pattern is expanded only by the shrink-wrapping optimization
1625 ;; on paths where the function prologue has not been executed.
1626 (define_expand "simple_return"
1632 (define_insn "return_internal"
1641 [(set_attr "type" "branch")
1642 (set_attr "enabled" "yes")
1643 (set (attr "length")
1644 (if_then_else (match_test "TARGET_16_BIT")
1649 ;; ----------------------------------------------------------------------------
1650 ;; Jump Table patterns
1651 ;; ----------------------------------------------------------------------------
1652 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
1653 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
1655 ;; operands[0]: The index to dispatch on.
1656 ;; operands[1]: The lower bound for indices in the table.
1657 ;; operands[2]: The total range of indices int the table.
1658 ;; i.e. The largest index minus the smallest one.
1659 ;; operands[3]: A label that precedes the table itself.
1660 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
1662 ;; We need to create following sequences for jump table code generation:
1663 ;; A) k <-- (plus (operands[0]) (-operands[1]))
1664 ;; B) if (gtu k operands[2]) then goto operands[4]
1665 ;; C) t <-- operands[3]
1666 ;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
1667 ;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
1668 ;; F) jump to target with register t or z
1670 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
1671 (define_expand "casesi"
1672 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
1673 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
1674 (match_operand:SI 2 "immediate_operand" "i") ; total range
1675 (match_operand:SI 3 "" "") ; table label
1676 (match_operand:SI 4 "" "")] ; Out of range label
1682 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
1683 if (operands[1] != const0_rtx)
1685 reg = gen_reg_rtx (SImode);
1686 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
1688 /* If the integer value is not in the range of imm15s,
1689 we need to force register first because our addsi3 pattern
1690 only accept nds32_rimm15s_operand predicate. */
1691 add_tmp = force_reg (SImode, add_tmp);
1693 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
1697 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
1698 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
1699 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
1702 /* Step C, D, E, and F, using another temporary register. */
1703 rtx tmp = gen_reg_rtx (SImode);
1704 emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
1708 ;; We are receiving operands from casesi pattern:
1710 ;; operands[0]: The index that have been substracted with lower bound.
1711 ;; operands[1]: A label that precedes the table itself.
1712 ;; operands[2]: A temporary register to retrieve value in table.
1714 ;; We need to perform steps C, D, E, and F:
1716 ;; C) t <-- operands[1]
1717 ;; D) z <-- (mem (plus (operands[0] << m) t))
1718 ;; m is 2 for normal jump table.
1719 ;; m is 0, 1, or 2 for pc relative jump table based on diff size.
1720 ;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
1721 ;; F) Jump to target with register t or z.
1723 ;; The USE in this pattern is needed to tell flow analysis that this is
1724 ;; a CASESI insn. It has no other purpose.
1725 (define_insn "casesi_internal"
1726 [(parallel [(set (pc)
1727 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1729 (label_ref (match_operand 1 "" "")))))
1730 (use (label_ref (match_dup 1)))
1731 (clobber (match_operand:SI 2 "register_operand" "=r"))
1732 (clobber (reg:SI TA_REGNUM))])]
1735 if (CASE_VECTOR_PC_RELATIVE)
1736 return nds32_output_casesi_pc_relative (operands);
1738 return nds32_output_casesi (operands);
1740 [(set_attr "length" "20")
1741 (set_attr "type" "branch")])
1743 ;; ----------------------------------------------------------------------------
1745 ;; Performance Extension
1747 (define_insn "clzsi2"
1748 [(set (match_operand:SI 0 "register_operand" "=r")
1749 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
1752 [(set_attr "type" "alu")
1753 (set_attr "length" "4")])
1755 (define_insn "smaxsi3"
1756 [(set (match_operand:SI 0 "register_operand" "=r")
1757 (smax:SI (match_operand:SI 1 "register_operand" " r")
1758 (match_operand:SI 2 "register_operand" " r")))]
1761 [(set_attr "type" "alu")
1762 (set_attr "length" "4")])
1764 (define_insn "sminsi3"
1765 [(set (match_operand:SI 0 "register_operand" "=r")
1766 (smin:SI (match_operand:SI 1 "register_operand" " r")
1767 (match_operand:SI 2 "register_operand" " r")))]
1770 [(set_attr "type" "alu")
1771 (set_attr "length" "4")])
1773 (define_insn "*btst"
1774 [(set (match_operand:SI 0 "register_operand" "= r")
1775 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
1777 (match_operand:SI 2 "immediate_operand" " Iu05")))]
1780 [(set_attr "type" "alu")
1781 (set_attr "length" "4")])
1783 ;; ----------------------------------------------------------------------------
1787 (define_insn "relax_group"
1788 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
1791 [(set_attr "length" "0")]
1794 (define_insn "pop25return"
1796 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
1798 "! return for pop 25"
1799 [(set_attr "length" "0")]
1802 ;; ----------------------------------------------------------------------------