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 floating-point patterns.
50 (include "nds32-fpu.md")
52 ;; Include peephole patterns.
53 (include "nds32-peephole2.md")
56 ;; ------------------------------------------------------------------------
58 ;; CPU pipeline model.
59 (define_attr "pipeline_model" "n7,n8,e8,n9,n10,graywolf,n13,simple"
61 (cond [(match_test "nds32_cpu_option == CPU_N7") (const_string "n7")
62 (match_test "nds32_cpu_option == CPU_E8") (const_string "e8")
63 (match_test "nds32_cpu_option == CPU_N6 || nds32_cpu_option == CPU_N8") (const_string "n8")
64 (match_test "nds32_cpu_option == CPU_N9") (const_string "n9")
65 (match_test "nds32_cpu_option == CPU_N10") (const_string "n10")
66 (match_test "nds32_cpu_option == CPU_GRAYWOLF") (const_string "graywolf")
67 (match_test "nds32_cpu_option == CPU_N12") (const_string "n13")
68 (match_test "nds32_cpu_option == CPU_N13") (const_string "n13")
69 (match_test "nds32_cpu_option == CPU_SIMPLE") (const_string "simple")]
70 (const_string "n9"))))
72 ;; Insn type, it is used to default other attribute values.
74 "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\
75 falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore,\
76 dalu,dalu64,daluround,dcmp,dclip,dmul,dmac,dinsb,dpack,dbpick,dwext"
77 (const_string "unknown"))
80 (define_attr "subtype"
81 "simple,shift,saturation"
82 (const_string "simple"))
84 ;; Length, in bytes, default is 4-bytes.
85 (define_attr "length" "" (const_int 4))
87 ;; Indicate the amount of micro instructions.
89 "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"
92 ;; Insn in which feature set, it is used to enable/disable insn alternatives.
93 ;; v1 : Baseline Instructions
94 ;; v2 : Baseline Version 2 Instructions
95 ;; v3m : Baseline Version 3m Instructions
96 ;; v3 : Baseline Version 3 Instructions
97 ;; pe1 : Performance Extension Instructions
98 ;; pe2 : Performance Extension Version 2 Instructions
99 ;; se : String Extension instructions
100 (define_attr "feature"
101 "v1,v2,v3m,v3,pe1,pe2,se,fpu"
104 ;; Enabled, which is used to enable/disable insn alternatives.
105 ;; Note that we use length and TARGET_16_BIT here as criteria.
106 ;; If the instruction pattern already check TARGET_16_BIT to determine
107 ;; the length by itself, its enabled attribute should be customized to
108 ;; avoid the conflict between length attribute and this default setting.
109 (define_attr "enabled" "no,yes"
111 (and (eq_attr "length" "2")
112 (match_test "!TARGET_16_BIT"))
114 (cond [(eq_attr "feature" "v1") (const_string "yes")
115 (eq_attr "feature" "v2") (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M")
118 (eq_attr "feature" "v3") (if_then_else (match_test "TARGET_ISA_V3")
121 (eq_attr "feature" "v3m") (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M")
124 (eq_attr "feature" "pe1") (if_then_else (match_test "TARGET_EXT_PERF")
127 (eq_attr "feature" "pe2") (if_then_else (match_test "TARGET_EXT_PERF2")
130 (eq_attr "feature" "se") (if_then_else (match_test "TARGET_EXT_STRING")
133 (eq_attr "feature" "fpu") (if_then_else (match_test "TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE")
135 (const_string "no"))]
136 (const_string "yes"))))
139 ;; ----------------------------------------------------------------------------
141 (include "nds32-dspext.md")
143 ;; Move instructions.
145 ;; For QImode and HImode, the immediate value can be fit in imm20s.
146 ;; So there is no need to split rtx for QI and HI patterns.
148 (define_expand "mov<mode>"
149 [(set (match_operand:QIHI 0 "general_operand" "")
150 (match_operand:QIHI 1 "general_operand" ""))]
153 /* Need to force register if mem <- !reg. */
154 if (MEM_P (operands[0]) && !REG_P (operands[1]))
155 operands[1] = force_reg (<MODE>mode, operands[1]);
157 if (MEM_P (operands[1]) && optimize > 0)
159 rtx reg = gen_reg_rtx (SImode);
161 emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
162 operands[1] = gen_lowpart (<MODE>mode, reg);
166 (define_expand "movmisalign<mode>"
167 [(set (match_operand:SIDI 0 "general_operand" "")
168 (match_operand:SIDI 1 "general_operand" ""))]
172 if (MEM_P (operands[0]) && !REG_P (operands[1]))
173 operands[1] = force_reg (<MODE>mode, operands[1]);
175 if (MEM_P (operands[0]))
177 addr = force_reg (Pmode, XEXP (operands[0], 0));
178 emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
182 addr = force_reg (Pmode, XEXP (operands[1], 0));
183 emit_insn (gen_unaligned_load<mode> (operands[0], addr));
188 (define_expand "movsi"
189 [(set (match_operand:SI 0 "general_operand" "")
190 (match_operand:SI 1 "general_operand" ""))]
193 /* Need to force register if mem <- !reg. */
194 if (MEM_P (operands[0]) && !REG_P (operands[1]))
195 operands[1] = force_reg (SImode, operands[1]);
197 /* If operands[1] is a large constant and cannot be performed
198 by a single instruction, we need to split it. */
199 if (CONST_INT_P (operands[1])
200 && !satisfies_constraint_Is20 (operands[1])
201 && !satisfies_constraint_Ihig (operands[1]))
204 HOST_WIDE_INT low12_int;
207 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
209 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
210 low12_int = INTVAL (operands[1]) & 0xfff;
212 emit_move_insn (tmp_rtx, high20_rtx);
213 emit_move_insn (operands[0], plus_constant (SImode,
219 if ((REG_P (operands[0]) || GET_CODE (operands[0]) == SUBREG)
220 && SYMBOLIC_CONST_P (operands[1]))
222 if (TARGET_ICT_MODEL_LARGE
223 && nds32_indirect_call_referenced_p (operands[1]))
225 nds32_expand_ict_move (operands);
228 else if (nds32_tls_referenced_p (operands [1]))
230 nds32_expand_tls_move (operands);
235 nds32_expand_pic_move (operands);
241 (define_insn "*mov<mode>"
242 [(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")
243 (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"))]
244 "register_operand(operands[0], <MODE>mode)
245 || register_operand(operands[1], <MODE>mode)"
247 switch (which_alternative)
250 return "mov55\t%0, %1";
252 return "ori\t%0, %1, 0";
257 return nds32_output_16bit_store (operands, <byte>);
259 return nds32_output_32bit_store (operands, <byte>);
265 return nds32_output_16bit_load (operands, <byte>);
267 return nds32_output_32bit_load (operands, <byte>);
269 return "movpi45\t%0, %1";
271 return "movi55\t%0, %1";
273 return "movi\t%0, %1";
275 return "sethi\t%0, hi20(%1)";
277 if (TARGET_FPU_SINGLE)
278 return "fcpyss\t%0, %1, %1";
282 return "fmtsr\t%1, %0";
284 return "fmfsr\t%0, %1";
286 return nds32_output_float_load (operands);
288 return nds32_output_float_store (operands);
293 [(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")
294 (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")
295 (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")])
298 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
299 ;; are able to match such instruction template.
300 (define_insn "move_addr"
301 [(set (match_operand:SI 0 "nds32_general_register_operand" "=l, r")
302 (match_operand:SI 1 "nds32_nonunspec_symbolic_operand" " i, i"))]
305 [(set_attr "type" "alu")
306 (set_attr "length" "8")])
310 [(set (match_operand:SI 0 "register_operand" "=r")
311 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
313 "sethi\t%0, hi20(%1)"
314 [(set_attr "type" "alu")
315 (set_attr "length" "4")])
318 (define_insn "lo_sum"
319 [(set (match_operand:SI 0 "register_operand" "=r")
320 (lo_sum:SI (match_operand:SI 1 "register_operand" " r")
321 (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
323 "ori\t%0, %1, lo12(%2)"
324 [(set_attr "type" "alu")
325 (set_attr "length" "4")])
328 ;; ----------------------------------------------------------------------------
330 ;; Zero extension instructions.
332 (define_insn "zero_extend<mode>si2"
333 [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r")
334 (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))]
337 switch (which_alternative)
340 return "ze<size>33\t%0, %1";
342 return "ze<size>\t%0, %1";
344 return nds32_output_16bit_load (operands, <byte>);
346 return nds32_output_32bit_load (operands, <byte>);
352 [(set_attr "type" "alu,alu,load,load")
353 (set_attr "length" " 2, 4, 2, 4")])
356 ;; Sign extension instructions.
358 (define_insn "extend<mode>si2"
359 [(set (match_operand:SI 0 "register_operand" "=l, r, r")
360 (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
363 switch (which_alternative)
366 return "se<size>33\t%0, %1";
368 return "se<size>\t%0, %1";
370 return nds32_output_32bit_load_s (operands, <byte>);
376 [(set_attr "type" "alu,alu,load")
377 (set_attr "length" " 2, 4, 4")])
380 ;; ----------------------------------------------------------------------------
381 (define_expand "extv"
382 [(set (match_operand 0 "register_operand" "")
383 (sign_extract (match_operand 1 "nonimmediate_operand" "")
384 (match_operand 2 "const_int_operand" "")
385 (match_operand 3 "const_int_operand" "")))]
388 enum nds32_expand_result_type result = nds32_expand_extv (operands);
397 case EXPAND_CREATE_TEMPLATE:
404 (define_expand "insv"
405 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
406 (match_operand 1 "const_int_operand" "")
407 (match_operand 2 "const_int_operand" ""))
408 (match_operand 3 "register_operand" ""))]
411 enum nds32_expand_result_type result = nds32_expand_insv (operands);
420 case EXPAND_CREATE_TEMPLATE:
427 ;; Arithmetic instructions.
429 (define_insn "addsi3"
430 [(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
431 (plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
432 (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,IU06, Is15, r")))]
435 switch (which_alternative)
438 /* addi Rt4,Rt4,-x ==> subi45 Rt4,x
439 where 0 <= x <= 31 */
440 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
441 return "subi45\t%0, %2";
443 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
445 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
446 return "subi333\t%0, %1, %2";
448 return "addi45\t%0, %2";
450 return "addi333\t%0, %1, %2";
452 return "add45\t%0, %2";
454 return "add333\t%0, %1, %2";
456 return "addi10.sp\t%2";
458 return "addri36.sp\t%0, %2";
460 return "addi\t%0, %1, %2";
462 return "add\t%0, %1, %2";
468 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
469 (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")
470 (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")])
472 (define_insn "subsi3"
473 [(set (match_operand:SI 0 "register_operand" "=d, l, r, r")
474 (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
475 (match_operand:SI 2 "register_operand" " r, l, r, r")))]
482 [(set_attr "type" "alu,alu,alu,alu")
483 (set_attr "length" " 2, 2, 4, 4")])
486 ;; GCC intends to simplify (plus (ashift ...) (reg))
487 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
488 ;; and needs to ensure it is exact_log2 value.
489 (define_insn "*add_slli"
490 [(set (match_operand:SI 0 "register_operand" "=r")
491 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
492 (match_operand:SI 2 "immediate_operand" " i"))
493 (match_operand:SI 3 "register_operand" " r")))]
494 "TARGET_ISA_V3 && optimize_size
495 && (exact_log2 (INTVAL (operands[2])) != -1)
496 && (exact_log2 (INTVAL (operands[2])) <= 31)"
498 /* Get floor_log2 of the immediate value
499 so that we can generate 'add_slli' instruction. */
500 operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
502 return "add_slli\t%0, %3, %1, %2";
504 [(set_attr "type" "alu_shift")
505 (set_attr "combo" "2")
506 (set_attr "length" "4")])
508 (define_insn "*add_srli"
509 [(set (match_operand:SI 0 "register_operand" "= r")
510 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
511 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
512 (match_operand:SI 3 "register_operand" " r")))]
513 "TARGET_ISA_V3 && optimize_size"
514 "add_srli\t%0, %3, %1, %2"
515 [(set_attr "type" "alu_shift")
516 (set_attr "combo" "2")
517 (set_attr "length" "4")])
520 ;; GCC intends to simplify (minus (reg) (ashift ...))
521 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
522 ;; and needs to ensure it is exact_log2 value.
523 (define_insn "*sub_slli"
524 [(set (match_operand:SI 0 "register_operand" "=r")
525 (minus:SI (match_operand:SI 1 "register_operand" " r")
526 (mult:SI (match_operand:SI 2 "register_operand" " r")
527 (match_operand:SI 3 "immediate_operand" " i"))))]
528 "TARGET_ISA_V3 && optimize_size
529 && (exact_log2 (INTVAL (operands[3])) != -1)
530 && (exact_log2 (INTVAL (operands[3])) <= 31)"
532 /* Get floor_log2 of the immediate value
533 so that we can generate 'sub_slli' instruction. */
534 operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
536 return "sub_slli\t%0, %1, %2, %3";
538 [(set_attr "type" "alu_shift")
539 (set_attr "combo" "2")
540 (set_attr "length" "4")])
542 (define_insn "*sub_srli"
543 [(set (match_operand:SI 0 "register_operand" "= r")
544 (minus:SI (match_operand:SI 1 "register_operand" " r")
545 (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
546 (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))]
547 "TARGET_ISA_V3 && optimize_size"
548 "sub_srli\t%0, %1, %2, %3"
549 [(set_attr "type" "alu_shift")
550 (set_attr "combo" "2")
551 (set_attr "length" "4")])
554 ;; Multiplication instructions.
556 (define_insn "mulsi3"
557 [(set (match_operand:SI 0 "register_operand" "=w, r")
558 (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
559 (match_operand:SI 2 "register_operand" " w, r")))]
564 [(set_attr "type" "mul,mul")
565 (set_attr "length" " 2, 4")
566 (set_attr "feature" "v3m, v1")])
568 (define_insn "mulsidi3"
569 [(set (match_operand:DI 0 "register_operand" "=r")
570 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
571 (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
572 "TARGET_ISA_V2 || TARGET_ISA_V3"
573 "mulsr64\t%0, %1, %2"
574 [(set_attr "type" "mul")
575 (set_attr "length" "4")])
577 (define_insn "umulsidi3"
578 [(set (match_operand:DI 0 "register_operand" "=r")
579 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
580 (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
581 "TARGET_ISA_V2 || TARGET_ISA_V3"
583 [(set_attr "type" "mul")
584 (set_attr "length" "4")])
587 ;; Multiply-accumulate instructions.
589 (define_insn "*maddr32_0"
590 [(set (match_operand:SI 0 "register_operand" "=r")
591 (plus:SI (match_operand:SI 3 "register_operand" " 0")
592 (mult:SI (match_operand:SI 1 "register_operand" " r")
593 (match_operand:SI 2 "register_operand" " r"))))]
595 "maddr32\t%0, %1, %2"
596 [(set_attr "type" "mac")
597 (set_attr "length" "4")])
599 (define_insn "*maddr32_1"
600 [(set (match_operand:SI 0 "register_operand" "=r")
601 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
602 (match_operand:SI 2 "register_operand" " r"))
603 (match_operand:SI 3 "register_operand" " 0")))]
605 "maddr32\t%0, %1, %2"
606 [(set_attr "type" "mac")
607 (set_attr "length" "4")])
609 (define_insn "*msubr32"
610 [(set (match_operand:SI 0 "register_operand" "=r")
611 (minus:SI (match_operand:SI 3 "register_operand" " 0")
612 (mult:SI (match_operand:SI 1 "register_operand" " r")
613 (match_operand:SI 2 "register_operand" " r"))))]
615 "msubr32\t%0, %1, %2"
616 [(set_attr "type" "mac")
617 (set_attr "length" "4")])
622 (define_insn "divmodsi4"
623 [(set (match_operand:SI 0 "register_operand" "=r")
624 (div:SI (match_operand:SI 1 "register_operand" " r")
625 (match_operand:SI 2 "register_operand" " r")))
626 (set (match_operand:SI 3 "register_operand" "=r")
627 (mod:SI (match_dup 1) (match_dup 2)))]
629 "divsr\t%0, %3, %1, %2"
630 [(set_attr "type" "div")
631 (set_attr "length" "4")])
633 (define_insn "udivmodsi4"
634 [(set (match_operand:SI 0 "register_operand" "=r")
635 (udiv:SI (match_operand:SI 1 "register_operand" " r")
636 (match_operand:SI 2 "register_operand" " r")))
637 (set (match_operand:SI 3 "register_operand" "=r")
638 (umod:SI (match_dup 1) (match_dup 2)))]
640 "divr\t%0, %3, %1, %2"
641 [(set_attr "type" "div")
642 (set_attr "length" "4")])
644 ;; divsr/divr will keep quotient only when quotient and remainder is the same
645 ;; register in our ISA spec, it's can reduce 1 register presure if we don't
647 (define_insn "divsi4"
648 [(set (match_operand:SI 0 "register_operand" "=r")
649 (div:SI (match_operand:SI 1 "register_operand" " r")
650 (match_operand:SI 2 "register_operand" " r")))]
652 "divsr\t%0, %0, %1, %2"
653 [(set_attr "type" "div")
654 (set_attr "length" "4")])
656 (define_insn "udivsi4"
657 [(set (match_operand:SI 0 "register_operand" "=r")
658 (udiv:SI (match_operand:SI 1 "register_operand" " r")
659 (match_operand:SI 2 "register_operand" " r")))]
661 "divr\t%0, %0, %1, %2"
662 [(set_attr "type" "div")
663 (set_attr "length" "4")])
665 ;; ----------------------------------------------------------------------------
667 ;; Boolean instructions.
668 ;; Note: We define the DImode versions in nds32-doubleword.md.
670 ;; ----------------------------------------------------------------------------
672 ;; ----------------------------------------------------------------------------
675 [(set (match_operand:SI 0 "register_operand" "=r")
676 (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
677 (match_operand:SI 2 "register_operand" " r")))]
680 [(set_attr "type" "alu")
681 (set_attr "length" "4")]
684 (define_expand "andsi3"
685 [(set (match_operand:SI 0 "register_operand" "")
686 (and:SI (match_operand:SI 1 "register_operand" "")
687 (match_operand:SI 2 "nds32_reg_constant_operand" "")))]
690 if (CONST_INT_P (operands[2])
691 && !nds32_and_operand (operands[2], SImode))
693 nds32_expand_constant (SImode, INTVAL (operands[2]),
694 operands[0], operands[1]);
699 (define_insn "*andsi3"
700 [(set (match_operand:SI 0 "register_operand" "=l, r, l, l, l, l, l, l, r, r, r, r, r")
701 (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r")
702 (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
705 HOST_WIDE_INT mask = INTVAL (operands[2]);
707 /* 16-bit andi instructions:
708 andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3
709 andi Rt3,Ra3,0xffff -> zeh33 Rt3,Ra3
710 andi Rt3,Ra3,0x01 -> xlsb33 Rt3,Ra3
711 andi Rt3,Ra3,0x7ff -> x11b33 Rt3,Ra3
712 andi Rt3,Rt3,2^imm3u -> bmski33 Rt3,imm3u
713 andi Rt3,Rt3,(2^(imm3u+1))-1 -> fexti33 Rt3,imm3u. */
715 switch (which_alternative)
718 return "and33\t%0, %2";
720 return "and\t%0, %1, %2";
722 return "zeb33\t%0, %1";
724 return "zeh33\t%0, %1";
726 return "xlsb33\t%0, %1";
728 return "x11b33\t%0, %1";
730 return "bmski33\t%0, %B2";
732 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
733 return "fexti33\t%0, %2";
735 return "zeb\t%0, %1";
737 return "zeh\t%0, %1";
739 return "andi\t%0, %1, %2";
741 operands[2] = GEN_INT (~mask);
742 return "bitci\t%0, %1, %2";
744 return "bclr\t%0, %1, %b2";
750 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
751 (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")
752 (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")])
754 (define_insn "*and_slli"
755 [(set (match_operand:SI 0 "register_operand" "= r")
756 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
757 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
758 (match_operand:SI 3 "register_operand" " r")))]
759 "TARGET_ISA_V3 && optimize_size"
760 "and_slli\t%0, %3, %1, %2"
761 [(set_attr "type" "alu_shift")
762 (set_attr "length" "4")])
764 (define_insn "*and_srli"
765 [(set (match_operand:SI 0 "register_operand" "= r")
766 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
767 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
768 (match_operand:SI 3 "register_operand" " r")))]
769 "TARGET_ISA_V3 && optimize_size"
770 "and_srli\t%0, %3, %1, %2"
771 [(set_attr "type" "alu_shift")
772 (set_attr "length" "4")])
775 ;; ----------------------------------------------------------------------------
777 ;; ----------------------------------------------------------------------------
779 ;; For V3/V3M ISA, we have 'or33' instruction.
780 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
782 (define_expand "iorsi3"
783 [(set (match_operand:SI 0 "register_operand" "")
784 (ior:SI (match_operand:SI 1 "register_operand" "")
785 (match_operand:SI 2 "general_operand" "")))]
788 if (!nds32_ior_operand (operands[2], SImode))
789 operands[2] = force_reg (SImode, operands[2]);
792 (define_insn "*iorsi3"
793 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
794 (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
795 (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))]
802 [(set_attr "type" "alu,alu,alu,alu")
803 (set_attr "length" " 2, 4, 4, 4")
804 (set_attr "feature" "v3m, v1, v1,pe1")])
806 (define_insn "*or_slli"
807 [(set (match_operand:SI 0 "register_operand" "= r")
808 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
809 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
810 (match_operand:SI 3 "register_operand" " r")))]
811 "TARGET_ISA_V3 && optimize_size"
812 "or_slli\t%0, %3, %1, %2"
813 [(set_attr "type" "alu_shift")
814 (set_attr "length" "4")])
816 (define_insn "*or_srli"
817 [(set (match_operand:SI 0 "register_operand" "= r")
818 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
819 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
820 (match_operand:SI 3 "register_operand" " r")))]
821 "TARGET_ISA_V3 && optimize_size"
822 "or_srli\t%0, %3, %1, %2"
823 [(set_attr "type" "alu_shift")
824 (set_attr "length" "4")])
827 ;; ----------------------------------------------------------------------------
829 ;; ----------------------------------------------------------------------------
831 ;; For V3/V3M ISA, we have 'xor33' instruction.
832 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
834 (define_expand "xorsi3"
835 [(set (match_operand:SI 0 "register_operand" "")
836 (xor:SI (match_operand:SI 1 "register_operand" "")
837 (match_operand:SI 2 "general_operand" "")))]
840 if (!nds32_xor_operand (operands[2], SImode))
841 operands[2] = force_reg (SImode, operands[2]);
844 (define_insn "*xorsi3"
845 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
846 (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
847 (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))]
854 [(set_attr "type" "alu,alu,alu,alu")
855 (set_attr "length" " 2, 4, 4, 4")
856 (set_attr "feature" "v3m, v1, v1,pe1")])
858 (define_insn "*xor_slli"
859 [(set (match_operand:SI 0 "register_operand" "= r")
860 (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
861 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
862 (match_operand:SI 3 "register_operand" " r")))]
863 "TARGET_ISA_V3 && optimize_size"
864 "xor_slli\t%0, %3, %1, %2"
865 [(set_attr "type" "alu_shift")
866 (set_attr "length" "4")])
868 (define_insn "*xor_srli"
869 [(set (match_operand:SI 0 "register_operand" "= r")
870 (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
871 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
872 (match_operand:SI 3 "register_operand" " r")))]
873 "TARGET_ISA_V3 && optimize_size"
874 "xor_srli\t%0, %3, %1, %2"
875 [(set_attr "type" "alu_shift")
876 (set_attr "length" "4")])
878 ;; Rotate Right Instructions.
880 (define_insn "*rotrsi3"
881 [(set (match_operand:SI 0 "register_operand" "= r, r")
882 (rotatert:SI (match_operand:SI 1 "register_operand" " r, r")
883 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
888 [(set_attr "type" " alu, alu")
889 (set_attr "subtype" "shift,shift")
890 (set_attr "length" " 4, 4")])
893 ;; ----------------------------------------------------------------------------
895 ;; ----------------------------------------------------------------------------
897 ;; For V3/V3M ISA, we have 'neg33' instruction.
898 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
899 ;; And for V2 ISA, there is NO 'neg33' instruction.
900 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
901 (define_insn "negsi2"
902 [(set (match_operand:SI 0 "register_operand" "=l, r")
903 (neg:SI (match_operand:SI 1 "register_operand" " l, r")))]
908 [(set_attr "type" "alu,alu")
909 (set_attr "length" " 2, 4")
910 (set_attr "feature" "v3m, v1")])
912 (define_expand "negsf2"
913 [(set (match_operand:SF 0 "register_operand" "")
914 (neg:SF (match_operand:SF 1 "register_operand" "")))]
917 if (!TARGET_FPU_SINGLE && !TARGET_EXT_PERF)
919 rtx new_dst = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
920 rtx new_src = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
922 emit_insn (gen_xorsi3 (new_dst,
924 gen_int_mode (0x80000000, SImode)));
930 (define_expand "negdf2"
931 [(set (match_operand:DF 0 "register_operand" "")
932 (neg:DF (match_operand:DF 1 "register_operand" "")))]
937 (define_insn_and_split "soft_negdf2"
938 [(set (match_operand:DF 0 "register_operand" "")
939 (neg:DF (match_operand:DF 1 "register_operand" "")))]
945 rtx src = operands[1];
946 rtx dst = operands[0];
947 rtx ori_dst = operands[0];
949 bool need_extra_move_for_dst_p;
950 /* FPU register can't change mode to SI directly, so we need create a
951 tmp register to handle it, and FPU register can't do `xor` or btgl. */
952 if (HARD_REGISTER_P (src)
953 && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (src)))
955 rtx tmp = gen_reg_rtx (DFmode);
956 emit_move_insn (tmp, src);
960 if (HARD_REGISTER_P (dst)
961 && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (dst)))
963 need_extra_move_for_dst_p = true;
964 rtx tmp = gen_reg_rtx (DFmode);
968 rtx dst_high_part = simplify_gen_subreg (
970 DFmode, subreg_highpart_offset (SImode, DFmode));
971 rtx dst_low_part = simplify_gen_subreg (
973 DFmode, subreg_lowpart_offset (SImode, DFmode));
974 rtx src_high_part = simplify_gen_subreg (
976 DFmode, subreg_highpart_offset (SImode, DFmode));
977 rtx src_low_part = simplify_gen_subreg (
979 DFmode, subreg_lowpart_offset (SImode, DFmode));
981 emit_insn (gen_xorsi3 (dst_high_part,
983 gen_int_mode (0x80000000, SImode)));
984 emit_move_insn (dst_low_part, src_low_part);
986 if (need_extra_move_for_dst_p)
987 emit_move_insn (ori_dst, dst);
993 ;; ----------------------------------------------------------------------------
994 ;; 'ONE_COMPLIMENT' operation
995 ;; ----------------------------------------------------------------------------
997 ;; For V3/V3M ISA, we have 'not33' instruction.
998 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
999 (define_insn "one_cmplsi2"
1000 [(set (match_operand:SI 0 "register_operand" "=w, r")
1001 (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
1006 [(set_attr "type" "alu,alu")
1007 (set_attr "length" " 2, 4")
1008 (set_attr "feature" "v3m, v1")])
1011 ;; ----------------------------------------------------------------------------
1013 ;; Shift instructions.
1015 (define_expand "<shift>si3"
1016 [(set (match_operand:SI 0 "register_operand" "")
1017 (shift_rotate:SI (match_operand:SI 1 "register_operand" "")
1018 (match_operand:SI 2 "nds32_rimm5u_operand" "")))]
1021 if (operands[2] == const0_rtx)
1023 emit_move_insn (operands[0], operands[1]);
1028 (define_insn "*ashlsi3"
1029 [(set (match_operand:SI 0 "register_operand" "= l, r, r")
1030 (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r")
1031 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))]
1037 [(set_attr "type" " alu, alu, alu")
1038 (set_attr "subtype" "shift,shift,shift")
1039 (set_attr "length" " 2, 4, 4")])
1041 (define_insn "*ashrsi3"
1042 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
1043 (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
1044 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
1050 [(set_attr "type" " alu, alu, alu")
1051 (set_attr "subtype" "shift,shift,shift")
1052 (set_attr "length" " 2, 4, 4")])
1054 (define_insn "*lshrsi3"
1055 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
1056 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
1057 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
1063 [(set_attr "type" " alu, alu, alu")
1064 (set_attr "subtype" "shift,shift,shift")
1065 (set_attr "length" " 2, 4, 4")])
1068 ;; ----------------------------------------------------------------------------
1070 ;; ----------------------------------------------------------------------------
1071 ;; Conditional Move patterns
1072 ;; ----------------------------------------------------------------------------
1074 (define_expand "mov<mode>cc"
1075 [(set (match_operand:QIHISI 0 "register_operand" "")
1076 (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
1077 (match_operand:QIHISI 2 "register_operand" "")
1078 (match_operand:QIHISI 3 "register_operand" "")))]
1079 "TARGET_CMOV && !optimize_size"
1081 enum nds32_expand_result_type result = nds32_expand_movcc (operands);
1090 case EXPAND_CREATE_TEMPLATE:
1097 (define_insn "cmovz<mode>"
1098 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
1099 (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
1101 (match_operand:QIHISI 2 "register_operand" " r, 0")
1102 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
1107 [(set_attr "type" "alu")
1108 (set_attr "length" "4")])
1110 (define_insn "cmovn<mode>"
1111 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
1112 (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
1114 (match_operand:QIHISI 2 "register_operand" " r, 0")
1115 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
1120 [(set_attr "type" "alu")
1121 (set_attr "length" "4")])
1123 ;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
1124 ;; It should be removed once after we change the expansion form of the cmovn.
1125 (define_insn "*cmovn_simplified_<mode>"
1126 [(set (match_operand:QIHISI 0 "register_operand" "=r")
1127 (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
1128 (match_operand:QIHISI 2 "register_operand" "r")
1129 (match_operand:QIHISI 3 "register_operand" "0")))]
1132 [(set_attr "type" "alu")])
1134 ;; ----------------------------------------------------------------------------
1135 ;; Conditional Branch patterns
1136 ;; ----------------------------------------------------------------------------
1138 (define_expand "cbranchsi4"
1140 (if_then_else (match_operator 0 "comparison_operator"
1141 [(match_operand:SI 1 "register_operand" "")
1142 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
1143 (label_ref (match_operand 3 "" ""))
1147 enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
1156 case EXPAND_CREATE_TEMPLATE:
1164 (define_insn "cbranchsi4_equality_zero"
1166 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1167 [(match_operand:SI 1 "register_operand" "t,l, r")
1169 (label_ref (match_operand 2 "" ""))
1173 return nds32_output_cbranchsi4_equality_zero (insn, operands);
1175 [(set_attr "type" "branch")
1176 (set_attr_alternative "enabled"
1179 (if_then_else (match_test "TARGET_16_BIT")
1180 (const_string "yes")
1181 (const_string "no"))
1183 (if_then_else (match_test "TARGET_16_BIT")
1184 (const_string "yes")
1185 (const_string "no"))
1187 (const_string "yes")
1189 (set_attr_alternative "length"
1192 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1193 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1194 (le (minus (match_dup 2) (pc)) (const_int 250)))
1195 (if_then_else (match_test "TARGET_16_BIT")
1198 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1199 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1201 (if_then_else (match_test "TARGET_16_BIT")
1206 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1207 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1208 (le (minus (match_dup 2) (pc)) (const_int 250)))
1209 (if_then_else (match_test "TARGET_16_BIT")
1212 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1213 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1215 (if_then_else (match_test "TARGET_16_BIT")
1220 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1221 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1222 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1229 ;; This pattern is dedicated to V2 ISA,
1230 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
1231 (define_insn "cbranchsi4_equality_reg"
1233 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1234 [(match_operand:SI 1 "register_operand" "v, r")
1235 (match_operand:SI 2 "register_operand" "l, r")])
1236 (label_ref (match_operand 3 "" ""))
1240 return nds32_output_cbranchsi4_equality_reg (insn, operands);
1242 [(set_attr "type" "branch")
1243 (set_attr_alternative "enabled"
1246 (if_then_else (match_test "TARGET_16_BIT")
1247 (const_string "yes")
1248 (const_string "no"))
1250 (const_string "yes")
1252 (set_attr_alternative "length"
1255 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1256 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1257 (le (minus (match_dup 3) (pc)) (const_int 250)))
1259 (if_then_else (and (ge (minus (match_dup 3) (pc))
1261 (le (minus (match_dup 3) (pc))
1267 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1268 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1269 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1276 ;; This pattern is dedicated to V3/V3M,
1277 ;; because V3/V3M DO HAVE beqc/bnec instruction.
1278 (define_insn "cbranchsi4_equality_reg_or_const_int"
1280 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1281 [(match_operand:SI 1 "register_operand" "v, r, r")
1282 (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
1283 (label_ref (match_operand 3 "" ""))
1285 "TARGET_ISA_V3 || TARGET_ISA_V3M"
1287 return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
1289 [(set_attr "type" "branch")
1290 (set_attr_alternative "enabled"
1293 (if_then_else (match_test "TARGET_16_BIT")
1294 (const_string "yes")
1295 (const_string "no"))
1297 (const_string "yes")
1299 (const_string "yes")
1301 (set_attr_alternative "length"
1304 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1305 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1306 (le (minus (match_dup 3) (pc)) (const_int 250)))
1308 (if_then_else (and (ge (minus (match_dup 3) (pc))
1310 (le (minus (match_dup 3) (pc))
1316 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1317 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1318 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1323 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1324 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1325 (le (minus (match_dup 3) (pc)) (const_int 250)))
1332 (define_insn "*cbranchsi4_greater_less_zero"
1334 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1335 [(match_operand:SI 1 "register_operand" "r")
1337 (label_ref (match_operand 2 "" ""))
1341 return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
1343 [(set_attr "type" "branch")
1344 (set (attr "length")
1345 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1346 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1347 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1353 (define_expand "cstoresi4"
1354 [(set (match_operand:SI 0 "register_operand" "")
1355 (match_operator:SI 1 "comparison_operator"
1356 [(match_operand:SI 2 "register_operand" "")
1357 (match_operand:SI 3 "nonmemory_operand" "")]))]
1360 enum nds32_expand_result_type result = nds32_expand_cstore (operands);
1369 case EXPAND_CREATE_TEMPLATE:
1377 (define_expand "slts_compare"
1378 [(set (match_operand:SI 0 "register_operand" "")
1379 (lt:SI (match_operand:SI 1 "general_operand" "")
1380 (match_operand:SI 2 "general_operand" "")))]
1383 if (!REG_P (operands[1]))
1384 operands[1] = force_reg (SImode, operands[1]);
1386 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1387 operands[2] = force_reg (SImode, operands[2]);
1390 (define_insn "slts_compare_impl"
1391 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1392 (lt:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1393 (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
1400 [(set_attr "type" "alu, alu, alu, alu")
1401 (set_attr "length" " 2, 2, 4, 4")])
1403 (define_insn "slt_eq0"
1404 [(set (match_operand:SI 0 "register_operand" "=t, r")
1405 (eq:SI (match_operand:SI 1 "register_operand" " d, r")
1411 [(set_attr "type" "alu, alu")
1412 (set_attr "length" " 2, 4")])
1414 (define_expand "slt_compare"
1415 [(set (match_operand:SI 0 "register_operand" "")
1416 (ltu:SI (match_operand:SI 1 "general_operand" "")
1417 (match_operand:SI 2 "general_operand" "")))]
1420 if (!REG_P (operands[1]))
1421 operands[1] = force_reg (SImode, operands[1]);
1423 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1424 operands[2] = force_reg (SImode, operands[2]);
1427 (define_insn "slt_compare_impl"
1428 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1429 (ltu:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1430 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
1437 [(set_attr "type" "alu, alu, alu, alu")
1438 (set_attr "length" " 2, 2, 4, 4")])
1441 ;; ----------------------------------------------------------------------------
1443 ;; Unconditional and other jump instructions.
1446 [(set (pc) (label_ref (match_operand 0 "" "")))]
1449 /* This unconditional jump has two forms:
1450 32-bit instruction => j imm24s << 1
1451 16-bit instruction => j8 imm8s << 1
1454 we assume it is always reachable.
1456 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1457 However, since the $pc for nds32 is at the beginning of the instruction,
1458 we should leave some length space for current insn.
1459 So we use range -250 ~ 250. */
1460 switch (get_attr_length (insn))
1470 [(set_attr "type" "branch")
1471 (set_attr "enabled" "yes")
1472 (set (attr "length")
1473 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1474 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1475 (le (minus (match_dup 0) (pc)) (const_int 250)))
1476 (if_then_else (match_test "TARGET_16_BIT")
1482 (define_insn "indirect_jump"
1483 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1488 [(set_attr "type" "branch,branch")
1489 (set_attr "length" " 2, 4")])
1491 ;; Subroutine call instruction returning no value.
1492 ;; operands[0]: It should be a mem RTX whose address is
1493 ;; the address of the function.
1494 ;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
1495 ;; operands[2]: It is the number of registers used as operands.
1497 (define_expand "call"
1498 [(parallel [(call (match_operand 0 "memory_operand" "")
1500 (clobber (reg:SI LP_REGNUM))
1501 (clobber (reg:SI TA_REGNUM))])]
1505 rtx sym = XEXP (operands[0], 0);
1507 if (TARGET_ICT_MODEL_LARGE
1508 && nds32_indirect_call_referenced_p (sym))
1510 rtx reg = gen_reg_rtx (Pmode);
1511 emit_move_insn (reg, sym);
1512 operands[0] = gen_const_mem (Pmode, reg);
1517 insn = emit_call_insn (gen_call_internal
1518 (XEXP (operands[0], 0), GEN_INT (0)));
1519 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
1525 (define_insn "call_internal"
1526 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S"))
1528 (clobber (reg:SI LP_REGNUM))
1529 (clobber (reg:SI TA_REGNUM))])]
1532 rtx_insn *next_insn = next_active_insn (insn);
1533 bool align_p = (!(next_insn && get_attr_length (next_insn) == 2))
1534 && NDS32_ALIGN_P ();
1535 switch (which_alternative)
1541 return "jral5\t%0\;.align 2";
1548 return "jral\t%0\;.align 2";
1553 return nds32_output_call (insn, operands, operands[0],
1554 "bal\t%0", "jal\t%0", align_p);
1559 [(set_attr "enabled" "yes")
1560 (set_attr "type" "branch")
1561 (set_attr_alternative "length"
1564 (if_then_else (match_test "TARGET_16_BIT")
1568 (if_then_else (match_test "flag_pic")
1570 (if_then_else (match_test "nds32_long_call_p (operands[0])")
1576 ;; Subroutine call instruction returning a value.
1577 ;; operands[0]: It is the hard regiser in which the value is returned.
1578 ;; The rest three operands are the same as the
1579 ;; three operands of the 'call' instruction.
1580 ;; (but with numbers increased by one)
1582 (define_expand "call_value"
1583 [(parallel [(set (match_operand 0)
1584 (call (match_operand 1 "memory_operand" "")
1586 (clobber (reg:SI LP_REGNUM))
1587 (clobber (reg:SI TA_REGNUM))])]
1591 rtx sym = XEXP (operands[1], 0);
1593 if (TARGET_ICT_MODEL_LARGE
1594 && nds32_indirect_call_referenced_p (sym))
1596 rtx reg = gen_reg_rtx (Pmode);
1597 emit_move_insn (reg, sym);
1598 operands[1] = gen_const_mem (Pmode, reg);
1604 emit_call_insn (gen_call_value_internal
1605 (operands[0], XEXP (operands[1], 0), GEN_INT (0)));
1606 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
1612 (define_insn "call_value_internal"
1613 [(parallel [(set (match_operand 0)
1614 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S"))
1616 (clobber (reg:SI LP_REGNUM))
1617 (clobber (reg:SI TA_REGNUM))])]
1620 rtx_insn *next_insn = next_active_insn (insn);
1621 bool align_p = (!(next_insn && get_attr_length (next_insn) == 2))
1622 && NDS32_ALIGN_P ();
1623 switch (which_alternative)
1629 return "jral5\t%1\;.align 2";
1636 return "jral\t%1\;.align 2";
1641 return nds32_output_call (insn, operands, operands[1],
1642 "bal\t%1", "jal\t%1", align_p);
1647 [(set_attr "enabled" "yes")
1648 (set_attr "type" "branch")
1649 (set_attr_alternative "length"
1652 (if_then_else (match_test "TARGET_16_BIT")
1656 (if_then_else (match_test "flag_pic")
1658 (if_then_else (match_test "nds32_long_call_p (operands[1])")
1664 ;; Call subroutine returning any type.
1666 (define_expand "untyped_call"
1667 [(parallel [(call (match_operand 0 "" "")
1669 (match_operand 1 "" "")
1670 (match_operand 2 "" "")])]
1675 emit_call_insn (gen_call (operands[0], const0_rtx));
1677 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1679 rtx set = XVECEXP (operands[2], 0, i);
1680 emit_move_insn (SET_DEST (set), SET_SRC (set));
1683 /* The optimizer does not know that the call sets the function value
1684 registers we stored in the result block. We avoid problems by
1685 claiming that all hard registers are used and clobbered at this
1687 emit_insn (gen_blockage ());
1691 ;; ----------------------------------------------------------------------------
1693 ;; The sibcall patterns.
1698 (define_expand "sibcall"
1699 [(parallel [(call (match_operand 0 "memory_operand" "")
1701 (clobber (reg:SI TA_REGNUM))
1705 rtx sym = XEXP (operands[0], 0);
1707 if (TARGET_ICT_MODEL_LARGE
1708 && nds32_indirect_call_referenced_p (sym))
1710 rtx reg = gen_reg_rtx (Pmode);
1711 emit_move_insn (reg, sym);
1712 operands[0] = gen_const_mem (Pmode, reg);
1716 (define_insn "sibcall_internal"
1717 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, S"))
1719 (clobber (reg:SI TA_REGNUM))
1723 switch (which_alternative)
1731 if (nds32_long_call_p (operands[0]))
1739 [(set_attr "enabled" "yes")
1740 (set_attr "type" "branch")
1741 (set_attr_alternative "length"
1744 (if_then_else (match_test "TARGET_16_BIT")
1748 (if_then_else (match_test "flag_pic")
1750 (if_then_else (match_test "nds32_long_call_p (operands[0])")
1757 ;; sibcall_value_internal
1758 ;; sibcall_value_immediate
1760 (define_expand "sibcall_value"
1761 [(parallel [(set (match_operand 0)
1762 (call (match_operand 1 "memory_operand" "")
1764 (clobber (reg:SI TA_REGNUM))
1768 rtx sym = XEXP (operands[1], 0);
1770 if (TARGET_ICT_MODEL_LARGE
1771 && nds32_indirect_call_referenced_p (sym))
1773 rtx reg = gen_reg_rtx (Pmode);
1774 emit_move_insn (reg, sym);
1775 operands[1] = gen_const_mem (Pmode, reg);
1779 (define_insn "sibcall_value_internal"
1780 [(parallel [(set (match_operand 0)
1781 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, S"))
1783 (clobber (reg:SI TA_REGNUM))
1787 switch (which_alternative)
1795 if (nds32_long_call_p (operands[1]))
1803 [(set_attr "enabled" "yes")
1804 (set_attr "type" "branch")
1805 (set_attr_alternative "length"
1808 (if_then_else (match_test "TARGET_16_BIT")
1812 (if_then_else (match_test "flag_pic")
1814 (if_then_else (match_test "nds32_long_call_p (operands[1])")
1820 ;; ----------------------------------------------------------------------------
1822 ;; prologue and epilogue.
1824 (define_expand "prologue" [(const_int 0)]
1827 /* Note that only under V3/V3M ISA, we could use v3push prologue.
1828 In addition, we need to check if v3push is indeed available. */
1829 if (NDS32_V3PUSH_AVAILABLE_P)
1830 nds32_expand_prologue_v3push ();
1832 nds32_expand_prologue ();
1836 (define_expand "epilogue" [(const_int 0)]
1839 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
1840 In addition, we need to check if v3push is indeed available. */
1841 if (NDS32_V3PUSH_AVAILABLE_P)
1842 nds32_expand_epilogue_v3pop (false);
1844 nds32_expand_epilogue (false);
1848 (define_expand "sibcall_epilogue" [(const_int 0)]
1851 /* Pass true to indicate that this is sibcall epilogue and
1852 exit from a function without the final branch back to the
1853 calling function. */
1854 nds32_expand_epilogue (true);
1871 [(set_attr "type" "misc")
1872 (set_attr "enabled" "yes")
1873 (set (attr "length")
1874 (if_then_else (match_test "TARGET_16_BIT")
1879 ;; ----------------------------------------------------------------------------
1880 ;; Stack push/pop operations
1881 ;; ----------------------------------------------------------------------------
1883 ;; The pattern for stack push.
1884 ;; Both stack_push_multiple and stack_v3push use the following pattern.
1885 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1886 (define_insn "*stack_push"
1887 [(match_parallel 0 "nds32_stack_push_operation"
1888 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1889 (match_operand:SI 1 "const_int_operand" "")))
1890 (match_operand:SI 2 "register_operand" ""))
1894 return nds32_output_stack_push (operands[0]);
1896 [(set_attr "type" "store_multiple")
1897 (set_attr "combo" "12")
1898 (set_attr "enabled" "yes")
1899 (set (attr "length")
1900 (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1905 ;; The pattern for stack pop.
1906 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1907 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1908 (define_insn "*stack_pop"
1909 [(match_parallel 0 "nds32_stack_pop_operation"
1910 [(set (match_operand:SI 1 "register_operand" "")
1911 (mem:SI (reg:SI SP_REGNUM)))
1915 return nds32_output_stack_pop (operands[0]);
1917 [(set_attr "type" "load_multiple")
1918 (set_attr "combo" "12")
1919 (set_attr "enabled" "yes")
1920 (set (attr "length")
1921 (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1926 ;; ----------------------------------------------------------------------------
1927 ;; Return operation patterns
1928 ;; ----------------------------------------------------------------------------
1930 ;; Use this pattern to expand a return instruction
1931 ;; with simple_return rtx if no epilogue is required.
1932 (define_expand "return"
1933 [(parallel [(return)
1934 (clobber (reg:SI FP_REGNUM))])]
1935 "nds32_can_use_return_insn ()"
1937 /* Emit as the simple return. */
1938 if (cfun->machine->naked_p
1939 && (cfun->machine->va_args_size == 0))
1941 emit_jump_insn (gen_return_internal ());
1946 ;; This pattern is expanded only by the shrink-wrapping optimization
1947 ;; on paths where the function prologue has not been executed.
1948 (define_expand "simple_return"
1954 (define_insn "*nds32_return"
1955 [(parallel [(return)
1956 (clobber (reg:SI FP_REGNUM))])]
1959 return nds32_output_return ();
1961 [(set_attr "type" "branch")
1962 (set_attr "enabled" "yes")
1963 (set_attr "length" "4")])
1965 (define_insn "return_internal"
1974 [(set_attr "type" "branch")
1975 (set_attr "enabled" "yes")
1976 (set (attr "length")
1977 (if_then_else (match_test "TARGET_16_BIT")
1982 ;; ----------------------------------------------------------------------------
1983 ;; Jump Table patterns
1984 ;; ----------------------------------------------------------------------------
1985 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
1986 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
1988 ;; operands[0]: The index to dispatch on.
1989 ;; operands[1]: The lower bound for indices in the table.
1990 ;; operands[2]: The total range of indices int the table.
1991 ;; i.e. The largest index minus the smallest one.
1992 ;; operands[3]: A label that precedes the table itself.
1993 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
1995 ;; We need to create following sequences for jump table code generation:
1996 ;; A) k <-- (plus (operands[0]) (-operands[1]))
1997 ;; B) if (gtu k operands[2]) then goto operands[4]
1998 ;; C) t <-- operands[3]
1999 ;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
2000 ;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
2001 ;; F) jump to target with register t or z
2003 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
2004 (define_expand "casesi"
2005 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
2006 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
2007 (match_operand:SI 2 "immediate_operand" "i") ; total range
2008 (match_operand:SI 3 "" "") ; table label
2009 (match_operand:SI 4 "" "")] ; Out of range label
2016 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
2017 if (operands[1] != const0_rtx)
2019 reg = gen_reg_rtx (SImode);
2020 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
2022 /* If the integer value is not in the range of imm15s,
2023 we need to force register first because our addsi3 pattern
2024 only accept nds32_rimm15s_operand predicate. */
2025 add_tmp = force_reg (SImode, add_tmp);
2027 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
2031 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
2032 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
2033 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
2036 tmp_reg = gen_reg_rtx (SImode);
2037 /* Step C, D, E, and F, using another temporary register tmp_reg. */
2039 emit_use (pic_offset_table_rtx);
2041 emit_jump_insn (gen_casesi_internal (operands[0],
2047 ;; We are receiving operands from casesi pattern:
2049 ;; operands[0]: The index that have been substracted with lower bound.
2050 ;; operands[1]: A label that precedes the table itself.
2051 ;; operands[2]: A temporary register to retrieve value in table.
2053 ;; We need to perform steps C, D, E, and F:
2055 ;; C) t <-- operands[1]
2056 ;; D) z <-- (mem (plus (operands[0] << m) t))
2057 ;; m is 2 for normal jump table.
2058 ;; m is 0, 1, or 2 for pc relative jump table based on diff size.
2059 ;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
2060 ;; F) Jump to target with register t or z.
2062 ;; The USE in this pattern is needed to tell flow analysis that this is
2063 ;; a CASESI insn. It has no other purpose.
2064 (define_insn "casesi_internal"
2065 [(parallel [(set (pc)
2066 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
2068 (label_ref (match_operand 1 "" "")))))
2069 (use (label_ref (match_dup 1)))
2070 (clobber (match_operand:SI 2 "register_operand" "=r"))
2071 (clobber (reg:SI TA_REGNUM))])]
2074 if (CASE_VECTOR_PC_RELATIVE)
2075 return nds32_output_casesi_pc_relative (operands);
2077 return nds32_output_casesi (operands);
2079 [(set_attr "type" "branch")
2080 (set (attr "length")
2081 (if_then_else (match_test "flag_pic")
2085 ;; ----------------------------------------------------------------------------
2087 ;; Performance Extension
2089 ; If -fwrapv option is issued, GCC expects there will be
2090 ; signed overflow situation. So the ABS(INT_MIN) is still INT_MIN
2091 ; (e.g. ABS(0x80000000)=0x80000000).
2092 ; However, the hardware ABS instruction of nds32 target
2093 ; always performs saturation: abs 0x80000000 -> 0x7fffffff.
2094 ; So that we can only enable abssi2 pattern if flag_wrapv is NOT presented.
2095 (define_insn "abssi2"
2096 [(set (match_operand:SI 0 "register_operand" "=r")
2097 (abs:SI (match_operand:SI 1 "register_operand" " r")))]
2098 "TARGET_EXT_PERF && TARGET_HW_ABS && !flag_wrapv"
2100 [(set_attr "type" "alu")
2101 (set_attr "length" "4")])
2103 (define_insn "clzsi2"
2104 [(set (match_operand:SI 0 "register_operand" "=r")
2105 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
2108 [(set_attr "type" "alu")
2109 (set_attr "length" "4")])
2111 (define_insn "smaxsi3"
2112 [(set (match_operand:SI 0 "register_operand" "=r")
2113 (smax:SI (match_operand:SI 1 "register_operand" " r")
2114 (match_operand:SI 2 "register_operand" " r")))]
2117 [(set_attr "type" "alu")
2118 (set_attr "length" "4")])
2120 (define_insn "sminsi3"
2121 [(set (match_operand:SI 0 "register_operand" "=r")
2122 (smin:SI (match_operand:SI 1 "register_operand" " r")
2123 (match_operand:SI 2 "register_operand" " r")))]
2126 [(set_attr "type" "alu")
2127 (set_attr "length" "4")])
2130 [(set (match_operand:SI 0 "register_operand" "= r")
2131 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
2133 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")))]
2136 [(set_attr "type" "alu")
2137 (set_attr "length" "4")])
2140 [(set (match_operand:SI 0 "register_operand" "=r")
2145 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
2146 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
2151 [(set_attr "type" "alu")
2152 (set_attr "length" "4")])
2154 ;; ----------------------------------------------------------------------------
2158 (define_insn "relax_group"
2159 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
2162 [(set_attr "length" "0")]
2165 (define_insn "pop25return"
2167 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
2169 "! return for pop 25"
2170 [(set_attr "length" "0")]
2174 (define_insn "add_pc"
2175 [(set (match_operand:SI 0 "register_operand" "=r")
2176 (plus:SI (match_operand:SI 1 "register_operand" "0")
2180 [(set_attr "type" "alu")
2181 (set_attr "length" "4")]
2183 ;; ----------------------------------------------------------------------------
2185 ;; Patterns for exception handling
2187 (define_expand "eh_return"
2188 [(use (match_operand 0 "general_operand"))]
2191 emit_insn (gen_nds32_eh_return (operands[0]));
2195 (define_insn_and_split "nds32_eh_return"
2196 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_EH_RETURN)]
2205 /* The operands[0] is the handler address. We need to assign it
2206 to return address rtx so that we can jump to exception handler
2207 when returning from current function. */
2209 if (cfun->machine->lp_size == 0)
2211 /* If $lp is not saved in the stack frame, we can take $lp directly. */
2212 place = gen_rtx_REG (SImode, LP_REGNUM);
2216 /* Otherwise, we need to locate the stack slot of return address.
2217 The return address is generally saved in [$fp-4] location.
2218 However, DSE (dead store elimination) does not detect an alias
2219 between [$fp-x] and [$sp+y]. This can result in a store to save
2220 $lp introduced by builtin_eh_return() being incorrectly deleted
2221 if it is based on $fp. The solution we take here is to compute
2222 the offset relative to stack pointer and then use $sp to access
2223 location so that the alias can be detected.
2224 FIXME: What if the immediate value "offset" is too large to be
2225 fit in a single addi instruction? */
2226 HOST_WIDE_INT offset;
2228 offset = (cfun->machine->fp_size
2229 + cfun->machine->gp_size
2230 + cfun->machine->lp_size
2231 + cfun->machine->callee_saved_gpr_regs_size
2232 + cfun->machine->callee_saved_area_gpr_padding_bytes
2233 + cfun->machine->callee_saved_fpr_regs_size
2234 + cfun->machine->eh_return_data_regs_size
2235 + cfun->machine->local_size
2236 + cfun->machine->out_args_size);
2238 addr = plus_constant (Pmode, stack_pointer_rtx, offset - 4);
2239 place = gen_frame_mem (SImode, addr);
2242 emit_move_insn (place, operands[0]);
2246 ;; ----------------------------------------------------------------------------
2248 ;; Patterns for TLS.
2249 ;; The following two tls patterns don't be expanded directly because the
2250 ;; intermediate value may be spilled into the stack. As a result, it is
2251 ;; hard to analyze the define-use chain in the relax_opt pass.
2254 ;; There is a unspec operand to record RELAX_GROUP number because each
2255 ;; emitted instruction need a relax_hint above it.
2256 (define_insn "tls_desc"
2258 (call (unspec_volatile:SI [(match_operand:SI 0 "nds32_symbolic_operand" "i")] UNSPEC_TLS_DESC)
2260 (use (unspec [(match_operand:SI 1 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
2261 (use (reg:SI GP_REGNUM))
2262 (clobber (reg:SI LP_REGNUM))
2263 (clobber (reg:SI TA_REGNUM))]
2266 return nds32_output_tls_desc (operands);
2268 [(set_attr "length" "20")
2269 (set_attr "type" "branch")]
2272 ;; There is a unspec operand to record RELAX_GROUP number because each
2273 ;; emitted instruction need a relax_hint above it.
2274 (define_insn "tls_ie"
2275 [(set (match_operand:SI 0 "register_operand" "=r")
2276 (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")] UNSPEC_TLS_IE))
2277 (use (unspec [(match_operand:SI 2 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP))
2278 (use (reg:SI GP_REGNUM))]
2281 return nds32_output_tls_ie (operands);
2283 [(set (attr "length") (if_then_else (match_test "flag_pic")
2286 (set_attr "type" "misc")]
2289 ;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode.
2290 (define_insn "addsi3_32bit"
2291 [(set (match_operand:SI 0 "register_operand" "=r")
2292 (unspec:SI [(match_operand:SI 1 "register_operand" "%r")
2293 (match_operand:SI 2 "register_operand" " r")] UNSPEC_ADD32))]
2296 [(set_attr "type" "alu")
2297 (set_attr "length" "4")
2298 (set_attr "feature" "v1")])
2300 ;; ----------------------------------------------------------------------------