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 ;; Insn type, it is used to default other attribute values.
58 "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,pbsad,pbsada,mul,mac,div,branch,mmu,misc,\
59 falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore"
60 (const_string "unknown"))
63 (define_attr "subtype"
65 (const_string "simple"))
67 ;; Length, in bytes, default is 4-bytes.
68 (define_attr "length" "" (const_int 4))
70 ;; Indicate the amount of micro instructions.
72 "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"
75 ;; Insn in which feature set, it is used to enable/disable insn alternatives.
76 ;; v1 : Baseline Instructions
77 ;; v2 : Baseline Version 2 Instructions
78 ;; v3m : Baseline Version 3m Instructions
79 ;; v3 : Baseline Version 3 Instructions
80 ;; pe1 : Performance Extension Instructions
81 ;; pe2 : Performance Extension Version 2 Instructions
82 ;; se : String Extension instructions
83 (define_attr "feature"
84 "v1,v2,v3m,v3,pe1,pe2,se,fpu"
87 ;; Enabled, which is used to enable/disable insn alternatives.
88 ;; Note that we use length and TARGET_16_BIT here as criteria.
89 ;; If the instruction pattern already check TARGET_16_BIT to determine
90 ;; the length by itself, its enabled attribute should be customized to
91 ;; avoid the conflict between length attribute and this default setting.
92 (define_attr "enabled" "no,yes"
94 (and (eq_attr "length" "2")
95 (match_test "!TARGET_16_BIT"))
97 (cond [(eq_attr "feature" "v1") (const_string "yes")
98 (eq_attr "feature" "v2") (if_then_else (match_test "TARGET_ISA_V2 || TARGET_ISA_V3 || TARGET_ISA_V3M")
101 (eq_attr "feature" "v3") (if_then_else (match_test "TARGET_ISA_V3")
104 (eq_attr "feature" "v3m") (if_then_else (match_test "TARGET_ISA_V3 || TARGET_ISA_V3M")
107 (eq_attr "feature" "pe1") (if_then_else (match_test "TARGET_EXT_PERF")
110 (eq_attr "feature" "pe2") (if_then_else (match_test "TARGET_EXT_PERF2")
113 (eq_attr "feature" "se") (if_then_else (match_test "TARGET_EXT_STRING")
116 (eq_attr "feature" "fpu") (if_then_else (match_test "TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE")
118 (const_string "no"))]
119 (const_string "yes"))))
122 ;; ----------------------------------------------------------------------------
125 ;; Move instructions.
127 ;; For QImode and HImode, the immediate value can be fit in imm20s.
128 ;; So there is no need to split rtx for QI and HI patterns.
130 (define_expand "mov<mode>"
131 [(set (match_operand:QIHI 0 "general_operand" "")
132 (match_operand:QIHI 1 "general_operand" ""))]
135 /* Need to force register if mem <- !reg. */
136 if (MEM_P (operands[0]) && !REG_P (operands[1]))
137 operands[1] = force_reg (<MODE>mode, operands[1]);
139 if (MEM_P (operands[1]) && optimize > 0)
141 rtx reg = gen_reg_rtx (SImode);
143 emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
144 operands[1] = gen_lowpart (<MODE>mode, reg);
148 (define_expand "movmisalign<mode>"
149 [(set (match_operand:SIDI 0 "general_operand" "")
150 (match_operand:SIDI 1 "general_operand" ""))]
154 if (MEM_P (operands[0]) && !REG_P (operands[1]))
155 operands[1] = force_reg (<MODE>mode, operands[1]);
157 if (MEM_P (operands[0]))
159 addr = force_reg (Pmode, XEXP (operands[0], 0));
160 emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
164 addr = force_reg (Pmode, XEXP (operands[1], 0));
165 emit_insn (gen_unaligned_load<mode> (operands[0], addr));
170 (define_expand "movsi"
171 [(set (match_operand:SI 0 "general_operand" "")
172 (match_operand:SI 1 "general_operand" ""))]
175 /* Need to force register if mem <- !reg. */
176 if (MEM_P (operands[0]) && !REG_P (operands[1]))
177 operands[1] = force_reg (SImode, operands[1]);
179 /* If operands[1] is a large constant and cannot be performed
180 by a single instruction, we need to split it. */
181 if (CONST_INT_P (operands[1])
182 && !satisfies_constraint_Is20 (operands[1])
183 && !satisfies_constraint_Ihig (operands[1]))
186 HOST_WIDE_INT low12_int;
189 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
191 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
192 low12_int = INTVAL (operands[1]) & 0xfff;
194 emit_move_insn (tmp_rtx, high20_rtx);
195 emit_move_insn (operands[0], plus_constant (SImode,
202 (define_insn "*mov<mode>"
203 [(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")
204 (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"))]
205 "register_operand(operands[0], <MODE>mode)
206 || register_operand(operands[1], <MODE>mode)"
208 switch (which_alternative)
211 return "mov55\t%0, %1";
213 return "ori\t%0, %1, 0";
218 return nds32_output_16bit_store (operands, <byte>);
220 return nds32_output_32bit_store (operands, <byte>);
226 return nds32_output_16bit_load (operands, <byte>);
228 return nds32_output_32bit_load (operands, <byte>);
230 return "movpi45\t%0, %1";
232 return "movi55\t%0, %1";
234 return "movi\t%0, %1";
236 return "sethi\t%0, hi20(%1)";
238 if (TARGET_FPU_SINGLE)
239 return "fcpyss\t%0, %1, %1";
243 return "fmtsr\t%1, %0";
245 return "fmfsr\t%0, %1";
247 return nds32_output_float_load (operands);
249 return nds32_output_float_store (operands);
254 [(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")
255 (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")
256 (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")])
259 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
260 ;; are able to match such instruction template.
261 (define_insn "move_addr"
262 [(set (match_operand:SI 0 "register_operand" "=l, r")
263 (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
266 [(set_attr "type" "alu")
267 (set_attr "length" "8")])
271 [(set (match_operand:SI 0 "register_operand" "=r")
272 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
274 "sethi\t%0, hi20(%1)"
275 [(set_attr "type" "alu")
276 (set_attr "length" "4")])
279 (define_insn "lo_sum"
280 [(set (match_operand:SI 0 "register_operand" "=r")
281 (lo_sum:SI (match_operand:SI 1 "register_operand" " r")
282 (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
284 "ori\t%0, %1, lo12(%2)"
285 [(set_attr "type" "alu")
286 (set_attr "length" "4")])
289 ;; ----------------------------------------------------------------------------
291 ;; Zero extension instructions.
293 (define_insn "zero_extend<mode>si2"
294 [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r")
295 (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))]
298 switch (which_alternative)
301 return "ze<size>33\t%0, %1";
303 return "ze<size>\t%0, %1";
305 return nds32_output_16bit_load (operands, <byte>);
307 return nds32_output_32bit_load (operands, <byte>);
313 [(set_attr "type" "alu,alu,load,load")
314 (set_attr "length" " 2, 4, 2, 4")])
317 ;; Sign extension instructions.
319 (define_insn "extend<mode>si2"
320 [(set (match_operand:SI 0 "register_operand" "=l, r, r")
321 (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
324 switch (which_alternative)
327 return "se<size>33\t%0, %1";
329 return "se<size>\t%0, %1";
331 return nds32_output_32bit_load_s (operands, <byte>);
337 [(set_attr "type" "alu,alu,load")
338 (set_attr "length" " 2, 4, 4")])
341 ;; ----------------------------------------------------------------------------
343 ;; Arithmetic instructions.
345 (define_insn "addsi3"
346 [(set (match_operand:SI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
347 (plus:SI (match_operand:SI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
348 (match_operand:SI 2 "nds32_rimm15s_operand" " In05,In03,Iu05,Iu03, r, l,Is10,Iu06, Is15, r")))]
351 switch (which_alternative)
354 /* addi Rt4,Rt4,-x ==> subi45 Rt4,x
355 where 0 <= x <= 31 */
356 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
357 return "subi45\t%0, %2";
359 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
361 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
362 return "subi333\t%0, %1, %2";
364 return "addi45\t%0, %2";
366 return "addi333\t%0, %1, %2";
368 return "add45\t%0, %2";
370 return "add333\t%0, %1, %2";
372 return "addi10.sp\t%2";
374 return "addri36.sp\t%0, %2";
376 return "addi\t%0, %1, %2";
378 return "add\t%0, %1, %2";
384 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
385 (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")
386 (set_attr "feature" " v1, v1, v1, v1, v1, v1, v2, v1, v1, v1")])
388 (define_insn "subsi3"
389 [(set (match_operand:SI 0 "register_operand" "=d, l, r, r")
390 (minus:SI (match_operand:SI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
391 (match_operand:SI 2 "register_operand" " r, l, r, r")))]
398 [(set_attr "type" "alu,alu,alu,alu")
399 (set_attr "length" " 2, 2, 4, 4")])
402 ;; GCC intends to simplify (plus (ashift ...) (reg))
403 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
404 ;; and needs to ensure it is exact_log2 value.
405 (define_insn "*add_slli"
406 [(set (match_operand:SI 0 "register_operand" "=r")
407 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
408 (match_operand:SI 2 "immediate_operand" " i"))
409 (match_operand:SI 3 "register_operand" " r")))]
410 "TARGET_ISA_V3 && optimize_size
411 && (exact_log2 (INTVAL (operands[2])) != -1)
412 && (exact_log2 (INTVAL (operands[2])) <= 31)"
414 /* Get floor_log2 of the immediate value
415 so that we can generate 'add_slli' instruction. */
416 operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
418 return "add_slli\t%0, %3, %1, %2";
420 [(set_attr "type" "alu_shift")
421 (set_attr "combo" "2")
422 (set_attr "length" "4")])
424 (define_insn "*add_srli"
425 [(set (match_operand:SI 0 "register_operand" "= r")
426 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
427 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
428 (match_operand:SI 3 "register_operand" " r")))]
429 "TARGET_ISA_V3 && optimize_size"
430 "add_srli\t%0, %3, %1, %2"
431 [(set_attr "type" "alu_shift")
432 (set_attr "combo" "2")
433 (set_attr "length" "4")])
436 ;; GCC intends to simplify (minus (reg) (ashift ...))
437 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
438 ;; and needs to ensure it is exact_log2 value.
439 (define_insn "*sub_slli"
440 [(set (match_operand:SI 0 "register_operand" "=r")
441 (minus:SI (match_operand:SI 1 "register_operand" " r")
442 (mult:SI (match_operand:SI 2 "register_operand" " r")
443 (match_operand:SI 3 "immediate_operand" " i"))))]
444 "TARGET_ISA_V3 && optimize_size
445 && (exact_log2 (INTVAL (operands[3])) != -1)
446 && (exact_log2 (INTVAL (operands[3])) <= 31)"
448 /* Get floor_log2 of the immediate value
449 so that we can generate 'sub_slli' instruction. */
450 operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
452 return "sub_slli\t%0, %1, %2, %3";
454 [(set_attr "type" "alu_shift")
455 (set_attr "combo" "2")
456 (set_attr "length" "4")])
458 (define_insn "*sub_srli"
459 [(set (match_operand:SI 0 "register_operand" "= r")
460 (minus:SI (match_operand:SI 1 "register_operand" " r")
461 (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
462 (match_operand:SI 3 "nds32_imm5u_operand" " Iu05"))))]
463 "TARGET_ISA_V3 && optimize_size"
464 "sub_srli\t%0, %1, %2, %3"
465 [(set_attr "type" "alu_shift")
466 (set_attr "combo" "2")
467 (set_attr "length" "4")])
470 ;; Multiplication instructions.
472 (define_insn "mulsi3"
473 [(set (match_operand:SI 0 "register_operand" "=w, r")
474 (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
475 (match_operand:SI 2 "register_operand" " w, r")))]
480 [(set_attr "type" "mul,mul")
481 (set_attr "length" " 2, 4")
482 (set_attr "feature" "v3m, v1")])
484 (define_insn "mulsidi3"
485 [(set (match_operand:DI 0 "register_operand" "=r")
486 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
487 (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
488 "TARGET_ISA_V2 || TARGET_ISA_V3"
489 "mulsr64\t%0, %1, %2"
490 [(set_attr "type" "mul")
491 (set_attr "length" "4")])
493 (define_insn "umulsidi3"
494 [(set (match_operand:DI 0 "register_operand" "=r")
495 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
496 (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
497 "TARGET_ISA_V2 || TARGET_ISA_V3"
499 [(set_attr "type" "mul")
500 (set_attr "length" "4")])
503 ;; Multiply-accumulate instructions.
505 (define_insn "*maddr32_0"
506 [(set (match_operand:SI 0 "register_operand" "=r")
507 (plus:SI (match_operand:SI 3 "register_operand" " 0")
508 (mult:SI (match_operand:SI 1 "register_operand" " r")
509 (match_operand:SI 2 "register_operand" " r"))))]
511 "maddr32\t%0, %1, %2"
512 [(set_attr "type" "mac")
513 (set_attr "length" "4")])
515 (define_insn "*maddr32_1"
516 [(set (match_operand:SI 0 "register_operand" "=r")
517 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
518 (match_operand:SI 2 "register_operand" " r"))
519 (match_operand:SI 3 "register_operand" " 0")))]
521 "maddr32\t%0, %1, %2"
522 [(set_attr "type" "mac")
523 (set_attr "length" "4")])
525 (define_insn "*msubr32"
526 [(set (match_operand:SI 0 "register_operand" "=r")
527 (minus:SI (match_operand:SI 3 "register_operand" " 0")
528 (mult:SI (match_operand:SI 1 "register_operand" " r")
529 (match_operand:SI 2 "register_operand" " r"))))]
531 "msubr32\t%0, %1, %2"
532 [(set_attr "type" "mac")
533 (set_attr "length" "4")])
538 (define_insn "divmodsi4"
539 [(set (match_operand:SI 0 "register_operand" "=r")
540 (div:SI (match_operand:SI 1 "register_operand" " r")
541 (match_operand:SI 2 "register_operand" " r")))
542 (set (match_operand:SI 3 "register_operand" "=r")
543 (mod:SI (match_dup 1) (match_dup 2)))]
545 "divsr\t%0, %3, %1, %2"
546 [(set_attr "type" "div")
547 (set_attr "length" "4")])
549 (define_insn "udivmodsi4"
550 [(set (match_operand:SI 0 "register_operand" "=r")
551 (udiv:SI (match_operand:SI 1 "register_operand" " r")
552 (match_operand:SI 2 "register_operand" " r")))
553 (set (match_operand:SI 3 "register_operand" "=r")
554 (umod:SI (match_dup 1) (match_dup 2)))]
556 "divr\t%0, %3, %1, %2"
557 [(set_attr "type" "div")
558 (set_attr "length" "4")])
560 ;; divsr/divr will keep quotient only when quotient and remainder is the same
561 ;; register in our ISA spec, it's can reduce 1 register presure if we don't
563 (define_insn "divsi4"
564 [(set (match_operand:SI 0 "register_operand" "=r")
565 (div:SI (match_operand:SI 1 "register_operand" " r")
566 (match_operand:SI 2 "register_operand" " r")))]
568 "divsr\t%0, %0, %1, %2"
569 [(set_attr "type" "div")
570 (set_attr "length" "4")])
572 (define_insn "udivsi4"
573 [(set (match_operand:SI 0 "register_operand" "=r")
574 (udiv:SI (match_operand:SI 1 "register_operand" " r")
575 (match_operand:SI 2 "register_operand" " r")))]
577 "divr\t%0, %0, %1, %2"
578 [(set_attr "type" "div")
579 (set_attr "length" "4")])
581 ;; ----------------------------------------------------------------------------
583 ;; Boolean instructions.
584 ;; Note: We define the DImode versions in nds32-doubleword.md.
586 ;; ----------------------------------------------------------------------------
588 ;; ----------------------------------------------------------------------------
591 [(set (match_operand:SI 0 "register_operand" "=r")
592 (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
593 (match_operand:SI 2 "register_operand" " r")))]
596 [(set_attr "type" "alu")
597 (set_attr "length" "4")]
600 (define_expand "andsi3"
601 [(set (match_operand:SI 0 "register_operand" "")
602 (and:SI (match_operand:SI 1 "register_operand" "")
603 (match_operand:SI 2 "nds32_reg_constant_operand" "")))]
606 if (CONST_INT_P (operands[2])
607 && !nds32_and_operand (operands[2], SImode))
609 nds32_expand_constant (SImode, INTVAL (operands[2]),
610 operands[0], operands[1]);
615 (define_insn "*andsi3"
616 [(set (match_operand:SI 0 "register_operand" "=l, r, l, l, l, l, l, l, r, r, r, r, r")
617 (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r")
618 (match_operand:SI 2 "nds32_and_operand" " l, r,Izeb,Izeh,Ixls,Ix11,Ibms,Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
621 HOST_WIDE_INT mask = INTVAL (operands[2]);
623 /* 16-bit andi instructions:
624 andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3
625 andi Rt3,Ra3,0xffff -> zeh33 Rt3,Ra3
626 andi Rt3,Ra3,0x01 -> xlsb33 Rt3,Ra3
627 andi Rt3,Ra3,0x7ff -> x11b33 Rt3,Ra3
628 andi Rt3,Rt3,2^imm3u -> bmski33 Rt3,imm3u
629 andi Rt3,Rt3,(2^(imm3u+1))-1 -> fexti33 Rt3,imm3u. */
631 switch (which_alternative)
634 return "and33\t%0, %2";
636 return "and\t%0, %1, %2";
638 return "zeb33\t%0, %1";
640 return "zeh33\t%0, %1";
642 return "xlsb33\t%0, %1";
644 return "x11b33\t%0, %1";
646 return "bmski33\t%0, %B2";
648 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
649 return "fexti33\t%0, %2";
651 return "zeb\t%0, %1";
653 return "zeh\t%0, %1";
655 return "andi\t%0, %1, %2";
657 operands[2] = GEN_INT (~mask);
658 return "bitci\t%0, %1, %2";
660 return "bclr\t%0, %1, %b2";
666 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
667 (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")
668 (set_attr "feature" "v3m, v1, v1, v1, v1, v1,v3m,v3m, v1, v1, v1, v3,pe1")])
670 (define_insn "*and_slli"
671 [(set (match_operand:SI 0 "register_operand" "= r")
672 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
673 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
674 (match_operand:SI 3 "register_operand" " r")))]
675 "TARGET_ISA_V3 && optimize_size"
676 "and_slli\t%0, %3, %1, %2"
677 [(set_attr "type" "alu_shift")
678 (set_attr "length" "4")])
680 (define_insn "*and_srli"
681 [(set (match_operand:SI 0 "register_operand" "= r")
682 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
683 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
684 (match_operand:SI 3 "register_operand" " r")))]
685 "TARGET_ISA_V3 && optimize_size"
686 "and_srli\t%0, %3, %1, %2"
687 [(set_attr "type" "alu_shift")
688 (set_attr "length" "4")])
691 ;; ----------------------------------------------------------------------------
693 ;; ----------------------------------------------------------------------------
695 ;; For V3/V3M ISA, we have 'or33' instruction.
696 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
698 (define_expand "iorsi3"
699 [(set (match_operand:SI 0 "register_operand" "")
700 (ior:SI (match_operand:SI 1 "register_operand" "")
701 (match_operand:SI 2 "general_operand" "")))]
704 if (!nds32_ior_operand (operands[2], SImode))
705 operands[2] = force_reg (SImode, operands[2]);
708 (define_insn "*iorsi3"
709 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
710 (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
711 (match_operand:SI 2 "nds32_ior_operand" " l, r, Iu15, Ie15")))]
718 [(set_attr "type" "alu,alu,alu,alu")
719 (set_attr "length" " 2, 4, 4, 4")
720 (set_attr "feature" "v3m, v1, v1,pe1")])
722 (define_insn "*or_slli"
723 [(set (match_operand:SI 0 "register_operand" "= r")
724 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
725 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
726 (match_operand:SI 3 "register_operand" " r")))]
727 "TARGET_ISA_V3 && optimize_size"
728 "or_slli\t%0, %3, %1, %2"
729 [(set_attr "type" "alu_shift")
730 (set_attr "length" "4")])
732 (define_insn "*or_srli"
733 [(set (match_operand:SI 0 "register_operand" "= r")
734 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
735 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
736 (match_operand:SI 3 "register_operand" " r")))]
737 "TARGET_ISA_V3 && optimize_size"
738 "or_srli\t%0, %3, %1, %2"
739 [(set_attr "type" "alu_shift")
740 (set_attr "length" "4")])
743 ;; ----------------------------------------------------------------------------
745 ;; ----------------------------------------------------------------------------
747 ;; For V3/V3M ISA, we have 'xor33' instruction.
748 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
750 (define_expand "xorsi3"
751 [(set (match_operand:SI 0 "register_operand" "")
752 (xor:SI (match_operand:SI 1 "register_operand" "")
753 (match_operand:SI 2 "general_operand" "")))]
756 if (!nds32_xor_operand (operands[2], SImode))
757 operands[2] = force_reg (SImode, operands[2]);
760 (define_insn "*xorsi3"
761 [(set (match_operand:SI 0 "register_operand" "=l, r, r, r")
762 (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
763 (match_operand:SI 2 "nds32_xor_operand" " l, r, Iu15, It15")))]
770 [(set_attr "type" "alu,alu,alu,alu")
771 (set_attr "length" " 2, 4, 4, 4")
772 (set_attr "feature" "v3m, v1, v1,pe1")])
774 (define_insn "*xor_slli"
775 [(set (match_operand:SI 0 "register_operand" "= r")
776 (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
777 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
778 (match_operand:SI 3 "register_operand" " r")))]
779 "TARGET_ISA_V3 && optimize_size"
780 "xor_slli\t%0, %3, %1, %2"
781 [(set_attr "type" "alu_shift")
782 (set_attr "length" "4")])
784 (define_insn "*xor_srli"
785 [(set (match_operand:SI 0 "register_operand" "= r")
786 (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
787 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05"))
788 (match_operand:SI 3 "register_operand" " r")))]
789 "TARGET_ISA_V3 && optimize_size"
790 "xor_srli\t%0, %3, %1, %2"
791 [(set_attr "type" "alu_shift")
792 (set_attr "length" "4")])
794 ;; Rotate Right Instructions.
796 (define_insn "*rotrsi3"
797 [(set (match_operand:SI 0 "register_operand" "= r, r")
798 (rotatert:SI (match_operand:SI 1 "register_operand" " r, r")
799 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, r")))]
804 [(set_attr "type" " alu, alu")
805 (set_attr "subtype" "shift,shift")
806 (set_attr "length" " 4, 4")])
809 ;; ----------------------------------------------------------------------------
811 ;; ----------------------------------------------------------------------------
813 ;; For V3/V3M ISA, we have 'neg33' instruction.
814 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
815 ;; And for V2 ISA, there is NO 'neg33' instruction.
816 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
817 (define_insn "negsi2"
818 [(set (match_operand:SI 0 "register_operand" "=l, r")
819 (neg:SI (match_operand:SI 1 "register_operand" " l, r")))]
824 [(set_attr "type" "alu,alu")
825 (set_attr "length" " 2, 4")
826 (set_attr "feature" "v3m, v1")])
828 (define_expand "negsf2"
829 [(set (match_operand:SF 0 "register_operand" "")
830 (neg:SF (match_operand:SF 1 "register_operand" "")))]
833 if (!TARGET_FPU_SINGLE && !TARGET_EXT_PERF)
835 rtx new_dst = simplify_gen_subreg (SImode, operands[0], SFmode, 0);
836 rtx new_src = simplify_gen_subreg (SImode, operands[1], SFmode, 0);
838 emit_insn (gen_xorsi3 (new_dst,
840 gen_int_mode (0x80000000, SImode)));
846 (define_expand "negdf2"
847 [(set (match_operand:DF 0 "register_operand" "")
848 (neg:DF (match_operand:DF 1 "register_operand" "")))]
853 (define_insn_and_split "soft_negdf2"
854 [(set (match_operand:DF 0 "register_operand" "")
855 (neg:DF (match_operand:DF 1 "register_operand" "")))]
861 rtx src = operands[1];
862 rtx dst = operands[0];
863 rtx ori_dst = operands[0];
865 bool need_extra_move_for_dst_p;
866 /* FPU register can't change mode to SI directly, so we need create a
867 tmp register to handle it, and FPU register can't do `xor` or btgl. */
868 if (HARD_REGISTER_P (src)
869 && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (src)))
871 rtx tmp = gen_reg_rtx (DFmode);
872 emit_move_insn (tmp, src);
876 if (HARD_REGISTER_P (dst)
877 && TEST_HARD_REG_BIT (reg_class_contents[FP_REGS], REGNO (dst)))
879 need_extra_move_for_dst_p = true;
880 rtx tmp = gen_reg_rtx (DFmode);
884 rtx dst_high_part = simplify_gen_subreg (
886 DFmode, subreg_highpart_offset (SImode, DFmode));
887 rtx dst_low_part = simplify_gen_subreg (
889 DFmode, subreg_lowpart_offset (SImode, DFmode));
890 rtx src_high_part = simplify_gen_subreg (
892 DFmode, subreg_highpart_offset (SImode, DFmode));
893 rtx src_low_part = simplify_gen_subreg (
895 DFmode, subreg_lowpart_offset (SImode, DFmode));
897 emit_insn (gen_xorsi3 (dst_high_part,
899 gen_int_mode (0x80000000, SImode)));
900 emit_move_insn (dst_low_part, src_low_part);
902 if (need_extra_move_for_dst_p)
903 emit_move_insn (ori_dst, dst);
909 ;; ----------------------------------------------------------------------------
910 ;; 'ONE_COMPLIMENT' operation
911 ;; ----------------------------------------------------------------------------
913 ;; For V3/V3M ISA, we have 'not33' instruction.
914 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
915 (define_insn "one_cmplsi2"
916 [(set (match_operand:SI 0 "register_operand" "=w, r")
917 (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
922 [(set_attr "type" "alu,alu")
923 (set_attr "length" " 2, 4")
924 (set_attr "feature" "v3m, v1")])
927 ;; ----------------------------------------------------------------------------
929 ;; Shift instructions.
931 (define_expand "<shift>si3"
932 [(set (match_operand:SI 0 "register_operand" "")
933 (shift_rotate:SI (match_operand:SI 1 "register_operand" "")
934 (match_operand:SI 2 "nds32_rimm5u_operand" "")))]
937 if (operands[2] == const0_rtx)
939 emit_move_insn (operands[0], operands[1]);
944 (define_insn "*ashlsi3"
945 [(set (match_operand:SI 0 "register_operand" "= l, r, r")
946 (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r")
947 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu03, Iu05, r")))]
953 [(set_attr "type" " alu, alu, alu")
954 (set_attr "subtype" "shift,shift,shift")
955 (set_attr "length" " 2, 4, 4")])
957 (define_insn "*ashrsi3"
958 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
959 (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
960 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
966 [(set_attr "type" " alu, alu, alu")
967 (set_attr "subtype" "shift,shift,shift")
968 (set_attr "length" " 2, 4, 4")])
970 (define_insn "*lshrsi3"
971 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
972 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
973 (match_operand:SI 2 "nds32_rimm5u_operand" " Iu05, Iu05, r")))]
979 [(set_attr "type" " alu, alu, alu")
980 (set_attr "subtype" "shift,shift,shift")
981 (set_attr "length" " 2, 4, 4")])
984 ;; ----------------------------------------------------------------------------
986 ;; ----------------------------------------------------------------------------
987 ;; Conditional Move patterns
988 ;; ----------------------------------------------------------------------------
990 (define_expand "mov<mode>cc"
991 [(set (match_operand:QIHISI 0 "register_operand" "")
992 (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
993 (match_operand:QIHISI 2 "register_operand" "")
994 (match_operand:QIHISI 3 "register_operand" "")))]
995 "TARGET_CMOV && !optimize_size"
997 enum nds32_expand_result_type result = nds32_expand_movcc (operands);
1006 case EXPAND_CREATE_TEMPLATE:
1013 (define_insn "cmovz<mode>"
1014 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
1015 (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
1017 (match_operand:QIHISI 2 "register_operand" " r, 0")
1018 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
1023 [(set_attr "type" "alu")
1024 (set_attr "length" "4")])
1026 (define_insn "cmovn<mode>"
1027 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
1028 (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
1030 (match_operand:QIHISI 2 "register_operand" " r, 0")
1031 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
1036 [(set_attr "type" "alu")
1037 (set_attr "length" "4")])
1039 ;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
1040 ;; It should be removed once after we change the expansion form of the cmovn.
1041 (define_insn "*cmovn_simplified_<mode>"
1042 [(set (match_operand:QIHISI 0 "register_operand" "=r")
1043 (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
1044 (match_operand:QIHISI 2 "register_operand" "r")
1045 (match_operand:QIHISI 3 "register_operand" "0")))]
1048 [(set_attr "type" "alu")])
1050 ;; ----------------------------------------------------------------------------
1051 ;; Conditional Branch patterns
1052 ;; ----------------------------------------------------------------------------
1054 (define_expand "cbranchsi4"
1056 (if_then_else (match_operator 0 "comparison_operator"
1057 [(match_operand:SI 1 "register_operand" "")
1058 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
1059 (label_ref (match_operand 3 "" ""))
1063 enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
1072 case EXPAND_CREATE_TEMPLATE:
1080 (define_insn "cbranchsi4_equality_zero"
1082 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1083 [(match_operand:SI 1 "register_operand" "t,l, r")
1085 (label_ref (match_operand 2 "" ""))
1089 return nds32_output_cbranchsi4_equality_zero (insn, operands);
1091 [(set_attr "type" "branch")
1092 (set_attr_alternative "enabled"
1095 (if_then_else (match_test "TARGET_16_BIT")
1096 (const_string "yes")
1097 (const_string "no"))
1099 (if_then_else (match_test "TARGET_16_BIT")
1100 (const_string "yes")
1101 (const_string "no"))
1103 (const_string "yes")
1105 (set_attr_alternative "length"
1108 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1109 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1110 (le (minus (match_dup 2) (pc)) (const_int 250)))
1111 (if_then_else (match_test "TARGET_16_BIT")
1114 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1115 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1117 (if_then_else (match_test "TARGET_16_BIT")
1122 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1123 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1124 (le (minus (match_dup 2) (pc)) (const_int 250)))
1125 (if_then_else (match_test "TARGET_16_BIT")
1128 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1129 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1131 (if_then_else (match_test "TARGET_16_BIT")
1136 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1137 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1138 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1145 ;; This pattern is dedicated to V2 ISA,
1146 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
1147 (define_insn "cbranchsi4_equality_reg"
1149 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1150 [(match_operand:SI 1 "register_operand" "v, r")
1151 (match_operand:SI 2 "register_operand" "l, r")])
1152 (label_ref (match_operand 3 "" ""))
1156 return nds32_output_cbranchsi4_equality_reg (insn, operands);
1158 [(set_attr "type" "branch")
1159 (set_attr_alternative "enabled"
1162 (if_then_else (match_test "TARGET_16_BIT")
1163 (const_string "yes")
1164 (const_string "no"))
1166 (const_string "yes")
1168 (set_attr_alternative "length"
1171 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1172 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1173 (le (minus (match_dup 3) (pc)) (const_int 250)))
1175 (if_then_else (and (ge (minus (match_dup 3) (pc))
1177 (le (minus (match_dup 3) (pc))
1183 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1184 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1185 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1192 ;; This pattern is dedicated to V3/V3M,
1193 ;; because V3/V3M DO HAVE beqc/bnec instruction.
1194 (define_insn "cbranchsi4_equality_reg_or_const_int"
1196 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1197 [(match_operand:SI 1 "register_operand" "v, r, r")
1198 (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
1199 (label_ref (match_operand 3 "" ""))
1201 "TARGET_ISA_V3 || TARGET_ISA_V3M"
1203 return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
1205 [(set_attr "type" "branch")
1206 (set_attr_alternative "enabled"
1209 (if_then_else (match_test "TARGET_16_BIT")
1210 (const_string "yes")
1211 (const_string "no"))
1213 (const_string "yes")
1215 (const_string "yes")
1217 (set_attr_alternative "length"
1220 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1221 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1222 (le (minus (match_dup 3) (pc)) (const_int 250)))
1224 (if_then_else (and (ge (minus (match_dup 3) (pc))
1226 (le (minus (match_dup 3) (pc))
1232 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1233 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1234 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1239 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1240 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1241 (le (minus (match_dup 3) (pc)) (const_int 250)))
1248 (define_insn "*cbranchsi4_greater_less_zero"
1250 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1251 [(match_operand:SI 1 "register_operand" "r")
1253 (label_ref (match_operand 2 "" ""))
1257 return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
1259 [(set_attr "type" "branch")
1260 (set (attr "length")
1261 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1262 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1263 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1269 (define_expand "cstoresi4"
1270 [(set (match_operand:SI 0 "register_operand" "")
1271 (match_operator:SI 1 "comparison_operator"
1272 [(match_operand:SI 2 "register_operand" "")
1273 (match_operand:SI 3 "nonmemory_operand" "")]))]
1276 enum nds32_expand_result_type result = nds32_expand_cstore (operands);
1285 case EXPAND_CREATE_TEMPLATE:
1293 (define_expand "slts_compare"
1294 [(set (match_operand:SI 0 "register_operand" "")
1295 (lt:SI (match_operand:SI 1 "general_operand" "")
1296 (match_operand:SI 2 "general_operand" "")))]
1299 if (!REG_P (operands[1]))
1300 operands[1] = force_reg (SImode, operands[1]);
1302 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1303 operands[2] = force_reg (SImode, operands[2]);
1306 (define_insn "slts_compare_impl"
1307 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1308 (lt:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1309 (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
1316 [(set_attr "type" "alu, alu, alu, alu")
1317 (set_attr "length" " 2, 2, 4, 4")])
1319 (define_insn "slt_eq0"
1320 [(set (match_operand:SI 0 "register_operand" "=t, r")
1321 (eq:SI (match_operand:SI 1 "register_operand" " d, r")
1327 [(set_attr "type" "alu, alu")
1328 (set_attr "length" " 2, 4")])
1330 (define_expand "slt_compare"
1331 [(set (match_operand:SI 0 "register_operand" "")
1332 (ltu:SI (match_operand:SI 1 "general_operand" "")
1333 (match_operand:SI 2 "general_operand" "")))]
1336 if (!REG_P (operands[1]))
1337 operands[1] = force_reg (SImode, operands[1]);
1339 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1340 operands[2] = force_reg (SImode, operands[2]);
1343 (define_insn "slt_compare_impl"
1344 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1345 (ltu:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1346 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
1353 [(set_attr "type" "alu, alu, alu, alu")
1354 (set_attr "length" " 2, 2, 4, 4")])
1357 ;; ----------------------------------------------------------------------------
1359 ;; Unconditional and other jump instructions.
1362 [(set (pc) (label_ref (match_operand 0 "" "")))]
1365 /* This unconditional jump has two forms:
1366 32-bit instruction => j imm24s << 1
1367 16-bit instruction => j8 imm8s << 1
1370 we assume it is always reachable.
1372 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1373 However, since the $pc for nds32 is at the beginning of the instruction,
1374 we should leave some length space for current insn.
1375 So we use range -250 ~ 250. */
1376 switch (get_attr_length (insn))
1386 [(set_attr "type" "branch")
1387 (set_attr "enabled" "yes")
1388 (set (attr "length")
1389 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1390 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1391 (le (minus (match_dup 0) (pc)) (const_int 250)))
1392 (if_then_else (match_test "TARGET_16_BIT")
1398 (define_insn "indirect_jump"
1399 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1404 [(set_attr "type" "branch,branch")
1405 (set_attr "length" " 2, 4")])
1407 ;; Subroutine call instruction returning no value.
1408 ;; operands[0]: It should be a mem RTX whose address is
1409 ;; the address of the function.
1410 ;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
1411 ;; operands[2]: It is the number of registers used as operands.
1413 (define_expand "call"
1414 [(parallel [(call (match_operand 0 "memory_operand" "")
1416 (clobber (reg:SI LP_REGNUM))
1417 (clobber (reg:SI TA_REGNUM))])]
1422 (define_insn "call_internal"
1423 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
1425 (clobber (reg:SI LP_REGNUM))
1426 (clobber (reg:SI TA_REGNUM))])]
1429 switch (which_alternative)
1437 return nds32_output_call (insn, operands, operands[0],
1438 "bal\t%0", "jal\t%0", false);
1443 [(set_attr "enabled" "yes")
1444 (set_attr "type" "branch")
1445 (set_attr_alternative "length"
1448 (if_then_else (match_test "TARGET_16_BIT")
1452 (if_then_else (match_test "nds32_long_call_p (operands[0])")
1458 ;; Subroutine call instruction returning a value.
1459 ;; operands[0]: It is the hard regiser in which the value is returned.
1460 ;; The rest three operands are the same as the
1461 ;; three operands of the 'call' instruction.
1462 ;; (but with numbers increased by one)
1464 (define_expand "call_value"
1465 [(parallel [(set (match_operand 0)
1466 (call (match_operand 1 "memory_operand" "")
1468 (clobber (reg:SI LP_REGNUM))
1469 (clobber (reg:SI TA_REGNUM))])]
1472 (define_insn "call_value_internal"
1473 [(parallel [(set (match_operand 0)
1474 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
1476 (clobber (reg:SI LP_REGNUM))
1477 (clobber (reg:SI TA_REGNUM))])]
1480 switch (which_alternative)
1488 return nds32_output_call (insn, operands, operands[1],
1489 "bal\t%1", "jal\t%1", false);
1494 [(set_attr "enabled" "yes")
1495 (set_attr "type" "branch")
1496 (set_attr_alternative "length"
1499 (if_then_else (match_test "TARGET_16_BIT")
1503 (if_then_else (match_test "nds32_long_call_p (operands[1])")
1509 ;; Call subroutine returning any type.
1511 (define_expand "untyped_call"
1512 [(parallel [(call (match_operand 0 "" "")
1514 (match_operand 1 "" "")
1515 (match_operand 2 "" "")])]
1520 emit_call_insn (gen_call (operands[0], const0_rtx));
1522 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1524 rtx set = XVECEXP (operands[2], 0, i);
1525 emit_move_insn (SET_DEST (set), SET_SRC (set));
1528 /* The optimizer does not know that the call sets the function value
1529 registers we stored in the result block. We avoid problems by
1530 claiming that all hard registers are used and clobbered at this
1532 emit_insn (gen_blockage ());
1536 ;; ----------------------------------------------------------------------------
1538 ;; The sibcall patterns.
1543 (define_expand "sibcall"
1544 [(parallel [(call (match_operand 0 "memory_operand" "")
1546 (clobber (reg:SI TA_REGNUM))
1550 (define_insn "sibcall_internal"
1551 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
1553 (clobber (reg:SI TA_REGNUM))
1557 switch (which_alternative)
1565 if (nds32_long_call_p (operands[0]))
1573 [(set_attr "enabled" "yes")
1574 (set_attr "type" "branch")
1575 (set_attr_alternative "length"
1578 (if_then_else (match_test "TARGET_16_BIT")
1582 (if_then_else (match_test "nds32_long_call_p (operands[0])")
1589 ;; sibcall_value_internal
1590 ;; sibcall_value_immediate
1592 (define_expand "sibcall_value"
1593 [(parallel [(set (match_operand 0)
1594 (call (match_operand 1 "memory_operand" "")
1596 (clobber (reg:SI TA_REGNUM))
1600 (define_insn "sibcall_value_internal"
1601 [(parallel [(set (match_operand 0)
1602 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
1604 (clobber (reg:SI TA_REGNUM))
1608 switch (which_alternative)
1616 if (nds32_long_call_p (operands[1]))
1624 [(set_attr "enabled" "yes")
1625 (set_attr "type" "branch")
1626 (set_attr_alternative "length"
1629 (if_then_else (match_test "TARGET_16_BIT")
1633 (if_then_else (match_test "nds32_long_call_p (operands[1])")
1639 ;; ----------------------------------------------------------------------------
1641 ;; prologue and epilogue.
1643 (define_expand "prologue" [(const_int 0)]
1646 /* Note that only under V3/V3M ISA, we could use v3push prologue.
1647 In addition, we need to check if v3push is indeed available. */
1648 if (NDS32_V3PUSH_AVAILABLE_P)
1649 nds32_expand_prologue_v3push ();
1651 nds32_expand_prologue ();
1655 (define_expand "epilogue" [(const_int 0)]
1658 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
1659 In addition, we need to check if v3push is indeed available. */
1660 if (NDS32_V3PUSH_AVAILABLE_P)
1661 nds32_expand_epilogue_v3pop (false);
1663 nds32_expand_epilogue (false);
1667 (define_expand "sibcall_epilogue" [(const_int 0)]
1670 /* Pass true to indicate that this is sibcall epilogue and
1671 exit from a function without the final branch back to the
1672 calling function. */
1673 nds32_expand_epilogue (true);
1690 [(set_attr "type" "misc")
1691 (set_attr "enabled" "yes")
1692 (set (attr "length")
1693 (if_then_else (match_test "TARGET_16_BIT")
1698 ;; ----------------------------------------------------------------------------
1699 ;; Stack push/pop operations
1700 ;; ----------------------------------------------------------------------------
1702 ;; The pattern for stack push.
1703 ;; Both stack_push_multiple and stack_v3push use the following pattern.
1704 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1705 (define_insn "*stack_push"
1706 [(match_parallel 0 "nds32_stack_push_operation"
1707 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1708 (match_operand:SI 1 "const_int_operand" "")))
1709 (match_operand:SI 2 "register_operand" ""))
1713 return nds32_output_stack_push (operands[0]);
1715 [(set_attr "type" "store_multiple")
1716 (set_attr "combo" "12")
1717 (set_attr "enabled" "yes")
1718 (set (attr "length")
1719 (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1724 ;; The pattern for stack pop.
1725 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1726 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
1727 (define_insn "*stack_pop"
1728 [(match_parallel 0 "nds32_stack_pop_operation"
1729 [(set (match_operand:SI 1 "register_operand" "")
1730 (mem:SI (reg:SI SP_REGNUM)))
1734 return nds32_output_stack_pop (operands[0]);
1736 [(set_attr "type" "load_multiple")
1737 (set_attr "combo" "12")
1738 (set_attr "enabled" "yes")
1739 (set (attr "length")
1740 (if_then_else (match_test "NDS32_V3PUSH_AVAILABLE_P")
1745 ;; ----------------------------------------------------------------------------
1746 ;; Return operation patterns
1747 ;; ----------------------------------------------------------------------------
1749 ;; Use this pattern to expand a return instruction
1750 ;; with simple_return rtx if no epilogue is required.
1751 (define_expand "return"
1752 [(parallel [(return)
1753 (clobber (reg:SI FP_REGNUM))])]
1754 "nds32_can_use_return_insn ()"
1756 /* Emit as the simple return. */
1757 if (cfun->machine->naked_p
1758 && (cfun->machine->va_args_size == 0))
1760 emit_jump_insn (gen_return_internal ());
1765 ;; This pattern is expanded only by the shrink-wrapping optimization
1766 ;; on paths where the function prologue has not been executed.
1767 (define_expand "simple_return"
1773 (define_insn "*nds32_return"
1774 [(parallel [(return)
1775 (clobber (reg:SI FP_REGNUM))])]
1778 return nds32_output_return ();
1780 [(set_attr "type" "branch")
1781 (set_attr "enabled" "yes")
1782 (set_attr "length" "4")])
1784 (define_insn "return_internal"
1793 [(set_attr "type" "branch")
1794 (set_attr "enabled" "yes")
1795 (set (attr "length")
1796 (if_then_else (match_test "TARGET_16_BIT")
1801 ;; ----------------------------------------------------------------------------
1802 ;; Jump Table patterns
1803 ;; ----------------------------------------------------------------------------
1804 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
1805 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
1807 ;; operands[0]: The index to dispatch on.
1808 ;; operands[1]: The lower bound for indices in the table.
1809 ;; operands[2]: The total range of indices int the table.
1810 ;; i.e. The largest index minus the smallest one.
1811 ;; operands[3]: A label that precedes the table itself.
1812 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
1814 ;; We need to create following sequences for jump table code generation:
1815 ;; A) k <-- (plus (operands[0]) (-operands[1]))
1816 ;; B) if (gtu k operands[2]) then goto operands[4]
1817 ;; C) t <-- operands[3]
1818 ;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
1819 ;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
1820 ;; F) jump to target with register t or z
1822 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
1823 (define_expand "casesi"
1824 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
1825 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
1826 (match_operand:SI 2 "immediate_operand" "i") ; total range
1827 (match_operand:SI 3 "" "") ; table label
1828 (match_operand:SI 4 "" "")] ; Out of range label
1834 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
1835 if (operands[1] != const0_rtx)
1837 reg = gen_reg_rtx (SImode);
1838 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
1840 /* If the integer value is not in the range of imm15s,
1841 we need to force register first because our addsi3 pattern
1842 only accept nds32_rimm15s_operand predicate. */
1843 add_tmp = force_reg (SImode, add_tmp);
1845 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
1849 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
1850 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
1851 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
1854 /* Step C, D, E, and F, using another temporary register. */
1855 rtx tmp = gen_reg_rtx (SImode);
1856 emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
1860 ;; We are receiving operands from casesi pattern:
1862 ;; operands[0]: The index that have been substracted with lower bound.
1863 ;; operands[1]: A label that precedes the table itself.
1864 ;; operands[2]: A temporary register to retrieve value in table.
1866 ;; We need to perform steps C, D, E, and F:
1868 ;; C) t <-- operands[1]
1869 ;; D) z <-- (mem (plus (operands[0] << m) t))
1870 ;; m is 2 for normal jump table.
1871 ;; m is 0, 1, or 2 for pc relative jump table based on diff size.
1872 ;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
1873 ;; F) Jump to target with register t or z.
1875 ;; The USE in this pattern is needed to tell flow analysis that this is
1876 ;; a CASESI insn. It has no other purpose.
1877 (define_insn "casesi_internal"
1878 [(parallel [(set (pc)
1879 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1881 (label_ref (match_operand 1 "" "")))))
1882 (use (label_ref (match_dup 1)))
1883 (clobber (match_operand:SI 2 "register_operand" "=r"))
1884 (clobber (reg:SI TA_REGNUM))])]
1887 if (CASE_VECTOR_PC_RELATIVE)
1888 return nds32_output_casesi_pc_relative (operands);
1890 return nds32_output_casesi (operands);
1892 [(set_attr "length" "20")
1893 (set_attr "type" "branch")])
1895 ;; ----------------------------------------------------------------------------
1897 ;; Performance Extension
1899 (define_insn "clzsi2"
1900 [(set (match_operand:SI 0 "register_operand" "=r")
1901 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
1904 [(set_attr "type" "alu")
1905 (set_attr "length" "4")])
1907 (define_insn "smaxsi3"
1908 [(set (match_operand:SI 0 "register_operand" "=r")
1909 (smax:SI (match_operand:SI 1 "register_operand" " r")
1910 (match_operand:SI 2 "register_operand" " r")))]
1913 [(set_attr "type" "alu")
1914 (set_attr "length" "4")])
1916 (define_insn "sminsi3"
1917 [(set (match_operand:SI 0 "register_operand" "=r")
1918 (smin:SI (match_operand:SI 1 "register_operand" " r")
1919 (match_operand:SI 2 "register_operand" " r")))]
1922 [(set_attr "type" "alu")
1923 (set_attr "length" "4")])
1926 [(set (match_operand:SI 0 "register_operand" "= r")
1927 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
1929 (match_operand:SI 2 "nds32_imm5u_operand" " Iu05")))]
1932 [(set_attr "type" "alu")
1933 (set_attr "length" "4")])
1936 [(set (match_operand:SI 0 "register_operand" "=r")
1941 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1942 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
1947 [(set_attr "type" "alu")
1948 (set_attr "length" "4")])
1950 ;; ----------------------------------------------------------------------------
1954 (define_insn "relax_group"
1955 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
1958 [(set_attr "length" "0")]
1961 (define_insn "pop25return"
1963 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
1965 "! return for pop 25"
1966 [(set_attr "length" "0")]
1969 ;; ----------------------------------------------------------------------------