]> gcc.gnu.org Git - gcc.git/blame - gcc/config/stormy16/stormy16.md
avr.c: Fix comment typos.
[gcc.git] / gcc / config / stormy16 / stormy16.md
CommitLineData
c6243b4c 1;; XSTORMY16 Machine description template
e03f5d43 2;; Copyright (C) 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
4b58290f
GK
3;; Contributed by Red Hat, Inc.
4
5;; This file is part of GNU CC.
6
7;; GNU CC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; GNU CC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU CC; see the file COPYING. If not, write to
19;; the Free Software Foundation, 59 Temple Place - Suite 330,
20;; Boston, MA 02111-1307, USA.
21
22;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23
24\f
25;; ::::::::::::::::::::
26;; ::
27;; :: Attributes
28;; ::
29;; ::::::::::::::::::::
30
31; Categorize branches for the conditional in the length attribute.
32(define_attr "branch_class" "notdirectbranch,br12,bcc12,bcc8p2,bcc8p4"
33 (const_string "notdirectbranch"))
34
35; The length of an instruction, used for branch shortening.
36(define_attr "length" ""
37 (cond
38 [(eq_attr "branch_class" "br12")
39 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2046))
40 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
41 (const_int 2)
42 (const_int 4))
43 (eq_attr "branch_class" "bcc12")
44 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
45 (lt (minus (match_dup 0) (pc)) (const_int 2048)))
46 (const_int 4)
47 (const_int 8))
48 (eq_attr "branch_class" "bcc8p2")
49 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -124))
50 (lt (minus (match_dup 0) (pc)) (const_int 128)))
51 (const_int 4)
52 (const_int 8))
53 (eq_attr "branch_class" "bcc8p4")
54 (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -122))
55 (lt (minus (match_dup 0) (pc)) (const_int 128)))
56 (const_int 6)
57 (const_int 10))]
58 (const_int 2)))
59
60; The operand which determines the setting of Rpsw.
61; The numbers indicate the operand number,
62; 'clobber' indicates it is changed in some unspecified way
63; 'nop' means it is not changed.
64(define_attr "psw_operand" "clobber,nop,0,1,2,3,4" (const_string "0"))
65
66(define_asm_attributes [(set_attr "length" "4")
67 (set_attr "psw_operand" "clobber")])
68
69\f
70;; ::::::::::::::::::::
71;; ::
72;; :: Moves
73;; ::
74;; ::::::::::::::::::::
75
76(define_expand "movqi"
77 [(set (match_operand:QI 0 "nonimmediate_operand" "")
78 (match_operand:QI 1 "general_operand" ""))]
79 ""
c6243b4c 80 "{ xstormy16_expand_move (QImode, operands[0], operands[1]); DONE; }")
4b58290f
GK
81
82(define_insn "*movqi_internal"
83 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,Q,r,m,e,e,T,r,S")
84 (match_operand:QI 1 "general_operand" "r,r,R,e,m,i,i,i,i"))]
85 ""
86 "@
87 mov %0,%1
88 push %1
89 pop %0
90 mov.b %0,%1
91 mov.b %0,%1
92 mov %0,%1
93 mov Rx,%1
94 mov %0,%1
95 mov.b %0,%1"
96 [(set_attr_alternative "length"
97 [(const_int 2)
98 (const_int 2)
99 (const_int 2)
100 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
101 (const_int 2)
102 (const_int 4))
103 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
104 (const_int 2)
105 (const_int 4))
106 (const_int 2)
107 (const_int 2)
108 (const_int 4)
109 (const_int 4)])
110 (set_attr "psw_operand" "0,nop,nop,0,0,0,nop,0,nop")])
111
112(define_expand "movhi"
113 [(set (match_operand:HI 0 "nonimmediate_operand" "")
114 (match_operand:HI 1 "general_operand" ""))]
115 ""
c6243b4c 116 "{ xstormy16_expand_move (HImode, operands[0], operands[1]); DONE; }")
4b58290f
GK
117
118(define_insn "*movhi_internal"
119 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,Q,r,m,e,e,T,r,S")
120 (match_operand:HI 1 "general_operand" "r,r,R,e,m,L,L,i,i"))]
121 ""
122 "@
123 mov %0,%1
124 push %1
125 pop %0
126 mov.w %0,%1
127 mov.w %0,%1
128 mov.w %0,%1
129 mov.w Rx,%1
130 mov.w %0,%1
131 mov.w %0,%1"
132 [(set_attr_alternative "length"
133 [(const_int 2)
134 (const_int 2)
135 (const_int 2)
136 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
137 (const_int 2)
138 (const_int 4))
139 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
140 (const_int 2)
141 (const_int 4))
142 (const_int 2)
143 (const_int 2)
144 (const_int 4)
145 (const_int 4)])
146 (set_attr "psw_operand" "0,nop,nop,0,0,0,nop,0,nop")])
147
148(define_expand "movsi"
149 [(set (match_operand:SI 0 "nonimmediate_operand" "")
150 (match_operand:SI 1 "general_operand" ""))]
151 ""
c6243b4c 152 "{ xstormy16_expand_move (SImode, operands[0], operands[1]); DONE; }")
4b58290f
GK
153
154(define_insn_and_split "*movsi_internal"
155 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S")
156 (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))]
157 ""
158 "#"
159 "reload_completed"
160 [(pc)]
c6243b4c 161 "{ xstormy16_split_move (SImode, operands[0], operands[1]); DONE; }"
4b58290f
GK
162 [(set_attr_alternative "length"
163 [(const_int 4)
164 (const_int 4)
165 (const_int 4)
166 (if_then_else (match_operand:QI 0 "short_memory_operand" "")
167 (const_int 6)
168 (const_int 8))
169 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
170 (const_int 6)
171 (const_int 8))
172 (if_then_else (match_operand:QI 1 "short_memory_operand" "")
173 (const_int 6)
174 (const_int 8))
175 (const_int 4)
176 (const_int 8)
177 (const_int 8)])])
178
179\f
180;; ::::::::::::::::::::
181;; ::
182;; :: Conversions
183;; ::
184;; ::::::::::::::::::::
185
186(define_insn "extendqihi2"
187 [(set (match_operand:HI 0 "register_operand" "=r")
188 (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
189 ""
190 "cbw %0")
191
192\f
193;; ::::::::::::::::::::
194;; ::
195;; :: Bit field extraction
196;; ::
197;; ::::::::::::::::::::
198
199;; Extract an unsigned bit field
200;(define_insn "extzv"
201; [(set (match_operand:SI 0 "register_operand" "=r")
202; (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
203; (match_operand:SI 2 "const_int_operand" "n")
204; (match_operand:SI 3 "const_int_operand" "n")))]
205; ""
206; "extzv %0,%1,%2,%3"
207; [(set_attr "length" "4")])
208
209;; Insert a bit field
210;(define_insn "insv"
211; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
212; (match_operand:SI 1 "const_int_operand" "n")
213; (match_operand:SI 2 "const_int_operand" "n"))
214; (match_operand:SI 3 "nonmemory_operand" "ri"))]
215; ""
216; "insv %0,%1,%2,%3"
217; [(set_attr "length" "4")])
218
219\f
220;; ::::::::::::::::::::
221;; ::
222;; :: 16 bit Integer arithmetic
223;; ::
224;; ::::::::::::::::::::
225
226;; Addition
227; Operand 3 is marked earlyclobber because that helps reload
228; to generate better code---this pattern will never need the
229; carry register as an input, and some output reloads or input
230; reloads might need to use it. In fact, without the '&' reload
231; will fail in some cases.
232(define_insn "addhi3"
233 [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
234 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0")
235 (match_operand:HI 2 "nonmemory_operand" "O,P,L,M,Ir,N,i")))
236 (clobber (match_scratch:BI 3 "=X,X,&y,&y,&y,&y,&y"))]
237 ""
238 "@
239 inc %0,%o2
240 dec %0,%O2
241 add Rx,%2
242 sub Rx,#%n2
243 add %0,%2
244 sub %0,#%n2
245 add %0,%2"
246 [(set_attr "length" "2,2,2,2,2,2,4")])
247
248; Reload can generate addition operations. The SECONDARY_RELOAD_CLASS
249; macro causes it to allocate the carry register; this pattern
250; shows it how to place the register in RTL to make the addition work.
251(define_expand "reload_inhi"
252 [(parallel [(set (match_operand:HI 0 "register_operand" "=r")
c6243b4c 253 (match_operand:HI 1 "xstormy16_carry_plus_operand" ""))
4b58290f
GK
254 (clobber (match_operand:BI 2 "" "=&y"))])]
255 ""
256 "if (! rtx_equal_p (operands[0], XEXP (operands[1], 0)))
257 {
258 emit_insn (gen_rtx_SET (VOIDmode, operands[0], XEXP (operands[1], 0)));
259 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), operands[0],
260 XEXP (operands[1], 1));
261 }
262 ")
263
264(define_insn "addchi4"
265 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
266 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
267 (match_operand:HI 2 "nonmemory_operand" "L,Ir,i")))
268 (set (match_operand:BI 3 "register_operand" "=y,y,y")
269 (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
270 (zero_extend:SI (match_dup 2)))
271 (const_int 16))))]
272 ""
273 "@
274 add Rx,%2
275 add %0,%2
276 add %0,%2"
277 [(set_attr "length" "2,2,4")])
278
279(define_insn "addchi5"
280 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
281 (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
282 (zero_extend:HI (match_operand:BI 3
283 "register_operand"
284 "y,y,y")))
285 (match_operand:HI 2 "nonmemory_operand" "L,Ir,i")))
286 (set (match_operand:BI 4 "register_operand" "=y,y,y")
287 (truncate:BI (lshiftrt:SI (plus:SI (plus:SI
288 (zero_extend:SI (match_dup 1))
289 (zero_extend:SI (match_dup 3)))
290 (zero_extend:SI (match_dup 2)))
291 (const_int 16))))]
292 ""
293 "@
294 adc Rx,%2
295 adc %0,%2
296 adc %0,%2"
297 [(set_attr "length" "2,2,4")])
298
299;; Subtraction
300; Operand 3 is marked earlyclobber because that helps reload
301; to generate better code---this pattern will never need the
302; carry register as an input, and some output reloads or input
303; reloads might need to use it. In fact, without the '&' reload
304; will fail in some cases.
305(define_insn "subhi3"
306 [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
307 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0")
308 (match_operand:HI 2 "nonmemory_operand" "O,P,L,M,rI,M,i")))
309 (clobber (match_scratch:BI 3 "=X,X,&y,&y,&y,&y,&y"))]
310 ""
311 "@
312 dec %0,%o2
313 inc %0,%O2
314 sub Rx,%2
315 add Rx,#%n2
316 sub %0,%2
317 add %0,#%n2
318 sub %0,%2"
319 [(set_attr "length" "2,2,2,2,2,2,4")])
320
321(define_insn "subchi4"
322 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
323 (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
324 (match_operand:HI 2 "nonmemory_operand" "L,Ir,i")))
325 (set (match_operand:BI 3 "register_operand" "=y,y,y")
326 (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1))
327 (zero_extend:SI (match_dup 2)))
328 (const_int 16))))]
329 ""
330 "@
331 sub Rx,%2
332 sub %0,%2
333 sub %0,%2"
334 [(set_attr "length" "2,2,4")])
335
336(define_insn "subchi5"
337 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
338 (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
339 (zero_extend:HI (match_operand:BI 3
340 "register_operand"
341 "y,y,y")))
342 (match_operand:HI 2 "nonmemory_operand" "L,Ir,i")))
343 (set (match_operand:BI 4 "register_operand" "=y,y,y")
344 (truncate:BI (lshiftrt:SI (minus:SI (minus:SI
345 (zero_extend:SI (match_dup 1))
346 (zero_extend:SI (match_dup 3)))
347 (zero_extend:SI (match_dup 2)))
348 (const_int 16))))]
349 ""
350 "@
351 sbc Rx,%2
352 sbc %0,%2
353 sbc %0,%2"
354 [(set_attr "length" "2,2,4")])
355
356; Basic multiplication
357(define_insn "mulhi3"
358 [(set (match_operand:HI 0 "register_operand" "=a")
359 (mult:HI (match_operand:HI 1 "register_operand" "%a")
360 (match_operand:HI 2 "register_operand" "c")))
361 (clobber (match_scratch:HI 3 "=b"))
362 ]
363 ""
364 "mul"
365 [(set_attr "psw_operand" "nop")])
366
367;; Unsigned multiplication producing 64 bit results from 32 bit inputs
368; The constraint on operand 0 is 't' because it is actually two regs
369; long, and both regs must match the constraint.
370(define_insn "umulhisi3"
371 [(set (match_operand:SI 0 "register_operand" "=t")
372 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a"))
373 (zero_extend:SI (match_operand:HI 2 "register_operand" "c"))))
374 ]
375 ""
376 "mul"
377 [(set_attr "psw_operand" "nop")])
378
379;; Unsigned division giving both quotient and remainder
380(define_insn "udivmodhi4"
381 [(set (match_operand:HI 0 "register_operand" "=a")
ed09481d
GK
382 (udiv:HI (match_operand:HI 1 "register_operand" "a")
383 (match_operand:HI 2 "register_operand" "c")))
4b58290f 384 (set (match_operand:HI 3 "register_operand" "=b")
ed09481d
GK
385 (umod:HI (match_dup 1)
386 (match_dup 2)))]
4b58290f
GK
387 ""
388 "div"
389 [(set_attr "psw_operand" "nop")])
390
391;; Negation
392
393(define_expand "neghi2"
394 [(set (match_operand:HI 0 "register_operand" "")
395 (not:HI (match_operand:HI 1 "register_operand" "")))
396 (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
397 (clobber (match_scratch:BI 3 ""))])]
398 ""
399 "")
400
401\f
402;; ::::::::::::::::::::
403;; ::
404;; :: 16 bit Integer Shifts and Rotates
405;; ::
406;; ::::::::::::::::::::
407
408;; Arithmetic Shift Left
409(define_insn "ashlhi3"
410 [(set (match_operand:HI 0 "register_operand" "=r")
411 (ashift:HI (match_operand:HI 1 "register_operand" "0")
412 (match_operand:HI 2 "nonmemory_operand" "ri")))
413 (clobber (match_scratch:BI 3 "=y"))]
414 ""
415 "shl %0,%2")
416
417;; Arithmetic Shift Right
418(define_insn "ashrhi3"
419 [(set (match_operand:HI 0 "register_operand" "=r")
420 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
421 (match_operand:HI 2 "nonmemory_operand" "ri")))
422 (clobber (match_scratch:BI 3 "=y"))]
423 ""
424 "asr %0,%2")
425
426;; Logical Shift Right
427(define_insn "lshrhi3"
428 [(set (match_operand:HI 0 "register_operand" "=r")
429 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
430 (match_operand:HI 2 "nonmemory_operand" "ri")))
431 (clobber (match_scratch:BI 3 "=y"))]
432 ""
433 "shr %0,%2")
434
435\f
436;; ::::::::::::::::::::
437;; ::
438;; :: 16 Bit Integer Logical operations
439;; ::
440;; ::::::::::::::::::::
441
442;; Logical AND, 16 bit integers
443(define_insn "andhi3"
444 [(set (match_operand:HI 0 "register_operand" "=T,r,r,r")
445 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0")
446 (match_operand:HI 2 "nonmemory_operand" "L,r,K,i")))]
447 ""
448 "@
449 and Rx,%2
450 and %0,%2
451 clr1 %0,%B2
452 and %0,%2"
453 [(set_attr "length" "2,2,2,4")])
454
455;; Inclusive OR, 16 bit integers
456(define_insn "iorhi3"
457 [(set (match_operand:HI 0 "register_operand" "=T,r,r,r")
458 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0")
459 (match_operand:HI 2 "nonmemory_operand" "L,r,J,i")))]
460 ""
461 "@
462 or Rx,%2
463 or %0,%2
464 set1 %0,%B2
465 or %0,%2"
466 [(set_attr "length" "2,2,2,4")])
467
468;; Exclusive OR, 16 bit integers
469(define_insn "xorhi3"
470 [(set (match_operand:HI 0 "register_operand" "=T,r,r")
471 (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
472 (match_operand:HI 2 "nonmemory_operand" "L,r,i")))]
473 ""
474 "@
475 xor Rx,%2
476 xor %0,%2
477 xor %0,%2"
478 [(set_attr "length" "2,2,4")])
479
480;; One's complement, 16 bit integers
481(define_insn "one_cmplhi2"
482 [(set (match_operand:HI 0 "register_operand" "=r")
483 (not:HI (match_operand:HI 1 "register_operand" "0")))]
484 ""
485 "not %0")
486
487\f
488;; ::::::::::::::::::::
489;; ::
490;; :: 32 bit Integer arithmetic
491;; ::
492;; ::::::::::::::::::::
493
494;; Addition
495(define_insn_and_split "addsi3"
496 [(set (match_operand:SI 0 "register_operand" "=r")
497 (plus:SI (match_operand:SI 1 "register_operand" "%0")
498 (match_operand:SI 2 "nonmemory_operand" "ri")))
499 (clobber (match_scratch:BI 3 "=y"))]
500 ""
501 "#"
502 "reload_completed"
503 [(pc)]
c6243b4c 504 "{ xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1],
4b58290f
GK
505 operands[2], operands[3]); DONE; } "
506 [(set_attr "length" "4")])
507
508;; Subtraction
509(define_insn_and_split "subsi3"
510 [(set (match_operand:SI 0 "register_operand" "=r")
511 (minus:SI (match_operand:SI 1 "register_operand" "0")
512 (match_operand:SI 2 "nonmemory_operand" "ri")))
513 (clobber (match_scratch:BI 3 "=y"))]
514 ""
515 "#"
516 "reload_completed"
517 [(pc)]
c6243b4c 518 "{ xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1],
4b58290f
GK
519 operands[2], operands[3]); DONE; } "
520 [(set_attr "length" "4")])
521
522(define_expand "negsi2"
523 [(set (match_operand:SI 0 "register_operand" "")
524 (neg:SI (match_operand:SI 1 "register_operand" "")))]
525 ""
c6243b4c 526 "{ xstormy16_expand_arith (SImode, NEG, operands[0], const0_rtx,
4b58290f
GK
527 operands[1], gen_reg_rtx (BImode)); DONE; }")
528
529;; ::::::::::::::::::::
530;; ::
531;; :: 32 bit Integer Shifts and Rotates
532;; ::
533;; ::::::::::::::::::::
534
535;; Arithmetic Shift Left
536(define_expand "ashlsi3"
537 [(parallel [(set (match_operand:SI 0 "register_operand" "")
538 (ashift:SI (match_operand:SI 1 "register_operand" "")
539 (match_operand:SI 2 "const_int_operand" "")))
540 (clobber (match_dup 3))
541 (clobber (match_dup 4))])]
542 ""
543 " if (! const_int_operand (operands[2], SImode)) FAIL;
544 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
545
546;; Arithmetic Shift Right
547(define_expand "ashrsi3"
548 [(parallel [(set (match_operand:SI 0 "register_operand" "")
549 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
550 (match_operand:SI 2 "const_int_operand" "")))
551 (clobber (match_dup 3))
552 (clobber (match_dup 4))])]
553 ""
554 " if (! const_int_operand (operands[2], SImode)) FAIL;
555 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
556
557;; Logical Shift Right
558(define_expand "lshrsi3"
559 [(parallel [(set (match_operand:SI 0 "register_operand" "")
560 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
561 (match_operand:SI 2 "const_int_operand" "")))
562 (clobber (match_dup 3))
563 (clobber (match_dup 4))])]
564 ""
565 " if (! const_int_operand (operands[2], SImode)) FAIL;
566 operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
567
568(define_insn "*shiftsi"
569 [(set (match_operand:SI 0 "register_operand" "=r,r")
570 (match_operator:SI 5 "shift_operator"
571 [(match_operand:SI 1 "register_operand" "0,0")
572 (match_operand:SI 2 "const_int_operand" "U,n")]))
573 (clobber (match_operand:BI 3 "register_operand" "=y,y"))
574 (clobber (match_operand:HI 4 "" "=X,r"))]
575 ""
c6243b4c 576 "* return xstormy16_output_shift (SImode, GET_CODE (operands[5]),
4b58290f
GK
577 operands[0], operands[2], operands[4]);"
578 [(set_attr "length" "6,10")
579 (set_attr "psw_operand" "clobber,clobber")])
580
581\f
582;; ::::::::::::::::::::
583;; ::
584;; :: Comparisons
585;; ::
586;; ::::::::::::::::::::
587
588;; Note, we store the operands in the comparison insns, and use them later
589;; when generating the branch or scc operation.
590
591;; First the routines called by the machine independent part of the compiler
592(define_expand "cmphi"
593 [(set (cc0)
594 (compare (match_operand:HI 0 "register_operand" "")
595 (match_operand:HI 1 "nonmemory_operand" "")))]
596 ""
597 "
598{
c6243b4c
GK
599 xstormy16_compare_op0 = operands[0];
600 xstormy16_compare_op1 = operands[1];
4b58290f
GK
601 DONE;
602}")
603
604; There are no real SImode comparisons, but some can be emulated
605; by performing a SImode subtract and looking at the condition flags.
606(define_expand "cmpsi"
607 [(set (cc0)
608 (compare (match_operand:SI 0 "register_operand" "")
609 (match_operand:SI 1 "nonmemory_operand" "")))]
610 ""
611 "
612{
c6243b4c
GK
613 xstormy16_compare_op0 = operands[0];
614 xstormy16_compare_op1 = operands[1];
4b58290f
GK
615 DONE;
616}")
617
618\f
619;; ::::::::::::::::::::
620;; ::
621;; :: Branches
622;; ::
623;; ::::::::::::::::::::
624
625(define_expand "beq"
626 [(use (match_operand 0 "" ""))]
627 ""
c6243b4c 628 "{ xstormy16_emit_cbranch (EQ, operands[0]); DONE; }")
4b58290f
GK
629
630(define_expand "bne"
631 [(use (match_operand 0 "" ""))]
632 ""
c6243b4c 633 "{ xstormy16_emit_cbranch (NE, operands[0]); DONE; }")
4b58290f
GK
634
635(define_expand "bge"
636 [(use (match_operand 0 "" ""))]
637 ""
c6243b4c 638 "{ xstormy16_emit_cbranch (GE, operands[0]); DONE; }")
4b58290f
GK
639
640(define_expand "bgt"
641 [(use (match_operand 0 "" ""))]
642 ""
c6243b4c 643 "{ xstormy16_emit_cbranch (GT, operands[0]); DONE; }")
4b58290f
GK
644
645(define_expand "ble"
646 [(use (match_operand 0 "" ""))]
647 ""
c6243b4c 648 "{ xstormy16_emit_cbranch (LE, operands[0]); DONE; }")
4b58290f
GK
649
650(define_expand "blt"
651 [(use (match_operand 0 "" ""))]
652 ""
c6243b4c 653 "{ xstormy16_emit_cbranch (LT, operands[0]); DONE; }")
4b58290f
GK
654
655(define_expand "bgeu"
656 [(use (match_operand 0 "" ""))]
657 ""
c6243b4c 658 "{ xstormy16_emit_cbranch (GEU, operands[0]); DONE; }")
4b58290f
GK
659
660(define_expand "bgtu"
661 [(use (match_operand 0 "" ""))]
662 ""
c6243b4c 663 "{ xstormy16_emit_cbranch (GTU, operands[0]); DONE; }")
4b58290f
GK
664
665(define_expand "bleu"
666 [(use (match_operand 0 "" ""))]
667 ""
c6243b4c 668 "{ xstormy16_emit_cbranch (LEU, operands[0]); DONE; }")
4b58290f
GK
669
670(define_expand "bltu"
671 [(use (match_operand 0 "" ""))]
672 ""
c6243b4c 673 "{ xstormy16_emit_cbranch (LTU, operands[0]); DONE; }")
4b58290f
GK
674
675
676(define_insn "*cbranchhi"
677 [(set (pc)
678 (if_then_else (match_operator:HI 1 "comparison_operator"
679 [(match_operand:HI 2 "nonmemory_operand"
680 "r,e,L")
681 (match_operand:HI 3 "nonmemory_operand"
682 "r,L,e")])
683 (label_ref (match_operand 0 "" ""))
684 (pc)))
685 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
686 ""
687 "*
688{
c6243b4c 689 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn);
4b58290f
GK
690}"
691 [(set_attr "branch_class" "bcc12")
692 (set_attr "psw_operand" "0,0,1")])
693
694(define_insn "*cbranchhi_neg"
695 [(set (pc)
696 (if_then_else (match_operator:HI 1 "comparison_operator"
697 [(match_operand:HI 2 "nonmemory_operand"
698 "r,e,L")
699 (match_operand:HI 3 "nonmemory_operand"
700 "r,L,e")])
701 (pc)
702 (label_ref (match_operand 0 "" ""))))
703 (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
704 ""
705 "*
706{
c6243b4c 707 return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn);
4b58290f
GK
708}"
709 [(set_attr "branch_class" "bcc12")
710 (set_attr "psw_operand" "0,0,1")])
711
712(define_insn "*eqbranchsi"
713 [(set (pc)
714 (if_then_else (match_operator:SI 1 "equality_operator"
715 [(match_operand:SI 2 "register_operand"
716 "+r")
717 (const_int 0)])
718 (label_ref (match_operand 0 "" ""))
719 (pc)))
720;; Although I would greatly like the 'match_dup' in the following line
721;; to actually be a register constraint, there is (at the time of writing) no
722;; way for reload to insert an output reload on the edges out of a branch.
723;; If reload is fixed to use insert_insn_on_edge, this can be changed.
724 (clobber (match_dup 2))]
725 ""
726 "*
727{
c6243b4c 728 return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn);
4b58290f
GK
729}"
730 [(set_attr "branch_class" "bcc8p2")
731 (set_attr "psw_operand" "clobber")])
732
733(define_insn_and_split "*ineqbranchsi"
734 [(set (pc)
c6243b4c 735 (if_then_else (match_operator:SI 1 "xstormy16_ineqsi_operator"
4b58290f
GK
736 [(match_operand:SI 2 "register_operand"
737 "+r")
738 (match_operand:SI 3 "nonmemory_operand"
739 "ri")])
740 (label_ref (match_operand 0 "" ""))
741 (pc)))
742;; Although I would greatly like the 'match_dup' in the following line
743;; to actually be a register constraint, there is (at the time of writing) no
744;; way for reload to insert an output reload on the edges out of a branch.
745;; If reload is fixed to use insert_insn_on_edge, this can be changed,
746;; preferably to a 'minus' operand that explains the actual operation, like:
747; (set (match_operand 5 "register_operand" "=2")
748; (minus:SI (match_operand 6 "register_operand" "2")
749; (match_operand 7 "register_operand" "3")))
750 (clobber (match_dup 2))
751 (clobber (match_operand:BI 4 "" "=&y"))]
752 ""
753 "#"
754 "reload_completed"
755 [(pc)]
c6243b4c 756 "{ xstormy16_split_cbranch (SImode, operands[0], operands[1], operands[2],
4b58290f
GK
757 operands[4]); DONE; }"
758 [(set_attr "length" "8")])
759
760(define_insn "*ineqbranch_1"
761 [(set (pc)
c6243b4c 762 (if_then_else (match_operator:HI 5 "xstormy16_ineqsi_operator"
4b58290f
GK
763 [(minus:HI (match_operand:HI 1 "register_operand"
764 "T,r,r")
765 (zero_extend:HI (match_operand:BI 4
766 "register_operand"
767 "y,y,y")))
768 (match_operand:HI 3 "nonmemory_operand" "L,Ir,i")])
769 (label_ref (match_operand 0 "" ""))
770 (pc)))
771 (set (match_operand:HI 2 "register_operand" "=2,2,2")
772 (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (match_dup 4)))
773 (match_dup 3)))
774 (clobber (match_operand:BI 6 "" "=y,y,y"))]
775 ""
776 "*
777{
c6243b4c 778 return xstormy16_output_cbranch_si (operands[5], \"%l0\", 0, insn);
4b58290f
GK
779}"
780 [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4")
781 (set_attr "psw_operand" "2,2,2")])
782
783\f
784;; ::::::::::::::::::::
785;; ::
786;; :: Call and branch instructions
787;; ::
788;; ::::::::::::::::::::
789
790;; Subroutine call instruction returning no value. Operand 0 is the function
791;; to call; operand 1 is the number of bytes of arguments pushed (in mode
792;; `SImode', except it is normally a `const_int'); operand 2 is the number of
793;; registers used as operands.
794
795;; On most machines, operand 2 is not actually stored into the RTL pattern. It
796;; is supplied for the sake of some RISC machines which need to put this
797;; information into the assembler code; they can put it in the RTL instead of
798;; operand 1.
799
800(define_expand "call"
801 [(call (match_operand:HI 0 "memory_operand" "m")
802 (match_operand 1 "" ""))
803 (use (match_operand 2 "immediate_operand" ""))]
804 ""
c6243b4c 805 "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;")
4b58290f
GK
806
807;; Subroutine call instruction returning a value. Operand 0 is the hard
808;; register in which the value is returned. There are three more operands, the
809;; same as the three operands of the `call' instruction (but with numbers
810;; increased by one).
811
812;; Subroutines that return `BLKmode' objects use the `call' insn.
813
814(define_expand "call_value"
815 [(set (match_operand 0 "register_operand" "=r")
816 (call (match_operand:HI 1 "memory_operand" "m")
817 (match_operand:SI 2 "" "")))
818 (use (match_operand 3 "immediate_operand" ""))]
819 ""
c6243b4c 820 "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;")
4b58290f
GK
821
822(define_insn "*call_internal"
823 [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
824 (match_operand 1 "" ""))
da6e254e 825 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
4b58290f
GK
826 ""
827 "@
828 callf %C0
829 call %2,%0"
830 [(set_attr "length" "4,2")
831 (set_attr "psw_operand" "clobber")])
832
833(define_insn "*call_value_internal"
834 [(set (match_operand 3 "register_operand" "=r,r")
835 (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
836 (match_operand 1 "" "")))
da6e254e 837 (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
4b58290f
GK
838 ""
839 "@
840 callf %C0
841 call %2,%0"
842 [(set_attr "length" "4,2")
843 (set_attr "psw_operand" "clobber")])
844
845;; Subroutine return
846(define_expand "return"
847 [(return)]
848 "direct_return()"
849 "")
850
851(define_insn "return_internal"
852 [(return)]
853 ""
854 "ret"
855 [(set_attr "psw_operand" "nop")])
856
857(define_insn "return_internal_interrupt"
858 [(return)
859 (unspec_volatile [(const_int 0)] 1)]
860 ""
861 "iret"
862 [(set_attr "psw_operand" "clobber")])
863
864;; Normal unconditional jump
865(define_insn "jump"
866 [(set (pc) (label_ref (match_operand 0 "" "")))]
867 ""
868 "*
869{
c6243b4c 870 return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn);
4b58290f
GK
871}"
872 [(set_attr "branch_class" "br12")
873 (set_attr "psw_operand" "nop")])
874
875;; Indirect jump through a register
876(define_expand "indirect_jump"
877 [(set (match_dup 1) (const_int 0))
878 (parallel [(set (pc) (match_operand:HI 0 "register_operand" "r"))
879 (use (match_dup 1))])]
880 ""
881 "operands[1] = gen_reg_rtx (HImode);")
882
883(define_insn ""
884 [(set (pc) (match_operand:HI 0 "register_operand" "r"))
da6e254e 885 (use (match_operand:HI 1 "register_operand" "z"))]
4b58290f
GK
886 ""
887 "jmp %1,%0"
888 [(set_attr "length" "4")
889 (set_attr "psw_operand" "nop")])
890
891;; Table-based switch statements.
892(define_expand "casesi"
893 [(use (match_operand:SI 0 "register_operand" ""))
894 (use (match_operand:SI 1 "immediate_operand" ""))
895 (use (match_operand:SI 2 "immediate_operand" ""))
896 (use (label_ref (match_operand 3 "" "")))
897 (use (label_ref (match_operand 4 "" "")))]
898 ""
899 "
900{
c6243b4c 901 xstormy16_expand_casesi (operands[0], operands[1], operands[2],
4b58290f
GK
902 operands[3], operands[4]);
903 DONE;
904}")
905
906(define_insn "tablejump_pcrel"
907 [(set (pc) (plus:HI (pc) (match_operand:HI 0 "register_operand" "r")))
908 (use (label_ref:SI (match_operand 1 "" "")))]
909 ""
910 "br %0"
911 [(set_attr "psw_operand" "nop")])
912
913\f
914;; ::::::::::::::::::::
915;; ::
916;; :: Prologue and Epilogue instructions
917;; ::
918;; ::::::::::::::::::::
919
41441dc7
NB
920;; Called after register allocation to add any instructions needed for
921;; the prologue. Using a prologue insn is favored compared to putting
922;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro,
923;; since it allows the scheduler to intermix instructions with the
924;; saves of the caller saved registers. In some cases, it might be
925;; necessary to emit a barrier instruction as the last insn to prevent
926;; such scheduling.
4b58290f
GK
927(define_expand "prologue"
928 [(const_int 1)]
929 ""
930 "
931{
c6243b4c 932 xstormy16_expand_prologue ();
4b58290f
GK
933 DONE;
934}")
935
41441dc7 936;; Called after register allocation to add any instructions needed for
e03f5d43 937;; the epilogue. Using an epilogue insn is favored compared to putting
41441dc7
NB
938;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro,
939;; since it allows the scheduler to intermix instructions with the
940;; restires of the caller saved registers. In some cases, it might be
941;; necessary to emit a barrier instruction as the first insn to
942;; prevent such scheduling.
4b58290f
GK
943(define_expand "epilogue"
944 [(const_int 2)]
945 ""
946 "
947{
c6243b4c 948 xstormy16_expand_epilogue ();
4b58290f
GK
949 DONE;
950}")
951
952\f
953;; ::::::::::::::::::::
954;; ::
955;; :: Miscellaneous instructions
956;; ::
957;; ::::::::::::::::::::
958
959;; No operation, needed in case the user uses -g but not -O.
960(define_insn "nop"
961 [(const_int 0)]
962 ""
963 "nop"
964 [(set_attr "psw_operand" "nop")])
965
966;; Pseudo instruction that prevents the scheduler from moving code above this
967;; point.
968(define_insn "blockage"
969 [(unspec_volatile [(const_int 0)] 0)]
970 ""
971 ""
972 [(set_attr "length" "0")
973 (set_attr "psw_operand" "nop")])
This page took 0.230765 seconds and 5 git commands to generate.