]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nds32/nds32.md
[NDS32] Provide TARGET_CMODEL_[SMALL|MEDIUM|LARGE] to check which code model is speci...
[thirdparty/gcc.git] / gcc / config / nds32 / nds32.md
CommitLineData
9304f876 1;; Machine description of Andes NDS32 cpu for GNU compiler
5624e564 2;; Copyright (C) 2012-2015 Free Software Foundation, Inc.
9304f876
CJW
3;; Contributed by Andes Technology Corporation.
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11;;
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15;; License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>.
20
21;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23;; Include predicates definition.
24(include "predicates.md")
25
26;; Include constraints definition.
27(include "constraints.md")
28
29;; Include iterators definition.
30(include "iterators.md")
31
32;; Include pipelines definition.
33(include "pipelines.md")
34
35
36;; Include constants definition.
37(include "constants.md")
38
39
40;; Include intrinsic functions definition.
41(include "nds32-intrinsic.md")
42
43;; Include block move for nds32 multiple load/store behavior.
44(include "nds32-multiple.md")
45
46;; Include DImode/DFmode operations.
47(include "nds32-doubleword.md")
48
49;; Include peephole patterns.
50(include "nds32-peephole2.md")
51
52
53;; Insn type, it is used to default other attribute values.
54(define_attr "type"
55 "unknown,move,load,store,alu,compare,branch,call,misc"
56 (const_string "unknown"))
57
58
59;; Length, in bytes, default is 4-bytes.
60(define_attr "length" "" (const_int 4))
61
62
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"))
71 (const_int 0)]
72 (const_int 1)))
73
74
75;; ----------------------------------------------------------------------------
76
77
78;; Move instructions.
79
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.
82
83(define_expand "movqi"
84 [(set (match_operand:QI 0 "general_operand" "")
85 (match_operand:QI 1 "general_operand" ""))]
86 ""
87{
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]);
91})
92
93(define_expand "movhi"
94 [(set (match_operand:HI 0 "general_operand" "")
95 (match_operand:HI 1 "general_operand" ""))]
96 ""
97{
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]);
101})
102
103(define_expand "movsi"
104 [(set (match_operand:SI 0 "general_operand" "")
105 (match_operand:SI 1 "general_operand" ""))]
106 ""
107{
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]);
111
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]))
117 {
118 rtx high20_rtx;
119 HOST_WIDE_INT low12_int;
120 rtx tmp_rtx;
121
122 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
123
124 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
125 low12_int = INTVAL (operands[1]) & 0xfff;
126
127 emit_move_insn (tmp_rtx, high20_rtx);
128 emit_move_insn (operands[0], plus_constant (SImode,
129 tmp_rtx,
130 low12_int));
131 DONE;
132 }
133})
134
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"))]
138 ""
139{
140 switch (which_alternative)
141 {
142 case 0:
143 return "mov55\t%0, %1";
144 case 1:
145 return "ori\t%0, %1, 0";
146 case 2:
147 case 3:
148 case 4:
149 case 5:
150 return nds32_output_16bit_store (operands, <byte>);
151 case 6:
152 return nds32_output_32bit_store (operands, <byte>);
153 case 7:
154 case 8:
155 case 9:
156 case 10:
157 return nds32_output_16bit_load (operands, <byte>);
158 case 11:
159 return nds32_output_32bit_load (operands, <byte>);
160 case 12:
161 return "movpi45\t%0, %1";
162 case 13:
163 return "movi55\t%0, %1";
164 case 14:
165 return "movi\t%0, %1";
166 case 15:
167 return "sethi\t%0, hi20(%1)";
168 default:
169 gcc_unreachable ();
170 }
171}
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")])
174
175
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"))]
181 ""
182 "la\t%0, %1"
183 [(set_attr "type" "move")
184 (set_attr "length" "8")])
185
186
187(define_insn "*sethi"
188 [(set (match_operand:SI 0 "register_operand" "=r")
189 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
190 ""
191 "sethi\t%0, hi20(%1)"
192 [(set_attr "type" "alu")
193 (set_attr "length" "4")])
194
195
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")))]
200 ""
201 "ori\t%0, %1, lo12(%2)"
202 [(set_attr "type" "alu")
203 (set_attr "length" "4")])
204
205
206;; ----------------------------------------------------------------------------
207
208;; Zero extension instructions.
209
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")))]
213 ""
214{
215 switch (which_alternative)
216 {
217 case 0:
218 return "ze<size>33\t%0, %1";
219 case 1:
220 return "ze<size>\t%0, %1";
221 case 2:
222 return nds32_output_16bit_load (operands, <byte>);
223 case 3:
224 return nds32_output_32bit_load (operands, <byte>);
225
226 default:
227 gcc_unreachable ();
228 }
229}
230 [(set_attr "type" "alu,alu,load,load")
231 (set_attr "length" " 2, 4, 2, 4")])
232
233
234;; Sign extension instructions.
235
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")))]
239 ""
240{
241 switch (which_alternative)
242 {
243 case 0:
244 return "se<size>33\t%0, %1";
245 case 1:
246 return "se<size>\t%0, %1";
247 case 2:
248 return nds32_output_32bit_load_s (operands, <byte>);
249
250 default:
251 gcc_unreachable ();
252 }
253}
254 [(set_attr "type" "alu,alu,load")
255 (set_attr "length" " 2, 4, 4")])
256
257
258;; ----------------------------------------------------------------------------
259
260;; Arithmetic instructions.
261
262(define_insn "add<mode>3"
263 [(set (match_operand:QIHISI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
73f793e3 264 (plus:QIHISI (match_operand:QIHISI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
9304f876
CJW
265 (match_operand:QIHISI 2 "nds32_rimm15s_operand" " In05, In03, Iu05, Iu03, r, l, Is10, Iu06, Is15, r")))]
266 ""
267{
268 switch (which_alternative)
269 {
270 case 0:
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";
275 case 1:
276 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
277 where 0 <= x <= 7 */
278 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
279 return "subi333\t%0, %1, %2";
280 case 2:
281 return "addi45\t%0, %2";
282 case 3:
283 return "addi333\t%0, %1, %2";
284 case 4:
285 return "add45\t%0, %2";
286 case 5:
287 return "add333\t%0, %1, %2";
288 case 6:
289 return "addi10.sp\t%2";
290 case 7:
291 return "addri36.sp\t%0, %2";
292 case 8:
293 return "addi\t%0, %1, %2";
294 case 9:
295 return "add\t%0, %1, %2";
296
297 default:
298 gcc_unreachable ();
299 }
300}
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")])
303
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")))]
308 ""
309 "@
310 sub45\t%0, %2
311 sub333\t%0, %1, %2
312 subri\t%0, %2, %1
313 sub\t%0, %1, %2"
314 [(set_attr "type" "alu,alu,alu,alu")
315 (set_attr "length" " 2, 2, 4, 4")])
316
317
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")))]
326 "TARGET_ISA_V3
327 && (exact_log2 (INTVAL (operands[2])) != -1)
328 && (exact_log2 (INTVAL (operands[2])) <= 31)"
329{
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])));
333
334 return "add_slli\t%0, %3, %1, %2";
335}
336 [(set_attr "type" "alu")
337 (set_attr "length" "4")])
338
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")))]
344 "TARGET_ISA_V3"
345 "add_srli\t%0, %3, %1, %2"
346 [(set_attr "type" "alu")
347 (set_attr "length" "4")])
348
349
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"))))]
358 "TARGET_ISA_V3
359 && (exact_log2 (INTVAL (operands[3])) != -1)
360 && (exact_log2 (INTVAL (operands[3])) <= 31)"
361{
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])));
365
366 return "sub_slli\t%0, %1, %2, %3";
367}
368 [(set_attr "type" "alu")
369 (set_attr "length" "4")])
370
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"))))]
376 "TARGET_ISA_V3"
377 "sub_srli\t%0, %1, %2, %3"
378 [(set_attr "type" "alu")
379 (set_attr "length" "4")])
380
381
382;; Multiplication instructions.
383
384(define_insn "mulsi3"
73f793e3
RS
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")))]
9304f876
CJW
388 ""
389 "@
390 mul33\t%0, %2
391 mul\t%0, %1, %2"
392 [(set_attr "type" "alu,alu")
393 (set_attr "length" " 2, 4")])
394
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")])
403
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"
409 "mulr64\t%0, %1, %2"
410 [(set_attr "type" "alu")
411 (set_attr "length" "4")])
412
413
414;; Multiply-accumulate instructions.
415
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"))))]
421 ""
422 "maddr32\t%0, %1, %2"
423 [(set_attr "type" "alu")
424 (set_attr "length" "4")])
425
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")))]
431 ""
432 "maddr32\t%0, %1, %2"
433 [(set_attr "type" "alu")
434 (set_attr "length" "4")])
435
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"))))]
441 ""
442 "msubr32\t%0, %1, %2"
443 [(set_attr "type" "alu")
444 (set_attr "length" "4")])
445
446
447;; Div Instructions.
448
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)))]
455 ""
456 "divsr\t%0, %3, %1, %2"
457 [(set_attr "type" "alu")
458 (set_attr "length" "4")])
459
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)))]
466 ""
467 "divr\t%0, %3, %1, %2"
468 [(set_attr "type" "alu")
469 (set_attr "length" "4")])
470
471
472;; ----------------------------------------------------------------------------
473
474;; Boolean instructions.
475;; Note: We define the DImode versions in nds32-doubleword.md.
476
477;; ----------------------------------------------------------------------------
478;; 'AND' operation
479;; ----------------------------------------------------------------------------
480
481(define_insn "bitc"
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")))]
485 "TARGET_ISA_V3"
486 "bitc\t%0, %2, %1"
487 [(set_attr "type" "alu")
488 (set_attr "length" "4")]
489)
490
491(define_insn "andsi3"
73f793e3
RS
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")))]
9304f876
CJW
495 ""
496{
497 HOST_WIDE_INT mask = INTVAL (operands[2]);
498 int zero_position;
499
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. */
507
508 switch (which_alternative)
509 {
510 case 0:
511 return "and33\t%0, %2";
512 case 1:
513 return "and\t%0, %1, %2";
514 case 2:
515 return "zeb33\t%0, %1";
516 case 3:
517 return "zeh33\t%0, %1";
518 case 4:
519 return "xlsb33\t%0, %1";
520 case 5:
521 return "x11b33\t%0, %1";
522 case 6:
523 operands[2] = GEN_INT (floor_log2 (mask));
524 return "bmski33\t%0, %2";
525 case 7:
526 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
527 return "fexti33\t%0, %2";
528 case 8:
529 return "zeb\t%0, %1";
530 case 9:
531 return "zeh\t%0, %1";
532 case 10:
533 return "andi\t%0, %1, %2";
534 case 11:
535 operands[2] = GEN_INT (~mask);
536 return "bitci\t%0, %1, %2";
537 case 12:
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--)
543 {
544 if ((INTVAL (operands[2]) & (1 << zero_position)) == 0)
545 {
546 /* Found the 0-bit position. */
547 operands[2] = GEN_INT (zero_position);
548 break;
549 }
550 }
551 return "bclr\t%0, %1, %2";
552
553 default:
554 gcc_unreachable ();
555 }
556}
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")])
559
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")))]
565 "TARGET_ISA_V3"
566 "and_slli\t%0, %3, %1, %2"
567 [(set_attr "type" "alu")
568 (set_attr "length" "4")])
569
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")))]
575 "TARGET_ISA_V3"
576 "and_srli\t%0, %3, %1, %2"
577 [(set_attr "type" "alu")
578 (set_attr "length" "4")])
579
580
581;; ----------------------------------------------------------------------------
582;; 'OR' operation
583;; ----------------------------------------------------------------------------
584
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"
73f793e3
RS
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")))]
9304f876
CJW
591 ""
592{
593 int one_position;
594
595 switch (which_alternative)
596 {
597 case 0:
598 return "or33\t%0, %2";
599 case 1:
600 return "or\t%0, %1, %2";
601 case 2:
602 return "ori\t%0, %1, %2";
603 case 3:
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";
612
613 default:
614 gcc_unreachable ();
615 }
616}
617 [(set_attr "type" "alu,alu,alu,alu")
618 (set_attr "length" " 2, 4, 4, 4")])
619
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")))]
625 "TARGET_ISA_V3"
626 "or_slli\t%0, %3, %1, %2"
627 [(set_attr "type" "alu")
628 (set_attr "length" "4")])
629
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")))]
635 "TARGET_ISA_V3"
636 "or_srli\t%0, %3, %1, %2"
637 [(set_attr "type" "alu")
638 (set_attr "length" "4")])
639
640
641;; ----------------------------------------------------------------------------
642;; 'XOR' operation
643;; ----------------------------------------------------------------------------
644
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"
73f793e3
RS
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")))]
9304f876
CJW
651 ""
652{
653 int one_position;
654
655 switch (which_alternative)
656 {
657 case 0:
658 return "xor33\t%0, %2";
659 case 1:
660 return "xor\t%0, %1, %2";
661 case 2:
662 return "xori\t%0, %1, %2";
663 case 3:
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";
672
673 default:
674 gcc_unreachable ();
675 }
676}
677 [(set_attr "type" "alu,alu,alu,alu")
678 (set_attr "length" " 2, 4, 4, 4")])
679
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")))]
685 "TARGET_ISA_V3"
686 "xor_slli\t%0, %3, %1, %2"
687 [(set_attr "type" "alu")
688 (set_attr "length" "4")])
689
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")))]
695 "TARGET_ISA_V3"
696 "xor_srli\t%0, %3, %1, %2"
697 [(set_attr "type" "alu")
698 (set_attr "length" "4")])
699
700;; Rotate Right Instructions.
701
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")))]
706 ""
707 "@
708 rotri\t%0, %1, %2
709 rotr\t%0, %1, %2"
710 [(set_attr "type" "alu,alu")
711 (set_attr "length" " 4, 4")])
712
713
714;; ----------------------------------------------------------------------------
715;; 'NEG' operation
716;; ----------------------------------------------------------------------------
717
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")))]
725 ""
726 "@
727 neg33\t%0, %1
728 subri\t%0, %1, 0"
729 [(set_attr "type" "alu,alu")
730 (set_attr "length" " 2, 4")])
731
732
733;; ----------------------------------------------------------------------------
734;; 'ONE_COMPLIMENT' operation
735;; ----------------------------------------------------------------------------
736
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")))]
742 ""
743 "@
744 not33\t%0, %1
745 nor\t%0, %1, %1"
746 [(set_attr "type" "alu,alu")
747 (set_attr "length" " 2, 4")])
748
749
750;; ----------------------------------------------------------------------------
751
752;; Shift instructions.
753
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")))]
758 ""
759 "@
760 slli333\t%0, %1, %2
761 slli\t%0, %1, %2
762 sll\t%0, %1, %2"
763 [(set_attr "type" "alu,alu,alu")
764 (set_attr "length" " 2, 4, 4")])
765
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")))]
770 ""
771 "@
772 srai45\t%0, %2
773 srai\t%0, %1, %2
774 sra\t%0, %1, %2"
775 [(set_attr "type" "alu,alu,alu")
776 (set_attr "length" " 2, 4, 4")])
777
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")))]
782 ""
783 "@
784 srli45\t%0, %2
785 srli\t%0, %1, %2
786 srl\t%0, %1, %2"
787 [(set_attr "type" "alu,alu,alu")
788 (set_attr "length" " 2, 4, 4")])
789
790
791;; ----------------------------------------------------------------------------
792
793;; ----------------------------------------------------------------------------
794;; Conditional Move patterns
795;; ----------------------------------------------------------------------------
796
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" "")))]
802 "TARGET_CMOV"
803{
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)
807 {
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;
811 }
812 else
813 {
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);
825 rtx tmp;
826 int reverse = 0;
827
828 /* Main Goal: Use 'LT + EQ' or 'LT + NE' to target "then" part
829 Strategy : Reverse condition and swap comparison operands
830
831 For example:
832
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')
836
837 a >= b ? P : Q (GE or GEU)
838 --> a < b ? Q : P (reverse condition to achieve 'LT/LTU')
839
840 a < b ? P : Q (LT or LTU)
841 --> (NO NEED TO CHANGE, it is already 'LT/LTU')
842
843 a > b ? P : Q (GT or GTU)
844 --> b < a ? P : Q (swap comparison operands to achieve 'LT/LTU') */
845 switch (code)
846 {
847 case NE:
848 /* (a != b ? P : Q)
849 can be expressed as
850 (a == b ? Q : P)
851 so, fall through to reverse condition */
852 case GE: case GEU: case LE: case LEU:
853 new_code = reverse_condition (code);
854 reverse = 1;
855 break;
856 case EQ: case GT: case GTU: case LT: case LTU:
857 /* no need to reverse condition */
858 break;
859 default:
860 FAIL;
861 }
862
863 /* For '>' comparison operator, we swap operands
864 so that we can have 'LT/LTU' operator. */
865 if (new_code == GT || new_code == GTU)
866 {
867 tmp = cmp_op0;
868 cmp_op0 = cmp_op1;
869 cmp_op1 = tmp;
870
871 new_code = swap_condition (new_code);
872 }
873
874 /* Use a temporary register to store slt/slts result. */
875 tmp = gen_reg_rtx (SImode);
876
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)). */
880 if (new_code == EQ)
881 {
882 emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1));
883 emit_insn (gen_slt_compare (tmp, tmp, GEN_INT (1)));
884 }
885 else if (new_code == NE)
886 {
887 emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1));
888 emit_insn (gen_slt_compare (tmp, GEN_INT (0), tmp));
889 }
890 else
891 /* This emit_insn will create corresponding 'slt/slts' insturction. */
892 emit_insn (gen_rtx_SET (VOIDmode, tmp,
893 gen_rtx_fmt_ee (new_code, SImode,
894 cmp_op0, cmp_op1)));
895
896 /* Change comparison semantic into (eq X 0) or (ne X 0) behavior
897 so that cmovz or cmovn will be matched later.
898
899 For reverse condition cases, we want to create a semantic that:
900 (eq X 0) --> pick up "else" part
901 For normal cases, we want to create a semantic that:
902 (ne X 0) --> pick up "then" part
903
904 Later we will have cmovz/cmovn instruction pattern to
905 match corresponding behavior and output instruction. */
906 operands[1] = gen_rtx_fmt_ee (reverse ? EQ : NE,
907 VOIDmode, tmp, const0_rtx);
908 }
909
910create_template:
911 do {} while(0); /* dummy line */
912})
913
914(define_insn "cmovz"
915 [(set (match_operand:SI 0 "register_operand" "=r, r")
916 (if_then_else:SI (eq (match_operand:SI 1 "register_operand" " r, r")
917 (const_int 0))
918 (match_operand:SI 2 "register_operand" " r, 0")
919 (match_operand:SI 3 "register_operand" " 0, r")))]
920 "TARGET_CMOV"
921 "@
922 cmovz\t%0, %2, %1
923 cmovn\t%0, %3, %1"
924 [(set_attr "type" "move")
925 (set_attr "length" "4")])
926
927(define_insn "cmovn"
928 [(set (match_operand:SI 0 "register_operand" "=r, r")
929 (if_then_else:SI (ne (match_operand:SI 1 "register_operand" " r, r")
930 (const_int 0))
931 (match_operand:SI 2 "register_operand" " r, 0")
932 (match_operand:SI 3 "register_operand" " 0, r")))]
933 "TARGET_CMOV"
934 "@
935 cmovn\t%0, %2, %1
936 cmovz\t%0, %3, %1"
937 [(set_attr "type" "move")
938 (set_attr "length" "4")])
939
940
941;; ----------------------------------------------------------------------------
942;; Conditional Branch patterns
943;; ----------------------------------------------------------------------------
944
945(define_expand "cbranchsi4"
946 [(set (pc)
947 (if_then_else (match_operator 0 "comparison_operator"
948 [(match_operand:SI 1 "register_operand" "")
949 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
950 (label_ref (match_operand 3 "" ""))
951 (pc)))]
952 ""
953{
954 rtx tmp_reg;
955 enum rtx_code code;
956
957 code = GET_CODE (operands[0]);
958
959 /* If operands[2] is (const_int 0),
960 we can use beqz,bnez,bgtz,bgez,bltz,or blez instructions.
961 So we have gcc generate original template rtx. */
962 if (GET_CODE (operands[2]) == CONST_INT)
963 if (INTVAL (operands[2]) == 0)
964 if ((code != GTU)
965 && (code != GEU)
966 && (code != LTU)
967 && (code != LEU))
968 goto create_template;
969
970 /* For other comparison, NDS32 ISA only has slt (Set-on-Less-Than)
971 behavior for the comparison, we might need to generate other
972 rtx patterns to achieve same semantic. */
973 switch (code)
974 {
975 case GT:
976 case GTU:
977 if (GET_CODE (operands[2]) == CONST_INT)
978 {
979 /* GT reg_A, const_int => !(LT reg_A, const_int + 1) */
980 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
981
982 /* We want to plus 1 into the integer value
983 of operands[2] to create 'slt' instruction.
984 This caculation is performed on the host machine,
985 which may be 64-bit integer.
986 So the meaning of caculation result may be
987 different from the 32-bit nds32 target.
988
989 For example:
990 0x7fffffff + 0x1 -> 0x80000000,
991 this value is POSITIVE on 64-bit machine,
992 but the expected value on 32-bit nds32 target
993 should be NEGATIVE value.
994
995 Hence, instead of using GEN_INT(), we use gen_int_mode() to
996 explicitly create SImode constant rtx. */
997 operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode);
998
999 if (code == GT)
1000 {
1001 /* GT, use slts instruction */
1002 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1003 }
1004 else
1005 {
1006 /* GTU, use slt instruction */
1007 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1008 }
1009
1010 PUT_CODE (operands[0], EQ);
1011 operands[1] = tmp_reg;
1012 operands[2] = const0_rtx;
1013 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1014 operands[2], operands[3]));
1015
1016 DONE;
1017 }
1018 else
1019 {
1020 /* GT reg_A, reg_B => LT reg_B, reg_A */
1021 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1022
1023 if (code == GT)
1024 {
1025 /* GT, use slts instruction */
1026 emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1]));
1027 }
1028 else
1029 {
1030 /* GTU, use slt instruction */
1031 emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1]));
1032 }
1033
1034 PUT_CODE (operands[0], NE);
1035 operands[1] = tmp_reg;
1036 operands[2] = const0_rtx;
1037 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1038 operands[2], operands[3]));
1039
1040 DONE;
1041 }
1042
1043 case GE:
1044 case GEU:
1045 /* GE reg_A, reg_B => !(LT reg_A, reg_B) */
1046 /* GE reg_A, const_int => !(LT reg_A, const_int) */
1047 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1048
1049 if (code == GE)
1050 {
1051 /* GE, use slts instruction */
1052 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1053 }
1054 else
1055 {
1056 /* GEU, use slt instruction */
1057 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1058 }
1059
1060 PUT_CODE (operands[0], EQ);
1061 operands[1] = tmp_reg;
1062 operands[2] = const0_rtx;
1063 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1064 operands[2], operands[3]));
1065
1066 DONE;
1067
1068 case LT:
1069 case LTU:
1070 /* LT reg_A, reg_B => LT reg_A, reg_B */
1071 /* LT reg_A, const_int => LT reg_A, const_int */
1072 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1073
1074 if (code == LT)
1075 {
1076 /* LT, use slts instruction */
1077 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1078 }
1079 else
1080 {
1081 /* LTU, use slt instruction */
1082 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1083 }
1084
1085 PUT_CODE (operands[0], NE);
1086 operands[1] = tmp_reg;
1087 operands[2] = const0_rtx;
1088 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1089 operands[2], operands[3]));
1090
1091 DONE;
1092
1093 case LE:
1094 case LEU:
1095 if (GET_CODE (operands[2]) == CONST_INT)
1096 {
1097 /* LE reg_A, const_int => LT reg_A, const_int + 1 */
1098 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1099
1100 /* Note that (le:SI X INT_MAX) is not the same as (lt:SI X INT_MIN).
1101 We better have an assert here in case GCC does not properly
1102 optimize it away. The INT_MAX here is 0x7fffffff for target. */
1103 gcc_assert (code != LE || INTVAL (operands[2]) != 0x7fffffff);
1104 operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode);
1105
1106 if (code == LE)
1107 {
1108 /* LE, use slts instruction */
1109 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1110 }
1111 else
1112 {
1113 /* LEU, use slt instruction */
1114 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1115 }
1116
1117 PUT_CODE (operands[0], NE);
1118 operands[1] = tmp_reg;
1119 operands[2] = const0_rtx;
1120 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1121 operands[2], operands[3]));
1122
1123 DONE;
1124 }
1125 else
1126 {
1127 /* LE reg_A, reg_B => !(LT reg_B, reg_A) */
1128 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1129
1130 if (code == LE)
1131 {
1132 /* LE, use slts instruction */
1133 emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1]));
1134 }
1135 else
1136 {
1137 /* LEU, use slt instruction */
1138 emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1]));
1139 }
1140
1141 PUT_CODE (operands[0], EQ);
1142 operands[1] = tmp_reg;
1143 operands[2] = const0_rtx;
1144 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1145 operands[2], operands[3]));
1146
1147 DONE;
1148 }
1149
1150 case EQ:
1151 case NE:
1152 /* NDS32 ISA has various form for eq/ne behavior no matter
1153 what kind of the operand is.
1154 So just generate original template rtx. */
1155 goto create_template;
1156
1157 default:
1158 FAIL;
1159 }
1160
1161create_template:
1162 do {} while(0); /* dummy line */
1163})
1164
1165
1166(define_insn "*cbranchsi4_equality_zero"
1167 [(set (pc)
1168 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1169 [(match_operand:SI 1 "register_operand" "t, l, r")
1170 (const_int 0)])
1171 (label_ref (match_operand 2 "" ""))
1172 (pc)))]
1173 ""
1174{
1175 enum rtx_code code;
1176
1177 code = GET_CODE (operands[0]);
1178
1179 /* This zero-comparison conditional branch has two forms:
1180 32-bit instruction => beqz/bnez imm16s << 1
1181 16-bit instruction => beqzs8/bnezs8/beqz38/bnez38 imm8s << 1
1182
1183 For 32-bit case,
1184 we assume it is always reachable. (but check range -65500 ~ 65500)
1185
1186 For 16-bit case,
1187 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1188 However, since the $pc for nds32 is at the beginning of the instruction,
1189 we should leave some length space for current insn.
1190 So we use range -250 ~ 250. */
1191
1192 switch (get_attr_length (insn))
1193 {
1194 case 2:
1195 if (which_alternative == 0)
1196 {
1197 /* constraint: t */
1198 return (code == EQ) ? "beqzs8\t%2" : "bnezs8\t%2";
1199 }
1200 else if (which_alternative == 1)
1201 {
1202 /* constraint: l */
1203 return (code == EQ) ? "beqz38\t%1, %2" : "bnez38\t%1, %2";
1204 }
1205 else
1206 {
1207 /* constraint: r */
1208 /* For which_alternative==2, it should not be here. */
1209 gcc_unreachable ();
1210 }
1211 case 4:
1212 /* including constraints: t, l, and r */
1213 return (code == EQ) ? "beqz\t%1, %2" : "bnez\t%1, %2";
1214 case 6:
1215 if (which_alternative == 0)
1216 {
1217 /* constraint: t */
1218 if (code == EQ)
1219 {
1220 /* beqzs8 .L0
1221 =>
1222 bnezs8 .LCB0
1223 j .L0
1224 .LCB0:
1225 */
1226 return "bnezs8\t.LCB%=\;j\t%2\n.LCB%=:";
1227 }
1228 else
1229 {
1230 /* bnezs8 .L0
1231 =>
1232 beqzs8 .LCB0
1233 j .L0
1234 .LCB0:
1235 */
1236 return "beqzs8\t.LCB%=\;j\t%2\n.LCB%=:";
1237 }
1238 }
1239 else if (which_alternative == 1)
1240 {
1241 /* constraint: l */
1242 if (code == EQ)
1243 {
1244 /* beqz38 $r0, .L0
1245 =>
1246 bnez38 $r0, .LCB0
1247 j .L0
1248 .LCB0:
1249 */
1250 return "bnez38\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1251 }
1252 else
1253 {
1254 /* bnez38 $r0, .L0
1255 =>
1256 beqz38 $r0, .LCB0
1257 j .L0
1258 .LCB0:
1259 */
1260 return "beqz38\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1261 }
1262 }
1263 else
1264 {
1265 /* constraint: r */
1266 /* For which_alternative==2, it should not be here. */
1267 gcc_unreachable ();
1268 }
1269 case 8:
1270 /* constraint: t, l, r. */
1271 if (code == EQ)
1272 {
1273 /* beqz $r8, .L0
1274 =>
1275 bnez $r8, .LCB0
1276 j .L0
1277 .LCB0:
1278 */
1279 return "bnez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1280 }
1281 else
1282 {
1283 /* bnez $r8, .L0
1284 =>
1285 beqz $r8, .LCB0
1286 j .L0
1287 .LCB0:
1288 */
1289 return "beqz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1290 }
1291 default:
1292 gcc_unreachable ();
1293 }
1294}
1295 [(set_attr "type" "branch")
1296 (set_attr "enabled" "1")
1297 (set_attr_alternative "length"
1298 [
1299 ;; Alternative 0
1300 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1301 (le (minus (match_dup 2) (pc)) (const_int 250)))
1302 (if_then_else (match_test "TARGET_16_BIT")
1303 (const_int 2)
1304 (const_int 4))
1305 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1306 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1307 (const_int 4)
1308 (if_then_else (match_test "TARGET_16_BIT")
1309 (const_int 6)
1310 (const_int 8))))
1311 ;; Alternative 1
1312 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1313 (le (minus (match_dup 2) (pc)) (const_int 250)))
1314 (if_then_else (match_test "TARGET_16_BIT")
1315 (const_int 2)
1316 (const_int 4))
1317 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1318 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1319 (const_int 4)
1320 (if_then_else (match_test "TARGET_16_BIT")
1321 (const_int 6)
1322 (const_int 8))))
1323 ;; Alternative 2
1324 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1325 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1326 (const_int 4)
1327 (const_int 8))
1328 ])])
1329
1330
1331;; This pattern is dedicated to V2 ISA,
1332;; because V2 DOES NOT HAVE beqc/bnec instruction.
1333(define_insn "*cbranchsi4_equality_reg"
1334 [(set (pc)
1335 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1336 [(match_operand:SI 1 "register_operand" "r")
1337 (match_operand:SI 2 "nds32_reg_constant_operand" "r")])
1338 (label_ref (match_operand 3 "" ""))
1339 (pc)))]
1340 "TARGET_ISA_V2"
1341{
1342 enum rtx_code code;
1343
1344 code = GET_CODE (operands[0]);
1345
1346 /* This register-comparison conditional branch has one form:
1347 32-bit instruction => beq/bne imm14s << 1
1348
1349 For 32-bit case,
1350 we assume it is always reachable. (but check range -16350 ~ 16350). */
1351
1352 switch (code)
1353 {
1354 case EQ:
1355 /* r, r */
1356 switch (get_attr_length (insn))
1357 {
1358 case 4:
1359 return "beq\t%1, %2, %3";
1360 case 8:
1361 /* beq $r0, $r1, .L0
1362 =>
1363 bne $r0, $r1, .LCB0
1364 j .L0
1365 .LCB0:
1366 */
1367 return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1368 default:
1369 gcc_unreachable ();
1370 }
1371
1372 case NE:
1373 /* r, r */
1374 switch (get_attr_length (insn))
1375 {
1376 case 4:
1377 return "bne\t%1, %2, %3";
1378 case 8:
1379 /* bne $r0, $r1, .L0
1380 =>
1381 beq $r0, $r1, .LCB0
1382 j .L0
1383 .LCB0:
1384 */
1385 return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1386 default:
1387 gcc_unreachable ();
1388 }
1389
1390 default:
1391 gcc_unreachable ();
1392 }
1393}
1394 [(set_attr "type" "branch")
1395 (set (attr "length")
1396 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1397 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1398 (const_int 4)
1399 (const_int 8)))])
1400
1401
1402;; This pattern is dedicated to V3/V3M,
1403;; because V3/V3M DO HAVE beqc/bnec instruction.
1404(define_insn "*cbranchsi4_equality_reg_or_const_int"
1405 [(set (pc)
1406 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1407 [(match_operand:SI 1 "register_operand" "r, r")
1408 (match_operand:SI 2 "nds32_reg_constant_operand" "r, Is11")])
1409 (label_ref (match_operand 3 "" ""))
1410 (pc)))]
1411 "TARGET_ISA_V3 || TARGET_ISA_V3M"
1412{
1413 enum rtx_code code;
1414
1415 code = GET_CODE (operands[0]);
1416
1417 /* This register-comparison conditional branch has one form:
1418 32-bit instruction => beq/bne imm14s << 1
1419 32-bit instruction => beqc/bnec imm8s << 1
1420
1421 For 32-bit case, we assume it is always reachable.
1422 (but check range -16350 ~ 16350 and -250 ~ 250). */
1423
1424 switch (code)
1425 {
1426 case EQ:
1427 if (which_alternative == 0)
1428 {
1429 /* r, r */
1430 switch (get_attr_length (insn))
1431 {
1432 case 4:
1433 return "beq\t%1, %2, %3";
1434 case 8:
1435 /* beq $r0, $r1, .L0
1436 =>
1437 bne $r0, $r1, .LCB0
1438 j .L0
1439 .LCB0:
1440 */
1441 return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1442 default:
1443 gcc_unreachable ();
1444 }
1445 }
1446 else
1447 {
1448 /* r, Is11 */
1449 switch (get_attr_length (insn))
1450 {
1451 case 4:
1452 return "beqc\t%1, %2, %3";
1453 case 8:
1454 /* beqc $r0, constant, .L0
1455 =>
1456 bnec $r0, constant, .LCB0
1457 j .L0
1458 .LCB0:
1459 */
1460 return "bnec\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1461 default:
1462 gcc_unreachable ();
1463 }
1464 }
1465 case NE:
1466 if (which_alternative == 0)
1467 {
1468 /* r, r */
1469 switch (get_attr_length (insn))
1470 {
1471 case 4:
1472 return "bne\t%1, %2, %3";
1473 case 8:
1474 /* bne $r0, $r1, .L0
1475 =>
1476 beq $r0, $r1, .LCB0
1477 j .L0
1478 .LCB0:
1479 */
1480 return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1481 default:
1482 gcc_unreachable ();
1483 }
1484 }
1485 else
1486 {
1487 /* r, Is11 */
1488 switch (get_attr_length (insn))
1489 {
1490 case 4:
1491 return "bnec\t%1, %2, %3";
1492 case 8:
1493 /* bnec $r0, constant, .L0
1494 =>
1495 beqc $r0, constant, .LCB0
1496 j .L0
1497 .LCB0:
1498 */
1499 return "beqc\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1500 default:
1501 gcc_unreachable ();
1502 }
1503 }
1504 default:
1505 gcc_unreachable ();
1506 }
1507}
1508 [(set_attr "type" "branch")
1509 (set_attr_alternative "length"
1510 [
1511 ;; Alternative 0
1512 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1513 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1514 (const_int 4)
1515 (const_int 8))
1516 ;; Alternative 1
1517 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1518 (le (minus (match_dup 3) (pc)) (const_int 250)))
1519 (const_int 4)
1520 (const_int 8))
1521 ])])
1522
1523
1524(define_insn "*cbranchsi4_greater_less_zero"
1525 [(set (pc)
1526 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1527 [(match_operand:SI 1 "register_operand" "r")
1528 (const_int 0)])
1529 (label_ref (match_operand 2 "" ""))
1530 (pc)))]
1531 ""
1532{
1533 enum rtx_code code;
1534
1535 code = GET_CODE (operands[0]);
1536
1537 /* This zero-greater-less-comparison conditional branch has one form:
1538 32-bit instruction => bgtz/bgez/bltz/blez imm16s << 1
1539
1540 For 32-bit case, we assume it is always reachable.
1541 (but check range -65500 ~ 65500). */
1542
1543 if (get_attr_length (insn) == 8)
1544 {
1545 /* The branch target is too far to simply use one
1546 bgtz/bgez/bltz/blez instruction.
1547 We need to reverse condition and use 'j' to jump to the target. */
1548 switch (code)
1549 {
1550 case GT:
1551 /* bgtz $r8, .L0
1552 =>
1553 blez $r8, .LCB0
1554 j .L0
1555 .LCB0:
1556 */
1557 return "blez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1558 case GE:
1559 /* bgez $r8, .L0
1560 =>
1561 bltz $r8, .LCB0
1562 j .L0
1563 .LCB0:
1564 */
1565 return "bltz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1566 case LT:
1567 /* bltz $r8, .L0
1568 =>
1569 bgez $r8, .LCB0
1570 j .L0
1571 .LCB0:
1572 */
1573 return "bgez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1574 case LE:
1575 /* blez $r8, .L0
1576 =>
1577 bgtz $r8, .LCB0
1578 j .L0
1579 .LCB0:
1580 */
1581 return "bgtz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1582 default:
1583 gcc_unreachable ();
1584 }
1585 }
1586
1587 switch (code)
1588 {
1589 case GT:
1590 return "bgtz\t%1, %2";
1591 case GE:
1592 return "bgez\t%1, %2";
1593 case LT:
1594 return "bltz\t%1, %2";
1595 case LE:
1596 return "blez\t%1, %2";
1597 default:
1598 gcc_unreachable ();
1599 }
1600}
1601 [(set_attr "type" "branch")
1602 (set (attr "length")
1603 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1604 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1605 (const_int 4)
1606 (const_int 8)))])
1607
1608
1609(define_expand "cstoresi4"
1610 [(set (match_operand:SI 0 "register_operand" "")
1611 (match_operator:SI 1 "comparison_operator"
1612 [(match_operand:SI 2 "register_operand" "")
1613 (match_operand:SI 3 "nonmemory_operand" "")]))]
1614 ""
1615{
1616 rtx tmp_reg;
1617 enum rtx_code code;
1618
1619 code = GET_CODE (operands[1]);
1620
1621 switch (code)
1622 {
1623 case EQ:
1624 if (GET_CODE (operands[3]) == CONST_INT)
1625 {
1626 /* reg_R = (reg_A == const_int_B)
1627 --> addi reg_C, reg_A, -const_int_B
1628 slti reg_R, reg_C, const_int_1 */
1629 tmp_reg = gen_reg_rtx (SImode);
1630 operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode);
1631 /* If the integer value is not in the range of imm15s,
1632 we need to force register first because our addsi3 pattern
1633 only accept nds32_rimm15s_operand predicate. */
1634 if (!satisfies_constraint_Is15 (operands[3]))
1635 operands[3] = force_reg (SImode, operands[3]);
1636 emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3]));
1637 emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx));
1638
1639 DONE;
1640 }
1641 else
1642 {
1643 /* reg_R = (reg_A == reg_B)
1644 --> xor reg_C, reg_A, reg_B
1645 slti reg_R, reg_C, const_int_1 */
1646 tmp_reg = gen_reg_rtx (SImode);
1647 emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3]));
1648 emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx));
1649
1650 DONE;
1651 }
1652
1653 case NE:
1654 if (GET_CODE (operands[3]) == CONST_INT)
1655 {
1656 /* reg_R = (reg_A != const_int_B)
1657 --> addi reg_C, reg_A, -const_int_B
1658 slti reg_R, const_int_0, reg_C */
1659 tmp_reg = gen_reg_rtx (SImode);
1660 operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode);
1661 /* If the integer value is not in the range of imm15s,
1662 we need to force register first because our addsi3 pattern
1663 only accept nds32_rimm15s_operand predicate. */
1664 if (!satisfies_constraint_Is15 (operands[3]))
1665 operands[3] = force_reg (SImode, operands[3]);
1666 emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3]));
1667 emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg));
1668
1669 DONE;
1670 }
1671 else
1672 {
1673 /* reg_R = (reg_A != reg_B)
1674 --> xor reg_C, reg_A, reg_B
1675 slti reg_R, const_int_0, reg_C */
1676 tmp_reg = gen_reg_rtx (SImode);
1677 emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3]));
1678 emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg));
1679
1680 DONE;
1681 }
1682
1683 case GT:
1684 case GTU:
1685 /* reg_R = (reg_A > reg_B) --> slt reg_R, reg_B, reg_A */
1686 /* reg_R = (reg_A > const_int_B) --> slt reg_R, const_int_B, reg_A */
1687 if (code == GT)
1688 {
1689 /* GT, use slts instruction */
1690 emit_insn (gen_slts_compare (operands[0], operands[3], operands[2]));
1691 }
1692 else
1693 {
1694 /* GTU, use slt instruction */
1695 emit_insn (gen_slt_compare (operands[0], operands[3], operands[2]));
1696 }
1697
1698 DONE;
1699
1700 case GE:
1701 case GEU:
1702 if (GET_CODE (operands[3]) == CONST_INT)
1703 {
1704 /* reg_R = (reg_A >= const_int_B)
1705 --> movi reg_C, const_int_B - 1
1706 slt reg_R, reg_C, reg_A */
1707 tmp_reg = gen_reg_rtx (SImode);
1708
1709 emit_insn (gen_movsi (tmp_reg,
1710 gen_int_mode (INTVAL (operands[3]) - 1,
1711 SImode)));
1712 if (code == GE)
1713 {
1714 /* GE, use slts instruction */
1715 emit_insn (gen_slts_compare (operands[0], tmp_reg, operands[2]));
1716 }
1717 else
1718 {
1719 /* GEU, use slt instruction */
1720 emit_insn (gen_slt_compare (operands[0], tmp_reg, operands[2]));
1721 }
1722
1723 DONE;
1724 }
1725 else
1726 {
1727 /* reg_R = (reg_A >= reg_B)
1728 --> slt reg_R, reg_A, reg_B
1729 xori reg_R, reg_R, const_int_1 */
1730 if (code == GE)
1731 {
1732 /* GE, use slts instruction */
1733 emit_insn (gen_slts_compare (operands[0],
1734 operands[2], operands[3]));
1735 }
1736 else
1737 {
1738 /* GEU, use slt instruction */
1739 emit_insn (gen_slt_compare (operands[0],
1740 operands[2], operands[3]));
1741 }
1742
1743 /* perform 'not' behavior */
1744 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
1745
1746 DONE;
1747 }
1748
1749 case LT:
1750 case LTU:
1751 /* reg_R = (reg_A < reg_B) --> slt reg_R, reg_A, reg_B */
1752 /* reg_R = (reg_A < const_int_B) --> slt reg_R, reg_A, const_int_B */
1753 if (code == LT)
1754 {
1755 /* LT, use slts instruction */
1756 emit_insn (gen_slts_compare (operands[0], operands[2], operands[3]));
1757 }
1758 else
1759 {
1760 /* LTU, use slt instruction */
1761 emit_insn (gen_slt_compare (operands[0], operands[2], operands[3]));
1762 }
1763
1764 DONE;
1765
1766 case LE:
1767 case LEU:
1768 if (GET_CODE (operands[3]) == CONST_INT)
1769 {
1770 /* reg_R = (reg_A <= const_int_B)
1771 --> movi reg_C, const_int_B + 1
1772 slt reg_R, reg_A, reg_C */
1773 tmp_reg = gen_reg_rtx (SImode);
1774
1775 emit_insn (gen_movsi (tmp_reg,
1776 gen_int_mode (INTVAL (operands[3]) + 1,
1777 SImode)));
1778 if (code == LE)
1779 {
1780 /* LE, use slts instruction */
1781 emit_insn (gen_slts_compare (operands[0], operands[2], tmp_reg));
1782 }
1783 else
1784 {
1785 /* LEU, use slt instruction */
1786 emit_insn (gen_slt_compare (operands[0], operands[2], tmp_reg));
1787 }
1788
1789 DONE;
1790 }
1791 else
1792 {
1793 /* reg_R = (reg_A <= reg_B) --> slt reg_R, reg_B, reg_A
1794 xori reg_R, reg_R, const_int_1 */
1795 if (code == LE)
1796 {
1797 /* LE, use slts instruction */
1798 emit_insn (gen_slts_compare (operands[0],
1799 operands[3], operands[2]));
1800 }
1801 else
1802 {
1803 /* LEU, use slt instruction */
1804 emit_insn (gen_slt_compare (operands[0],
1805 operands[3], operands[2]));
1806 }
1807
1808 /* perform 'not' behavior */
1809 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
1810
1811 DONE;
1812 }
1813
1814
1815 default:
1816 gcc_unreachable ();
1817 }
1818})
1819
1820
1821(define_insn "slts_compare"
1822 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1823 (lt:SI (match_operand:SI 1 "nonmemory_operand" " d, d, r, r")
1824 (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))]
1825 ""
1826 "@
1827 slts45\t%1, %2
1828 sltsi45\t%1, %2
1829 slts\t%0, %1, %2
1830 sltsi\t%0, %1, %2"
1831 [(set_attr "type" "compare,compare,compare,compare")
1832 (set_attr "length" " 2, 2, 4, 4")])
1833
1834(define_insn "slt_compare"
1835 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1836 (ltu:SI (match_operand:SI 1 "nonmemory_operand" " d, d, r, r")
1837 (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))]
1838 ""
1839 "@
1840 slt45\t%1, %2
1841 slti45\t%1, %2
1842 slt\t%0, %1, %2
1843 slti\t%0, %1, %2"
1844 [(set_attr "type" "compare,compare,compare,compare")
1845 (set_attr "length" " 2, 2, 4, 4")])
1846
1847
1848;; ----------------------------------------------------------------------------
1849
1850;; Unconditional and other jump instructions.
1851
1852(define_insn "jump"
1853 [(set (pc) (label_ref (match_operand 0 "" "")))]
1854 ""
1855{
1856 /* This unconditional jump has two forms:
1857 32-bit instruction => j imm24s << 1
1858 16-bit instruction => j8 imm8s << 1
1859
1860 For 32-bit case,
1861 we assume it is always reachable.
1862 For 16-bit case,
1863 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1864 However, since the $pc for nds32 is at the beginning of the instruction,
1865 we should leave some length space for current insn.
1866 So we use range -250 ~ 250. */
1867 switch (get_attr_length (insn))
1868 {
1869 case 2:
1870 return "j8\t%0";
1871 case 4:
1872 return "j\t%0";
1873 default:
1874 gcc_unreachable ();
1875 }
1876}
1877 [(set_attr "type" "branch")
1878 (set_attr "enabled" "1")
1879 (set (attr "length")
1880 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1881 (le (minus (match_dup 0) (pc)) (const_int 250)))
1882 (if_then_else (match_test "TARGET_16_BIT")
1883 (const_int 2)
1884 (const_int 4))
1885 (const_int 4)))])
1886
1887(define_insn "indirect_jump"
1888 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1889 ""
1890 "@
1891 jr5\t%0
1892 jr\t%0"
1893 [(set_attr "type" "branch,branch")
1894 (set_attr "length" " 2, 4")])
1895
1896;; Subroutine call instruction returning no value.
1897;; operands[0]: It should be a mem RTX whose address is
1898;; the the address of the function.
1899;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
1900;; operands[2]: It is the number of registers used as operands.
1901
1902(define_expand "call"
1903 [(parallel [(call (match_operand 0 "memory_operand" "")
1904 (match_operand 1))
1905 (clobber (reg:SI LP_REGNUM))])]
1906 ""
1907 ""
1908)
1909
1910(define_insn "*call_register"
1911 [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
1912 (match_operand 1))
1913 (clobber (reg:SI LP_REGNUM))])]
1914 ""
1915 "@
1916 jral5\t%0
1917 jral\t%0"
1918 [(set_attr "type" "branch,branch")
1919 (set_attr "length" " 2, 4")])
1920
1921(define_insn "*call_immediate"
1922 [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
1923 (match_operand 1))
1924 (clobber (reg:SI LP_REGNUM))])]
1925 ""
1926 "jal\t%0"
1927 [(set_attr "type" "branch")
1928 (set_attr "length" "4")])
1929
1930
1931;; Subroutine call instruction returning a value.
1932;; operands[0]: It is the hard regiser in which the value is returned.
1933;; The rest three operands are the same as the
1934;; three operands of the 'call' instruction.
1935;; (but with numbers increased by one)
1936
1937(define_expand "call_value"
1938 [(parallel [(set (match_operand 0)
1939 (call (match_operand 1 "memory_operand" "")
1940 (match_operand 2)))
1941 (clobber (reg:SI LP_REGNUM))])]
1942 ""
1943 ""
1944)
1945
1946(define_insn "*call_value_register"
1947 [(parallel [(set (match_operand 0)
1948 (call (mem (match_operand:SI 1 "register_operand" "r, r"))
1949 (match_operand 2)))
1950 (clobber (reg:SI LP_REGNUM))])]
1951 ""
1952 "@
1953 jral5\t%1
1954 jral\t%1"
1955 [(set_attr "type" "branch,branch")
1956 (set_attr "length" " 2, 4")])
1957
1958(define_insn "*call_value_immediate"
1959 [(parallel [(set (match_operand 0)
1960 (call (mem (match_operand:SI 1 "immediate_operand" "i"))
1961 (match_operand 2)))
1962 (clobber (reg:SI LP_REGNUM))])]
1963 ""
1964 "jal\t%1"
1965 [(set_attr "type" "branch")
1966 (set_attr "length" "4")])
1967
1968
1969;; prologue and epilogue.
1970
1971(define_expand "prologue" [(const_int 0)]
1972 ""
1973{
2da1e7c0
CJW
1974 /* Note that only under V3/V3M ISA, we could use v3push prologue.
1975 In addition, we do not want to use v3push for isr function
1976 and variadic function. */
1977 if (TARGET_V3PUSH
1978 && !nds32_isr_function_p (current_function_decl)
1979 && (cfun->machine->va_args_size == 0))
9304f876
CJW
1980 nds32_expand_prologue_v3push ();
1981 else
1982 nds32_expand_prologue ();
1983 DONE;
1984})
1985
1986(define_expand "epilogue" [(const_int 0)]
1987 ""
1988{
2da1e7c0
CJW
1989 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
1990 In addition, we do not want to use v3pop for isr function
1991 and variadic function. */
1992 if (TARGET_V3PUSH
1993 && !nds32_isr_function_p (current_function_decl)
1994 && (cfun->machine->va_args_size == 0))
9304f876
CJW
1995 nds32_expand_epilogue_v3pop ();
1996 else
1997 nds32_expand_epilogue ();
1998 DONE;
1999})
2000
2001
2002;; nop instruction.
2003
2004(define_insn "nop"
2005 [(const_int 0)]
2006 ""
2007{
2008 if (TARGET_16_BIT)
2009 return "nop16";
2010 else
2011 return "nop";
2012}
2013 [(set_attr "type" "misc")
2014 (set_attr "enabled" "1")
2015 (set (attr "length")
2016 (if_then_else (match_test "TARGET_16_BIT")
2017 (const_int 2)
2018 (const_int 4)))])
2019
2020
2021;; ----------------------------------------------------------------------------
2022;; Stack push/pop operations
2023;; ----------------------------------------------------------------------------
2024
2025;; The pattern for stack push.
2026;; Both stack_push_multiple and stack_v3push use the following pattern.
2027;; So we need to use TARGET_V3PUSH to determine the instruction length.
2028(define_insn "*stack_push"
2029 [(match_parallel 0 "nds32_stack_push_operation"
2030 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
2031 (match_operand:SI 1 "const_int_operand" "")))
2032 (match_operand:SI 2 "register_operand" ""))
2033 ])]
2034 ""
2035{
6f3d3f9c 2036 return nds32_output_stack_push (operands[0]);
9304f876
CJW
2037}
2038 [(set_attr "type" "misc")
2039 (set_attr "enabled" "1")
2040 (set (attr "length")
6f3d3f9c
CJW
2041 (if_then_else (match_test "TARGET_V3PUSH
2042 && !nds32_isr_function_p (cfun->decl)
2043 && (cfun->machine->va_args_size == 0)")
9304f876
CJW
2044 (const_int 2)
2045 (const_int 4)))])
2046
2047
2048;; The pattern for stack pop.
2049;; Both stack_pop_multiple and stack_v3pop use the following pattern.
2050;; So we need to use TARGET_V3PUSH to determine the instruction length.
2051(define_insn "*stack_pop"
2052 [(match_parallel 0 "nds32_stack_pop_operation"
2053 [(set (match_operand:SI 1 "register_operand" "")
2054 (mem:SI (reg:SI SP_REGNUM)))
2055 ])]
2056 ""
2057{
6f3d3f9c 2058 return nds32_output_stack_pop (operands[0]);
9304f876
CJW
2059}
2060 [(set_attr "type" "misc")
2061 (set_attr "enabled" "1")
2062 (set (attr "length")
6f3d3f9c
CJW
2063 (if_then_else (match_test "TARGET_V3PUSH
2064 && !nds32_isr_function_p (cfun->decl)
2065 && (cfun->machine->va_args_size == 0)")
9304f876
CJW
2066 (const_int 2)
2067 (const_int 4)))])
2068
2069
2070;; ----------------------------------------------------------------------------
2071;; unspec operation patterns
2072;; ----------------------------------------------------------------------------
2073
2074;; In nds32 target, the 'ret5' instuction is actually 'jr5 $lp'.
2075;; This pattern is designed to distinguish function return
2076;; from general indirect_jump pattern so that we can directly
2077;; generate 'ret5' for readability.
2078
2079(define_insn "unspec_volatile_func_return"
2080 [(set (pc)
2081 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_FUNC_RETURN))]
2082 ""
2083{
2084 if (TARGET_16_BIT)
2085 return "ret5";
2086 else
2087 return "ret";
2088}
2089 [(set_attr "type" "misc")
2090 (set_attr "enabled" "1")
2091 (set (attr "length")
2092 (if_then_else (match_test "TARGET_16_BIT")
2093 (const_int 2)
2094 (const_int 4)))])
2095
2096
2097;; ----------------------------------------------------------------------------
2098;; Jump Table patterns
2099;; ----------------------------------------------------------------------------
2100;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
2101;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
2102;;
2103;; operands[0]: The index to dispatch on.
2104;; operands[1]: The lower bound for indices in the table.
2105;; operands[2]: The total range of indices int the table.
2106;; i.e. The largest index minus the smallest one.
2107;; operands[3]: A label that precedes the table itself.
2108;; operands[4]: A label to jump to if the index has a value outside the bounds.
2109;;
2110;; We need to create following sequences for jump table code generation:
2111;; A) k <-- (plus (operands[0]) (-operands[1]))
2112;; B) if (gtu k operands[2]) then goto operands[4]
2113;; C) t <-- operands[3]
2114;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
2115;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
2116;; F) jump to target with register t or z
2117;;
2118;; The steps C, D, E, and F are performed by casesi_internal pattern.
2119(define_expand "casesi"
2120 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
2121 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
2122 (match_operand:SI 2 "immediate_operand" "i") ; total range
2123 (match_operand:SI 3 "" "") ; table label
2124 (match_operand:SI 4 "" "")] ; Out of range label
2125 ""
2126{
2127 rtx add_tmp;
2128 rtx reg, test;
2129
2130 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
2131 if (operands[1] != const0_rtx)
2132 {
2133 reg = gen_reg_rtx (SImode);
2134 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
2135
2136 /* If the integer value is not in the range of imm15s,
2137 we need to force register first because our addsi3 pattern
2138 only accept nds32_rimm15s_operand predicate. */
2139 add_tmp = force_reg (SImode, add_tmp);
2140
2141 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
2142 operands[0] = reg;
2143 }
2144
2145 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
2146 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
2147 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
2148 operands[4]));
2149
2150 operands[5] = gen_reg_rtx (SImode);
2151 /* Step C, D, E, and F, using another temporary register operands[5]. */
2152 emit_jump_insn (gen_casesi_internal (operands[0],
2153 operands[3],
2154 operands[5]));
2155 DONE;
2156})
2157
2158;; We are receiving operands from casesi pattern:
2159;;
2160;; operands[0]: The index that have been substracted with lower bound.
2161;; operands[1]: A label that precedes the table itself.
2162;; operands[2]: A temporary register to retrieve value in table.
2163;;
2164;; We need to perform steps C, D, E, and F:
2165;;
2166;; C) t <-- operands[1]
2167;; D) z <-- (mem (plus (operands[0] << m) t))
2168;; m is 2 for normal jump table.
2169;; m is 0, 1, or 2 for pc relative jump table based on diff size.
2170;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
2171;; F) Jump to target with register t or z.
2172;;
2173;; The USE in this pattern is needed to tell flow analysis that this is
2174;; a CASESI insn. It has no other purpose.
2175(define_insn "casesi_internal"
2176 [(parallel [(set (pc)
2177 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
2178 (const_int 4))
2179 (label_ref (match_operand 1 "" "")))))
2180 (use (label_ref (match_dup 1)))
24f036fb 2181 (clobber (match_operand:SI 2 "register_operand" "=r"))
9304f876
CJW
2182 (clobber (reg:SI TA_REGNUM))])]
2183 ""
2184{
2185 if (CASE_VECTOR_PC_RELATIVE)
2186 return nds32_output_casesi_pc_relative (operands);
2187 else
2188 return nds32_output_casesi (operands);
2189}
2190 [(set_attr "length" "20")
2191 (set_attr "type" "alu")])
2192
2193;; ----------------------------------------------------------------------------
2194
2195;; Performance Extension
2196
2197(define_insn "clzsi2"
2198 [(set (match_operand:SI 0 "register_operand" "=r")
2199 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
2200 "TARGET_PERF_EXT"
2201 "clz\t%0, %1"
2202 [(set_attr "type" "alu")
2203 (set_attr "length" "4")])
2204
2205(define_insn "smaxsi3"
2206 [(set (match_operand:SI 0 "register_operand" "=r")
2207 (smax:SI (match_operand:SI 1 "register_operand" " r")
2208 (match_operand:SI 2 "register_operand" " r")))]
2209 "TARGET_PERF_EXT"
2210 "max\t%0, %1, %2"
2211 [(set_attr "type" "alu")
2212 (set_attr "length" "4")])
2213
2214(define_insn "sminsi3"
2215 [(set (match_operand:SI 0 "register_operand" "=r")
2216 (smin:SI (match_operand:SI 1 "register_operand" " r")
2217 (match_operand:SI 2 "register_operand" " r")))]
2218 "TARGET_PERF_EXT"
2219 "min\t%0, %1, %2"
2220 [(set_attr "type" "alu")
2221 (set_attr "length" "4")])
2222
2223(define_insn "*btst"
2224 [(set (match_operand:SI 0 "register_operand" "= r")
2225 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
2226 (const_int 1)
2227 (match_operand:SI 2 "immediate_operand" " Iu05")))]
2228 "TARGET_PERF_EXT"
2229 "btst\t%0, %1, %2"
2230 [(set_attr "type" "alu")
2231 (set_attr "length" "4")])
2232
2233;; ----------------------------------------------------------------------------