]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nds32/nds32.md
[NDS32] Add subtype attribute for instructions.
[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"
5ba6d585 55 "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,call,misc"
9304f876
CJW
56 (const_string "unknown"))
57
0aa683b3
CJW
58;; Insn sub-type
59(define_attr "subtype"
60 "simple,shift"
61 (const_string "simple"))
62
9304f876
CJW
63;; Length, in bytes, default is 4-bytes.
64(define_attr "length" "" (const_int 4))
65
264159d2
KC
66;; Indicate the amount of micro instructions.
67(define_attr "combo"
68 "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"
69 (const_string "1"))
9304f876
CJW
70
71;; Enabled, which is used to enable/disable insn alternatives.
72;; Note that we use length and TARGET_16_BIT here as criteria.
73;; If the instruction pattern already check TARGET_16_BIT to
74;; determine the length by itself, its enabled attribute should be
75;; always 1 to avoid the conflict with the settings here.
30feb954 76(define_attr "enabled" "no,yes"
9304f876
CJW
77 (cond [(and (eq_attr "length" "2")
78 (match_test "!TARGET_16_BIT"))
30feb954
CJW
79 (const_string "no")]
80 (const_string "yes")))
9304f876
CJW
81
82
83;; ----------------------------------------------------------------------------
84
85
86;; Move instructions.
87
88;; For QImode and HImode, the immediate value can be fit in imm20s.
89;; So there is no need to split rtx for QI and HI patterns.
90
76dc9cb5
CJW
91(define_expand "mov<mode>"
92 [(set (match_operand:QIHI 0 "general_operand" "")
93 (match_operand:QIHI 1 "general_operand" ""))]
9304f876
CJW
94 ""
95{
96 /* Need to force register if mem <- !reg. */
97 if (MEM_P (operands[0]) && !REG_P (operands[1]))
76dc9cb5 98 operands[1] = force_reg (<MODE>mode, operands[1]);
9304f876 99
76dc9cb5
CJW
100 if (MEM_P (operands[1]) && optimize > 0)
101 {
102 rtx reg = gen_reg_rtx (SImode);
103
104 emit_insn (gen_zero_extend<mode>si2 (reg, operands[1]));
105 operands[1] = gen_lowpart (<MODE>mode, reg);
106 }
9304f876
CJW
107})
108
2cf09a99
KC
109(define_expand "movmisalign<mode>"
110 [(set (match_operand:SIDI 0 "general_operand" "")
111 (match_operand:SIDI 1 "general_operand" ""))]
112 ""
113{
114 rtx addr;
115 if (MEM_P (operands[0]) && !REG_P (operands[1]))
116 operands[1] = force_reg (<MODE>mode, operands[1]);
117
118 if (MEM_P (operands[0]))
119 {
120 addr = force_reg (Pmode, XEXP (operands[0], 0));
121 emit_insn (gen_unaligned_store<mode> (addr, operands[1]));
122 }
123 else
124 {
125 addr = force_reg (Pmode, XEXP (operands[1], 0));
126 emit_insn (gen_unaligned_load<mode> (operands[0], addr));
127 }
128 DONE;
129})
76dc9cb5 130
9304f876
CJW
131(define_expand "movsi"
132 [(set (match_operand:SI 0 "general_operand" "")
133 (match_operand:SI 1 "general_operand" ""))]
134 ""
135{
136 /* Need to force register if mem <- !reg. */
137 if (MEM_P (operands[0]) && !REG_P (operands[1]))
138 operands[1] = force_reg (SImode, operands[1]);
139
140 /* If operands[1] is a large constant and cannot be performed
141 by a single instruction, we need to split it. */
142 if (CONST_INT_P (operands[1])
143 && !satisfies_constraint_Is20 (operands[1])
144 && !satisfies_constraint_Ihig (operands[1]))
145 {
146 rtx high20_rtx;
147 HOST_WIDE_INT low12_int;
148 rtx tmp_rtx;
149
150 tmp_rtx = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
151
152 high20_rtx = gen_int_mode ((INTVAL (operands[1]) >> 12) << 12, SImode);
153 low12_int = INTVAL (operands[1]) & 0xfff;
154
155 emit_move_insn (tmp_rtx, high20_rtx);
156 emit_move_insn (operands[0], plus_constant (SImode,
157 tmp_rtx,
158 low12_int));
159 DONE;
160 }
161})
162
163(define_insn "*mov<mode>"
164 [(set (match_operand:QIHISI 0 "nonimmediate_operand" "=r, r, U45, U33, U37, U45, m, l, l, l, d, r, d, r, r, r")
165 (match_operand:QIHISI 1 "nds32_move_operand" " r, r, l, l, l, d, r, U45, U33, U37, U45, m, Ip05, Is05, Is20, Ihig"))]
b4350271
KC
166 "register_operand(operands[0], <MODE>mode)
167 || register_operand(operands[1], <MODE>mode)"
9304f876
CJW
168{
169 switch (which_alternative)
170 {
171 case 0:
172 return "mov55\t%0, %1";
173 case 1:
174 return "ori\t%0, %1, 0";
175 case 2:
176 case 3:
177 case 4:
178 case 5:
179 return nds32_output_16bit_store (operands, <byte>);
180 case 6:
181 return nds32_output_32bit_store (operands, <byte>);
182 case 7:
183 case 8:
184 case 9:
185 case 10:
186 return nds32_output_16bit_load (operands, <byte>);
187 case 11:
188 return nds32_output_32bit_load (operands, <byte>);
189 case 12:
190 return "movpi45\t%0, %1";
191 case 13:
192 return "movi55\t%0, %1";
193 case 14:
194 return "movi\t%0, %1";
195 case 15:
196 return "sethi\t%0, hi20(%1)";
197 default:
198 gcc_unreachable ();
199 }
200}
201 [(set_attr "type" "alu,alu,store,store,store,store,store,load,load,load,load,load,alu,alu,alu,alu")
202 (set_attr "length" " 2, 4, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, 2, 4, 4")])
203
204
205;; We use nds32_symbolic_operand to limit that only CONST/SYMBOL_REF/LABEL_REF
206;; are able to match such instruction template.
c4d8d050 207(define_insn "move_addr"
9304f876
CJW
208 [(set (match_operand:SI 0 "register_operand" "=l, r")
209 (match_operand:SI 1 "nds32_symbolic_operand" " i, i"))]
210 ""
211 "la\t%0, %1"
5ba6d585 212 [(set_attr "type" "alu")
9304f876
CJW
213 (set_attr "length" "8")])
214
215
c4d8d050 216(define_insn "sethi"
9304f876
CJW
217 [(set (match_operand:SI 0 "register_operand" "=r")
218 (high:SI (match_operand:SI 1 "nds32_symbolic_operand" " i")))]
219 ""
220 "sethi\t%0, hi20(%1)"
221 [(set_attr "type" "alu")
222 (set_attr "length" "4")])
223
224
c4d8d050 225(define_insn "lo_sum"
9304f876
CJW
226 [(set (match_operand:SI 0 "register_operand" "=r")
227 (lo_sum:SI (match_operand:SI 1 "register_operand" " r")
228 (match_operand:SI 2 "nds32_symbolic_operand" " i")))]
229 ""
230 "ori\t%0, %1, lo12(%2)"
231 [(set_attr "type" "alu")
232 (set_attr "length" "4")])
233
234
235;; ----------------------------------------------------------------------------
236
237;; Zero extension instructions.
238
239(define_insn "zero_extend<mode>si2"
240 [(set (match_operand:SI 0 "register_operand" "=l, r, l, *r")
241 (zero_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, U33, m")))]
242 ""
243{
244 switch (which_alternative)
245 {
246 case 0:
247 return "ze<size>33\t%0, %1";
248 case 1:
249 return "ze<size>\t%0, %1";
250 case 2:
251 return nds32_output_16bit_load (operands, <byte>);
252 case 3:
253 return nds32_output_32bit_load (operands, <byte>);
254
255 default:
256 gcc_unreachable ();
257 }
258}
259 [(set_attr "type" "alu,alu,load,load")
260 (set_attr "length" " 2, 4, 2, 4")])
261
262
263;; Sign extension instructions.
264
265(define_insn "extend<mode>si2"
266 [(set (match_operand:SI 0 "register_operand" "=l, r, r")
267 (sign_extend:SI (match_operand:QIHI 1 "nonimmediate_operand" " l, r, m")))]
268 ""
269{
270 switch (which_alternative)
271 {
272 case 0:
273 return "se<size>33\t%0, %1";
274 case 1:
275 return "se<size>\t%0, %1";
276 case 2:
277 return nds32_output_32bit_load_s (operands, <byte>);
278
279 default:
280 gcc_unreachable ();
281 }
282}
283 [(set_attr "type" "alu,alu,load")
284 (set_attr "length" " 2, 4, 4")])
285
286
287;; ----------------------------------------------------------------------------
288
289;; Arithmetic instructions.
290
291(define_insn "add<mode>3"
292 [(set (match_operand:QIHISI 0 "register_operand" "= d, l, d, l, d, l, k, l, r, r")
73f793e3 293 (plus:QIHISI (match_operand:QIHISI 1 "register_operand" "% 0, l, 0, l, 0, l, 0, k, r, r")
9304f876
CJW
294 (match_operand:QIHISI 2 "nds32_rimm15s_operand" " In05, In03, Iu05, Iu03, r, l, Is10, Iu06, Is15, r")))]
295 ""
296{
297 switch (which_alternative)
298 {
299 case 0:
300 /* addi Rt4,Rt4,-x ==> subi45 Rt4,x
8a498f99 301 where 0 <= x <= 31 */
9304f876
CJW
302 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
303 return "subi45\t%0, %2";
304 case 1:
305 /* addi Rt3,Ra3,-x ==> subi333 Rt3,Ra3,x
8a498f99 306 where 0 <= x <= 7 */
9304f876
CJW
307 operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
308 return "subi333\t%0, %1, %2";
309 case 2:
310 return "addi45\t%0, %2";
311 case 3:
312 return "addi333\t%0, %1, %2";
313 case 4:
314 return "add45\t%0, %2";
315 case 5:
316 return "add333\t%0, %1, %2";
317 case 6:
318 return "addi10.sp\t%2";
319 case 7:
320 return "addri36.sp\t%0, %2";
321 case 8:
322 return "addi\t%0, %1, %2";
323 case 9:
324 return "add\t%0, %1, %2";
325
326 default:
327 gcc_unreachable ();
328 }
329}
330 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
331 (set_attr "length" " 2, 2, 2, 2, 2, 2, 2, 2, 4, 4")])
332
333(define_insn "sub<mode>3"
334 [(set (match_operand:QIHISI 0 "register_operand" "=d, l, r, r")
335 (minus:QIHISI (match_operand:QIHISI 1 "nds32_rimm15s_operand" " 0, l, Is15, r")
336 (match_operand:QIHISI 2 "register_operand" " r, l, r, r")))]
337 ""
338 "@
339 sub45\t%0, %2
340 sub333\t%0, %1, %2
341 subri\t%0, %2, %1
342 sub\t%0, %1, %2"
343 [(set_attr "type" "alu,alu,alu,alu")
344 (set_attr "length" " 2, 2, 4, 4")])
345
346
347;; GCC intends to simplify (plus (ashift ...) (reg))
348;; into (plus (mult ...) (reg)), so our matching pattern takes 'mult'
349;; and needs to ensure it is exact_log2 value.
350(define_insn "*add_slli"
351 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99 352 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
9304f876
CJW
353 (match_operand:SI 2 "immediate_operand" " i"))
354 (match_operand:SI 3 "register_operand" " r")))]
355 "TARGET_ISA_V3
356 && (exact_log2 (INTVAL (operands[2])) != -1)
357 && (exact_log2 (INTVAL (operands[2])) <= 31)"
358{
359 /* Get floor_log2 of the immediate value
360 so that we can generate 'add_slli' instruction. */
361 operands[2] = GEN_INT (floor_log2 (INTVAL (operands[2])));
362
363 return "add_slli\t%0, %3, %1, %2";
364}
5ba6d585
KC
365 [(set_attr "type" "alu_shift")
366 (set_attr "combo" "2")
367 (set_attr "length" "4")])
9304f876
CJW
368
369(define_insn "*add_srli"
370 [(set (match_operand:SI 0 "register_operand" "= r")
371 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
372 (match_operand:SI 2 "immediate_operand" " Iu05"))
373 (match_operand:SI 3 "register_operand" " r")))]
374 "TARGET_ISA_V3"
375 "add_srli\t%0, %3, %1, %2"
5ba6d585
KC
376 [(set_attr "type" "alu_shift")
377 (set_attr "combo" "2")
378 (set_attr "length" "4")])
9304f876
CJW
379
380
381;; GCC intends to simplify (minus (reg) (ashift ...))
382;; into (minus (reg) (mult ...)), so our matching pattern takes 'mult'
383;; and needs to ensure it is exact_log2 value.
384(define_insn "*sub_slli"
385 [(set (match_operand:SI 0 "register_operand" "=r")
386 (minus:SI (match_operand:SI 1 "register_operand" " r")
387 (mult:SI (match_operand:SI 2 "register_operand" " r")
388 (match_operand:SI 3 "immediate_operand" " i"))))]
389 "TARGET_ISA_V3
390 && (exact_log2 (INTVAL (operands[3])) != -1)
391 && (exact_log2 (INTVAL (operands[3])) <= 31)"
392{
393 /* Get floor_log2 of the immediate value
394 so that we can generate 'sub_slli' instruction. */
395 operands[3] = GEN_INT (floor_log2 (INTVAL (operands[3])));
396
397 return "sub_slli\t%0, %1, %2, %3";
398}
5ba6d585
KC
399 [(set_attr "type" "alu_shift")
400 (set_attr "combo" "2")
401 (set_attr "length" "4")])
9304f876
CJW
402
403(define_insn "*sub_srli"
404 [(set (match_operand:SI 0 "register_operand" "= r")
405 (minus:SI (match_operand:SI 1 "register_operand" " r")
406 (lshiftrt:SI (match_operand:SI 2 "register_operand" " r")
407 (match_operand:SI 3 "immediate_operand" " Iu05"))))]
408 "TARGET_ISA_V3"
409 "sub_srli\t%0, %1, %2, %3"
5ba6d585
KC
410 [(set_attr "type" "alu_shift")
411 (set_attr "combo" "2")
412 (set_attr "length" "4")])
9304f876
CJW
413
414
415;; Multiplication instructions.
416
417(define_insn "mulsi3"
73f793e3
RS
418 [(set (match_operand:SI 0 "register_operand" "=w, r")
419 (mult:SI (match_operand:SI 1 "register_operand" "%0, r")
420 (match_operand:SI 2 "register_operand" " w, r")))]
9304f876
CJW
421 ""
422 "@
423 mul33\t%0, %2
424 mul\t%0, %1, %2"
5ba6d585 425 [(set_attr "type" "mul,mul")
9304f876
CJW
426 (set_attr "length" " 2, 4")])
427
428(define_insn "mulsidi3"
429 [(set (match_operand:DI 0 "register_operand" "=r")
430 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " r"))
431 (sign_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
432 "TARGET_ISA_V2 || TARGET_ISA_V3"
433 "mulsr64\t%0, %1, %2"
5ba6d585 434 [(set_attr "type" "mul")
9304f876
CJW
435 (set_attr "length" "4")])
436
437(define_insn "umulsidi3"
438 [(set (match_operand:DI 0 "register_operand" "=r")
439 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " r"))
440 (zero_extend:DI (match_operand:SI 2 "register_operand" " r"))))]
441 "TARGET_ISA_V2 || TARGET_ISA_V3"
442 "mulr64\t%0, %1, %2"
5ba6d585 443 [(set_attr "type" "mul")
9304f876
CJW
444 (set_attr "length" "4")])
445
446
447;; Multiply-accumulate instructions.
448
449(define_insn "*maddr32_0"
450 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
451 (plus:SI (match_operand:SI 3 "register_operand" " 0")
452 (mult:SI (match_operand:SI 1 "register_operand" " r")
453 (match_operand:SI 2 "register_operand" " r"))))]
9304f876
CJW
454 ""
455 "maddr32\t%0, %1, %2"
5ba6d585 456 [(set_attr "type" "mac")
9304f876
CJW
457 (set_attr "length" "4")])
458
459(define_insn "*maddr32_1"
460 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
461 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" " r")
462 (match_operand:SI 2 "register_operand" " r"))
463 (match_operand:SI 3 "register_operand" " 0")))]
9304f876
CJW
464 ""
465 "maddr32\t%0, %1, %2"
5ba6d585 466 [(set_attr "type" "mac")
9304f876
CJW
467 (set_attr "length" "4")])
468
469(define_insn "*msubr32"
470 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
471 (minus:SI (match_operand:SI 3 "register_operand" " 0")
472 (mult:SI (match_operand:SI 1 "register_operand" " r")
473 (match_operand:SI 2 "register_operand" " r"))))]
9304f876
CJW
474 ""
475 "msubr32\t%0, %1, %2"
5ba6d585 476 [(set_attr "type" "mac")
9304f876
CJW
477 (set_attr "length" "4")])
478
479
480;; Div Instructions.
481
482(define_insn "divmodsi4"
483 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
484 (div:SI (match_operand:SI 1 "register_operand" " r")
485 (match_operand:SI 2 "register_operand" " r")))
9304f876 486 (set (match_operand:SI 3 "register_operand" "=r")
8a498f99 487 (mod:SI (match_dup 1) (match_dup 2)))]
9304f876
CJW
488 ""
489 "divsr\t%0, %3, %1, %2"
5ba6d585 490 [(set_attr "type" "div")
9304f876
CJW
491 (set_attr "length" "4")])
492
493(define_insn "udivmodsi4"
494 [(set (match_operand:SI 0 "register_operand" "=r")
8a498f99
CJW
495 (udiv:SI (match_operand:SI 1 "register_operand" " r")
496 (match_operand:SI 2 "register_operand" " r")))
9304f876 497 (set (match_operand:SI 3 "register_operand" "=r")
8a498f99 498 (umod:SI (match_dup 1) (match_dup 2)))]
9304f876
CJW
499 ""
500 "divr\t%0, %3, %1, %2"
5ba6d585 501 [(set_attr "type" "div")
9304f876
CJW
502 (set_attr "length" "4")])
503
504
505;; ----------------------------------------------------------------------------
506
507;; Boolean instructions.
508;; Note: We define the DImode versions in nds32-doubleword.md.
509
510;; ----------------------------------------------------------------------------
511;; 'AND' operation
512;; ----------------------------------------------------------------------------
513
514(define_insn "bitc"
515 [(set (match_operand:SI 0 "register_operand" "=r")
516 (and:SI (not:SI (match_operand:SI 1 "register_operand" " r"))
517 (match_operand:SI 2 "register_operand" " r")))]
518 "TARGET_ISA_V3"
519 "bitc\t%0, %2, %1"
520 [(set_attr "type" "alu")
521 (set_attr "length" "4")]
522)
523
524(define_insn "andsi3"
73f793e3
RS
525 [(set (match_operand:SI 0 "register_operand" "=w, r, l, l, l, l, l, l, r, r, r, r, r")
526 (and:SI (match_operand:SI 1 "register_operand" "%0, r, l, l, l, l, 0, 0, r, r, r, r, r")
527 (match_operand:SI 2 "general_operand" " w, r, Izeb, Izeh, Ixls, Ix11, Ibms, Ifex, Izeb, Izeh, Iu15, Ii15, Ic15")))]
9304f876
CJW
528 ""
529{
530 HOST_WIDE_INT mask = INTVAL (operands[2]);
531 int zero_position;
532
533 /* 16-bit andi instructions:
534 andi Rt3,Ra3,0xff -> zeb33 Rt3,Ra3
535 andi Rt3,Ra3,0xffff -> zeh33 Rt3,Ra3
536 andi Rt3,Ra3,0x01 -> xlsb33 Rt3,Ra3
537 andi Rt3,Ra3,0x7ff -> x11b33 Rt3,Ra3
538 andi Rt3,Rt3,2^imm3u -> bmski33 Rt3,imm3u
539 andi Rt3,Rt3,(2^(imm3u+1))-1 -> fexti33 Rt3,imm3u. */
540
541 switch (which_alternative)
542 {
543 case 0:
544 return "and33\t%0, %2";
545 case 1:
546 return "and\t%0, %1, %2";
547 case 2:
548 return "zeb33\t%0, %1";
549 case 3:
550 return "zeh33\t%0, %1";
551 case 4:
552 return "xlsb33\t%0, %1";
553 case 5:
554 return "x11b33\t%0, %1";
555 case 6:
556 operands[2] = GEN_INT (floor_log2 (mask));
557 return "bmski33\t%0, %2";
558 case 7:
559 operands[2] = GEN_INT (floor_log2 (mask + 1) - 1);
560 return "fexti33\t%0, %2";
561 case 8:
562 return "zeb\t%0, %1";
563 case 9:
564 return "zeh\t%0, %1";
565 case 10:
566 return "andi\t%0, %1, %2";
567 case 11:
568 operands[2] = GEN_INT (~mask);
569 return "bitci\t%0, %1, %2";
570 case 12:
571 /* If we reach this alternative,
572 it must pass the nds32_can_use_bclr_p() test,
573 so that we can guarantee there is only one 0-bit
574 within the immediate value. */
575 for (zero_position = 31; zero_position >= 0; zero_position--)
576 {
577 if ((INTVAL (operands[2]) & (1 << zero_position)) == 0)
578 {
579 /* Found the 0-bit position. */
580 operands[2] = GEN_INT (zero_position);
581 break;
582 }
583 }
584 return "bclr\t%0, %1, %2";
585
586 default:
587 gcc_unreachable ();
588 }
589}
590 [(set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu,alu")
591 (set_attr "length" " 2, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4")])
592
593(define_insn "*and_slli"
594 [(set (match_operand:SI 0 "register_operand" "= r")
595 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
596 (match_operand:SI 2 "immediate_operand" " Iu05"))
597 (match_operand:SI 3 "register_operand" " r")))]
598 "TARGET_ISA_V3"
599 "and_slli\t%0, %3, %1, %2"
5ba6d585
KC
600 [(set_attr "type" "alu_shift")
601 (set_attr "length" "4")])
9304f876
CJW
602
603(define_insn "*and_srli"
604 [(set (match_operand:SI 0 "register_operand" "= r")
605 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
606 (match_operand:SI 2 "immediate_operand" " Iu05"))
607 (match_operand:SI 3 "register_operand" " r")))]
608 "TARGET_ISA_V3"
609 "and_srli\t%0, %3, %1, %2"
5ba6d585
KC
610 [(set_attr "type" "alu_shift")
611 (set_attr "length" "4")])
9304f876
CJW
612
613
614;; ----------------------------------------------------------------------------
615;; 'OR' operation
616;; ----------------------------------------------------------------------------
617
618;; For V3/V3M ISA, we have 'or33' instruction.
619;; So we can identify 'or Rt3,Rt3,Ra3' case and set its length to be 2.
620(define_insn "iorsi3"
73f793e3
RS
621 [(set (match_operand:SI 0 "register_operand" "=w, r, r, r")
622 (ior:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
623 (match_operand:SI 2 "general_operand" " w, r, Iu15, Ie15")))]
9304f876
CJW
624 ""
625{
626 int one_position;
627
628 switch (which_alternative)
629 {
630 case 0:
631 return "or33\t%0, %2";
632 case 1:
633 return "or\t%0, %1, %2";
634 case 2:
635 return "ori\t%0, %1, %2";
636 case 3:
637 /* If we reach this alternative,
638 it must pass the nds32_can_use_bset_p() test,
639 so that we can guarantee there is only one 1-bit
640 within the immediate value. */
641 /* Use exact_log2() to search the 1-bit position. */
642 one_position = exact_log2 (INTVAL (operands[2]));
643 operands[2] = GEN_INT (one_position);
644 return "bset\t%0, %1, %2";
645
646 default:
647 gcc_unreachable ();
648 }
649}
650 [(set_attr "type" "alu,alu,alu,alu")
651 (set_attr "length" " 2, 4, 4, 4")])
652
653(define_insn "*or_slli"
654 [(set (match_operand:SI 0 "register_operand" "= r")
655 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
656 (match_operand:SI 2 "immediate_operand" " Iu05"))
657 (match_operand:SI 3 "register_operand" " r")))]
658 "TARGET_ISA_V3"
659 "or_slli\t%0, %3, %1, %2"
5ba6d585
KC
660 [(set_attr "type" "alu_shift")
661 (set_attr "length" "4")])
9304f876
CJW
662
663(define_insn "*or_srli"
664 [(set (match_operand:SI 0 "register_operand" "= r")
665 (ior:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
666 (match_operand:SI 2 "immediate_operand" " Iu05"))
667 (match_operand:SI 3 "register_operand" " r")))]
668 "TARGET_ISA_V3"
669 "or_srli\t%0, %3, %1, %2"
5ba6d585
KC
670 [(set_attr "type" "alu_shift")
671 (set_attr "length" "4")])
9304f876
CJW
672
673
674;; ----------------------------------------------------------------------------
675;; 'XOR' operation
676;; ----------------------------------------------------------------------------
677
678;; For V3/V3M ISA, we have 'xor33' instruction.
679;; So we can identify 'xor Rt3,Rt3,Ra3' case and set its length to be 2.
680(define_insn "xorsi3"
73f793e3
RS
681 [(set (match_operand:SI 0 "register_operand" "=w, r, r, r")
682 (xor:SI (match_operand:SI 1 "register_operand" "%0, r, r, r")
683 (match_operand:SI 2 "general_operand" " w, r, Iu15, It15")))]
9304f876
CJW
684 ""
685{
686 int one_position;
687
688 switch (which_alternative)
689 {
690 case 0:
691 return "xor33\t%0, %2";
692 case 1:
693 return "xor\t%0, %1, %2";
694 case 2:
695 return "xori\t%0, %1, %2";
696 case 3:
697 /* If we reach this alternative,
698 it must pass the nds32_can_use_btgl_p() test,
699 so that we can guarantee there is only one 1-bit
700 within the immediate value. */
701 /* Use exact_log2() to search the 1-bit position. */
702 one_position = exact_log2 (INTVAL (operands[2]));
703 operands[2] = GEN_INT (one_position);
704 return "btgl\t%0, %1, %2";
705
706 default:
707 gcc_unreachable ();
708 }
709}
710 [(set_attr "type" "alu,alu,alu,alu")
711 (set_attr "length" " 2, 4, 4, 4")])
712
713(define_insn "*xor_slli"
714 [(set (match_operand:SI 0 "register_operand" "= r")
715 (xor:SI (ashift:SI (match_operand:SI 1 "register_operand" " r")
716 (match_operand:SI 2 "immediate_operand" " Iu05"))
717 (match_operand:SI 3 "register_operand" " r")))]
718 "TARGET_ISA_V3"
719 "xor_slli\t%0, %3, %1, %2"
5ba6d585
KC
720 [(set_attr "type" "alu_shift")
721 (set_attr "length" "4")])
9304f876
CJW
722
723(define_insn "*xor_srli"
724 [(set (match_operand:SI 0 "register_operand" "= r")
725 (xor:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" " r")
726 (match_operand:SI 2 "immediate_operand" " Iu05"))
727 (match_operand:SI 3 "register_operand" " r")))]
728 "TARGET_ISA_V3"
729 "xor_srli\t%0, %3, %1, %2"
5ba6d585
KC
730 [(set_attr "type" "alu_shift")
731 (set_attr "length" "4")])
9304f876
CJW
732
733;; Rotate Right Instructions.
734
735(define_insn "rotrsi3"
736 [(set (match_operand:SI 0 "register_operand" "= r, r")
737 (rotatert:SI (match_operand:SI 1 "register_operand" " r, r")
738 (match_operand:SI 2 "nonmemory_operand" " Iu05, r")))]
739 ""
740 "@
741 rotri\t%0, %1, %2
742 rotr\t%0, %1, %2"
5ba6d585 743 [(set_attr "type" " alu, alu")
0aa683b3 744 (set_attr "subtype" "shift,shift")
5ba6d585 745 (set_attr "length" " 4, 4")])
9304f876
CJW
746
747
748;; ----------------------------------------------------------------------------
749;; 'NEG' operation
750;; ----------------------------------------------------------------------------
751
752;; For V3/V3M ISA, we have 'neg33' instruction.
753;; So we can identify 'xor Rt3,Ra3' case and set its length to be 2.
754;; And for V2 ISA, there is NO 'neg33' instruction.
755;; The only option is to use 'subri A,B,0' (its semantic is 'A = 0 - B').
756(define_insn "negsi2"
757 [(set (match_operand:SI 0 "register_operand" "=w, r")
758 (neg:SI (match_operand:SI 1 "register_operand" " w, r")))]
759 ""
760 "@
761 neg33\t%0, %1
762 subri\t%0, %1, 0"
763 [(set_attr "type" "alu,alu")
764 (set_attr "length" " 2, 4")])
765
766
767;; ----------------------------------------------------------------------------
768;; 'ONE_COMPLIMENT' operation
769;; ----------------------------------------------------------------------------
770
771;; For V3/V3M ISA, we have 'not33' instruction.
772;; So we can identify 'not Rt3,Ra3' case and set its length to be 2.
773(define_insn "one_cmplsi2"
774 [(set (match_operand:SI 0 "register_operand" "=w, r")
775 (not:SI (match_operand:SI 1 "register_operand" " w, r")))]
776 ""
777 "@
778 not33\t%0, %1
779 nor\t%0, %1, %1"
780 [(set_attr "type" "alu,alu")
781 (set_attr "length" " 2, 4")])
782
783
784;; ----------------------------------------------------------------------------
785
786;; Shift instructions.
787
788(define_insn "ashlsi3"
789 [(set (match_operand:SI 0 "register_operand" "= l, r, r")
790 (ashift:SI (match_operand:SI 1 "register_operand" " l, r, r")
791 (match_operand:SI 2 "nonmemory_operand" " Iu03, Iu05, r")))]
792 ""
793 "@
794 slli333\t%0, %1, %2
795 slli\t%0, %1, %2
796 sll\t%0, %1, %2"
0aa683b3
CJW
797 [(set_attr "type" " alu, alu, alu")
798 (set_attr "subtype" "shift,shift,shift")
799 (set_attr "length" " 2, 4, 4")])
9304f876
CJW
800(define_insn "ashrsi3"
801 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
802 (ashiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
803 (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))]
804 ""
805 "@
806 srai45\t%0, %2
807 srai\t%0, %1, %2
808 sra\t%0, %1, %2"
0aa683b3
CJW
809 [(set_attr "type" " alu, alu, alu")
810 (set_attr "subtype" "shift,shift,shift")
811 (set_attr "length" " 2, 4, 4")])
9304f876
CJW
812
813(define_insn "lshrsi3"
814 [(set (match_operand:SI 0 "register_operand" "= d, r, r")
815 (lshiftrt:SI (match_operand:SI 1 "register_operand" " 0, r, r")
816 (match_operand:SI 2 "nonmemory_operand" " Iu05, Iu05, r")))]
817 ""
818 "@
819 srli45\t%0, %2
820 srli\t%0, %1, %2
821 srl\t%0, %1, %2"
0aa683b3
CJW
822 [(set_attr "type" " alu, alu, alu")
823 (set_attr "subtype" "shift,shift,shift")
824 (set_attr "length" " 2, 4, 4")])
9304f876
CJW
825
826
827;; ----------------------------------------------------------------------------
828
829;; ----------------------------------------------------------------------------
830;; Conditional Move patterns
831;; ----------------------------------------------------------------------------
832
6e9ca932
CJW
833(define_expand "mov<mode>cc"
834 [(set (match_operand:QIHISI 0 "register_operand" "")
835 (if_then_else:QIHISI (match_operand 1 "nds32_movecc_comparison_operator" "")
836 (match_operand:QIHISI 2 "register_operand" "")
837 (match_operand:QIHISI 3 "register_operand" "")))]
838 "TARGET_CMOV && !optimize_size"
9304f876 839{
6e9ca932
CJW
840 enum nds32_expand_result_type result = nds32_expand_movcc (operands);
841 switch (result)
9304f876 842 {
6e9ca932
CJW
843 case EXPAND_DONE:
844 DONE;
845 break;
846 case EXPAND_FAIL:
847 FAIL;
848 break;
849 case EXPAND_CREATE_TEMPLATE:
850 break;
851 default:
852 gcc_unreachable ();
9304f876 853 }
9304f876
CJW
854})
855
6e9ca932
CJW
856(define_insn "cmovz<mode>"
857 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
858 (if_then_else:QIHISI (eq (match_operand:SI 1 "register_operand" " r, r")
9304f876 859 (const_int 0))
6e9ca932
CJW
860 (match_operand:QIHISI 2 "register_operand" " r, 0")
861 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
9304f876
CJW
862 "TARGET_CMOV"
863 "@
864 cmovz\t%0, %2, %1
865 cmovn\t%0, %3, %1"
5ba6d585 866 [(set_attr "type" "alu")
9304f876
CJW
867 (set_attr "length" "4")])
868
6e9ca932
CJW
869(define_insn "cmovn<mode>"
870 [(set (match_operand:QIHISI 0 "register_operand" "=r, r")
871 (if_then_else:QIHISI (ne (match_operand:SI 1 "register_operand" " r, r")
9304f876 872 (const_int 0))
6e9ca932
CJW
873 (match_operand:QIHISI 2 "register_operand" " r, 0")
874 (match_operand:QIHISI 3 "register_operand" " 0, r")))]
9304f876
CJW
875 "TARGET_CMOV"
876 "@
877 cmovn\t%0, %2, %1
878 cmovz\t%0, %3, %1"
5ba6d585 879 [(set_attr "type" "alu")
9304f876
CJW
880 (set_attr "length" "4")])
881
6e9ca932
CJW
882;; A hotfix to help RTL combiner to merge a cmovn insn and a zero_extend insn.
883;; It should be removed once after we change the expansion form of the cmovn.
884(define_insn "*cmovn_simplified_<mode>"
885 [(set (match_operand:QIHISI 0 "register_operand" "=r")
886 (if_then_else:QIHISI (match_operand:SI 1 "register_operand" "r")
887 (match_operand:QIHISI 2 "register_operand" "r")
888 (match_operand:QIHISI 3 "register_operand" "0")))]
889 ""
890 "cmovn\t%0, %2, %1"
891 [(set_attr "type" "alu")])
9304f876
CJW
892
893;; ----------------------------------------------------------------------------
894;; Conditional Branch patterns
895;; ----------------------------------------------------------------------------
896
897(define_expand "cbranchsi4"
898 [(set (pc)
899 (if_then_else (match_operator 0 "comparison_operator"
900 [(match_operand:SI 1 "register_operand" "")
901 (match_operand:SI 2 "nds32_reg_constant_operand" "")])
902 (label_ref (match_operand 3 "" ""))
903 (pc)))]
904 ""
905{
6e9ca932
CJW
906 enum nds32_expand_result_type result = nds32_expand_cbranch (operands);
907 switch (result)
9304f876 908 {
6e9ca932 909 case EXPAND_DONE:
9304f876 910 DONE;
6e9ca932
CJW
911 break;
912 case EXPAND_FAIL:
9304f876 913 FAIL;
6e9ca932
CJW
914 break;
915 case EXPAND_CREATE_TEMPLATE:
916 break;
917 default:
918 gcc_unreachable ();
9304f876 919 }
9304f876
CJW
920})
921
922
6e9ca932 923(define_insn "cbranchsi4_equality_zero"
9304f876
CJW
924 [(set (pc)
925 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
6e9ca932 926 [(match_operand:SI 1 "register_operand" "t,l, r")
9304f876
CJW
927 (const_int 0)])
928 (label_ref (match_operand 2 "" ""))
929 (pc)))]
930 ""
931{
6e9ca932 932 return nds32_output_cbranchsi4_equality_zero (insn, operands);
9304f876
CJW
933}
934 [(set_attr "type" "branch")
6e9ca932
CJW
935 (set_attr_alternative "enabled"
936 [
937 ;; Alternative 0
938 (if_then_else (match_test "TARGET_16_BIT")
939 (const_string "yes")
940 (const_string "no"))
941 ;; Alternative 1
942 (if_then_else (match_test "TARGET_16_BIT")
943 (const_string "yes")
944 (const_string "no"))
945 ;; Alternative 2
946 (const_string "yes")
947 ])
9304f876
CJW
948 (set_attr_alternative "length"
949 [
950 ;; Alternative 0
6e9ca932
CJW
951 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
952 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
953 (le (minus (match_dup 2) (pc)) (const_int 250)))
9304f876 954 (if_then_else (match_test "TARGET_16_BIT")
6e9ca932
CJW
955 (const_int 2)
956 (const_int 4))
957 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
958 (le (minus (match_dup 2) (pc)) (const_int 65500)))
959 (const_int 4)
960 (if_then_else (match_test "TARGET_16_BIT")
961 (const_int 8)
962 (const_int 10))))
963 (const_int 10))
9304f876 964 ;; Alternative 1
6e9ca932
CJW
965 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
966 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -250))
967 (le (minus (match_dup 2) (pc)) (const_int 250)))
968 (if_then_else (match_test "TARGET_16_BIT")
969 (const_int 2)
970 (const_int 4))
971 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
972 (le (minus (match_dup 2) (pc)) (const_int 65500)))
973 (const_int 4)
974 (if_then_else (match_test "TARGET_16_BIT")
975 (const_int 8)
976 (const_int 10))))
977 (const_int 10))
978 ;; Alternative 2
979 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
9304f876
CJW
980 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
981 (le (minus (match_dup 2) (pc)) (const_int 65500)))
982 (const_int 4)
6e9ca932
CJW
983 (const_int 10))
984 (const_int 10))
9304f876
CJW
985 ])])
986
987
988;; This pattern is dedicated to V2 ISA,
989;; because V2 DOES NOT HAVE beqc/bnec instruction.
6e9ca932 990(define_insn "cbranchsi4_equality_reg"
9304f876
CJW
991 [(set (pc)
992 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
6e9ca932
CJW
993 [(match_operand:SI 1 "register_operand" "v, r")
994 (match_operand:SI 2 "register_operand" "l, r")])
9304f876
CJW
995 (label_ref (match_operand 3 "" ""))
996 (pc)))]
997 "TARGET_ISA_V2"
998{
6e9ca932 999 return nds32_output_cbranchsi4_equality_reg (insn, operands);
9304f876
CJW
1000}
1001 [(set_attr "type" "branch")
6e9ca932
CJW
1002 (set_attr_alternative "enabled"
1003 [
1004 ;; Alternative 0
1005 (if_then_else (match_test "TARGET_16_BIT")
1006 (const_string "yes")
1007 (const_string "no"))
1008 ;; Alternative 1
1009 (const_string "yes")
1010 ])
1011 (set_attr_alternative "length"
1012 [
1013 ;; Alternative 0
1014 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1015 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1016 (le (minus (match_dup 3) (pc)) (const_int 250)))
1017 (const_int 2)
1018 (if_then_else (and (ge (minus (match_dup 3) (pc))
1019 (const_int -16350))
1020 (le (minus (match_dup 3) (pc))
1021 (const_int 16350)))
1022 (const_int 4)
1023 (const_int 8)))
1024 (const_int 8))
1025 ;; Alternative 1
1026 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1027 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1028 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1029 (const_int 4)
1030 (const_int 10))
1031 (const_int 10))
1032 ])])
9304f876
CJW
1033
1034
1035;; This pattern is dedicated to V3/V3M,
1036;; because V3/V3M DO HAVE beqc/bnec instruction.
6e9ca932 1037(define_insn "cbranchsi4_equality_reg_or_const_int"
9304f876
CJW
1038 [(set (pc)
1039 (if_then_else (match_operator 0 "nds32_equality_comparison_operator"
6e9ca932
CJW
1040 [(match_operand:SI 1 "register_operand" "v, r, r")
1041 (match_operand:SI 2 "nds32_rimm11s_operand" "l, r, Is11")])
9304f876
CJW
1042 (label_ref (match_operand 3 "" ""))
1043 (pc)))]
1044 "TARGET_ISA_V3 || TARGET_ISA_V3M"
1045{
6e9ca932 1046 return nds32_output_cbranchsi4_equality_reg_or_const_int (insn, operands);
9304f876
CJW
1047}
1048 [(set_attr "type" "branch")
6e9ca932
CJW
1049 (set_attr_alternative "enabled"
1050 [
1051 ;; Alternative 0
1052 (if_then_else (match_test "TARGET_16_BIT")
1053 (const_string "yes")
1054 (const_string "no"))
1055 ;; Alternative 1
1056 (const_string "yes")
1057 ;; Alternative 2
1058 (const_string "yes")
1059 ])
9304f876
CJW
1060 (set_attr_alternative "length"
1061 [
1062 ;; Alternative 0
6e9ca932
CJW
1063 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1064 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1065 (le (minus (match_dup 3) (pc)) (const_int 250)))
1066 (const_int 2)
1067 (if_then_else (and (ge (minus (match_dup 3) (pc))
1068 (const_int -16350))
1069 (le (minus (match_dup 3) (pc))
1070 (const_int 16350)))
1071 (const_int 4)
1072 (const_int 8)))
1073 (const_int 8))
9304f876 1074 ;; Alternative 1
6e9ca932
CJW
1075 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1076 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -16350))
1077 (le (minus (match_dup 3) (pc)) (const_int 16350)))
1078 (const_int 4)
1079 (const_int 10))
1080 (const_int 10))
1081 ;; Alternative 2
1082 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1083 (if_then_else (and (ge (minus (match_dup 3) (pc)) (const_int -250))
1084 (le (minus (match_dup 3) (pc)) (const_int 250)))
1085 (const_int 4)
1086 (const_int 10))
1087 (const_int 10))
9304f876
CJW
1088 ])])
1089
1090
1091(define_insn "*cbranchsi4_greater_less_zero"
1092 [(set (pc)
1093 (if_then_else (match_operator 0 "nds32_greater_less_comparison_operator"
1094 [(match_operand:SI 1 "register_operand" "r")
1095 (const_int 0)])
1096 (label_ref (match_operand 2 "" ""))
1097 (pc)))]
1098 ""
1099{
6e9ca932 1100 return nds32_output_cbranchsi4_greater_less_zero (insn, operands);
9304f876
CJW
1101}
1102 [(set_attr "type" "branch")
1103 (set (attr "length")
6e9ca932
CJW
1104 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1105 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -65500))
1106 (le (minus (match_dup 2) (pc)) (const_int 65500)))
1107 (const_int 4)
1108 (const_int 10))
1109 (const_int 10)))])
9304f876
CJW
1110
1111
1112(define_expand "cstoresi4"
1113 [(set (match_operand:SI 0 "register_operand" "")
1114 (match_operator:SI 1 "comparison_operator"
1115 [(match_operand:SI 2 "register_operand" "")
1116 (match_operand:SI 3 "nonmemory_operand" "")]))]
1117 ""
1118{
6e9ca932
CJW
1119 enum nds32_expand_result_type result = nds32_expand_cstore (operands);
1120 switch (result)
9304f876 1121 {
6e9ca932 1122 case EXPAND_DONE:
9304f876 1123 DONE;
6e9ca932
CJW
1124 break;
1125 case EXPAND_FAIL:
1126 FAIL;
1127 break;
1128 case EXPAND_CREATE_TEMPLATE:
1129 break;
9304f876
CJW
1130 default:
1131 gcc_unreachable ();
1132 }
1133})
1134
1135
6e9ca932
CJW
1136(define_expand "slts_compare"
1137 [(set (match_operand:SI 0 "register_operand" "")
1138 (lt:SI (match_operand:SI 1 "general_operand" "")
1139 (match_operand:SI 2 "general_operand" "")))]
1140 ""
1141{
1142 if (!REG_P (operands[1]))
1143 operands[1] = force_reg (SImode, operands[1]);
1144
1145 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1146 operands[2] = force_reg (SImode, operands[2]);
1147})
1148
1149(define_insn "slts_compare_impl"
1150 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1151 (lt:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1152 (match_operand:SI 2 "nds32_rimm15s_operand" " r,Iu05, r, Is15")))]
9304f876
CJW
1153 ""
1154 "@
1155 slts45\t%1, %2
1156 sltsi45\t%1, %2
1157 slts\t%0, %1, %2
1158 sltsi\t%0, %1, %2"
6e9ca932
CJW
1159 [(set_attr "type" "alu, alu, alu, alu")
1160 (set_attr "length" " 2, 2, 4, 4")])
1161
1162(define_insn "slt_eq0"
1163 [(set (match_operand:SI 0 "register_operand" "=t, r")
1164 (eq:SI (match_operand:SI 1 "register_operand" " d, r")
1165 (const_int 0)))]
1166 ""
1167 "@
1168 slti45\t%1, 1
1169 slti\t%0, %1, 1"
1170 [(set_attr "type" "alu, alu")
1171 (set_attr "length" " 2, 4")])
1172
1173(define_expand "slt_compare"
1174 [(set (match_operand:SI 0 "register_operand" "")
1175 (ltu:SI (match_operand:SI 1 "general_operand" "")
1176 (match_operand:SI 2 "general_operand" "")))]
1177 ""
1178{
1179 if (!REG_P (operands[1]))
1180 operands[1] = force_reg (SImode, operands[1]);
1181
1182 if (!REG_P (operands[2]) && !satisfies_constraint_Is15 (operands[2]))
1183 operands[2] = force_reg (SImode, operands[2]);
1184})
9304f876 1185
6e9ca932
CJW
1186(define_insn "slt_compare_impl"
1187 [(set (match_operand:SI 0 "register_operand" "=t, t, r, r")
1188 (ltu:SI (match_operand:SI 1 "register_operand" " d, d, r, r")
1189 (match_operand:SI 2 "nds32_rimm15s_operand" " r, Iu05, r, Is15")))]
9304f876
CJW
1190 ""
1191 "@
1192 slt45\t%1, %2
1193 slti45\t%1, %2
1194 slt\t%0, %1, %2
1195 slti\t%0, %1, %2"
5ba6d585
KC
1196 [(set_attr "type" "alu, alu, alu, alu")
1197 (set_attr "length" " 2, 2, 4, 4")])
9304f876
CJW
1198
1199
1200;; ----------------------------------------------------------------------------
1201
1202;; Unconditional and other jump instructions.
1203
1204(define_insn "jump"
1205 [(set (pc) (label_ref (match_operand 0 "" "")))]
1206 ""
1207{
1208 /* This unconditional jump has two forms:
1209 32-bit instruction => j imm24s << 1
1210 16-bit instruction => j8 imm8s << 1
1211
1212 For 32-bit case,
1213 we assume it is always reachable.
1214 For 16-bit case,
1215 it must satisfy { 255 >= (label - pc) >= -256 } condition.
1216 However, since the $pc for nds32 is at the beginning of the instruction,
1217 we should leave some length space for current insn.
1218 So we use range -250 ~ 250. */
1219 switch (get_attr_length (insn))
1220 {
1221 case 2:
1222 return "j8\t%0";
1223 case 4:
1224 return "j\t%0";
1225 default:
1226 gcc_unreachable ();
1227 }
1228}
1229 [(set_attr "type" "branch")
30feb954 1230 (set_attr "enabled" "yes")
9304f876 1231 (set (attr "length")
6e9ca932
CJW
1232 (if_then_else (match_test "!CROSSING_JUMP_P (insn)")
1233 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -250))
1234 (le (minus (match_dup 0) (pc)) (const_int 250)))
1235 (if_then_else (match_test "TARGET_16_BIT")
1236 (const_int 2)
1237 (const_int 4))
9304f876
CJW
1238 (const_int 4))
1239 (const_int 4)))])
1240
1241(define_insn "indirect_jump"
1242 [(set (pc) (match_operand:SI 0 "register_operand" "r, r"))]
1243 ""
1244 "@
1245 jr5\t%0
1246 jr\t%0"
1247 [(set_attr "type" "branch,branch")
1248 (set_attr "length" " 2, 4")])
1249
1250;; Subroutine call instruction returning no value.
1251;; operands[0]: It should be a mem RTX whose address is
026c3cfd 1252;; the address of the function.
9304f876
CJW
1253;; operands[1]: It is the number of bytes of arguments pushed as a const_int.
1254;; operands[2]: It is the number of registers used as operands.
1255
1256(define_expand "call"
1257 [(parallel [(call (match_operand 0 "memory_operand" "")
1258 (match_operand 1))
1f7b8028
CJW
1259 (clobber (reg:SI LP_REGNUM))
1260 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1261 ""
1262 ""
1263)
1264
1265(define_insn "*call_register"
1266 [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
1267 (match_operand 1))
1f7b8028
CJW
1268 (clobber (reg:SI LP_REGNUM))
1269 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1270 ""
1271 "@
1272 jral5\t%0
1273 jral\t%0"
1274 [(set_attr "type" "branch,branch")
1275 (set_attr "length" " 2, 4")])
1276
1277(define_insn "*call_immediate"
1278 [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
1279 (match_operand 1))
1f7b8028
CJW
1280 (clobber (reg:SI LP_REGNUM))
1281 (clobber (reg:SI TA_REGNUM))])]
9304f876 1282 ""
1f7b8028
CJW
1283{
1284 if (TARGET_CMODEL_LARGE)
1285 return "bal\t%0";
1286 else
1287 return "jal\t%0";
1288}
9304f876 1289 [(set_attr "type" "branch")
1f7b8028
CJW
1290 (set (attr "length")
1291 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1292 (const_int 12)
1293 (const_int 4)))])
9304f876
CJW
1294
1295
1296;; Subroutine call instruction returning a value.
1297;; operands[0]: It is the hard regiser in which the value is returned.
1298;; The rest three operands are the same as the
1299;; three operands of the 'call' instruction.
1300;; (but with numbers increased by one)
1301
1302(define_expand "call_value"
1303 [(parallel [(set (match_operand 0)
1304 (call (match_operand 1 "memory_operand" "")
1305 (match_operand 2)))
1f7b8028
CJW
1306 (clobber (reg:SI LP_REGNUM))
1307 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1308 ""
1309 ""
1310)
1311
1312(define_insn "*call_value_register"
1313 [(parallel [(set (match_operand 0)
1314 (call (mem (match_operand:SI 1 "register_operand" "r, r"))
1315 (match_operand 2)))
1f7b8028
CJW
1316 (clobber (reg:SI LP_REGNUM))
1317 (clobber (reg:SI TA_REGNUM))])]
9304f876
CJW
1318 ""
1319 "@
1320 jral5\t%1
1321 jral\t%1"
1322 [(set_attr "type" "branch,branch")
1323 (set_attr "length" " 2, 4")])
1324
1325(define_insn "*call_value_immediate"
1326 [(parallel [(set (match_operand 0)
1327 (call (mem (match_operand:SI 1 "immediate_operand" "i"))
1328 (match_operand 2)))
1f7b8028
CJW
1329 (clobber (reg:SI LP_REGNUM))
1330 (clobber (reg:SI TA_REGNUM))])]
9304f876 1331 ""
1f7b8028
CJW
1332{
1333 if (TARGET_CMODEL_LARGE)
1334 return "bal\t%1";
1335 else
1336 return "jal\t%1";
1337}
9304f876 1338 [(set_attr "type" "branch")
1f7b8028
CJW
1339 (set (attr "length")
1340 (if_then_else (match_test "TARGET_CMODEL_LARGE")
1341 (const_int 12)
1342 (const_int 4)))])
9304f876
CJW
1343
1344
d6529176
CJW
1345;; ----------------------------------------------------------------------------
1346
1347;; The sibcall patterns.
1348
1349;; sibcall
cc48a87f 1350;; sibcall_internal
d6529176
CJW
1351
1352(define_expand "sibcall"
1353 [(parallel [(call (match_operand 0 "memory_operand" "")
1354 (const_int 0))
1355 (clobber (reg:SI TA_REGNUM))
1356 (return)])]
cc48a87f 1357 "")
d6529176 1358
cc48a87f
CJW
1359(define_insn "sibcall_internal"
1360 [(parallel [(call (mem (match_operand:SI 0 "nds32_call_address_operand" "r, i"))
d6529176
CJW
1361 (match_operand 1))
1362 (clobber (reg:SI TA_REGNUM))
1363 (return)])]
1364 ""
1365{
cc48a87f
CJW
1366 switch (which_alternative)
1367 {
1368 case 0:
1369 if (TARGET_16_BIT)
1370 return "jr5\t%0";
1371 else
1372 return "jr\t%0";
1373 case 1:
1374 if (nds32_long_call_p (operands[0]))
1375 return "b\t%0";
1376 else
1377 return "j\t%0";
1378 default:
1379 gcc_unreachable ();
1380 }
d6529176 1381}
30feb954 1382 [(set_attr "enabled" "yes")
cc48a87f
CJW
1383 (set_attr "type" "branch")
1384 (set_attr_alternative "length"
1385 [
1386 ;; Alternative 0
1387 (if_then_else (match_test "TARGET_16_BIT")
1388 (const_int 2)
1389 (const_int 4))
1390 ;; Alternative 1
1391 (if_then_else (match_test "nds32_long_call_p (operands[0])")
1392 (const_int 12)
1393 (const_int 4))
1394 ])]
1395)
d6529176
CJW
1396
1397;; sibcall_value
cc48a87f 1398;; sibcall_value_internal
d6529176
CJW
1399;; sibcall_value_immediate
1400
1401(define_expand "sibcall_value"
1402 [(parallel [(set (match_operand 0)
1403 (call (match_operand 1 "memory_operand" "")
1404 (const_int 0)))
1405 (clobber (reg:SI TA_REGNUM))
1406 (return)])]
cc48a87f 1407 "")
d6529176 1408
cc48a87f 1409(define_insn "sibcall_value_internal"
d6529176 1410 [(parallel [(set (match_operand 0)
cc48a87f 1411 (call (mem (match_operand:SI 1 "nds32_call_address_operand" "r, i"))
d6529176
CJW
1412 (match_operand 2)))
1413 (clobber (reg:SI TA_REGNUM))
1414 (return)])]
1415 ""
1416{
cc48a87f
CJW
1417 switch (which_alternative)
1418 {
1419 case 0:
1420 if (TARGET_16_BIT)
1421 return "jr5\t%1";
1422 else
1423 return "jr\t%1";
1424 case 1:
1425 if (nds32_long_call_p (operands[1]))
1426 return "b\t%1";
1427 else
1428 return "j\t%1";
1429 default:
1430 gcc_unreachable ();
1431 }
d6529176 1432}
30feb954 1433 [(set_attr "enabled" "yes")
cc48a87f
CJW
1434 (set_attr "type" "branch")
1435 (set_attr_alternative "length"
1436 [
1437 ;; Alternative 0
1438 (if_then_else (match_test "TARGET_16_BIT")
1439 (const_int 2)
1440 (const_int 4))
1441 ;; Alternative 1
1442 (if_then_else (match_test "nds32_long_call_p (operands[1])")
1443 (const_int 12)
1444 (const_int 4))
1445 ])]
1446)
d6529176
CJW
1447
1448;; ----------------------------------------------------------------------------
1449
9304f876
CJW
1450;; prologue and epilogue.
1451
1452(define_expand "prologue" [(const_int 0)]
1453 ""
1454{
2da1e7c0 1455 /* Note that only under V3/V3M ISA, we could use v3push prologue.
a6c7e777
MC
1456 In addition, we need to check if v3push is indeed available. */
1457 if (NDS32_V3PUSH_AVAILABLE_P)
9304f876
CJW
1458 nds32_expand_prologue_v3push ();
1459 else
1460 nds32_expand_prologue ();
1461 DONE;
1462})
1463
1464(define_expand "epilogue" [(const_int 0)]
1465 ""
1466{
2da1e7c0 1467 /* Note that only under V3/V3M ISA, we could use v3pop epilogue.
a6c7e777
MC
1468 In addition, we need to check if v3push is indeed available. */
1469 if (NDS32_V3PUSH_AVAILABLE_P)
d6529176
CJW
1470 nds32_expand_epilogue_v3pop (false);
1471 else
1472 nds32_expand_epilogue (false);
1473 DONE;
1474})
1475
1476(define_expand "sibcall_epilogue" [(const_int 0)]
1477 ""
1478{
1479 /* Pass true to indicate that this is sibcall epilogue and
1480 exit from a function without the final branch back to the
1481 calling function. */
a6c7e777 1482 nds32_expand_epilogue (true);
d6529176 1483
9304f876
CJW
1484 DONE;
1485})
1486
1487
1488;; nop instruction.
1489
1490(define_insn "nop"
1491 [(const_int 0)]
1492 ""
1493{
1494 if (TARGET_16_BIT)
1495 return "nop16";
1496 else
1497 return "nop";
1498}
1499 [(set_attr "type" "misc")
30feb954 1500 (set_attr "enabled" "yes")
9304f876
CJW
1501 (set (attr "length")
1502 (if_then_else (match_test "TARGET_16_BIT")
1503 (const_int 2)
1504 (const_int 4)))])
1505
1506
1507;; ----------------------------------------------------------------------------
1508;; Stack push/pop operations
1509;; ----------------------------------------------------------------------------
1510
1511;; The pattern for stack push.
1512;; Both stack_push_multiple and stack_v3push use the following pattern.
1513;; So we need to use TARGET_V3PUSH to determine the instruction length.
1514(define_insn "*stack_push"
1515 [(match_parallel 0 "nds32_stack_push_operation"
1516 [(set (mem:SI (plus:SI (reg:SI SP_REGNUM)
1517 (match_operand:SI 1 "const_int_operand" "")))
1518 (match_operand:SI 2 "register_operand" ""))
1519 ])]
1520 ""
1521{
6f3d3f9c 1522 return nds32_output_stack_push (operands[0]);
9304f876 1523}
264159d2
KC
1524 [(set_attr "type" "store_multiple")
1525 (set_attr "combo" "12")
30feb954 1526 (set_attr "enabled" "yes")
9304f876 1527 (set (attr "length")
6f3d3f9c
CJW
1528 (if_then_else (match_test "TARGET_V3PUSH
1529 && !nds32_isr_function_p (cfun->decl)
1530 && (cfun->machine->va_args_size == 0)")
9304f876
CJW
1531 (const_int 2)
1532 (const_int 4)))])
1533
1534
1535;; The pattern for stack pop.
1536;; Both stack_pop_multiple and stack_v3pop use the following pattern.
1537;; So we need to use TARGET_V3PUSH to determine the instruction length.
1538(define_insn "*stack_pop"
1539 [(match_parallel 0 "nds32_stack_pop_operation"
1540 [(set (match_operand:SI 1 "register_operand" "")
1541 (mem:SI (reg:SI SP_REGNUM)))
1542 ])]
1543 ""
1544{
6f3d3f9c 1545 return nds32_output_stack_pop (operands[0]);
9304f876 1546}
264159d2
KC
1547 [(set_attr "type" "load_multiple")
1548 (set_attr "combo" "12")
30feb954 1549 (set_attr "enabled" "yes")
9304f876 1550 (set (attr "length")
6f3d3f9c
CJW
1551 (if_then_else (match_test "TARGET_V3PUSH
1552 && !nds32_isr_function_p (cfun->decl)
1553 && (cfun->machine->va_args_size == 0)")
9304f876
CJW
1554 (const_int 2)
1555 (const_int 4)))])
1556
1557
1558;; ----------------------------------------------------------------------------
03390cda 1559;; Return operation patterns
9304f876
CJW
1560;; ----------------------------------------------------------------------------
1561
03390cda
CJW
1562;; Use this pattern to expand a return instruction
1563;; with simple_return rtx if no epilogue is required.
1564(define_expand "return"
1565 [(simple_return)]
1566 "nds32_can_use_return_insn ()"
1567 ""
1568)
9304f876 1569
03390cda
CJW
1570;; This pattern is expanded only by the shrink-wrapping optimization
1571;; on paths where the function prologue has not been executed.
1572(define_expand "simple_return"
1573 [(simple_return)]
1574 ""
1575 ""
1576)
1577
1578(define_insn "return_internal"
1579 [(simple_return)]
9304f876
CJW
1580 ""
1581{
1582 if (TARGET_16_BIT)
1583 return "ret5";
1584 else
1585 return "ret";
1586}
03390cda 1587 [(set_attr "type" "branch")
30feb954 1588 (set_attr "enabled" "yes")
9304f876
CJW
1589 (set (attr "length")
1590 (if_then_else (match_test "TARGET_16_BIT")
1591 (const_int 2)
1592 (const_int 4)))])
1593
1594
1595;; ----------------------------------------------------------------------------
1596;; Jump Table patterns
1597;; ----------------------------------------------------------------------------
1598;; Need to implement ASM_OUTPUT_ADDR_VEC_ELT (for normal jump table)
1599;; or ASM_OUTPUT_ADDR_DIFF_ELT (for pc relative jump table) as well.
1600;;
1601;; operands[0]: The index to dispatch on.
1602;; operands[1]: The lower bound for indices in the table.
1603;; operands[2]: The total range of indices int the table.
1604;; i.e. The largest index minus the smallest one.
1605;; operands[3]: A label that precedes the table itself.
1606;; operands[4]: A label to jump to if the index has a value outside the bounds.
1607;;
1608;; We need to create following sequences for jump table code generation:
1609;; A) k <-- (plus (operands[0]) (-operands[1]))
1610;; B) if (gtu k operands[2]) then goto operands[4]
1611;; C) t <-- operands[3]
1612;; D) z <-- (mem (plus (k << 0 or 1 or 2) t))
1613;; E) z <-- t + z (NOTE: This is only required for pc relative jump table.)
1614;; F) jump to target with register t or z
1615;;
1616;; The steps C, D, E, and F are performed by casesi_internal pattern.
1617(define_expand "casesi"
1618 [(match_operand:SI 0 "register_operand" "r") ; index to jump on
1619 (match_operand:SI 1 "immediate_operand" "i") ; lower bound
1620 (match_operand:SI 2 "immediate_operand" "i") ; total range
1621 (match_operand:SI 3 "" "") ; table label
1622 (match_operand:SI 4 "" "")] ; Out of range label
1623 ""
1624{
1625 rtx add_tmp;
1626 rtx reg, test;
1627
1628 /* Step A: "k <-- (plus (operands[0]) (-operands[1]))". */
1629 if (operands[1] != const0_rtx)
1630 {
1631 reg = gen_reg_rtx (SImode);
1632 add_tmp = gen_int_mode (-INTVAL (operands[1]), SImode);
1633
1634 /* If the integer value is not in the range of imm15s,
8a498f99
CJW
1635 we need to force register first because our addsi3 pattern
1636 only accept nds32_rimm15s_operand predicate. */
9304f876
CJW
1637 add_tmp = force_reg (SImode, add_tmp);
1638
1639 emit_insn (gen_addsi3 (reg, operands[0], add_tmp));
1640 operands[0] = reg;
1641 }
1642
1643 /* Step B: "if (gtu k operands[2]) then goto operands[4]". */
1644 test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
1645 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2],
1646 operands[4]));
1647
9759608c
SB
1648 /* Step C, D, E, and F, using another temporary register. */
1649 rtx tmp = gen_reg_rtx (SImode);
1650 emit_jump_insn (gen_casesi_internal (operands[0], operands[3], tmp));
9304f876
CJW
1651 DONE;
1652})
1653
1654;; We are receiving operands from casesi pattern:
1655;;
1656;; operands[0]: The index that have been substracted with lower bound.
1657;; operands[1]: A label that precedes the table itself.
1658;; operands[2]: A temporary register to retrieve value in table.
1659;;
1660;; We need to perform steps C, D, E, and F:
1661;;
1662;; C) t <-- operands[1]
1663;; D) z <-- (mem (plus (operands[0] << m) t))
1664;; m is 2 for normal jump table.
1665;; m is 0, 1, or 2 for pc relative jump table based on diff size.
1666;; E) t <-- z + t (NOTE: This is only required for pc relative jump table.)
1667;; F) Jump to target with register t or z.
1668;;
1669;; The USE in this pattern is needed to tell flow analysis that this is
1670;; a CASESI insn. It has no other purpose.
1671(define_insn "casesi_internal"
1672 [(parallel [(set (pc)
1673 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1674 (const_int 4))
1675 (label_ref (match_operand 1 "" "")))))
1676 (use (label_ref (match_dup 1)))
24f036fb 1677 (clobber (match_operand:SI 2 "register_operand" "=r"))
9304f876
CJW
1678 (clobber (reg:SI TA_REGNUM))])]
1679 ""
1680{
1681 if (CASE_VECTOR_PC_RELATIVE)
1682 return nds32_output_casesi_pc_relative (operands);
1683 else
1684 return nds32_output_casesi (operands);
1685}
1686 [(set_attr "length" "20")
5ba6d585 1687 (set_attr "type" "branch")])
9304f876
CJW
1688
1689;; ----------------------------------------------------------------------------
1690
1691;; Performance Extension
1692
1693(define_insn "clzsi2"
1694 [(set (match_operand:SI 0 "register_operand" "=r")
1695 (clz:SI (match_operand:SI 1 "register_operand" " r")))]
aa4b851c 1696 "TARGET_EXT_PERF"
9304f876
CJW
1697 "clz\t%0, %1"
1698 [(set_attr "type" "alu")
1699 (set_attr "length" "4")])
1700
1701(define_insn "smaxsi3"
1702 [(set (match_operand:SI 0 "register_operand" "=r")
1703 (smax:SI (match_operand:SI 1 "register_operand" " r")
1704 (match_operand:SI 2 "register_operand" " r")))]
aa4b851c 1705 "TARGET_EXT_PERF"
9304f876
CJW
1706 "max\t%0, %1, %2"
1707 [(set_attr "type" "alu")
1708 (set_attr "length" "4")])
1709
1710(define_insn "sminsi3"
1711 [(set (match_operand:SI 0 "register_operand" "=r")
1712 (smin:SI (match_operand:SI 1 "register_operand" " r")
1713 (match_operand:SI 2 "register_operand" " r")))]
aa4b851c 1714 "TARGET_EXT_PERF"
9304f876
CJW
1715 "min\t%0, %1, %2"
1716 [(set_attr "type" "alu")
1717 (set_attr "length" "4")])
1718
1719(define_insn "*btst"
1720 [(set (match_operand:SI 0 "register_operand" "= r")
1721 (zero_extract:SI (match_operand:SI 1 "register_operand" " r")
1722 (const_int 1)
1723 (match_operand:SI 2 "immediate_operand" " Iu05")))]
aa4b851c 1724 "TARGET_EXT_PERF"
9304f876
CJW
1725 "btst\t%0, %1, %2"
1726 [(set_attr "type" "alu")
1727 (set_attr "length" "4")])
1728
1729;; ----------------------------------------------------------------------------
aa2642ef
CJW
1730
1731;; Pseudo NOPs
1732
c4d8d050
CJW
1733(define_insn "relax_group"
1734 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "i")] UNSPEC_VOLATILE_RELAX_GROUP)]
1735 ""
1736 ".relax_hint %0"
1737 [(set_attr "length" "0")]
1738)
1739
aa2642ef
CJW
1740(define_insn "pop25return"
1741 [(return)
1742 (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
1743 ""
1744 "! return for pop 25"
1745 [(set_attr "length" "0")]
1746)
1747
1748;; ----------------------------------------------------------------------------