1 ;; Machine description of Andes NDS32 cpu for GNU compiler
2 ;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
3 ;; Contributed by Andes Technology Corporation.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 ;; Include predicates definition.
24 (include "predicates.md")
26 ;; Include constraints definition.
27 (include "constraints.md")
29 ;; Include iterators definition.
30 (include "iterators.md")
32 ;; Include pipelines definition.
33 (include "pipelines.md")
36 ;; Include constants definition.
37 (include "constants.md")
40 ;; Include intrinsic functions definition.
41 (include "nds32-intrinsic.md")
43 ;; Include block move for nds32 multiple load/store behavior.
44 (include "nds32-multiple.md")
46 ;; Include DImode/DFmode operations.
47 (include "nds32-doubleword.md")
49 ;; Include peephole patterns.
50 (include "nds32-peephole2.md")
53 ;; Insn type, it is used to default other attribute values.
55 "unknown,move,load,store,alu,compare,branch,call,misc"
56 (const_string "unknown"))
59 ;; Length, in bytes, default is 4-bytes.
60 (define_attr "length" "" (const_int 4))
63 ;; Enabled, which is used to enable/disable insn alternatives.
64 ;; Note that we use length and TARGET_16_BIT here as criteria.
65 ;; If the instruction pattern already check TARGET_16_BIT to
66 ;; determine the length by itself, its enabled attribute should be
67 ;; always 1 to avoid the conflict with the settings here.
68 (define_attr "enabled" ""
69 (cond [(and (eq_attr "length" "2")
70 (match_test "!TARGET_16_BIT"))
75 ;; ----------------------------------------------------------------------------
80 ;; For QImode and HImode, the immediate value can be fit in imm20s.
81 ;; So there is no need to split rtx for QI and HI patterns.
83 (define_expand "movqi"
84 [(set (match_operand:QI 0 "general_operand" "")
85 (match_operand:QI 1 "general_operand" ""))]
88 /* Need to force register if mem <- !reg. */
89 if (MEM_P (operands[0]) && !REG_P (operands[1]))
90 operands[1] = force_reg (QImode, operands[1]);
93 (define_expand "movhi"
94 [(set (match_operand:HI 0 "general_operand" "")
95 (match_operand:HI 1 "general_operand" ""))]
98 /* Need to force register if mem <- !reg. */
99 if (MEM_P (operands[0]) && !REG_P (operands[1]))
100 operands[1] = force_reg (HImode, operands[1]);
103 (define_expand "movsi"
104 [(set (match_operand:SI 0 "general_operand" "")
105 (match_operand:SI 1 "general_operand" ""))]
108 /* Need to force register if mem <- !reg. */
109 if (MEM_P (operands[0]) && !REG_P (operands[1]))
110 operands[1] = force_reg (SImode, operands[1]);
112 /* If operands[1] is a large constant and cannot be performed
113 by a single instruction, we need to split it. */
114 if (CONST_INT_P (operands[1])
115 && !satisfies_constraint_Is20 (operands[1])
116 && !satisfies_constraint_Ihig (operands[1]))
119 HOST_WIDE_INT low12_int;
122 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
124 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
125 low12_int = INTVAL (operands[1]) & 0xfff;
127 emit_move_insn (tmp_rtx, high20_rtx);
128 emit_move_insn (operands[0], plus_constant (SImode,
135 (define_insn "*mov<mode>"
136 [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r, U45, U33, U37, U45, m, l, l, l, d, r, d, r, r, r")
137 (match_operand:QIHISI 1 "nds32_move_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45, m, Ip05, Is05, Is20, Ihig"))]
140 switch (which_alternative)
143 return "mov55\t%0, %1";
145 return "ori\t%0, %1, 0";
150 return nds32_output_16bit_store (operands, <byte>);
152 return nds32_output_32bit_store (operands, <byte>);
157 return nds32_output_16bit_load (operands, <byte>);
159 return nds32_output_32bit_load (operands, <byte>);
161 return "movpi45\t%0, %1";
163 return "movi55\t%0, %1";
165 return "movi\t%0, %1";
167 return "sethi\t%0, hi20(%1)";
172 [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,alu,alu,alu,alu")
173 (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 4, 4")])
176 ;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
177 ;; are able to match such instruction template.
178 (define_insn "*move_addr"
179 [(set (match_operand:SI 0 "register_operand" "=l, r")
180 (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
183 [(set_attr "type" "move")
184 (set_attr "length" "8")])
187 (define_insn "*sethi"
188 [(set (match_operand:SI 0 "register_operand" "=r")
189 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
191 "sethi\t%0, hi20(%1)"
192 [(set_attr "type" "alu")
193 (set_attr "length" "4")])
196 (define_insn "*lo_sum"
197 [(set (match_operand:SI 0 "register_operand" "=r")
198 (lo_sum:SI (match_operand:SI 1 "register_operand" " r")
199 (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
201 "ori\t%0, %1, lo12(%2)"
202 [(set_attr "type" "alu")
203 (set_attr "length" "4")])
206 ;; ----------------------------------------------------------------------------
208 ;; Zero extension instructions.
210 (define_insn "zero_extend<mode>si2"
211 [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r")
212 (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))]
215 switch (which_alternative)
218 return "ze<size>33\t%0, %1";
220 return "ze<size>\t%0, %1";
222 return nds32_output_16bit_load (operands, <byte>);
224 return nds32_output_32bit_load (operands, <byte>);
230 [(set_attr "type" "alu,alu,load,load")
231 (set_attr "length" " 2, 4, 2, 4")])
234 ;; Sign extension instructions.
236 (define_insn "extend<mode>si2"
237 [(set (match_operand:SI 0 "register_operand" "=l, r, r")
238 (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
241 switch (which_alternative)
244 return "se<size>33\t%0, %1";
246 return "se<size>\t%0, %1";
248 return nds32_output_32bit_load_s (operands, <byte>);
254 [(set_attr "type" "alu,alu,load")
255 (set_attr "length" " 2, 4, 4")])
258 ;; ----------------------------------------------------------------------------
260 ;; Arithmetic instructions.
262 (define_insn "add<mode>3"
263 [(set (match_operand:QIHISI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
264 (plus:QIHISI (match_operand:QIHISI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
265 (match_operand:QIHISI 2 "nds32_rimm15s_operand" " In05, In03, Iu05, Iu03, r, l, Is10, Iu06, Is15, r")))]
268 switch (which_alternative)
271 /* addi Rt4,Rt4,-x ==> subi45 Rt4,x
272 where 0 <= x <= 31 */
273 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
274 return "subi45\t%0, %2";
276 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
278 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
279 return "subi333\t%0, %1, %2";
281 return "addi45\t%0, %2";
283 return "addi333\t%0, %1, %2";
285 return "add45\t%0, %2";
287 return "add333\t%0, %1, %2";
289 return "addi10.sp\t%2";
291 return "addri36.sp\t%0, %2";
293 return "addi\t%0, %1, %2";
295 return "add\t%0, %1, %2";
301 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
302 (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")])
304 (define_insn "sub<mode>3"
305 [(set (match_operand:QIHISI 0 "register_operand" "=d, l, r, r")
306 (minus:QIHISI (match_operand:QIHISI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
307 (match_operand:QIHISI 2 "register_operand" " r, l, r, r")))]
314 [(set_attr "type" "alu,alu,alu,alu")
315 (set_attr "length" " 2, 2, 4, 4")])
318 ;; GCC intends to simplify (plus (ashift ...) (reg))
319 ;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
320 ;; and needs to ensure it is exact_log2 value.
321 (define_insn "*add_slli"
322 [(set (match_operand:SI 0 "register_operand" "=r")
323 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
324 (match_operand:SI 2 "immediate_operand" " i"))
325 (match_operand:SI 3 "register_operand" " r")))]
327 && (exact_log2 (INTVAL (operands[2])) != -1)
328 && (exact_log2 (INTVAL (operands[2])) <= 31)"
330 /* Get floor_log2 of the immediate value
331 so that we can generate 'add_slli' instruction. */
332 operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
334 return "add_slli\t%0, %3, %1, %2";
336 [(set_attr "type" "alu")
337 (set_attr "length" "4")])
339 (define_insn "*add_srli"
340 [(set (match_operand:SI 0 "register_operand" "= r")
341 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
342 (match_operand:SI 2 "immediate_operand" " Iu05"))
343 (match_operand:SI 3 "register_operand" " r")))]
345 "add_srli\t%0, %3, %1, %2"
346 [(set_attr "type" "alu")
347 (set_attr "length" "4")])
350 ;; GCC intends to simplify (minus (reg) (ashift ...))
351 ;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
352 ;; and needs to ensure it is exact_log2 value.
353 (define_insn "*sub_slli"
354 [(set (match_operand:SI 0 "register_operand" "=r")
355 (minus:SI (match_operand:SI 1 "register_operand" " r")
356 (mult:SI (match_operand:SI 2 "register_operand" " r")
357 (match_operand:SI 3 "immediate_operand" " i"))))]
359 && (exact_log2 (INTVAL (operands[3])) != -1)
360 && (exact_log2 (INTVAL (operands[3])) <= 31)"
362 /* Get floor_log2 of the immediate value
363 so that we can generate 'sub_slli' instruction. */
364 operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
366 return "sub_slli\t%0, %1, %2, %3";
368 [(set_attr "type" "alu")
369 (set_attr "length" "4")])
371 (define_insn "*sub_srli"
372 [(set (match_operand:SI 0 "register_operand" "= r")
373 (minus:SI (match_operand:SI 1 "register_operand" " r")
374 (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
375 (match_operand:SI 3 "immediate_operand" " Iu05"))))]
377 "sub_srli\t%0, %1, %2, %3"
378 [(set_attr "type" "alu")
379 (set_attr "length" "4")])
382 ;; Multiplication instructions.
384 (define_insn "mulsi3"
385 [(set (match_operand:SI 0 "register_operand" "=w, r")
386 (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
387 (match_operand:SI 2 "register_operand" " w, r")))]
392 [(set_attr "type" "alu,alu")
393 (set_attr "length" " 2, 4")])
395 (define_insn "mulsidi3"
396 [(set (match_operand:DI 0 "register_operand" "=r")
397 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
398 (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
399 "TARGET_ISA_V2 || TARGET_ISA_V3"
400 "mulsr64\t%0, %1, %2"
401 [(set_attr "type" "alu")
402 (set_attr "length" "4")])
404 (define_insn "umulsidi3"
405 [(set (match_operand:DI 0 "register_operand" "=r")
406 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
407 (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
408 "TARGET_ISA_V2 || TARGET_ISA_V3"
410 [(set_attr "type" "alu")
411 (set_attr "length" "4")])
414 ;; Multiply-accumulate instructions.
416 (define_insn "*maddr32_0"
417 [(set (match_operand:SI 0 "register_operand" "=r")
418 (plus:SI (match_operand:SI 3 "register_operand" " 0")
419 (mult:SI (match_operand:SI 1 "register_operand" " r")
420 (match_operand:SI 2 "register_operand" " r"))))]
422 "maddr32\t%0, %1, %2"
423 [(set_attr "type" "alu")
424 (set_attr "length" "4")])
426 (define_insn "*maddr32_1"
427 [(set (match_operand:SI 0 "register_operand" "=r")
428 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
429 (match_operand:SI 2 "register_operand" " r"))
430 (match_operand:SI 3 "register_operand" " 0")))]
432 "maddr32\t%0, %1, %2"
433 [(set_attr "type" "alu")
434 (set_attr "length" "4")])
436 (define_insn "*msubr32"
437 [(set (match_operand:SI 0 "register_operand" "=r")
438 (minus:SI (match_operand:SI 3 "register_operand" " 0")
439 (mult:SI (match_operand:SI 1 "register_operand" " r")
440 (match_operand:SI 2 "register_operand" " r"))))]
442 "msubr32\t%0, %1, %2"
443 [(set_attr "type" "alu")
444 (set_attr "length" "4")])
449 (define_insn "divmodsi4"
450 [(set (match_operand:SI 0 "register_operand" "=r")
451 (div:SI (match_operand:SI 1 "register_operand" " r")
452 (match_operand:SI 2 "register_operand" " r")))
453 (set (match_operand:SI 3 "register_operand" "=r")
454 (mod:SI (match_dup 1) (match_dup 2)))]
456 "divsr\t%0, %3, %1, %2"
457 [(set_attr "type" "alu")
458 (set_attr "length" "4")])
460 (define_insn "udivmodsi4"
461 [(set (match_operand:SI 0 "register_operand" "=r")
462 (udiv:SI (match_operand:SI 1 "register_operand" " r")
463 (match_operand:SI 2 "register_operand" " r")))
464 (set (match_operand:SI 3 "register_operand" "=r")
465 (umod:SI (match_dup 1) (match_dup 2)))]
467 "divr\t%0, %3, %1, %2"
468 [(set_attr "type" "alu")
469 (set_attr "length" "4")])
472 ;; ----------------------------------------------------------------------------
474 ;; Boolean instructions.
475 ;; Note: We define the DImode versions in nds32-doubleword.md.
477 ;; ----------------------------------------------------------------------------
479 ;; ----------------------------------------------------------------------------
482 [(set (match_operand:SI 0 "register_operand" "=r")
483 (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
484 (match_operand:SI 2 "register_operand" " r")))]
487 [(set_attr "type" "alu")
488 (set_attr "length" "4")]
491 (define_insn "andsi3"
492 [(set (match_operand:SI 0 "register_operand" "=w, r, l, l, l, l, l, l, r, r, r, r, r")
493 (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r")
494 (match_operand:SI 2 "general_operand" " w, r, Izeb, Izeh, Ixls, Ix11, Ibms, Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
497 HOST_WIDE_INT mask = INTVAL (operands[2]);
500 /* 16-bit andi instructions:
501 andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3
502 andi Rt3,Ra3,0xffff -> zeh33 Rt3,Ra3
503 andi Rt3,Ra3,0x01 -> xlsb33 Rt3,Ra3
504 andi Rt3,Ra3,0x7ff -> x11b33 Rt3,Ra3
505 andi Rt3,Rt3,2^imm3u -> bmski33 Rt3,imm3u
506 andi Rt3,Rt3,(2^(imm3u+1))-1 -> fexti33 Rt3,imm3u. */
508 switch (which_alternative)
511 return "and33\t%0, %2";
513 return "and\t%0, %1, %2";
515 return "zeb33\t%0, %1";
517 return "zeh33\t%0, %1";
519 return "xlsb33\t%0, %1";
521 return "x11b33\t%0, %1";
523 operands[2] = GEN_INT (floor_log2 (mask));
524 return "bmski33\t%0, %2";
526 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
527 return "fexti33\t%0, %2";
529 return "zeb\t%0, %1";
531 return "zeh\t%0, %1";
533 return "andi\t%0, %1, %2";
535 operands[2] = GEN_INT (~mask);
536 return "bitci\t%0, %1, %2";
538 /* If we reach this alternative,
539 it must pass the nds32_can_use_bclr_p() test,
540 so that we can guarantee there is only one 0-bit
541 within the immediate value. */
542 for (zero_position = 31; zero_position >= 0; zero_position--)
544 if ((INTVAL (operands[2]) & (1 << zero_position)) == 0)
546 /* Found the 0-bit position. */
547 operands[2] = GEN_INT (zero_position);
551 return "bclr\t%0, %1, %2";
557 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
558 (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")])
560 (define_insn "*and_slli"
561 [(set (match_operand:SI 0 "register_operand" "= r")
562 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
563 (match_operand:SI 2 "immediate_operand" " Iu05"))
564 (match_operand:SI 3 "register_operand" " r")))]
566 "and_slli\t%0, %3, %1, %2"
567 [(set_attr "type" "alu")
568 (set_attr "length" "4")])
570 (define_insn "*and_srli"
571 [(set (match_operand:SI 0 "register_operand" "= r")
572 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
573 (match_operand:SI 2 "immediate_operand" " Iu05"))
574 (match_operand:SI 3 "register_operand" " r")))]
576 "and_srli\t%0, %3, %1, %2"
577 [(set_attr "type" "alu")
578 (set_attr "length" "4")])
581 ;; ----------------------------------------------------------------------------
583 ;; ----------------------------------------------------------------------------
585 ;; For V3/V3M ISA, we have 'or33' instruction.
586 ;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
587 (define_insn "iorsi3"
588 [(set (match_operand:SI 0 "register_operand" "=w, r, r, r")
589 (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
590 (match_operand:SI 2 "general_operand" " w, r, Iu15, Ie15")))]
595 switch (which_alternative)
598 return "or33\t%0, %2";
600 return "or\t%0, %1, %2";
602 return "ori\t%0, %1, %2";
604 /* If we reach this alternative,
605 it must pass the nds32_can_use_bset_p() test,
606 so that we can guarantee there is only one 1-bit
607 within the immediate value. */
608 /* Use exact_log2() to search the 1-bit position. */
609 one_position = exact_log2 (INTVAL (operands[2]));
610 operands[2] = GEN_INT (one_position);
611 return "bset\t%0, %1, %2";
617 [(set_attr "type" "alu,alu,alu,alu")
618 (set_attr "length" " 2, 4, 4, 4")])
620 (define_insn "*or_slli"
621 [(set (match_operand:SI 0 "register_operand" "= r")
622 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
623 (match_operand:SI 2 "immediate_operand" " Iu05"))
624 (match_operand:SI 3 "register_operand" " r")))]
626 "or_slli\t%0, %3, %1, %2"
627 [(set_attr "type" "alu")
628 (set_attr "length" "4")])
630 (define_insn "*or_srli"
631 [(set (match_operand:SI 0 "register_operand" "= r")
632 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
633 (match_operand:SI 2 "immediate_operand" " Iu05"))
634 (match_operand:SI 3 "register_operand" " r")))]
636 "or_srli\t%0, %3, %1, %2"
637 [(set_attr "type" "alu")
638 (set_attr "length" "4")])
641 ;; ----------------------------------------------------------------------------
643 ;; ----------------------------------------------------------------------------
645 ;; For V3/V3M ISA, we have 'xor33' instruction.
646 ;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
647 (define_insn "xorsi3"
648 [(set (match_operand:SI 0 "register_operand" "=w, r, r, r")
649 (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
650 (match_operand:SI 2 "general_operand" " w, r, Iu15, It15")))]
655 switch (which_alternative)
658 return "xor33\t%0, %2";
660 return "xor\t%0, %1, %2";
662 return "xori\t%0, %1, %2";
664 /* If we reach this alternative,
665 it must pass the nds32_can_use_btgl_p() test,
666 so that we can guarantee there is only one 1-bit
667 within the immediate value. */
668 /* Use exact_log2() to search the 1-bit position. */
669 one_position = exact_log2 (INTVAL (operands[2]));
670 operands[2] = GEN_INT (one_position);
671 return "btgl\t%0, %1, %2";
677 [(set_attr "type" "alu,alu,alu,alu")
678 (set_attr "length" " 2, 4, 4, 4")])
680 (define_insn "*xor_slli"
681 [(set (match_operand:SI 0 "register_operand" "= r")
682 (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
683 (match_operand:SI 2 "immediate_operand" " Iu05"))
684 (match_operand:SI 3 "register_operand" " r")))]
686 "xor_slli\t%0, %3, %1, %2"
687 [(set_attr "type" "alu")
688 (set_attr "length" "4")])
690 (define_insn "*xor_srli"
691 [(set (match_operand:SI 0 "register_operand" "= r")
692 (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
693 (match_operand:SI 2 "immediate_operand" " Iu05"))
694 (match_operand:SI 3 "register_operand" " r")))]
696 "xor_srli\t%0, %3, %1, %2"
697 [(set_attr "type" "alu")
698 (set_attr "length" "4")])
700 ;; Rotate Right Instructions.
702 (define_insn "rotrsi3"
703 [(set (match_operand:SI 0 "register_operand" "= r, r")
704 (rotatert:SI (match_operand:SI 1 "register_operand" " r, r")
705 (match_operand:SI 2 "nonmemory_operand" " Iu05, r")))]
710 [(set_attr "type" "alu,alu")
711 (set_attr "length" " 4, 4")])
714 ;; ----------------------------------------------------------------------------
716 ;; ----------------------------------------------------------------------------
718 ;; For V3/V3M ISA, we have 'neg33' instruction.
719 ;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
720 ;; And for V2 ISA, there is NO 'neg33' instruction.
721 ;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
722 (define_insn "negsi2"
723 [(set (match_operand:SI 0 "register_operand" "=w, r")
724 (neg:SI (match_operand:SI 1 "register_operand" " w, r")))]
729 [(set_attr "type" "alu,alu")
730 (set_attr "length" " 2, 4")])
733 ;; ----------------------------------------------------------------------------
734 ;; 'ONE_COMPLIMENT' operation
735 ;; ----------------------------------------------------------------------------
737 ;; For V3/V3M ISA, we have 'not33' instruction.
738 ;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
739 (define_insn "one_cmplsi2"
740 [(set (match_operand:SI 0 "register_operand" "=w, r")
741 (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
746 [(set_attr "type" "alu,alu")
747 (set_attr "length" " 2, 4")])
750 ;; ----------------------------------------------------------------------------
752 ;; Shift instructions.
754 (define_insn "ashlsi3"
755 [(set (match_operand:SI 0 "register_operand" "= l, r, r")
756 (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r")
757 (match_operand:SI 2 "nonmemory_operand" " Iu03, Iu05, r")))]
763 [(set_attr "type" "alu,alu,alu")
764 (set_attr "length" " 2, 4, 4")])
766 (define_insn "ashrsi3"
767 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
768 (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
769 (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))]
775 [(set_attr "type" "alu,alu,alu")
776 (set_attr "length" " 2, 4, 4")])
778 (define_insn "lshrsi3"
779 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
780 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
781 (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))]
787 [(set_attr "type" "alu,alu,alu")
788 (set_attr "length" " 2, 4, 4")])
791 ;; ----------------------------------------------------------------------------
793 ;; ----------------------------------------------------------------------------
794 ;; Conditional Move patterns
795 ;; ----------------------------------------------------------------------------
797 (define_expand "movsicc"
798 [(set (match_operand:SI 0 "register_operand" "")
799 (if_then_else:SI (match_operand 1 "comparison_operator" "")
800 (match_operand:SI 2 "register_operand" "")
801 (match_operand:SI 3 "register_operand" "")))]
804 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
805 && GET_MODE (XEXP (operands[1], 0)) == SImode
806 && XEXP (operands[1], 1) == const0_rtx)
808 /* If the operands[1] rtx is already (eq X 0) or (ne X 0),
809 we have gcc generate original template rtx. */
810 goto create_template;
814 /* Since there is only 'slt'(Set when Less Than) instruction for
815 comparison in Andes ISA, the major strategy we use here is to
816 convert conditional move into 'LT + EQ' or 'LT + NE' rtx combination.
817 We design constraints properly so that the reload phase will assist
818 to make one source operand to use same register as result operand.
819 Then we can use cmovz/cmovn to catch the other source operand
820 which has different register. */
821 enum rtx_code code = GET_CODE (operands[1]);
822 enum rtx_code new_code = code;
823 rtx cmp_op0 = XEXP (operands[1], 0);
824 rtx cmp_op1 = XEXP (operands[1], 1);
828 /* Main Goal: Use 'LT + EQ' or 'LT + NE' to target "then" part
829 Strategy : Reverse condition and swap comparison operands
833 a <= b ? P : Q (LE or LEU)
834 --> a > b ? Q : P (reverse condition)
835 --> b < a ? Q : P (swap comparison operands to achieve 'LT/LTU')
837 a >= b ? P : Q (GE or GEU)
838 --> a < b ? Q : P (reverse condition to achieve 'LT/LTU')
840 a < b ? P : Q (LT or LTU)
841 --> (NO NEED TO CHANGE, it is already 'LT/LTU')
843 a > b ? P : Q (GT or GTU)
844 --> b < a ? P : Q (swap comparison operands to achieve 'LT/LTU') */
851 so, fall through to reverse condition */
852 case GE: case GEU: case LE: case LEU:
853 new_code = reverse_condition (code);
856 case EQ: case GT: case GTU: case LT: case LTU:
857 /* no need to reverse condition */
863 /* For '>' comparison operator, we swap operands
864 so that we can have 'LT/LTU' operator. */
865 if (new_code == GT || new_code == GTU)
871 new_code = swap_condition (new_code);
874 /* Use a temporary register to store slt/slts result. */
875 tmp = gen_reg_rtx (SImode);
877 /* Split EQ and NE because we don't have direct comparison of EQ and NE.
878 If we don't split it, the conditional move transformation will fail
879 when producing (SET A (EQ B C)) or (SET A (NE B C)). */
882 emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1));
883 emit_insn (gen_slt_compare (tmp, tmp, GEN_INT (1)));
885 else if (new_code == NE)
887 emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1));
888 emit_insn (gen_slt_compare (tmp, GEN_INT (0), tmp));
891 /* This emit_insn will create corresponding 'slt/slts' insturction. */
892 emit_insn (gen_rtx_SET (tmp, gen_rtx_fmt_ee (new_code, SImode,
895 /* Change comparison semantic into (eq X 0) or (ne X 0) behavior
896 so that cmovz or cmovn will be matched later.
898 For reverse condition cases, we want to create a semantic that:
899 (eq X 0) --> pick up "else" part
900 For normal cases, we want to create a semantic that:
901 (ne X 0) --> pick up "then" part
903 Later we will have cmovz/cmovn instruction pattern to
904 match corresponding behavior and output instruction. */
905 operands[1] = gen_rtx_fmt_ee (reverse ? EQ : NE,
906 VOIDmode, tmp, const0_rtx);
910 do {} while(0); /* dummy line */
914 [(set (match_operand:SI 0 "register_operand" "=r, r")
915 (if_then_else:SI (eq (match_operand:SI 1 "register_operand" " r, r")
917 (match_operand:SI 2 "register_operand" " r, 0")
918 (match_operand:SI 3 "register_operand" " 0, r")))]
923 [(set_attr "type" "move")
924 (set_attr "length" "4")])
927 [(set (match_operand:SI 0 "register_operand" "=r, r")
928 (if_then_else:SI (ne (match_operand:SI 1 "register_operand" " r, r")
930 (match_operand:SI 2 "register_operand" " r, 0")
931 (match_operand:SI 3 "register_operand" " 0, r")))]
936 [(set_attr "type" "move")
937 (set_attr "length" "4")])
940 ;; ----------------------------------------------------------------------------
941 ;; Conditional Branch patterns
942 ;; ----------------------------------------------------------------------------
944 (define_expand "cbranchsi4"
946 (if_then_else (match_operator 0 "comparison_operator"
947 [(match_operand:SI 1 "register_operand" "")
948 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
949 (label_ref (match_operand 3 "" ""))
956 code = GET_CODE (operands[0]);
958 /* If operands[2] is (const_int 0),
959 we can use beqz,bnez,bgtz,bgez,bltz,or blez instructions.
960 So we have gcc generate original template rtx. */
961 if (GET_CODE (operands[2]) == CONST_INT)
962 if (INTVAL (operands[2]) == 0)
967 goto create_template;
969 /* For other comparison, NDS32 ISA only has slt (Set-on-Less-Than)
970 behavior for the comparison, we might need to generate other
971 rtx patterns to achieve same semantic. */
976 if (GET_CODE (operands[2]) == CONST_INT)
978 /* GT reg_A, const_int => !(LT reg_A, const_int + 1) */
979 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
981 /* We want to plus 1 into the integer value
982 of operands[2] to create 'slt' instruction.
983 This caculation is performed on the host machine,
984 which may be 64-bit integer.
985 So the meaning of caculation result may be
986 different from the 32-bit nds32 target.
989 0x7fffffff + 0x1 -> 0x80000000,
990 this value is POSITIVE on 64-bit machine,
991 but the expected value on 32-bit nds32 target
992 should be NEGATIVE value.
994 Hence, instead of using GEN_INT(), we use gen_int_mode() to
995 explicitly create SImode constant rtx. */
996 operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode);
1000 /* GT, use slts instruction */
1001 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1005 /* GTU, use slt instruction */
1006 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1009 PUT_CODE (operands[0], EQ);
1010 operands[1] = tmp_reg;
1011 operands[2] = const0_rtx;
1012 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1013 operands[2], operands[3]));
1019 /* GT reg_A, reg_B => LT reg_B, reg_A */
1020 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1024 /* GT, use slts instruction */
1025 emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1]));
1029 /* GTU, use slt instruction */
1030 emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1]));
1033 PUT_CODE (operands[0], NE);
1034 operands[1] = tmp_reg;
1035 operands[2] = const0_rtx;
1036 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1037 operands[2], operands[3]));
1044 /* GE reg_A, reg_B => !(LT reg_A, reg_B) */
1045 /* GE reg_A, const_int => !(LT reg_A, const_int) */
1046 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1050 /* GE, use slts instruction */
1051 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1055 /* GEU, use slt instruction */
1056 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1059 PUT_CODE (operands[0], EQ);
1060 operands[1] = tmp_reg;
1061 operands[2] = const0_rtx;
1062 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1063 operands[2], operands[3]));
1069 /* LT reg_A, reg_B => LT reg_A, reg_B */
1070 /* LT reg_A, const_int => LT reg_A, const_int */
1071 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1075 /* LT, use slts instruction */
1076 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1080 /* LTU, use slt instruction */
1081 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1084 PUT_CODE (operands[0], NE);
1085 operands[1] = tmp_reg;
1086 operands[2] = const0_rtx;
1087 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1088 operands[2], operands[3]));
1094 if (GET_CODE (operands[2]) == CONST_INT)
1096 /* LE reg_A, const_int => LT reg_A, const_int + 1 */
1097 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1099 /* Note that (le:SI X INT_MAX) is not the same as (lt:SI X INT_MIN).
1100 We better have an assert here in case GCC does not properly
1101 optimize it away. The INT_MAX here is 0x7fffffff for target. */
1102 gcc_assert (code != LE || INTVAL (operands[2]) != 0x7fffffff);
1103 operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode);
1107 /* LE, use slts instruction */
1108 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1112 /* LEU, use slt instruction */
1113 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1116 PUT_CODE (operands[0], NE);
1117 operands[1] = tmp_reg;
1118 operands[2] = const0_rtx;
1119 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1120 operands[2], operands[3]));
1126 /* LE reg_A, reg_B => !(LT reg_B, reg_A) */
1127 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1131 /* LE, use slts instruction */
1132 emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1]));
1136 /* LEU, use slt instruction */
1137 emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1]));
1140 PUT_CODE (operands[0], EQ);
1141 operands[1] = tmp_reg;
1142 operands[2] = const0_rtx;
1143 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1144 operands[2], operands[3]));
1151 /* NDS32 ISA has various form for eq/ne behavior no matter
1152 what kind of the operand is.
1153 So just generate original template rtx. */
1154 goto create_template;
1161 do {} while(0); /* dummy line */
1165 (define_insn "*cbranchsi4_equality_zero"
1167 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1168 [(match_operand:SI 1 "register_operand" "t, l, r")
1170 (label_ref (match_operand 2 "" ""))
1176 code = GET_CODE (operands[0]);
1178 /* This zero-comparison conditional branch has two forms:
1179 32-bit instruction => beqz/bnez imm16s << 1
1180 16-bit instruction => beqzs8/bnezs8/beqz38/bnez38 imm8s << 1
1183 we assume it is always reachable. (but check range -65500 ~ 65500)
1186 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1187 However, since the $pc for nds32 is at the beginning of the instruction,
1188 we should leave some length space for current insn.
1189 So we use range -250 ~ 250. */
1191 switch (get_attr_length (insn))
1194 if (which_alternative == 0)
1197 return (code == EQ) ? "beqzs8\t%2" : "bnezs8\t%2";
1199 else if (which_alternative == 1)
1202 return (code == EQ) ? "beqz38\t%1, %2" : "bnez38\t%1, %2";
1207 /* For which_alternative==2, it should not be here. */
1211 /* including constraints: t, l, and r */
1212 return (code == EQ) ? "beqz\t%1, %2" : "bnez\t%1, %2";
1214 if (which_alternative == 0)
1225 return "bnezs8\t.LCB%=\;j\t%2\n.LCB%=:";
1235 return "beqzs8\t.LCB%=\;j\t%2\n.LCB%=:";
1238 else if (which_alternative == 1)
1249 return "bnez38\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1259 return "beqz38\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1265 /* For which_alternative==2, it should not be here. */
1269 /* constraint: t, l, r. */
1278 return "bnez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1288 return "beqz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1294 [(set_attr "type" "branch")
1295 (set_attr "enabled" "1")
1296 (set_attr_alternative "length"
1299 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1300 (le (minus (match_dup 2) (pc)) (const_int 250)))
1301 (if_then_else (match_test "TARGET_16_BIT")
1304 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1305 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1307 (if_then_else (match_test "TARGET_16_BIT")
1311 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1312 (le (minus (match_dup 2) (pc)) (const_int 250)))
1313 (if_then_else (match_test "TARGET_16_BIT")
1316 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1317 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1319 (if_then_else (match_test "TARGET_16_BIT")
1323 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1324 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1330 ;; This pattern is dedicated to V2 ISA,
1331 ;; because V2 DOES NOT HAVE beqc/bnec instruction.
1332 (define_insn "*cbranchsi4_equality_reg"
1334 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1335 [(match_operand:SI 1 "register_operand" "r")
1336 (match_operand:SI 2 "nds32_reg_constant_operand" "r")])
1337 (label_ref (match_operand 3 "" ""))
1343 code = GET_CODE (operands[0]);
1345 /* This register-comparison conditional branch has one form:
1346 32-bit instruction => beq/bne imm14s << 1
1349 we assume it is always reachable. (but check range -16350 ~ 16350). */
1355 switch (get_attr_length (insn))
1358 return "beq\t%1, %2, %3";
1360 /* beq $r0, $r1, .L0
1366 return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1373 switch (get_attr_length (insn))
1376 return "bne\t%1, %2, %3";
1378 /* bne $r0, $r1, .L0
1384 return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1393 [(set_attr "type" "branch")
1394 (set (attr "length")
1395 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1396 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1401 ;; This pattern is dedicated to V3/V3M,
1402 ;; because V3/V3M DO HAVE beqc/bnec instruction.
1403 (define_insn "*cbranchsi4_equality_reg_or_const_int"
1405 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1406 [(match_operand:SI 1 "register_operand" "r, r")
1407 (match_operand:SI 2 "nds32_reg_constant_operand" "r, Is11")])
1408 (label_ref (match_operand 3 "" ""))
1410 "TARGET_ISA_V3 || TARGET_ISA_V3M"
1414 code = GET_CODE (operands[0]);
1416 /* This register-comparison conditional branch has one form:
1417 32-bit instruction => beq/bne imm14s << 1
1418 32-bit instruction => beqc/bnec imm8s << 1
1420 For 32-bit case, we assume it is always reachable.
1421 (but check range -16350 ~ 16350 and -250 ~ 250). */
1426 if (which_alternative == 0)
1429 switch (get_attr_length (insn))
1432 return "beq\t%1, %2, %3";
1434 /* beq $r0, $r1, .L0
1440 return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1448 switch (get_attr_length (insn))
1451 return "beqc\t%1, %2, %3";
1453 /* beqc $r0, constant, .L0
1455 bnec $r0, constant, .LCB0
1459 return "bnec\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1465 if (which_alternative == 0)
1468 switch (get_attr_length (insn))
1471 return "bne\t%1, %2, %3";
1473 /* bne $r0, $r1, .L0
1479 return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1487 switch (get_attr_length (insn))
1490 return "bnec\t%1, %2, %3";
1492 /* bnec $r0, constant, .L0
1494 beqc $r0, constant, .LCB0
1498 return "beqc\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1507 [(set_attr "type" "branch")
1508 (set_attr_alternative "length"
1511 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1512 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1516 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1517 (le (minus (match_dup 3) (pc)) (const_int 250)))
1523 (define_insn "*cbranchsi4_greater_less_zero"
1525 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1526 [(match_operand:SI 1 "register_operand" "r")
1528 (label_ref (match_operand 2 "" ""))
1534 code = GET_CODE (operands[0]);
1536 /* This zero-greater-less-comparison conditional branch has one form:
1537 32-bit instruction => bgtz/bgez/bltz/blez imm16s << 1
1539 For 32-bit case, we assume it is always reachable.
1540 (but check range -65500 ~ 65500). */
1542 if (get_attr_length (insn) == 8)
1544 /* The branch target is too far to simply use one
1545 bgtz/bgez/bltz/blez instruction.
1546 We need to reverse condition and use 'j' to jump to the target. */
1556 return "blez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1564 return "bltz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1572 return "bgez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1580 return "bgtz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1589 return "bgtz\t%1, %2";
1591 return "bgez\t%1, %2";
1593 return "bltz\t%1, %2";
1595 return "blez\t%1, %2";
1600 [(set_attr "type" "branch")
1601 (set (attr "length")
1602 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1603 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1608 (define_expand "cstoresi4"
1609 [(set (match_operand:SI 0 "register_operand" "")
1610 (match_operator:SI 1 "comparison_operator"
1611 [(match_operand:SI 2 "register_operand" "")
1612 (match_operand:SI 3 "nonmemory_operand" "")]))]
1618 code = GET_CODE (operands[1]);
1623 if (GET_CODE (operands[3]) == CONST_INT)
1625 /* reg_R = (reg_A == const_int_B)
1626 --> addi reg_C, reg_A, -const_int_B
1627 slti reg_R, reg_C, const_int_1 */
1628 tmp_reg = gen_reg_rtx (SImode);
1629 operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode);
1630 /* If the integer value is not in the range of imm15s,
1631 we need to force register first because our addsi3 pattern
1632 only accept nds32_rimm15s_operand predicate. */
1633 if (!satisfies_constraint_Is15 (operands[3]))
1634 operands[3] = force_reg (SImode, operands[3]);
1635 emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3]));
1636 emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx));
1642 /* reg_R = (reg_A == reg_B)
1643 --> xor reg_C, reg_A, reg_B
1644 slti reg_R, reg_C, const_int_1 */
1645 tmp_reg = gen_reg_rtx (SImode);
1646 emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3]));
1647 emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx));
1653 if (GET_CODE (operands[3]) == CONST_INT)
1655 /* reg_R = (reg_A != const_int_B)
1656 --> addi reg_C, reg_A, -const_int_B
1657 slti reg_R, const_int_0, reg_C */
1658 tmp_reg = gen_reg_rtx (SImode);
1659 operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode);
1660 /* If the integer value is not in the range of imm15s,
1661 we need to force register first because our addsi3 pattern
1662 only accept nds32_rimm15s_operand predicate. */
1663 if (!satisfies_constraint_Is15 (operands[3]))
1664 operands[3] = force_reg (SImode, operands[3]);
1665 emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3]));
1666 emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg));
1672 /* reg_R = (reg_A != reg_B)
1673 --> xor reg_C, reg_A, reg_B
1674 slti reg_R, const_int_0, reg_C */
1675 tmp_reg = gen_reg_rtx (SImode);
1676 emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3]));
1677 emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg));
1684 /* reg_R = (reg_A > reg_B) --> slt reg_R, reg_B, reg_A */
1685 /* reg_R = (reg_A > const_int_B) --> slt reg_R, const_int_B, reg_A */
1688 /* GT, use slts instruction */
1689 emit_insn (gen_slts_compare (operands[0], operands[3], operands[2]));
1693 /* GTU, use slt instruction */
1694 emit_insn (gen_slt_compare (operands[0], operands[3], operands[2]));
1701 if (GET_CODE (operands[3]) == CONST_INT)
1703 /* reg_R = (reg_A >= const_int_B)
1704 --> movi reg_C, const_int_B - 1
1705 slt reg_R, reg_C, reg_A */
1706 tmp_reg = gen_reg_rtx (SImode);
1708 emit_insn (gen_movsi (tmp_reg,
1709 gen_int_mode (INTVAL (operands[3]) - 1,
1713 /* GE, use slts instruction */
1714 emit_insn (gen_slts_compare (operands[0], tmp_reg, operands[2]));
1718 /* GEU, use slt instruction */
1719 emit_insn (gen_slt_compare (operands[0], tmp_reg, operands[2]));
1726 /* reg_R = (reg_A >= reg_B)
1727 --> slt reg_R, reg_A, reg_B
1728 xori reg_R, reg_R, const_int_1 */
1731 /* GE, use slts instruction */
1732 emit_insn (gen_slts_compare (operands[0],
1733 operands[2], operands[3]));
1737 /* GEU, use slt instruction */
1738 emit_insn (gen_slt_compare (operands[0],
1739 operands[2], operands[3]));
1742 /* perform 'not' behavior */
1743 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
1750 /* reg_R = (reg_A < reg_B) --> slt reg_R, reg_A, reg_B */
1751 /* reg_R = (reg_A < const_int_B) --> slt reg_R, reg_A, const_int_B */
1754 /* LT, use slts instruction */
1755 emit_insn (gen_slts_compare (operands[0], operands[2], operands[3]));
1759 /* LTU, use slt instruction */
1760 emit_insn (gen_slt_compare (operands[0], operands[2], operands[3]));
1767 if (GET_CODE (operands[3]) == CONST_INT)
1769 /* reg_R = (reg_A <= const_int_B)
1770 --> movi reg_C, const_int_B + 1
1771 slt reg_R, reg_A, reg_C */
1772 tmp_reg = gen_reg_rtx (SImode);
1774 emit_insn (gen_movsi (tmp_reg,
1775 gen_int_mode (INTVAL (operands[3]) + 1,
1779 /* LE, use slts instruction */
1780 emit_insn (gen_slts_compare (operands[0], operands[2], tmp_reg));
1784 /* LEU, use slt instruction */
1785 emit_insn (gen_slt_compare (operands[0], operands[2], tmp_reg));
1792 /* reg_R = (reg_A <= reg_B) --> slt reg_R, reg_B, reg_A
1793 xori reg_R, reg_R, const_int_1 */
1796 /* LE, use slts instruction */
1797 emit_insn (gen_slts_compare (operands[0],
1798 operands[3], operands[2]));
1802 /* LEU, use slt instruction */
1803 emit_insn (gen_slt_compare (operands[0],
1804 operands[3], operands[2]));
1807 /* perform 'not' behavior */
1808 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
1820 (define_insn "slts_compare"
1821 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1822 (lt:SI (match_operand:SI 1 "nonmemory_operand" " d, d, r, r")
1823 (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))]
1830 [(set_attr "type" "compare,compare,compare,compare")
1831 (set_attr "length" " 2, 2, 4, 4")])
1833 (define_insn "slt_compare"
1834 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1835 (ltu:SI (match_operand:SI 1 "nonmemory_operand" " d, d, r, r")
1836 (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))]
1843 [(set_attr "type" "compare,compare,compare,compare")
1844 (set_attr "length" " 2, 2, 4, 4")])
1847 ;; ----------------------------------------------------------------------------
1849 ;; Unconditional and other jump instructions.
1852 [(set (pc) (label_ref (match_operand 0 "" "")))]
1855 /* This unconditional jump has two forms:
1856 32-bit instruction => j imm24s << 1
1857 16-bit instruction => j8 imm8s << 1
1860 we assume it is always reachable.
1862 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1863 However, since the $pc for nds32 is at the beginning of the instruction,
1864 we should leave some length space for current insn.
1865 So we use range -250 ~ 250. */
1866 switch (get_attr_length (insn))
1876 [(set_attr "type" "branch")
1877 (set_attr "enabled" "1")
1878 (set (attr "length")
1879 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1880 (le (minus (match_dup 0) (pc)) (const_int 250)))
1881 (if_then_else (match_test "TARGET_16_BIT")
1886 (define_insn "indirect_jump"
1887 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1892 [(set_attr "type" "branch,branch")
1893 (set_attr "length" " 2, 4")])
1895 ;; Subroutine call instruction returning no value.
1896 ;; operands[0]: It should be a mem RTX whose address is
1897 ;; the address of the function.
1898 ;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
1899 ;; operands[2]: It is the number of registers used as operands.
1901 (define_expand "call"
1902 [(parallel [(call (match_operand 0 "memory_operand" "")
1904 (clobber (reg:SI LP_REGNUM))
1905 (clobber (reg:SI TA_REGNUM))])]
1910 (define_insn "*call_register"
1911 [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
1913 (clobber (reg:SI LP_REGNUM))
1914 (clobber (reg:SI TA_REGNUM))])]
1919 [(set_attr "type" "branch,branch")
1920 (set_attr "length" " 2, 4")])
1922 (define_insn "*call_immediate"
1923 [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
1925 (clobber (reg:SI LP_REGNUM))
1926 (clobber (reg:SI TA_REGNUM))])]
1929 if (TARGET_CMODEL_LARGE)
1934 [(set_attr "type" "branch")
1935 (set (attr "length")
1936 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1941 ;; Subroutine call instruction returning a value.
1942 ;; operands[0]: It is the hard regiser in which the value is returned.
1943 ;; The rest three operands are the same as the
1944 ;; three operands of the 'call' instruction.
1945 ;; (but with numbers increased by one)
1947 (define_expand "call_value"
1948 [(parallel [(set (match_operand 0)
1949 (call (match_operand 1 "memory_operand" "")
1951 (clobber (reg:SI LP_REGNUM))
1952 (clobber (reg:SI TA_REGNUM))])]
1957 (define_insn "*call_value_register"
1958 [(parallel [(set (match_operand 0)
1959 (call (mem (match_operand:SI 1 "register_operand" "r, r"))
1961 (clobber (reg:SI LP_REGNUM))
1962 (clobber (reg:SI TA_REGNUM))])]
1967 [(set_attr "type" "branch,branch")
1968 (set_attr "length" " 2, 4")])
1970 (define_insn "*call_value_immediate"
1971 [(parallel [(set (match_operand 0)
1972 (call (mem (match_operand:SI 1 "immediate_operand" "i"))
1974 (clobber (reg:SI LP_REGNUM))
1975 (clobber (reg:SI TA_REGNUM))])]
1978 if (TARGET_CMODEL_LARGE)
1983 [(set_attr "type" "branch")
1984 (set (attr "length")
1985 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1990 ;; ----------------------------------------------------------------------------
1992 ;; The sibcall patterns.
1996 ;; sibcall_immediate
1998 (define_expand "sibcall"
1999 [(parallel [(call (match_operand 0 "memory_operand" "")
2001 (clobber (reg:SI TA_REGNUM))
2007 (define_insn "*sibcall_register"
2008 [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
2010 (clobber (reg:SI TA_REGNUM))
2016 [(set_attr "type" "branch,branch")
2017 (set_attr "length" " 2, 4")])
2019 (define_insn "*sibcall_immediate"
2020 [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
2022 (clobber (reg:SI TA_REGNUM))
2026 if (TARGET_CMODEL_LARGE)
2031 [(set_attr "type" "branch")
2032 (set (attr "length")
2033 (if_then_else (match_test "TARGET_CMODEL_LARGE")
2038 ;; sibcall_value_register
2039 ;; sibcall_value_immediate
2041 (define_expand "sibcall_value"
2042 [(parallel [(set (match_operand 0)
2043 (call (match_operand 1 "memory_operand" "")
2045 (clobber (reg:SI TA_REGNUM))
2051 (define_insn "*sibcall_value_register"
2052 [(parallel [(set (match_operand 0)
2053 (call (mem (match_operand:SI 1 "register_operand" "r, r"))
2055 (clobber (reg:SI TA_REGNUM))
2061 [(set_attr "type" "branch,branch")
2062 (set_attr "length" " 2, 4")])
2064 (define_insn "*sibcall_value_immediate"
2065 [(parallel [(set (match_operand 0)
2066 (call (mem (match_operand:SI 1 "immediate_operand" "i"))
2068 (clobber (reg:SI TA_REGNUM))
2072 if (TARGET_CMODEL_LARGE)
2077 [(set_attr "type" "branch")
2078 (set (attr "length")
2079 (if_then_else (match_test "TARGET_CMODEL_LARGE")
2084 ;; ----------------------------------------------------------------------------
2086 ;; prologue and epilogue.
2088 (define_expand "prologue" [(const_int 0)]
2091 /* Note that only under V3/V3M ISA, we could use v3push prologue.
2092 In addition, we do not want to use v3push for isr function
2093 and variadic function. */
2095 && !nds32_isr_function_p (current_function_decl)
2096 && (cfun->machine->va_args_size == 0))
2097 nds32_expand_prologue_v3push ();
2099 nds32_expand_prologue ();
2103 (define_expand "epilogue" [(const_int 0)]
2106 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
2107 In addition, we do not want to use v3pop for isr function
2108 and variadic function. */
2110 && !nds32_isr_function_p (current_function_decl)
2111 && (cfun->machine->va_args_size == 0))
2112 nds32_expand_epilogue_v3pop (false);
2114 nds32_expand_epilogue (false);
2118 (define_expand "sibcall_epilogue" [(const_int 0)]
2121 /* Pass true to indicate that this is sibcall epilogue and
2122 exit from a function without the final branch back to the
2123 calling function. */
2124 if (TARGET_V3PUSH && !nds32_isr_function_p (current_function_decl))
2125 nds32_expand_epilogue_v3pop (true);
2127 nds32_expand_epilogue (true);
2144 [(set_attr "type" "misc")
2145 (set_attr "enabled" "1")
2146 (set (attr "length")
2147 (if_then_else (match_test "TARGET_16_BIT")
2152 ;; ----------------------------------------------------------------------------
2153 ;; Stack push/pop operations
2154 ;; ----------------------------------------------------------------------------
2156 ;; The pattern for stack push.
2157 ;; Both stack_push_multiple and stack_v3push use the following pattern.
2158 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
2159 (define_insn "*stack_push"
2160 [(match_parallel 0 "nds32_stack_push_operation"
2161 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
2162 (match_operand:SI 1 "const_int_operand" "")))
2163 (match_operand:SI 2 "register_operand" ""))
2167 return nds32_output_stack_push (operands[0]);
2169 [(set_attr "type" "misc")
2170 (set_attr "enabled" "1")
2171 (set (attr "length")
2172 (if_then_else (match_test "TARGET_V3PUSH
2173 && !nds32_isr_function_p (cfun->decl)
2174 && (cfun->machine->va_args_size == 0)")
2179 ;; The pattern for stack pop.
2180 ;; Both stack_pop_multiple and stack_v3pop use the following pattern.
2181 ;; So we need to use TARGET_V3PUSH to determine the instruction length.
2182 (define_insn "*stack_pop"
2183 [(match_parallel 0 "nds32_stack_pop_operation"
2184 [(set (match_operand:SI 1 "register_operand" "")
2185 (mem:SI (reg:SI SP_REGNUM)))
2189 return nds32_output_stack_pop (operands[0]);
2191 [(set_attr "type" "misc")
2192 (set_attr "enabled" "1")
2193 (set (attr "length")
2194 (if_then_else (match_test "TARGET_V3PUSH
2195 && !nds32_isr_function_p (cfun->decl)
2196 && (cfun->machine->va_args_size == 0)")
2201 ;; ----------------------------------------------------------------------------
2202 ;; Return operation patterns
2203 ;; ----------------------------------------------------------------------------
2205 ;; Use this pattern to expand a return instruction
2206 ;; with simple_return rtx if no epilogue is required.
2207 (define_expand "return"
2209 "nds32_can_use_return_insn ()"
2213 ;; This pattern is expanded only by the shrink-wrapping optimization
2214 ;; on paths where the function prologue has not been executed.
2215 (define_expand "simple_return"
2221 (define_insn "return_internal"
2230 [(set_attr "type" "branch")
2231 (set_attr "enabled" "1")
2232 (set (attr "length")
2233 (if_then_else (match_test "TARGET_16_BIT")
2238 ;; ----------------------------------------------------------------------------
2239 ;; Jump Table patterns
2240 ;; ----------------------------------------------------------------------------
2241 ;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
2242 ;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
2244 ;; operands[0]: The index to dispatch on.
2245 ;; operands[1]: The lower bound for indices in the table.
2246 ;; operands[2]: The total range of indices int the table.
2247 ;; i.e. The largest index minus the smallest one.
2248 ;; operands[3]: A label that precedes the table itself.
2249 ;; operands[4]: A label to jump to if the index has a value outside the bounds.
2251 ;; We need to create following sequences for jump table code generation:
2252 ;; A) k <-- (plus (operands[0]) (-operands[1]))
2253 ;; B) if (gtu k operands[2]) then goto operands[4]
2254 ;; C) t <-- operands[3]
2255 ;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
2256 ;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
2257 ;; F) jump to target with register t or z
2259 ;; The steps C, D, E, and F are performed by casesi_internal pattern.
2260 (define_expand "casesi"
2261 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
2262 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
2263 (match_operand:SI 2 "immediate_operand" "i") ; total range
2264 (match_operand:SI 3 "" "") ; table label
2265 (match_operand:SI 4 "" "")] ; Out of range label
2271 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
2272 if (operands[1] != const0_rtx)
2274 reg = gen_reg_rtx (SImode);
2275 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
2277 /* If the integer value is not in the range of imm15s,
2278 we need to force register first because our addsi3 pattern
2279 only accept nds32_rimm15s_operand predicate. */
2280 add_tmp = force_reg (SImode, add_tmp);
2282 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
2286 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
2287 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
2288 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
2291 /* Step C, D, E, and F, using another temporary register. */
2292 rtx tmp = gen_reg_rtx (SImode);
2293 emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
2297 ;; We are receiving operands from casesi pattern:
2299 ;; operands[0]: The index that have been substracted with lower bound.
2300 ;; operands[1]: A label that precedes the table itself.
2301 ;; operands[2]: A temporary register to retrieve value in table.
2303 ;; We need to perform steps C, D, E, and F:
2305 ;; C) t <-- operands[1]
2306 ;; D) z <-- (mem (plus (operands[0] << m) t))
2307 ;; m is 2 for normal jump table.
2308 ;; m is 0, 1, or 2 for pc relative jump table based on diff size.
2309 ;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
2310 ;; F) Jump to target with register t or z.
2312 ;; The USE in this pattern is needed to tell flow analysis that this is
2313 ;; a CASESI insn. It has no other purpose.
2314 (define_insn "casesi_internal"
2315 [(parallel [(set (pc)
2316 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
2318 (label_ref (match_operand 1 "" "")))))
2319 (use (label_ref (match_dup 1)))
2320 (clobber (match_operand:SI 2 "register_operand" "=r"))
2321 (clobber (reg:SI TA_REGNUM))])]
2324 if (CASE_VECTOR_PC_RELATIVE)
2325 return nds32_output_casesi_pc_relative (operands);
2327 return nds32_output_casesi (operands);
2329 [(set_attr "length" "20")
2330 (set_attr "type" "alu")])
2332 ;; ----------------------------------------------------------------------------
2334 ;; Performance Extension
2336 (define_insn "clzsi2"
2337 [(set (match_operand:SI 0 "register_operand" "=r")
2338 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
2341 [(set_attr "type" "alu")
2342 (set_attr "length" "4")])
2344 (define_insn "smaxsi3"
2345 [(set (match_operand:SI 0 "register_operand" "=r")
2346 (smax:SI (match_operand:SI 1 "register_operand" " r")
2347 (match_operand:SI 2 "register_operand" " r")))]
2350 [(set_attr "type" "alu")
2351 (set_attr "length" "4")])
2353 (define_insn "sminsi3"
2354 [(set (match_operand:SI 0 "register_operand" "=r")
2355 (smin:SI (match_operand:SI 1 "register_operand" " r")
2356 (match_operand:SI 2 "register_operand" " r")))]
2359 [(set_attr "type" "alu")
2360 (set_attr "length" "4")])
2362 (define_insn "*btst"
2363 [(set (match_operand:SI 0 "register_operand" "= r")
2364 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
2366 (match_operand:SI 2 "immediate_operand" " Iu05")))]
2369 [(set_attr "type" "alu")
2370 (set_attr "length" "4")])
2372 ;; ----------------------------------------------------------------------------
2376 (define_insn "pop25return"
2378 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
2380 "! return for pop 25"
2381 [(set_attr "length" "0")]
2384 ;; ----------------------------------------------------------------------------