]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nds32/nds32.md
Daily bump.
[thirdparty/gcc.git] / gcc / config / nds32 / nds32.md
CommitLineData
9304f876 1;; Machine description of Andes NDS32 cpu for GNU compiler
85ec4feb 2;; Copyright (C) 2012-2018 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"
264159d2 55 "unknown,move,load,store,load_multiple,store_multiple,alu,compare,branch,call,misc"
9304f876
CJW
56 (const_string "unknown"))
57
58
59;; Length, in bytes, default is 4-bytes.
60(define_attr "length" "" (const_int 4))
61
264159d2
KC
62;; Indicate the amount of micro instructions.
63(define_attr "combo"
64 "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25"
65 (const_string "1"))
9304f876
CJW
66
67;; Enabled, which is used to enable/disable insn alternatives.
68;; Note that we use length and TARGET_16_BIT here as criteria.
69;; If the instruction pattern already check TARGET_16_BIT to
70;; determine the length by itself, its enabled attribute should be
71;; always 1 to avoid the conflict with the settings here.
72(define_attr "enabled" ""
73 (cond [(and (eq_attr "length" "2")
74 (match_test "!TARGET_16_BIT"))
75 (const_int 0)]
76 (const_int 1)))
77
78
79;; ----------------------------------------------------------------------------
80
81
82;; Move instructions.
83
84;; For QImode and HImode, the immediate value can be fit in imm20s.
85;; So there is no need to split rtx for QI and HI patterns.
86
87(define_expand "movqi"
88 [(set (match_operand:QI 0 "general_operand" "")
89 (match_operand:QI 1 "general_operand" ""))]
90 ""
91{
92 /* Need to force register if mem <- !reg. */
93 if (MEM_P (operands[0]) && !REG_P (operands[1]))
94 operands[1] = force_reg (QImode, operands[1]);
95})
96
97(define_expand "movhi"
98 [(set (match_operand:HI 0 "general_operand" "")
99 (match_operand:HI 1 "general_operand" ""))]
100 ""
101{
102 /* Need to force register if mem <- !reg. */
103 if (MEM_P (operands[0]) && !REG_P (operands[1]))
104 operands[1] = force_reg (HImode, operands[1]);
105})
106
107(define_expand "movsi"
108 [(set (match_operand:SI 0 "general_operand" "")
109 (match_operand:SI 1 "general_operand" ""))]
110 ""
111{
112 /* Need to force register if mem <- !reg. */
113 if (MEM_P (operands[0]) && !REG_P (operands[1]))
114 operands[1] = force_reg (SImode, operands[1]);
115
116 /* If operands[1] is a large constant and cannot be performed
117 by a single instruction, we need to split it. */
118 if (CONST_INT_P (operands[1])
119 && !satisfies_constraint_Is20 (operands[1])
120 && !satisfies_constraint_Ihig (operands[1]))
121 {
122 rtx high20_rtx;
123 HOST_WIDE_INT low12_int;
124 rtx tmp_rtx;
125
126 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
127
128 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
129 low12_int = INTVAL (operands[1]) & 0xfff;
130
131 emit_move_insn (tmp_rtx, high20_rtx);
132 emit_move_insn (operands[0], plus_constant (SImode,
133 tmp_rtx,
134 low12_int));
135 DONE;
136 }
137})
138
139(define_insn "*mov<mode>"
140 [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r, U45, U33, U37, U45, m, l, l, l, d, r, d, r, r, r")
141 (match_operand:QIHISI 1 "nds32_move_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45, m, Ip05, Is05, Is20, Ihig"))]
142 ""
143{
144 switch (which_alternative)
145 {
146 case 0:
147 return "mov55\t%0, %1";
148 case 1:
149 return "ori\t%0, %1, 0";
150 case 2:
151 case 3:
152 case 4:
153 case 5:
154 return nds32_output_16bit_store (operands, <byte>);
155 case 6:
156 return nds32_output_32bit_store (operands, <byte>);
157 case 7:
158 case 8:
159 case 9:
160 case 10:
161 return nds32_output_16bit_load (operands, <byte>);
162 case 11:
163 return nds32_output_32bit_load (operands, <byte>);
164 case 12:
165 return "movpi45\t%0, %1";
166 case 13:
167 return "movi55\t%0, %1";
168 case 14:
169 return "movi\t%0, %1";
170 case 15:
171 return "sethi\t%0, hi20(%1)";
172 default:
173 gcc_unreachable ();
174 }
175}
176 [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,alu,alu,alu,alu")
177 (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 4, 4")])
178
179
180;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
181;; are able to match such instruction template.
c4d8d050 182(define_insn "move_addr"
9304f876
CJW
183 [(set (match_operand:SI 0 "register_operand" "=l, r")
184 (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
185 ""
186 "la\t%0, %1"
187 [(set_attr "type" "move")
188 (set_attr "length" "8")])
189
190
c4d8d050 191(define_insn "sethi"
9304f876
CJW
192 [(set (match_operand:SI 0 "register_operand" "=r")
193 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
194 ""
195 "sethi\t%0, hi20(%1)"
196 [(set_attr "type" "alu")
197 (set_attr "length" "4")])
198
199
c4d8d050 200(define_insn "lo_sum"
9304f876
CJW
201 [(set (match_operand:SI 0 "register_operand" "=r")
202 (lo_sum:SI (match_operand:SI 1 "register_operand" " r")
203 (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
204 ""
205 "ori\t%0, %1, lo12(%2)"
206 [(set_attr "type" "alu")
207 (set_attr "length" "4")])
208
209
210;; ----------------------------------------------------------------------------
211
212;; Zero extension instructions.
213
214(define_insn "zero_extend<mode>si2"
215 [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r")
216 (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))]
217 ""
218{
219 switch (which_alternative)
220 {
221 case 0:
222 return "ze<size>33\t%0, %1";
223 case 1:
224 return "ze<size>\t%0, %1";
225 case 2:
226 return nds32_output_16bit_load (operands, <byte>);
227 case 3:
228 return nds32_output_32bit_load (operands, <byte>);
229
230 default:
231 gcc_unreachable ();
232 }
233}
234 [(set_attr "type" "alu,alu,load,load")
235 (set_attr "length" " 2, 4, 2, 4")])
236
237
238;; Sign extension instructions.
239
240(define_insn "extend<mode>si2"
241 [(set (match_operand:SI 0 "register_operand" "=l, r, r")
242 (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
243 ""
244{
245 switch (which_alternative)
246 {
247 case 0:
248 return "se<size>33\t%0, %1";
249 case 1:
250 return "se<size>\t%0, %1";
251 case 2:
252 return nds32_output_32bit_load_s (operands, <byte>);
253
254 default:
255 gcc_unreachable ();
256 }
257}
258 [(set_attr "type" "alu,alu,load")
259 (set_attr "length" " 2, 4, 4")])
260
261
262;; ----------------------------------------------------------------------------
263
264;; Arithmetic instructions.
265
266(define_insn "add<mode>3"
267 [(set (match_operand:QIHISI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
73f793e3 268 (plus:QIHISI (match_operand:QIHISI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
9304f876
CJW
269 (match_operand:QIHISI 2 "nds32_rimm15s_operand" " In05, In03, Iu05, Iu03, r, l, Is10, Iu06, Is15, r")))]
270 ""
271{
272 switch (which_alternative)
273 {
274 case 0:
275 /* addi Rt4,Rt4,-x ==> subi45 Rt4,x
8a498f99 276 where 0 <= x <= 31 */
9304f876
CJW
277 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
278 return "subi45\t%0, %2";
279 case 1:
280 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
8a498f99 281 where 0 <= x <= 7 */
9304f876
CJW
282 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
283 return "subi333\t%0, %1, %2";
284 case 2:
285 return "addi45\t%0, %2";
286 case 3:
287 return "addi333\t%0, %1, %2";
288 case 4:
289 return "add45\t%0, %2";
290 case 5:
291 return "add333\t%0, %1, %2";
292 case 6:
293 return "addi10.sp\t%2";
294 case 7:
295 return "addri36.sp\t%0, %2";
296 case 8:
297 return "addi\t%0, %1, %2";
298 case 9:
299 return "add\t%0, %1, %2";
300
301 default:
302 gcc_unreachable ();
303 }
304}
305 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
306 (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")])
307
308(define_insn "sub<mode>3"
309 [(set (match_operand:QIHISI 0 "register_operand" "=d, l, r, r")
310 (minus:QIHISI (match_operand:QIHISI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
311 (match_operand:QIHISI 2 "register_operand" " r, l, r, r")))]
312 ""
313 "@
314 sub45\t%0, %2
315 sub333\t%0, %1, %2
316 subri\t%0, %2, %1
317 sub\t%0, %1, %2"
318 [(set_attr "type" "alu,alu,alu,alu")
319 (set_attr "length" " 2, 2, 4, 4")])
320
321
322;; GCC intends to simplify (plus (ashift ...) (reg))
323;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
324;; and needs to ensure it is exact_log2 value.
325(define_insn "*add_slli"
326 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99 327 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
9304f876
CJW
328 (match_operand:SI 2 "immediate_operand" " i"))
329 (match_operand:SI 3 "register_operand" " r")))]
330 "TARGET_ISA_V3
331 && (exact_log2 (INTVAL (operands[2])) != -1)
332 && (exact_log2 (INTVAL (operands[2])) <= 31)"
333{
334 /* Get floor_log2 of the immediate value
335 so that we can generate 'add_slli' instruction. */
336 operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
337
338 return "add_slli\t%0, %3, %1, %2";
339}
340 [(set_attr "type" "alu")
341 (set_attr "length" "4")])
342
343(define_insn "*add_srli"
344 [(set (match_operand:SI 0 "register_operand" "= r")
345 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
346 (match_operand:SI 2 "immediate_operand" " Iu05"))
347 (match_operand:SI 3 "register_operand" " r")))]
348 "TARGET_ISA_V3"
349 "add_srli\t%0, %3, %1, %2"
350 [(set_attr "type" "alu")
351 (set_attr "length" "4")])
352
353
354;; GCC intends to simplify (minus (reg) (ashift ...))
355;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
356;; and needs to ensure it is exact_log2 value.
357(define_insn "*sub_slli"
358 [(set (match_operand:SI 0 "register_operand" "=r")
359 (minus:SI (match_operand:SI 1 "register_operand" " r")
360 (mult:SI (match_operand:SI 2 "register_operand" " r")
361 (match_operand:SI 3 "immediate_operand" " i"))))]
362 "TARGET_ISA_V3
363 && (exact_log2 (INTVAL (operands[3])) != -1)
364 && (exact_log2 (INTVAL (operands[3])) <= 31)"
365{
366 /* Get floor_log2 of the immediate value
367 so that we can generate 'sub_slli' instruction. */
368 operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
369
370 return "sub_slli\t%0, %1, %2, %3";
371}
372 [(set_attr "type" "alu")
373 (set_attr "length" "4")])
374
375(define_insn "*sub_srli"
376 [(set (match_operand:SI 0 "register_operand" "= r")
377 (minus:SI (match_operand:SI 1 "register_operand" " r")
378 (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
379 (match_operand:SI 3 "immediate_operand" " Iu05"))))]
380 "TARGET_ISA_V3"
381 "sub_srli\t%0, %1, %2, %3"
382 [(set_attr "type" "alu")
383 (set_attr "length" "4")])
384
385
386;; Multiplication instructions.
387
388(define_insn "mulsi3"
73f793e3
RS
389 [(set (match_operand:SI 0 "register_operand" "=w, r")
390 (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
391 (match_operand:SI 2 "register_operand" " w, r")))]
9304f876
CJW
392 ""
393 "@
394 mul33\t%0, %2
395 mul\t%0, %1, %2"
396 [(set_attr "type" "alu,alu")
397 (set_attr "length" " 2, 4")])
398
399(define_insn "mulsidi3"
400 [(set (match_operand:DI 0 "register_operand" "=r")
401 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
402 (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
403 "TARGET_ISA_V2 || TARGET_ISA_V3"
404 "mulsr64\t%0, %1, %2"
405 [(set_attr "type" "alu")
406 (set_attr "length" "4")])
407
408(define_insn "umulsidi3"
409 [(set (match_operand:DI 0 "register_operand" "=r")
410 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
411 (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
412 "TARGET_ISA_V2 || TARGET_ISA_V3"
413 "mulr64\t%0, %1, %2"
414 [(set_attr "type" "alu")
415 (set_attr "length" "4")])
416
417
418;; Multiply-accumulate instructions.
419
420(define_insn "*maddr32_0"
421 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
422 (plus:SI (match_operand:SI 3 "register_operand" " 0")
423 (mult:SI (match_operand:SI 1 "register_operand" " r")
424 (match_operand:SI 2 "register_operand" " r"))))]
9304f876
CJW
425 ""
426 "maddr32\t%0, %1, %2"
427 [(set_attr "type" "alu")
428 (set_attr "length" "4")])
429
430(define_insn "*maddr32_1"
431 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
432 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
433 (match_operand:SI 2 "register_operand" " r"))
434 (match_operand:SI 3 "register_operand" " 0")))]
9304f876
CJW
435 ""
436 "maddr32\t%0, %1, %2"
437 [(set_attr "type" "alu")
438 (set_attr "length" "4")])
439
440(define_insn "*msubr32"
441 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
442 (minus:SI (match_operand:SI 3 "register_operand" " 0")
443 (mult:SI (match_operand:SI 1 "register_operand" " r")
444 (match_operand:SI 2 "register_operand" " r"))))]
9304f876
CJW
445 ""
446 "msubr32\t%0, %1, %2"
447 [(set_attr "type" "alu")
448 (set_attr "length" "4")])
449
450
451;; Div Instructions.
452
453(define_insn "divmodsi4"
454 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
455 (div:SI (match_operand:SI 1 "register_operand" " r")
456 (match_operand:SI 2 "register_operand" " r")))
9304f876 457 (set (match_operand:SI 3 "register_operand" "=r")
8a498f99 458 (mod:SI (match_dup 1) (match_dup 2)))]
9304f876
CJW
459 ""
460 "divsr\t%0, %3, %1, %2"
461 [(set_attr "type" "alu")
462 (set_attr "length" "4")])
463
464(define_insn "udivmodsi4"
465 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
466 (udiv:SI (match_operand:SI 1 "register_operand" " r")
467 (match_operand:SI 2 "register_operand" " r")))
9304f876 468 (set (match_operand:SI 3 "register_operand" "=r")
8a498f99 469 (umod:SI (match_dup 1) (match_dup 2)))]
9304f876
CJW
470 ""
471 "divr\t%0, %3, %1, %2"
472 [(set_attr "type" "alu")
473 (set_attr "length" "4")])
474
475
476;; ----------------------------------------------------------------------------
477
478;; Boolean instructions.
479;; Note: We define the DImode versions in nds32-doubleword.md.
480
481;; ----------------------------------------------------------------------------
482;; 'AND' operation
483;; ----------------------------------------------------------------------------
484
485(define_insn "bitc"
486 [(set (match_operand:SI 0 "register_operand" "=r")
487 (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
488 (match_operand:SI 2 "register_operand" " r")))]
489 "TARGET_ISA_V3"
490 "bitc\t%0, %2, %1"
491 [(set_attr "type" "alu")
492 (set_attr "length" "4")]
493)
494
495(define_insn "andsi3"
73f793e3
RS
496 [(set (match_operand:SI 0 "register_operand" "=w, r, l, l, l, l, l, l, r, r, r, r, r")
497 (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r")
498 (match_operand:SI 2 "general_operand" " w, r, Izeb, Izeh, Ixls, Ix11, Ibms, Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
9304f876
CJW
499 ""
500{
501 HOST_WIDE_INT mask = INTVAL (operands[2]);
502 int zero_position;
503
504 /* 16-bit andi instructions:
505 andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3
506 andi Rt3,Ra3,0xffff -> zeh33 Rt3,Ra3
507 andi Rt3,Ra3,0x01 -> xlsb33 Rt3,Ra3
508 andi Rt3,Ra3,0x7ff -> x11b33 Rt3,Ra3
509 andi Rt3,Rt3,2^imm3u -> bmski33 Rt3,imm3u
510 andi Rt3,Rt3,(2^(imm3u+1))-1 -> fexti33 Rt3,imm3u. */
511
512 switch (which_alternative)
513 {
514 case 0:
515 return "and33\t%0, %2";
516 case 1:
517 return "and\t%0, %1, %2";
518 case 2:
519 return "zeb33\t%0, %1";
520 case 3:
521 return "zeh33\t%0, %1";
522 case 4:
523 return "xlsb33\t%0, %1";
524 case 5:
525 return "x11b33\t%0, %1";
526 case 6:
527 operands[2] = GEN_INT (floor_log2 (mask));
528 return "bmski33\t%0, %2";
529 case 7:
530 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
531 return "fexti33\t%0, %2";
532 case 8:
533 return "zeb\t%0, %1";
534 case 9:
535 return "zeh\t%0, %1";
536 case 10:
537 return "andi\t%0, %1, %2";
538 case 11:
539 operands[2] = GEN_INT (~mask);
540 return "bitci\t%0, %1, %2";
541 case 12:
542 /* If we reach this alternative,
543 it must pass the nds32_can_use_bclr_p() test,
544 so that we can guarantee there is only one 0-bit
545 within the immediate value. */
546 for (zero_position = 31; zero_position >= 0; zero_position--)
547 {
548 if ((INTVAL (operands[2]) & (1 << zero_position)) == 0)
549 {
550 /* Found the 0-bit position. */
551 operands[2] = GEN_INT (zero_position);
552 break;
553 }
554 }
555 return "bclr\t%0, %1, %2";
556
557 default:
558 gcc_unreachable ();
559 }
560}
561 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
562 (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")])
563
564(define_insn "*and_slli"
565 [(set (match_operand:SI 0 "register_operand" "= r")
566 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
567 (match_operand:SI 2 "immediate_operand" " Iu05"))
568 (match_operand:SI 3 "register_operand" " r")))]
569 "TARGET_ISA_V3"
570 "and_slli\t%0, %3, %1, %2"
571 [(set_attr "type" "alu")
572 (set_attr "length" "4")])
573
574(define_insn "*and_srli"
575 [(set (match_operand:SI 0 "register_operand" "= r")
576 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
577 (match_operand:SI 2 "immediate_operand" " Iu05"))
578 (match_operand:SI 3 "register_operand" " r")))]
579 "TARGET_ISA_V3"
580 "and_srli\t%0, %3, %1, %2"
581 [(set_attr "type" "alu")
582 (set_attr "length" "4")])
583
584
585;; ----------------------------------------------------------------------------
586;; 'OR' operation
587;; ----------------------------------------------------------------------------
588
589;; For V3/V3M ISA, we have 'or33' instruction.
590;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
591(define_insn "iorsi3"
73f793e3
RS
592 [(set (match_operand:SI 0 "register_operand" "=w, r, r, r")
593 (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
594 (match_operand:SI 2 "general_operand" " w, r, Iu15, Ie15")))]
9304f876
CJW
595 ""
596{
597 int one_position;
598
599 switch (which_alternative)
600 {
601 case 0:
602 return "or33\t%0, %2";
603 case 1:
604 return "or\t%0, %1, %2";
605 case 2:
606 return "ori\t%0, %1, %2";
607 case 3:
608 /* If we reach this alternative,
609 it must pass the nds32_can_use_bset_p() test,
610 so that we can guarantee there is only one 1-bit
611 within the immediate value. */
612 /* Use exact_log2() to search the 1-bit position. */
613 one_position = exact_log2 (INTVAL (operands[2]));
614 operands[2] = GEN_INT (one_position);
615 return "bset\t%0, %1, %2";
616
617 default:
618 gcc_unreachable ();
619 }
620}
621 [(set_attr "type" "alu,alu,alu,alu")
622 (set_attr "length" " 2, 4, 4, 4")])
623
624(define_insn "*or_slli"
625 [(set (match_operand:SI 0 "register_operand" "= r")
626 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
627 (match_operand:SI 2 "immediate_operand" " Iu05"))
628 (match_operand:SI 3 "register_operand" " r")))]
629 "TARGET_ISA_V3"
630 "or_slli\t%0, %3, %1, %2"
631 [(set_attr "type" "alu")
632 (set_attr "length" "4")])
633
634(define_insn "*or_srli"
635 [(set (match_operand:SI 0 "register_operand" "= r")
636 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
637 (match_operand:SI 2 "immediate_operand" " Iu05"))
638 (match_operand:SI 3 "register_operand" " r")))]
639 "TARGET_ISA_V3"
640 "or_srli\t%0, %3, %1, %2"
641 [(set_attr "type" "alu")
642 (set_attr "length" "4")])
643
644
645;; ----------------------------------------------------------------------------
646;; 'XOR' operation
647;; ----------------------------------------------------------------------------
648
649;; For V3/V3M ISA, we have 'xor33' instruction.
650;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
651(define_insn "xorsi3"
73f793e3
RS
652 [(set (match_operand:SI 0 "register_operand" "=w, r, r, r")
653 (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
654 (match_operand:SI 2 "general_operand" " w, r, Iu15, It15")))]
9304f876
CJW
655 ""
656{
657 int one_position;
658
659 switch (which_alternative)
660 {
661 case 0:
662 return "xor33\t%0, %2";
663 case 1:
664 return "xor\t%0, %1, %2";
665 case 2:
666 return "xori\t%0, %1, %2";
667 case 3:
668 /* If we reach this alternative,
669 it must pass the nds32_can_use_btgl_p() test,
670 so that we can guarantee there is only one 1-bit
671 within the immediate value. */
672 /* Use exact_log2() to search the 1-bit position. */
673 one_position = exact_log2 (INTVAL (operands[2]));
674 operands[2] = GEN_INT (one_position);
675 return "btgl\t%0, %1, %2";
676
677 default:
678 gcc_unreachable ();
679 }
680}
681 [(set_attr "type" "alu,alu,alu,alu")
682 (set_attr "length" " 2, 4, 4, 4")])
683
684(define_insn "*xor_slli"
685 [(set (match_operand:SI 0 "register_operand" "= r")
686 (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
687 (match_operand:SI 2 "immediate_operand" " Iu05"))
688 (match_operand:SI 3 "register_operand" " r")))]
689 "TARGET_ISA_V3"
690 "xor_slli\t%0, %3, %1, %2"
691 [(set_attr "type" "alu")
692 (set_attr "length" "4")])
693
694(define_insn "*xor_srli"
695 [(set (match_operand:SI 0 "register_operand" "= r")
696 (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
697 (match_operand:SI 2 "immediate_operand" " Iu05"))
698 (match_operand:SI 3 "register_operand" " r")))]
699 "TARGET_ISA_V3"
700 "xor_srli\t%0, %3, %1, %2"
701 [(set_attr "type" "alu")
702 (set_attr "length" "4")])
703
704;; Rotate Right Instructions.
705
706(define_insn "rotrsi3"
707 [(set (match_operand:SI 0 "register_operand" "= r, r")
708 (rotatert:SI (match_operand:SI 1 "register_operand" " r, r")
709 (match_operand:SI 2 "nonmemory_operand" " Iu05, r")))]
710 ""
711 "@
712 rotri\t%0, %1, %2
713 rotr\t%0, %1, %2"
714 [(set_attr "type" "alu,alu")
715 (set_attr "length" " 4, 4")])
716
717
718;; ----------------------------------------------------------------------------
719;; 'NEG' operation
720;; ----------------------------------------------------------------------------
721
722;; For V3/V3M ISA, we have 'neg33' instruction.
723;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
724;; And for V2 ISA, there is NO 'neg33' instruction.
725;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
726(define_insn "negsi2"
727 [(set (match_operand:SI 0 "register_operand" "=w, r")
728 (neg:SI (match_operand:SI 1 "register_operand" " w, r")))]
729 ""
730 "@
731 neg33\t%0, %1
732 subri\t%0, %1, 0"
733 [(set_attr "type" "alu,alu")
734 (set_attr "length" " 2, 4")])
735
736
737;; ----------------------------------------------------------------------------
738;; 'ONE_COMPLIMENT' operation
739;; ----------------------------------------------------------------------------
740
741;; For V3/V3M ISA, we have 'not33' instruction.
742;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
743(define_insn "one_cmplsi2"
744 [(set (match_operand:SI 0 "register_operand" "=w, r")
745 (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
746 ""
747 "@
748 not33\t%0, %1
749 nor\t%0, %1, %1"
750 [(set_attr "type" "alu,alu")
751 (set_attr "length" " 2, 4")])
752
753
754;; ----------------------------------------------------------------------------
755
756;; Shift instructions.
757
758(define_insn "ashlsi3"
759 [(set (match_operand:SI 0 "register_operand" "= l, r, r")
760 (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r")
761 (match_operand:SI 2 "nonmemory_operand" " Iu03, Iu05, r")))]
762 ""
763 "@
764 slli333\t%0, %1, %2
765 slli\t%0, %1, %2
766 sll\t%0, %1, %2"
767 [(set_attr "type" "alu,alu,alu")
768 (set_attr "length" " 2, 4, 4")])
769
770(define_insn "ashrsi3"
771 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
772 (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
773 (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))]
774 ""
775 "@
776 srai45\t%0, %2
777 srai\t%0, %1, %2
778 sra\t%0, %1, %2"
779 [(set_attr "type" "alu,alu,alu")
780 (set_attr "length" " 2, 4, 4")])
781
782(define_insn "lshrsi3"
783 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
784 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
785 (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))]
786 ""
787 "@
788 srli45\t%0, %2
789 srli\t%0, %1, %2
790 srl\t%0, %1, %2"
791 [(set_attr "type" "alu,alu,alu")
792 (set_attr "length" " 2, 4, 4")])
793
794
795;; ----------------------------------------------------------------------------
796
797;; ----------------------------------------------------------------------------
798;; Conditional Move patterns
799;; ----------------------------------------------------------------------------
800
801(define_expand "movsicc"
802 [(set (match_operand:SI 0 "register_operand" "")
803 (if_then_else:SI (match_operand 1 "comparison_operator" "")
804 (match_operand:SI 2 "register_operand" "")
805 (match_operand:SI 3 "register_operand" "")))]
806 "TARGET_CMOV"
807{
808 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
809 && GET_MODE (XEXP (operands[1], 0)) == SImode
810 && XEXP (operands[1], 1) == const0_rtx)
811 {
812 /* If the operands[1] rtx is already (eq X 0) or (ne X 0),
813 we have gcc generate original template rtx. */
814 goto create_template;
815 }
816 else
817 {
818 /* Since there is only 'slt'(Set when Less Than) instruction for
819 comparison in Andes ISA, the major strategy we use here is to
820 convert conditional move into 'LT + EQ' or 'LT + NE' rtx combination.
821 We design constraints properly so that the reload phase will assist
822 to make one source operand to use same register as result operand.
823 Then we can use cmovz/cmovn to catch the other source operand
824 which has different register. */
825 enum rtx_code code = GET_CODE (operands[1]);
826 enum rtx_code new_code = code;
827 rtx cmp_op0 = XEXP (operands[1], 0);
828 rtx cmp_op1 = XEXP (operands[1], 1);
829 rtx tmp;
830 int reverse = 0;
831
832 /* Main Goal: Use 'LT + EQ' or 'LT + NE' to target "then" part
833 Strategy : Reverse condition and swap comparison operands
834
835 For example:
836
837 a <= b ? P : Q (LE or LEU)
838 --> a > b ? Q : P (reverse condition)
839 --> b < a ? Q : P (swap comparison operands to achieve 'LT/LTU')
840
841 a >= b ? P : Q (GE or GEU)
842 --> a < b ? Q : P (reverse condition to achieve 'LT/LTU')
843
844 a < b ? P : Q (LT or LTU)
845 --> (NO NEED TO CHANGE, it is already 'LT/LTU')
846
847 a > b ? P : Q (GT or GTU)
848 --> b < a ? P : Q (swap comparison operands to achieve 'LT/LTU') */
849 switch (code)
850 {
851 case NE:
852 /* (a != b ? P : Q)
853 can be expressed as
854 (a == b ? Q : P)
855 so, fall through to reverse condition */
856 case GE: case GEU: case LE: case LEU:
857 new_code = reverse_condition (code);
858 reverse = 1;
859 break;
860 case EQ: case GT: case GTU: case LT: case LTU:
861 /* no need to reverse condition */
862 break;
863 default:
864 FAIL;
865 }
866
867 /* For '>' comparison operator, we swap operands
868 so that we can have 'LT/LTU' operator. */
869 if (new_code == GT || new_code == GTU)
870 {
871 tmp = cmp_op0;
872 cmp_op0 = cmp_op1;
873 cmp_op1 = tmp;
874
875 new_code = swap_condition (new_code);
876 }
877
878 /* Use a temporary register to store slt/slts result. */
879 tmp = gen_reg_rtx (SImode);
880
881 /* Split EQ and NE because we don't have direct comparison of EQ and NE.
882 If we don't split it, the conditional move transformation will fail
883 when producing (SET A (EQ B C)) or (SET A (NE B C)). */
884 if (new_code == EQ)
885 {
886 emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1));
887 emit_insn (gen_slt_compare (tmp, tmp, GEN_INT (1)));
888 }
889 else if (new_code == NE)
890 {
891 emit_insn (gen_xorsi3 (tmp, cmp_op0, cmp_op1));
892 emit_insn (gen_slt_compare (tmp, GEN_INT (0), tmp));
893 }
894 else
895 /* This emit_insn will create corresponding 'slt/slts' insturction. */
f7df4a84
RS
896 emit_insn (gen_rtx_SET (tmp, gen_rtx_fmt_ee (new_code, SImode,
897 cmp_op0, cmp_op1)));
9304f876
CJW
898
899 /* Change comparison semantic into (eq X 0) or (ne X 0) behavior
900 so that cmovz or cmovn will be matched later.
901
902 For reverse condition cases, we want to create a semantic that:
903 (eq X 0) --> pick up "else" part
904 For normal cases, we want to create a semantic that:
905 (ne X 0) --> pick up "then" part
906
907 Later we will have cmovz/cmovn instruction pattern to
908 match corresponding behavior and output instruction. */
909 operands[1] = gen_rtx_fmt_ee (reverse ? EQ : NE,
910 VOIDmode, tmp, const0_rtx);
911 }
912
913create_template:
914 do {} while(0); /* dummy line */
915})
916
917(define_insn "cmovz"
918 [(set (match_operand:SI 0 "register_operand" "=r, r")
919 (if_then_else:SI (eq (match_operand:SI 1 "register_operand" " r, r")
920 (const_int 0))
921 (match_operand:SI 2 "register_operand" " r, 0")
922 (match_operand:SI 3 "register_operand" " 0, r")))]
923 "TARGET_CMOV"
924 "@
925 cmovz\t%0, %2, %1
926 cmovn\t%0, %3, %1"
927 [(set_attr "type" "move")
928 (set_attr "length" "4")])
929
930(define_insn "cmovn"
931 [(set (match_operand:SI 0 "register_operand" "=r, r")
932 (if_then_else:SI (ne (match_operand:SI 1 "register_operand" " r, r")
933 (const_int 0))
934 (match_operand:SI 2 "register_operand" " r, 0")
935 (match_operand:SI 3 "register_operand" " 0, r")))]
936 "TARGET_CMOV"
937 "@
938 cmovn\t%0, %2, %1
939 cmovz\t%0, %3, %1"
940 [(set_attr "type" "move")
941 (set_attr "length" "4")])
942
943
944;; ----------------------------------------------------------------------------
945;; Conditional Branch patterns
946;; ----------------------------------------------------------------------------
947
948(define_expand "cbranchsi4"
949 [(set (pc)
950 (if_then_else (match_operator 0 "comparison_operator"
951 [(match_operand:SI 1 "register_operand" "")
952 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
953 (label_ref (match_operand 3 "" ""))
954 (pc)))]
955 ""
956{
957 rtx tmp_reg;
958 enum rtx_code code;
959
960 code = GET_CODE (operands[0]);
961
962 /* If operands[2] is (const_int 0),
963 we can use beqz,bnez,bgtz,bgez,bltz,or blez instructions.
964 So we have gcc generate original template rtx. */
965 if (GET_CODE (operands[2]) == CONST_INT)
966 if (INTVAL (operands[2]) == 0)
967 if ((code != GTU)
968 && (code != GEU)
969 && (code != LTU)
970 && (code != LEU))
971 goto create_template;
972
973 /* For other comparison, NDS32 ISA only has slt (Set-on-Less-Than)
974 behavior for the comparison, we might need to generate other
975 rtx patterns to achieve same semantic. */
976 switch (code)
977 {
978 case GT:
979 case GTU:
980 if (GET_CODE (operands[2]) == CONST_INT)
981 {
982 /* GT reg_A, const_int => !(LT reg_A, const_int + 1) */
983 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
984
985 /* We want to plus 1 into the integer value
986 of operands[2] to create 'slt' instruction.
987 This caculation is performed on the host machine,
988 which may be 64-bit integer.
989 So the meaning of caculation result may be
990 different from the 32-bit nds32 target.
991
992 For example:
993 0x7fffffff + 0x1 -> 0x80000000,
994 this value is POSITIVE on 64-bit machine,
995 but the expected value on 32-bit nds32 target
996 should be NEGATIVE value.
997
998 Hence, instead of using GEN_INT(), we use gen_int_mode() to
999 explicitly create SImode constant rtx. */
1000 operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode);
1001
1002 if (code == GT)
1003 {
1004 /* GT, use slts instruction */
1005 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1006 }
1007 else
1008 {
1009 /* GTU, use slt instruction */
1010 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1011 }
1012
1013 PUT_CODE (operands[0], EQ);
1014 operands[1] = tmp_reg;
1015 operands[2] = const0_rtx;
1016 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1017 operands[2], operands[3]));
1018
1019 DONE;
1020 }
1021 else
1022 {
1023 /* GT reg_A, reg_B => LT reg_B, reg_A */
1024 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1025
1026 if (code == GT)
1027 {
1028 /* GT, use slts instruction */
1029 emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1]));
1030 }
1031 else
1032 {
1033 /* GTU, use slt instruction */
1034 emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1]));
1035 }
1036
1037 PUT_CODE (operands[0], NE);
1038 operands[1] = tmp_reg;
1039 operands[2] = const0_rtx;
1040 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1041 operands[2], operands[3]));
1042
1043 DONE;
1044 }
1045
1046 case GE:
1047 case GEU:
1048 /* GE reg_A, reg_B => !(LT reg_A, reg_B) */
1049 /* GE reg_A, const_int => !(LT reg_A, const_int) */
1050 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1051
1052 if (code == GE)
1053 {
1054 /* GE, use slts instruction */
1055 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1056 }
1057 else
1058 {
1059 /* GEU, use slt instruction */
1060 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1061 }
1062
1063 PUT_CODE (operands[0], EQ);
1064 operands[1] = tmp_reg;
1065 operands[2] = const0_rtx;
1066 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1067 operands[2], operands[3]));
1068
1069 DONE;
1070
1071 case LT:
1072 case LTU:
1073 /* LT reg_A, reg_B => LT reg_A, reg_B */
1074 /* LT reg_A, const_int => LT reg_A, const_int */
1075 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1076
1077 if (code == LT)
1078 {
1079 /* LT, use slts instruction */
1080 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1081 }
1082 else
1083 {
1084 /* LTU, use slt instruction */
1085 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1086 }
1087
1088 PUT_CODE (operands[0], NE);
1089 operands[1] = tmp_reg;
1090 operands[2] = const0_rtx;
1091 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1092 operands[2], operands[3]));
1093
1094 DONE;
1095
1096 case LE:
1097 case LEU:
1098 if (GET_CODE (operands[2]) == CONST_INT)
1099 {
1100 /* LE reg_A, const_int => LT reg_A, const_int + 1 */
1101 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1102
1103 /* Note that (le:SI X INT_MAX) is not the same as (lt:SI X INT_MIN).
1104 We better have an assert here in case GCC does not properly
1105 optimize it away. The INT_MAX here is 0x7fffffff for target. */
1106 gcc_assert (code != LE || INTVAL (operands[2]) != 0x7fffffff);
1107 operands[2] = gen_int_mode (INTVAL (operands[2]) + 1, SImode);
1108
1109 if (code == LE)
1110 {
1111 /* LE, use slts instruction */
1112 emit_insn (gen_slts_compare (tmp_reg, operands[1], operands[2]));
1113 }
1114 else
1115 {
1116 /* LEU, use slt instruction */
1117 emit_insn (gen_slt_compare (tmp_reg, operands[1], operands[2]));
1118 }
1119
1120 PUT_CODE (operands[0], NE);
1121 operands[1] = tmp_reg;
1122 operands[2] = const0_rtx;
1123 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1124 operands[2], operands[3]));
1125
1126 DONE;
1127 }
1128 else
1129 {
1130 /* LE reg_A, reg_B => !(LT reg_B, reg_A) */
1131 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1132
1133 if (code == LE)
1134 {
1135 /* LE, use slts instruction */
1136 emit_insn (gen_slts_compare (tmp_reg, operands[2], operands[1]));
1137 }
1138 else
1139 {
1140 /* LEU, use slt instruction */
1141 emit_insn (gen_slt_compare (tmp_reg, operands[2], operands[1]));
1142 }
1143
1144 PUT_CODE (operands[0], EQ);
1145 operands[1] = tmp_reg;
1146 operands[2] = const0_rtx;
1147 emit_insn (gen_cbranchsi4 (operands[0], operands[1],
1148 operands[2], operands[3]));
1149
1150 DONE;
1151 }
1152
1153 case EQ:
1154 case NE:
1155 /* NDS32 ISA has various form for eq/ne behavior no matter
1156 what kind of the operand is.
1157 So just generate original template rtx. */
1158 goto create_template;
1159
1160 default:
1161 FAIL;
1162 }
1163
1164create_template:
1165 do {} while(0); /* dummy line */
1166})
1167
1168
1169(define_insn "*cbranchsi4_equality_zero"
1170 [(set (pc)
1171 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1172 [(match_operand:SI 1 "register_operand" "t, l, r")
1173 (const_int 0)])
1174 (label_ref (match_operand 2 "" ""))
1175 (pc)))]
1176 ""
1177{
1178 enum rtx_code code;
1179
1180 code = GET_CODE (operands[0]);
1181
1182 /* This zero-comparison conditional branch has two forms:
1183 32-bit instruction => beqz/bnez imm16s << 1
1184 16-bit instruction => beqzs8/bnezs8/beqz38/bnez38 imm8s << 1
1185
1186 For 32-bit case,
1187 we assume it is always reachable. (but check range -65500 ~ 65500)
1188
1189 For 16-bit case,
1190 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1191 However, since the $pc for nds32 is at the beginning of the instruction,
1192 we should leave some length space for current insn.
1193 So we use range -250 ~ 250. */
1194
1195 switch (get_attr_length (insn))
1196 {
1197 case 2:
1198 if (which_alternative == 0)
1199 {
1200 /* constraint: t */
1201 return (code == EQ) ? "beqzs8\t%2" : "bnezs8\t%2";
1202 }
1203 else if (which_alternative == 1)
1204 {
1205 /* constraint: l */
1206 return (code == EQ) ? "beqz38\t%1, %2" : "bnez38\t%1, %2";
1207 }
1208 else
1209 {
1210 /* constraint: r */
1211 /* For which_alternative==2, it should not be here. */
1212 gcc_unreachable ();
1213 }
1214 case 4:
1215 /* including constraints: t, l, and r */
1216 return (code == EQ) ? "beqz\t%1, %2" : "bnez\t%1, %2";
1217 case 6:
1218 if (which_alternative == 0)
1219 {
1220 /* constraint: t */
1221 if (code == EQ)
1222 {
1223 /* beqzs8 .L0
1224 =>
1225 bnezs8 .LCB0
1226 j .L0
1227 .LCB0:
1228 */
1229 return "bnezs8\t.LCB%=\;j\t%2\n.LCB%=:";
1230 }
1231 else
1232 {
1233 /* bnezs8 .L0
1234 =>
1235 beqzs8 .LCB0
1236 j .L0
1237 .LCB0:
1238 */
1239 return "beqzs8\t.LCB%=\;j\t%2\n.LCB%=:";
1240 }
1241 }
1242 else if (which_alternative == 1)
1243 {
1244 /* constraint: l */
1245 if (code == EQ)
1246 {
1247 /* beqz38 $r0, .L0
1248 =>
1249 bnez38 $r0, .LCB0
1250 j .L0
1251 .LCB0:
1252 */
1253 return "bnez38\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1254 }
1255 else
1256 {
1257 /* bnez38 $r0, .L0
1258 =>
1259 beqz38 $r0, .LCB0
1260 j .L0
1261 .LCB0:
1262 */
1263 return "beqz38\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1264 }
1265 }
1266 else
1267 {
1268 /* constraint: r */
1269 /* For which_alternative==2, it should not be here. */
1270 gcc_unreachable ();
1271 }
1272 case 8:
1273 /* constraint: t, l, r. */
1274 if (code == EQ)
1275 {
1276 /* beqz $r8, .L0
1277 =>
1278 bnez $r8, .LCB0
1279 j .L0
1280 .LCB0:
1281 */
1282 return "bnez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1283 }
1284 else
1285 {
1286 /* bnez $r8, .L0
1287 =>
1288 beqz $r8, .LCB0
1289 j .L0
1290 .LCB0:
1291 */
1292 return "beqz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1293 }
1294 default:
1295 gcc_unreachable ();
1296 }
1297}
1298 [(set_attr "type" "branch")
1299 (set_attr "enabled" "1")
1300 (set_attr_alternative "length"
1301 [
1302 ;; Alternative 0
1303 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1304 (le (minus (match_dup 2) (pc)) (const_int 250)))
1305 (if_then_else (match_test "TARGET_16_BIT")
1306 (const_int 2)
1307 (const_int 4))
1308 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1309 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1310 (const_int 4)
1311 (if_then_else (match_test "TARGET_16_BIT")
1312 (const_int 6)
1313 (const_int 8))))
1314 ;; Alternative 1
1315 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
1316 (le (minus (match_dup 2) (pc)) (const_int 250)))
1317 (if_then_else (match_test "TARGET_16_BIT")
1318 (const_int 2)
1319 (const_int 4))
1320 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1321 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1322 (const_int 4)
1323 (if_then_else (match_test "TARGET_16_BIT")
1324 (const_int 6)
1325 (const_int 8))))
1326 ;; Alternative 2
1327 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1328 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1329 (const_int 4)
1330 (const_int 8))
1331 ])])
1332
1333
1334;; This pattern is dedicated to V2 ISA,
1335;; because V2 DOES NOT HAVE beqc/bnec instruction.
1336(define_insn "*cbranchsi4_equality_reg"
1337 [(set (pc)
1338 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1339 [(match_operand:SI 1 "register_operand" "r")
1340 (match_operand:SI 2 "nds32_reg_constant_operand" "r")])
1341 (label_ref (match_operand 3 "" ""))
1342 (pc)))]
1343 "TARGET_ISA_V2"
1344{
1345 enum rtx_code code;
1346
1347 code = GET_CODE (operands[0]);
1348
1349 /* This register-comparison conditional branch has one form:
1350 32-bit instruction => beq/bne imm14s << 1
1351
1352 For 32-bit case,
1353 we assume it is always reachable. (but check range -16350 ~ 16350). */
1354
1355 switch (code)
1356 {
1357 case EQ:
1358 /* r, r */
1359 switch (get_attr_length (insn))
1360 {
1361 case 4:
1362 return "beq\t%1, %2, %3";
1363 case 8:
1364 /* beq $r0, $r1, .L0
1365 =>
1366 bne $r0, $r1, .LCB0
1367 j .L0
1368 .LCB0:
1369 */
1370 return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1371 default:
1372 gcc_unreachable ();
1373 }
1374
1375 case NE:
1376 /* r, r */
1377 switch (get_attr_length (insn))
1378 {
1379 case 4:
1380 return "bne\t%1, %2, %3";
1381 case 8:
1382 /* bne $r0, $r1, .L0
1383 =>
1384 beq $r0, $r1, .LCB0
1385 j .L0
1386 .LCB0:
1387 */
1388 return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1389 default:
1390 gcc_unreachable ();
1391 }
1392
1393 default:
1394 gcc_unreachable ();
1395 }
1396}
1397 [(set_attr "type" "branch")
1398 (set (attr "length")
1399 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1400 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1401 (const_int 4)
1402 (const_int 8)))])
1403
1404
1405;; This pattern is dedicated to V3/V3M,
1406;; because V3/V3M DO HAVE beqc/bnec instruction.
1407(define_insn "*cbranchsi4_equality_reg_or_const_int"
1408 [(set (pc)
1409 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
1410 [(match_operand:SI 1 "register_operand" "r, r")
1411 (match_operand:SI 2 "nds32_reg_constant_operand" "r, Is11")])
1412 (label_ref (match_operand 3 "" ""))
1413 (pc)))]
1414 "TARGET_ISA_V3 || TARGET_ISA_V3M"
1415{
1416 enum rtx_code code;
1417
1418 code = GET_CODE (operands[0]);
1419
1420 /* This register-comparison conditional branch has one form:
1421 32-bit instruction => beq/bne imm14s << 1
1422 32-bit instruction => beqc/bnec imm8s << 1
1423
1424 For 32-bit case, we assume it is always reachable.
1425 (but check range -16350 ~ 16350 and -250 ~ 250). */
1426
1427 switch (code)
1428 {
1429 case EQ:
1430 if (which_alternative == 0)
1431 {
1432 /* r, r */
1433 switch (get_attr_length (insn))
1434 {
1435 case 4:
1436 return "beq\t%1, %2, %3";
1437 case 8:
1438 /* beq $r0, $r1, .L0
1439 =>
1440 bne $r0, $r1, .LCB0
1441 j .L0
1442 .LCB0:
1443 */
1444 return "bne\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1445 default:
1446 gcc_unreachable ();
1447 }
1448 }
1449 else
1450 {
1451 /* r, Is11 */
1452 switch (get_attr_length (insn))
1453 {
1454 case 4:
1455 return "beqc\t%1, %2, %3";
1456 case 8:
1457 /* beqc $r0, constant, .L0
1458 =>
1459 bnec $r0, constant, .LCB0
1460 j .L0
1461 .LCB0:
1462 */
1463 return "bnec\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1464 default:
1465 gcc_unreachable ();
1466 }
1467 }
1468 case NE:
1469 if (which_alternative == 0)
1470 {
1471 /* r, r */
1472 switch (get_attr_length (insn))
1473 {
1474 case 4:
1475 return "bne\t%1, %2, %3";
1476 case 8:
1477 /* bne $r0, $r1, .L0
1478 =>
1479 beq $r0, $r1, .LCB0
1480 j .L0
1481 .LCB0:
1482 */
1483 return "beq\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1484 default:
1485 gcc_unreachable ();
1486 }
1487 }
1488 else
1489 {
1490 /* r, Is11 */
1491 switch (get_attr_length (insn))
1492 {
1493 case 4:
1494 return "bnec\t%1, %2, %3";
1495 case 8:
1496 /* bnec $r0, constant, .L0
1497 =>
1498 beqc $r0, constant, .LCB0
1499 j .L0
1500 .LCB0:
1501 */
1502 return "beqc\t%1, %2, .LCB%=\;j\t%3\n.LCB%=:";
1503 default:
1504 gcc_unreachable ();
1505 }
1506 }
1507 default:
1508 gcc_unreachable ();
1509 }
1510}
1511 [(set_attr "type" "branch")
1512 (set_attr_alternative "length"
1513 [
1514 ;; Alternative 0
1515 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1516 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1517 (const_int 4)
1518 (const_int 8))
1519 ;; Alternative 1
1520 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1521 (le (minus (match_dup 3) (pc)) (const_int 250)))
1522 (const_int 4)
1523 (const_int 8))
1524 ])])
1525
1526
1527(define_insn "*cbranchsi4_greater_less_zero"
1528 [(set (pc)
1529 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1530 [(match_operand:SI 1 "register_operand" "r")
1531 (const_int 0)])
1532 (label_ref (match_operand 2 "" ""))
1533 (pc)))]
1534 ""
1535{
1536 enum rtx_code code;
1537
1538 code = GET_CODE (operands[0]);
1539
1540 /* This zero-greater-less-comparison conditional branch has one form:
1541 32-bit instruction => bgtz/bgez/bltz/blez imm16s << 1
1542
1543 For 32-bit case, we assume it is always reachable.
1544 (but check range -65500 ~ 65500). */
1545
1546 if (get_attr_length (insn) == 8)
1547 {
1548 /* The branch target is too far to simply use one
1549 bgtz/bgez/bltz/blez instruction.
1550 We need to reverse condition and use 'j' to jump to the target. */
1551 switch (code)
1552 {
1553 case GT:
1554 /* bgtz $r8, .L0
1555 =>
1556 blez $r8, .LCB0
1557 j .L0
1558 .LCB0:
1559 */
1560 return "blez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1561 case GE:
1562 /* bgez $r8, .L0
1563 =>
1564 bltz $r8, .LCB0
1565 j .L0
1566 .LCB0:
1567 */
1568 return "bltz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1569 case LT:
1570 /* bltz $r8, .L0
1571 =>
1572 bgez $r8, .LCB0
1573 j .L0
1574 .LCB0:
1575 */
1576 return "bgez\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1577 case LE:
1578 /* blez $r8, .L0
1579 =>
1580 bgtz $r8, .LCB0
1581 j .L0
1582 .LCB0:
1583 */
1584 return "bgtz\t%1, .LCB%=\;j\t%2\n.LCB%=:";
1585 default:
1586 gcc_unreachable ();
1587 }
1588 }
1589
1590 switch (code)
1591 {
1592 case GT:
1593 return "bgtz\t%1, %2";
1594 case GE:
1595 return "bgez\t%1, %2";
1596 case LT:
1597 return "bltz\t%1, %2";
1598 case LE:
1599 return "blez\t%1, %2";
1600 default:
1601 gcc_unreachable ();
1602 }
1603}
1604 [(set_attr "type" "branch")
1605 (set (attr "length")
1606 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1607 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1608 (const_int 4)
1609 (const_int 8)))])
1610
1611
1612(define_expand "cstoresi4"
1613 [(set (match_operand:SI 0 "register_operand" "")
1614 (match_operator:SI 1 "comparison_operator"
1615 [(match_operand:SI 2 "register_operand" "")
1616 (match_operand:SI 3 "nonmemory_operand" "")]))]
1617 ""
1618{
1619 rtx tmp_reg;
1620 enum rtx_code code;
1621
1622 code = GET_CODE (operands[1]);
1623
1624 switch (code)
1625 {
1626 case EQ:
1627 if (GET_CODE (operands[3]) == CONST_INT)
1628 {
1629 /* reg_R = (reg_A == const_int_B)
1630 --> addi reg_C, reg_A, -const_int_B
1631 slti reg_R, reg_C, const_int_1 */
1632 tmp_reg = gen_reg_rtx (SImode);
1633 operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode);
1634 /* If the integer value is not in the range of imm15s,
1635 we need to force register first because our addsi3 pattern
1636 only accept nds32_rimm15s_operand predicate. */
1637 if (!satisfies_constraint_Is15 (operands[3]))
1638 operands[3] = force_reg (SImode, operands[3]);
1639 emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3]));
1640 emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx));
1641
1642 DONE;
1643 }
1644 else
1645 {
1646 /* reg_R = (reg_A == reg_B)
1647 --> xor reg_C, reg_A, reg_B
1648 slti reg_R, reg_C, const_int_1 */
1649 tmp_reg = gen_reg_rtx (SImode);
1650 emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3]));
1651 emit_insn (gen_slt_compare (operands[0], tmp_reg, const1_rtx));
1652
1653 DONE;
1654 }
1655
1656 case NE:
1657 if (GET_CODE (operands[3]) == CONST_INT)
1658 {
1659 /* reg_R = (reg_A != const_int_B)
1660 --> addi reg_C, reg_A, -const_int_B
1661 slti reg_R, const_int_0, reg_C */
1662 tmp_reg = gen_reg_rtx (SImode);
1663 operands[3] = gen_int_mode (-INTVAL (operands[3]), SImode);
1664 /* If the integer value is not in the range of imm15s,
1665 we need to force register first because our addsi3 pattern
1666 only accept nds32_rimm15s_operand predicate. */
1667 if (!satisfies_constraint_Is15 (operands[3]))
1668 operands[3] = force_reg (SImode, operands[3]);
1669 emit_insn (gen_addsi3 (tmp_reg, operands[2], operands[3]));
1670 emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg));
1671
1672 DONE;
1673 }
1674 else
1675 {
1676 /* reg_R = (reg_A != reg_B)
1677 --> xor reg_C, reg_A, reg_B
1678 slti reg_R, const_int_0, reg_C */
1679 tmp_reg = gen_reg_rtx (SImode);
1680 emit_insn (gen_xorsi3 (tmp_reg, operands[2], operands[3]));
1681 emit_insn (gen_slt_compare (operands[0], const0_rtx, tmp_reg));
1682
1683 DONE;
1684 }
1685
1686 case GT:
1687 case GTU:
1688 /* reg_R = (reg_A > reg_B) --> slt reg_R, reg_B, reg_A */
1689 /* reg_R = (reg_A > const_int_B) --> slt reg_R, const_int_B, reg_A */
1690 if (code == GT)
1691 {
1692 /* GT, use slts instruction */
1693 emit_insn (gen_slts_compare (operands[0], operands[3], operands[2]));
1694 }
1695 else
1696 {
1697 /* GTU, use slt instruction */
1698 emit_insn (gen_slt_compare (operands[0], operands[3], operands[2]));
1699 }
1700
1701 DONE;
1702
1703 case GE:
1704 case GEU:
1705 if (GET_CODE (operands[3]) == CONST_INT)
1706 {
1707 /* reg_R = (reg_A >= const_int_B)
1708 --> movi reg_C, const_int_B - 1
1709 slt reg_R, reg_C, reg_A */
1710 tmp_reg = gen_reg_rtx (SImode);
1711
1712 emit_insn (gen_movsi (tmp_reg,
1713 gen_int_mode (INTVAL (operands[3]) - 1,
1714 SImode)));
1715 if (code == GE)
1716 {
1717 /* GE, use slts instruction */
1718 emit_insn (gen_slts_compare (operands[0], tmp_reg, operands[2]));
1719 }
1720 else
1721 {
1722 /* GEU, use slt instruction */
1723 emit_insn (gen_slt_compare (operands[0], tmp_reg, operands[2]));
1724 }
1725
1726 DONE;
1727 }
1728 else
1729 {
1730 /* reg_R = (reg_A >= reg_B)
1731 --> slt reg_R, reg_A, reg_B
1732 xori reg_R, reg_R, const_int_1 */
1733 if (code == GE)
1734 {
1735 /* GE, use slts instruction */
1736 emit_insn (gen_slts_compare (operands[0],
1737 operands[2], operands[3]));
1738 }
1739 else
1740 {
1741 /* GEU, use slt instruction */
1742 emit_insn (gen_slt_compare (operands[0],
1743 operands[2], operands[3]));
1744 }
1745
1746 /* perform 'not' behavior */
1747 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
1748
1749 DONE;
1750 }
1751
1752 case LT:
1753 case LTU:
1754 /* reg_R = (reg_A < reg_B) --> slt reg_R, reg_A, reg_B */
1755 /* reg_R = (reg_A < const_int_B) --> slt reg_R, reg_A, const_int_B */
1756 if (code == LT)
1757 {
1758 /* LT, use slts instruction */
1759 emit_insn (gen_slts_compare (operands[0], operands[2], operands[3]));
1760 }
1761 else
1762 {
1763 /* LTU, use slt instruction */
1764 emit_insn (gen_slt_compare (operands[0], operands[2], operands[3]));
1765 }
1766
1767 DONE;
1768
1769 case LE:
1770 case LEU:
1771 if (GET_CODE (operands[3]) == CONST_INT)
1772 {
1773 /* reg_R = (reg_A <= const_int_B)
1774 --> movi reg_C, const_int_B + 1
1775 slt reg_R, reg_A, reg_C */
1776 tmp_reg = gen_reg_rtx (SImode);
1777
1778 emit_insn (gen_movsi (tmp_reg,
1779 gen_int_mode (INTVAL (operands[3]) + 1,
1780 SImode)));
1781 if (code == LE)
1782 {
1783 /* LE, use slts instruction */
1784 emit_insn (gen_slts_compare (operands[0], operands[2], tmp_reg));
1785 }
1786 else
1787 {
1788 /* LEU, use slt instruction */
1789 emit_insn (gen_slt_compare (operands[0], operands[2], tmp_reg));
1790 }
1791
1792 DONE;
1793 }
1794 else
1795 {
1796 /* reg_R = (reg_A <= reg_B) --> slt reg_R, reg_B, reg_A
1797 xori reg_R, reg_R, const_int_1 */
1798 if (code == LE)
1799 {
1800 /* LE, use slts instruction */
1801 emit_insn (gen_slts_compare (operands[0],
1802 operands[3], operands[2]));
1803 }
1804 else
1805 {
1806 /* LEU, use slt instruction */
1807 emit_insn (gen_slt_compare (operands[0],
1808 operands[3], operands[2]));
1809 }
1810
1811 /* perform 'not' behavior */
1812 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
1813
1814 DONE;
1815 }
1816
1817
1818 default:
1819 gcc_unreachable ();
1820 }
1821})
1822
1823
1824(define_insn "slts_compare"
1825 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1826 (lt:SI (match_operand:SI 1 "nonmemory_operand" " d, d, r, r")
1827 (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))]
1828 ""
1829 "@
1830 slts45\t%1, %2
1831 sltsi45\t%1, %2
1832 slts\t%0, %1, %2
1833 sltsi\t%0, %1, %2"
1834 [(set_attr "type" "compare,compare,compare,compare")
1835 (set_attr "length" " 2, 2, 4, 4")])
1836
1837(define_insn "slt_compare"
1838 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1839 (ltu:SI (match_operand:SI 1 "nonmemory_operand" " d, d, r, r")
1840 (match_operand:SI 2 "nonmemory_operand" " r, Iu05, r, Is15")))]
1841 ""
1842 "@
1843 slt45\t%1, %2
1844 slti45\t%1, %2
1845 slt\t%0, %1, %2
1846 slti\t%0, %1, %2"
1847 [(set_attr "type" "compare,compare,compare,compare")
1848 (set_attr "length" " 2, 2, 4, 4")])
1849
1850
1851;; ----------------------------------------------------------------------------
1852
1853;; Unconditional and other jump instructions.
1854
1855(define_insn "jump"
1856 [(set (pc) (label_ref (match_operand 0 "" "")))]
1857 ""
1858{
1859 /* This unconditional jump has two forms:
1860 32-bit instruction => j imm24s << 1
1861 16-bit instruction => j8 imm8s << 1
1862
1863 For 32-bit case,
1864 we assume it is always reachable.
1865 For 16-bit case,
1866 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1867 However, since the $pc for nds32 is at the beginning of the instruction,
1868 we should leave some length space for current insn.
1869 So we use range -250 ~ 250. */
1870 switch (get_attr_length (insn))
1871 {
1872 case 2:
1873 return "j8\t%0";
1874 case 4:
1875 return "j\t%0";
1876 default:
1877 gcc_unreachable ();
1878 }
1879}
1880 [(set_attr "type" "branch")
1881 (set_attr "enabled" "1")
1882 (set (attr "length")
1883 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1884 (le (minus (match_dup 0) (pc)) (const_int 250)))
1885 (if_then_else (match_test "TARGET_16_BIT")
1886 (const_int 2)
1887 (const_int 4))
1888 (const_int 4)))])
1889
1890(define_insn "indirect_jump"
1891 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1892 ""
1893 "@
1894 jr5\t%0
1895 jr\t%0"
1896 [(set_attr "type" "branch,branch")
1897 (set_attr "length" " 2, 4")])
1898
1899;; Subroutine call instruction returning no value.
1900;; operands[0]: It should be a mem RTX whose address is
026c3cfd 1901;; the address of the function.
9304f876
CJW
1902;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
1903;; operands[2]: It is the number of registers used as operands.
1904
1905(define_expand "call"
1906 [(parallel [(call (match_operand 0 "memory_operand" "")
1907 (match_operand 1))
1f7b8028
CJW
1908 (clobber (reg:SI LP_REGNUM))
1909 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1910 ""
1911 ""
1912)
1913
1914(define_insn "*call_register"
1915 [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
1916 (match_operand 1))
1f7b8028
CJW
1917 (clobber (reg:SI LP_REGNUM))
1918 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1919 ""
1920 "@
1921 jral5\t%0
1922 jral\t%0"
1923 [(set_attr "type" "branch,branch")
1924 (set_attr "length" " 2, 4")])
1925
1926(define_insn "*call_immediate"
1927 [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
1928 (match_operand 1))
1f7b8028
CJW
1929 (clobber (reg:SI LP_REGNUM))
1930 (clobber (reg:SI TA_REGNUM))])]
9304f876 1931 ""
1f7b8028
CJW
1932{
1933 if (TARGET_CMODEL_LARGE)
1934 return "bal\t%0";
1935 else
1936 return "jal\t%0";
1937}
9304f876 1938 [(set_attr "type" "branch")
1f7b8028
CJW
1939 (set (attr "length")
1940 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1941 (const_int 12)
1942 (const_int 4)))])
9304f876
CJW
1943
1944
1945;; Subroutine call instruction returning a value.
1946;; operands[0]: It is the hard regiser in which the value is returned.
1947;; The rest three operands are the same as the
1948;; three operands of the 'call' instruction.
1949;; (but with numbers increased by one)
1950
1951(define_expand "call_value"
1952 [(parallel [(set (match_operand 0)
1953 (call (match_operand 1 "memory_operand" "")
1954 (match_operand 2)))
1f7b8028
CJW
1955 (clobber (reg:SI LP_REGNUM))
1956 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1957 ""
1958 ""
1959)
1960
1961(define_insn "*call_value_register"
1962 [(parallel [(set (match_operand 0)
1963 (call (mem (match_operand:SI 1 "register_operand" "r, r"))
1964 (match_operand 2)))
1f7b8028
CJW
1965 (clobber (reg:SI LP_REGNUM))
1966 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1967 ""
1968 "@
1969 jral5\t%1
1970 jral\t%1"
1971 [(set_attr "type" "branch,branch")
1972 (set_attr "length" " 2, 4")])
1973
1974(define_insn "*call_value_immediate"
1975 [(parallel [(set (match_operand 0)
1976 (call (mem (match_operand:SI 1 "immediate_operand" "i"))
1977 (match_operand 2)))
1f7b8028
CJW
1978 (clobber (reg:SI LP_REGNUM))
1979 (clobber (reg:SI TA_REGNUM))])]
9304f876 1980 ""
1f7b8028
CJW
1981{
1982 if (TARGET_CMODEL_LARGE)
1983 return "bal\t%1";
1984 else
1985 return "jal\t%1";
1986}
9304f876 1987 [(set_attr "type" "branch")
1f7b8028
CJW
1988 (set (attr "length")
1989 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1990 (const_int 12)
1991 (const_int 4)))])
9304f876
CJW
1992
1993
d6529176
CJW
1994;; ----------------------------------------------------------------------------
1995
1996;; The sibcall patterns.
1997
1998;; sibcall
1999;; sibcall_register
2000;; sibcall_immediate
2001
2002(define_expand "sibcall"
2003 [(parallel [(call (match_operand 0 "memory_operand" "")
2004 (const_int 0))
2005 (clobber (reg:SI TA_REGNUM))
2006 (return)])]
2007 ""
2008 ""
2009)
2010
2011(define_insn "*sibcall_register"
2012 [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
2013 (match_operand 1))
2014 (clobber (reg:SI TA_REGNUM))
2015 (return)])]
2016 ""
2017 "@
2018 jr5\t%0
2019 jr\t%0"
2020 [(set_attr "type" "branch,branch")
2021 (set_attr "length" " 2, 4")])
2022
2023(define_insn "*sibcall_immediate"
2024 [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
2025 (match_operand 1))
2026 (clobber (reg:SI TA_REGNUM))
2027 (return)])]
2028 ""
2029{
2030 if (TARGET_CMODEL_LARGE)
2031 return "b\t%0";
2032 else
2033 return "j\t%0";
2034}
2035 [(set_attr "type" "branch")
2036 (set (attr "length")
2037 (if_then_else (match_test "TARGET_CMODEL_LARGE")
2038 (const_int 12)
2039 (const_int 4)))])
2040
2041;; sibcall_value
2042;; sibcall_value_register
2043;; sibcall_value_immediate
2044
2045(define_expand "sibcall_value"
2046 [(parallel [(set (match_operand 0)
2047 (call (match_operand 1 "memory_operand" "")
2048 (const_int 0)))
2049 (clobber (reg:SI TA_REGNUM))
2050 (return)])]
2051 ""
2052 ""
2053)
2054
2055(define_insn "*sibcall_value_register"
2056 [(parallel [(set (match_operand 0)
2057 (call (mem (match_operand:SI 1 "register_operand" "r, r"))
2058 (match_operand 2)))
2059 (clobber (reg:SI TA_REGNUM))
2060 (return)])]
2061 ""
2062 "@
2063 jr5\t%1
2064 jr\t%1"
2065 [(set_attr "type" "branch,branch")
2066 (set_attr "length" " 2, 4")])
2067
2068(define_insn "*sibcall_value_immediate"
2069 [(parallel [(set (match_operand 0)
2070 (call (mem (match_operand:SI 1 "immediate_operand" "i"))
2071 (match_operand 2)))
2072 (clobber (reg:SI TA_REGNUM))
2073 (return)])]
2074 ""
2075{
2076 if (TARGET_CMODEL_LARGE)
2077 return "b\t%1";
2078 else
2079 return "j\t%1";
2080}
2081 [(set_attr "type" "branch")
2082 (set (attr "length")
2083 (if_then_else (match_test "TARGET_CMODEL_LARGE")
2084 (const_int 12)
2085 (const_int 4)))])
2086
2087
2088;; ----------------------------------------------------------------------------
2089
9304f876
CJW
2090;; prologue and epilogue.
2091
2092(define_expand "prologue" [(const_int 0)]
2093 ""
2094{
2da1e7c0 2095 /* Note that only under V3/V3M ISA, we could use v3push prologue.
a6c7e777
MC
2096 In addition, we need to check if v3push is indeed available. */
2097 if (NDS32_V3PUSH_AVAILABLE_P)
9304f876
CJW
2098 nds32_expand_prologue_v3push ();
2099 else
2100 nds32_expand_prologue ();
2101 DONE;
2102})
2103
2104(define_expand "epilogue" [(const_int 0)]
2105 ""
2106{
2da1e7c0 2107 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
a6c7e777
MC
2108 In addition, we need to check if v3push is indeed available. */
2109 if (NDS32_V3PUSH_AVAILABLE_P)
d6529176
CJW
2110 nds32_expand_epilogue_v3pop (false);
2111 else
2112 nds32_expand_epilogue (false);
2113 DONE;
2114})
2115
2116(define_expand "sibcall_epilogue" [(const_int 0)]
2117 ""
2118{
2119 /* Pass true to indicate that this is sibcall epilogue and
2120 exit from a function without the final branch back to the
2121 calling function. */
a6c7e777 2122 nds32_expand_epilogue (true);
d6529176 2123
9304f876
CJW
2124 DONE;
2125})
2126
2127
2128;; nop instruction.
2129
2130(define_insn "nop"
2131 [(const_int 0)]
2132 ""
2133{
2134 if (TARGET_16_BIT)
2135 return "nop16";
2136 else
2137 return "nop";
2138}
2139 [(set_attr "type" "misc")
2140 (set_attr "enabled" "1")
2141 (set (attr "length")
2142 (if_then_else (match_test "TARGET_16_BIT")
2143 (const_int 2)
2144 (const_int 4)))])
2145
2146
2147;; ----------------------------------------------------------------------------
2148;; Stack push/pop operations
2149;; ----------------------------------------------------------------------------
2150
2151;; The pattern for stack push.
2152;; Both stack_push_multiple and stack_v3push use the following pattern.
2153;; So we need to use TARGET_V3PUSH to determine the instruction length.
2154(define_insn "*stack_push"
2155 [(match_parallel 0 "nds32_stack_push_operation"
2156 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
2157 (match_operand:SI 1 "const_int_operand" "")))
2158 (match_operand:SI 2 "register_operand" ""))
2159 ])]
2160 ""
2161{
6f3d3f9c 2162 return nds32_output_stack_push (operands[0]);
9304f876 2163}
264159d2
KC
2164 [(set_attr "type" "store_multiple")
2165 (set_attr "combo" "12")
9304f876
CJW
2166 (set_attr "enabled" "1")
2167 (set (attr "length")
6f3d3f9c
CJW
2168 (if_then_else (match_test "TARGET_V3PUSH
2169 && !nds32_isr_function_p (cfun->decl)
2170 && (cfun->machine->va_args_size == 0)")
9304f876
CJW
2171 (const_int 2)
2172 (const_int 4)))])
2173
2174
2175;; The pattern for stack pop.
2176;; Both stack_pop_multiple and stack_v3pop use the following pattern.
2177;; So we need to use TARGET_V3PUSH to determine the instruction length.
2178(define_insn "*stack_pop"
2179 [(match_parallel 0 "nds32_stack_pop_operation"
2180 [(set (match_operand:SI 1 "register_operand" "")
2181 (mem:SI (reg:SI SP_REGNUM)))
2182 ])]
2183 ""
2184{
6f3d3f9c 2185 return nds32_output_stack_pop (operands[0]);
9304f876 2186}
264159d2
KC
2187 [(set_attr "type" "load_multiple")
2188 (set_attr "combo" "12")
9304f876
CJW
2189 (set_attr "enabled" "1")
2190 (set (attr "length")
6f3d3f9c
CJW
2191 (if_then_else (match_test "TARGET_V3PUSH
2192 && !nds32_isr_function_p (cfun->decl)
2193 && (cfun->machine->va_args_size == 0)")
9304f876
CJW
2194 (const_int 2)
2195 (const_int 4)))])
2196
2197
2198;; ----------------------------------------------------------------------------
03390cda 2199;; Return operation patterns
9304f876
CJW
2200;; ----------------------------------------------------------------------------
2201
03390cda
CJW
2202;; Use this pattern to expand a return instruction
2203;; with simple_return rtx if no epilogue is required.
2204(define_expand "return"
2205 [(simple_return)]
2206 "nds32_can_use_return_insn ()"
2207 ""
2208)
9304f876 2209
03390cda
CJW
2210;; This pattern is expanded only by the shrink-wrapping optimization
2211;; on paths where the function prologue has not been executed.
2212(define_expand "simple_return"
2213 [(simple_return)]
2214 ""
2215 ""
2216)
2217
2218(define_insn "return_internal"
2219 [(simple_return)]
9304f876
CJW
2220 ""
2221{
2222 if (TARGET_16_BIT)
2223 return "ret5";
2224 else
2225 return "ret";
2226}
03390cda 2227 [(set_attr "type" "branch")
9304f876
CJW
2228 (set_attr "enabled" "1")
2229 (set (attr "length")
2230 (if_then_else (match_test "TARGET_16_BIT")
2231 (const_int 2)
2232 (const_int 4)))])
2233
2234
2235;; ----------------------------------------------------------------------------
2236;; Jump Table patterns
2237;; ----------------------------------------------------------------------------
2238;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
2239;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
2240;;
2241;; operands[0]: The index to dispatch on.
2242;; operands[1]: The lower bound for indices in the table.
2243;; operands[2]: The total range of indices int the table.
2244;; i.e. The largest index minus the smallest one.
2245;; operands[3]: A label that precedes the table itself.
2246;; operands[4]: A label to jump to if the index has a value outside the bounds.
2247;;
2248;; We need to create following sequences for jump table code generation:
2249;; A) k <-- (plus (operands[0]) (-operands[1]))
2250;; B) if (gtu k operands[2]) then goto operands[4]
2251;; C) t <-- operands[3]
2252;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
2253;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
2254;; F) jump to target with register t or z
2255;;
2256;; The steps C, D, E, and F are performed by casesi_internal pattern.
2257(define_expand "casesi"
2258 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
2259 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
2260 (match_operand:SI 2 "immediate_operand" "i") ; total range
2261 (match_operand:SI 3 "" "") ; table label
2262 (match_operand:SI 4 "" "")] ; Out of range label
2263 ""
2264{
2265 rtx add_tmp;
2266 rtx reg, test;
2267
2268 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
2269 if (operands[1] != const0_rtx)
2270 {
2271 reg = gen_reg_rtx (SImode);
2272 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
2273
2274 /* If the integer value is not in the range of imm15s,
8a498f99
CJW
2275 we need to force register first because our addsi3 pattern
2276 only accept nds32_rimm15s_operand predicate. */
9304f876
CJW
2277 add_tmp = force_reg (SImode, add_tmp);
2278
2279 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
2280 operands[0] = reg;
2281 }
2282
2283 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
2284 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
2285 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
2286 operands[4]));
2287
9759608c
SB
2288 /* Step C, D, E, and F, using another temporary register. */
2289 rtx tmp = gen_reg_rtx (SImode);
2290 emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
9304f876
CJW
2291 DONE;
2292})
2293
2294;; We are receiving operands from casesi pattern:
2295;;
2296;; operands[0]: The index that have been substracted with lower bound.
2297;; operands[1]: A label that precedes the table itself.
2298;; operands[2]: A temporary register to retrieve value in table.
2299;;
2300;; We need to perform steps C, D, E, and F:
2301;;
2302;; C) t <-- operands[1]
2303;; D) z <-- (mem (plus (operands[0] << m) t))
2304;; m is 2 for normal jump table.
2305;; m is 0, 1, or 2 for pc relative jump table based on diff size.
2306;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
2307;; F) Jump to target with register t or z.
2308;;
2309;; The USE in this pattern is needed to tell flow analysis that this is
2310;; a CASESI insn. It has no other purpose.
2311(define_insn "casesi_internal"
2312 [(parallel [(set (pc)
2313 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
2314 (const_int 4))
2315 (label_ref (match_operand 1 "" "")))))
2316 (use (label_ref (match_dup 1)))
24f036fb 2317 (clobber (match_operand:SI 2 "register_operand" "=r"))
9304f876
CJW
2318 (clobber (reg:SI TA_REGNUM))])]
2319 ""
2320{
2321 if (CASE_VECTOR_PC_RELATIVE)
2322 return nds32_output_casesi_pc_relative (operands);
2323 else
2324 return nds32_output_casesi (operands);
2325}
2326 [(set_attr "length" "20")
2327 (set_attr "type" "alu")])
2328
2329;; ----------------------------------------------------------------------------
2330
2331;; Performance Extension
2332
2333(define_insn "clzsi2"
2334 [(set (match_operand:SI 0 "register_operand" "=r")
2335 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
aa4b851c 2336 "TARGET_EXT_PERF"
9304f876
CJW
2337 "clz\t%0, %1"
2338 [(set_attr "type" "alu")
2339 (set_attr "length" "4")])
2340
2341(define_insn "smaxsi3"
2342 [(set (match_operand:SI 0 "register_operand" "=r")
2343 (smax:SI (match_operand:SI 1 "register_operand" " r")
2344 (match_operand:SI 2 "register_operand" " r")))]
aa4b851c 2345 "TARGET_EXT_PERF"
9304f876
CJW
2346 "max\t%0, %1, %2"
2347 [(set_attr "type" "alu")
2348 (set_attr "length" "4")])
2349
2350(define_insn "sminsi3"
2351 [(set (match_operand:SI 0 "register_operand" "=r")
2352 (smin:SI (match_operand:SI 1 "register_operand" " r")
2353 (match_operand:SI 2 "register_operand" " r")))]
aa4b851c 2354 "TARGET_EXT_PERF"
9304f876
CJW
2355 "min\t%0, %1, %2"
2356 [(set_attr "type" "alu")
2357 (set_attr "length" "4")])
2358
2359(define_insn "*btst"
2360 [(set (match_operand:SI 0 "register_operand" "= r")
2361 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
2362 (const_int 1)
2363 (match_operand:SI 2 "immediate_operand" " Iu05")))]
aa4b851c 2364 "TARGET_EXT_PERF"
9304f876
CJW
2365 "btst\t%0, %1, %2"
2366 [(set_attr "type" "alu")
2367 (set_attr "length" "4")])
2368
2369;; ----------------------------------------------------------------------------
aa2642ef
CJW
2370
2371;; Pseudo NOPs
2372
c4d8d050
CJW
2373(define_insn "relax_group"
2374 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
2375 ""
2376 ".relax_hint %0"
2377 [(set_attr "length" "0")]
2378)
2379
aa2642ef
CJW
2380(define_insn "pop25return"
2381 [(return)
2382 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
2383 ""
2384 "! return for pop 25"
2385 [(set_attr "length" "0")]
2386)
2387
2388;; ----------------------------------------------------------------------------