]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/v850/v850.md
v850.c (ep_memory_offset): New function.
[thirdparty/gcc.git] / gcc / config / v850 / v850.md
1 ;; GCC machine description for NEC V850
2 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3
4 ;; Contributed by Jeff Law (law@cygnus.com).
5
6 ;; This file is part of GNU CC.
7
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
25
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
28 ;; The V851 manual states that the instruction address space is 16M;
29 ;; the various branch/call instructions only have a 22bit offset (4M range).
30 ;;
31 ;; One day we'll probably need to handle calls to targets more than 4M
32 ;; away.
33
34 ;; The size of instructions in bytes.
35
36 (define_attr "length" ""
37 (const_int 200))
38
39 ;; Types of instructions (for scheduling purposes).
40
41 (define_attr "type" "load,mult,other"
42 (const_string "other"))
43
44 ;; Condition code settings.
45 ;; none - insn does not affect cc
46 ;; none_0hit - insn does not affect cc but it does modify operand 0
47 ;; This attribute is used to keep track of when operand 0 changes.
48 ;; See the description of NOTICE_UPDATE_CC for more info.
49 ;; set_znv - sets z,n,v to useable values; c is unknown.
50 ;; set_zn - sets z,n to usable values; v,c is unknown.
51 ;; compare - compare instruction
52 ;; clobber - value of cc is unknown
53 (define_attr "cc" "none,none_0hit,set_zn,set_znv,compare,clobber"
54 (const_string "clobber"))
55 \f
56 ;; Function units for the V850. As best as I can tell, there's
57 ;; a traditional memory load/use stall as well as a stall if
58 ;; the result of a multiply is used too early.
59 ;;
60 (define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
61 (define_function_unit "mult" 1 0 (eq_attr "type" "mult") 2 0)
62
63 \f
64 ;; ----------------------------------------------------------------------
65 ;; MOVE INSTRUCTIONS
66 ;; ----------------------------------------------------------------------
67
68 ;; movqi
69
70 (define_expand "movqi"
71 [(set (match_operand:QI 0 "general_operand" "")
72 (match_operand:QI 1 "general_operand" ""))]
73 ""
74 "
75 {
76 /* One of the ops has to be in a register or 0 */
77 if (!register_operand (operand0, QImode)
78 && !reg_or_0_operand (operand1, QImode))
79 operands[1] = copy_to_mode_reg (QImode, operand1);
80 }")
81
82 (define_insn "*movqi_internal"
83 [(set (match_operand:QI 0 "general_operand" "=r,r,r,Q,r,m,m")
84 (match_operand:QI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
85 "register_operand (operands[0], QImode)
86 || reg_or_0_operand (operands[1], QImode)"
87 "* return output_move_single (operands);"
88 [(set_attr "length" "2,4,2,2,4,4,4")
89 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
90 (set_attr "type" "other,other,load,other,load,other,other")])
91
92 ;; movhi
93
94 (define_expand "movhi"
95 [(set (match_operand:HI 0 "general_operand" "")
96 (match_operand:HI 1 "general_operand" ""))]
97 ""
98 "
99 {
100 /* One of the ops has to be in a register or 0 */
101 if (!register_operand (operand0, HImode)
102 && !reg_or_0_operand (operand1, HImode))
103 operands[1] = copy_to_mode_reg (HImode, operand1);
104 }")
105
106 (define_insn "*movhi_internal"
107 [(set (match_operand:HI 0 "general_operand" "=r,r,r,Q,r,m,m")
108 (match_operand:HI 1 "general_operand" "Jr,n,Q,Ir,m,r,I"))]
109 "register_operand (operands[0], HImode)
110 || reg_or_0_operand (operands[1], HImode)"
111 "* return output_move_single (operands);"
112 [(set_attr "length" "2,4,2,2,4,4,4")
113 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
114 (set_attr "type" "other,other,load,other,load,other,other")])
115
116 ;; movsi and helpers
117
118 (define_insn "*movsi_high"
119 [(set (match_operand:SI 0 "register_operand" "=r")
120 (high:SI (match_operand 1 "" "")))]
121 ""
122 "movhi hi(%1),%.,%0"
123 [(set_attr "length" "4")
124 (set_attr "cc" "none_0hit")
125 (set_attr "type" "other")])
126
127 (define_insn "*movsi_lo"
128 [(set (match_operand:SI 0 "register_operand" "=r")
129 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
130 (match_operand:SI 2 "immediate_operand" "i")))]
131 ""
132 "movea lo(%2),%1,%0"
133 [(set_attr "length" "4")
134 (set_attr "cc" "none_0hit")
135 (set_attr "type" "other")])
136
137 (define_expand "movsi"
138 [(set (match_operand:SI 0 "general_operand" "")
139 (match_operand:SI 1 "general_operand" ""))]
140 ""
141 "
142 {
143 /* One of the ops has to be in a register or 0 */
144 if (!register_operand (operand0, SImode)
145 && !reg_or_0_operand (operand1, SImode))
146 operands[1] = copy_to_mode_reg (SImode, operand1);
147
148 /* Some constants, as well as symbolic operands
149 must be done with HIGH & LO_SUM patterns. */
150 if (CONSTANT_P (operands[1])
151 && GET_CODE (operands[1]) != HIGH
152 && !special_symbolref_operand (operands[1], VOIDmode)
153 && !(GET_CODE (operands[1]) == CONST_INT
154 && (CONST_OK_FOR_J (INTVAL (operands[1]))
155 || CONST_OK_FOR_K (INTVAL (operands[1]))
156 || CONST_OK_FOR_L (INTVAL (operands[1])))))
157 {
158 rtx high;
159 rtx temp;
160
161 if (reload_in_progress || reload_completed)
162 temp = operands[0];
163 else
164 temp = gen_reg_rtx (SImode);
165
166 emit_insn (gen_rtx (SET, SImode, temp,
167 gen_rtx (HIGH, SImode, operand1)));
168 emit_insn (gen_rtx (SET, SImode, operand0,
169 gen_rtx (LO_SUM, SImode, temp, operand1)));
170 DONE;
171 }
172 }")
173
174 (define_insn "*movsi_internal"
175 [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,Q,r,r,m,m")
176 (match_operand:SI 1 "movsi_source_operand" "Jr,K,L,Q,Ir,m,R,r,I"))]
177 "register_operand (operands[0], SImode)
178 || reg_or_0_operand (operands[1], SImode)"
179 "* return output_move_single (operands);"
180 [(set_attr "length" "2,4,4,2,2,4,4,4,4")
181 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
182 (set_attr "type" "other,other,other,load,other,load,other,other,other")])
183
184
185
186 (define_expand "movdi"
187 [(set (match_operand:DI 0 "general_operand" "")
188 (match_operand:DI 1 "general_operand" ""))]
189 ""
190 "
191 {
192 /* One of the ops has to be in a register or 0 */
193 if (!register_operand (operand0, DImode)
194 && !reg_or_0_operand (operand1, DImode))
195 operands[1] = copy_to_mode_reg (DImode, operand1);
196 }")
197
198 (define_insn "*movdi_internal"
199 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,m,r")
200 (match_operand:DI 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
201 "register_operand (operands[0], DImode)
202 || reg_or_0_operand (operands[1], DImode)"
203 "* return output_move_double (operands);"
204 [(set_attr "length" "4,8,8,16,8,8,8,16")
205 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
206 (set_attr "type" "other,other,other,other,load,other,other,other")])
207
208 (define_expand "movsf"
209 [(set (match_operand:SF 0 "general_operand" "")
210 (match_operand:SF 1 "general_operand" ""))]
211 ""
212 "
213 {
214 /* One of the ops has to be in a register or 0 */
215 if (!register_operand (operand0, SFmode)
216 && !reg_or_0_operand (operand1, SFmode))
217 operands[1] = copy_to_mode_reg (SFmode, operand1);
218 }")
219
220 (define_insn "*movsf_internal"
221 [(set (match_operand:SF 0 "general_operand" "=r,r,r,r,r,Q,r,m,m,r")
222 (match_operand:SF 1 "general_operand" "Jr,K,L,n,Q,Ir,m,r,IG,iF"))]
223 "register_operand (operands[0], SFmode)
224 || reg_or_0_operand (operands[1], SFmode)"
225 "* return output_move_single (operands);"
226 [(set_attr "length" "2,4,4,8,2,2,4,4,4,8")
227 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
228 (set_attr "type" "other,other,other,other,load,other,load,other,other,other")])
229
230 (define_expand "movdf"
231 [(set (match_operand:DF 0 "general_operand" "")
232 (match_operand:DF 1 "general_operand" ""))]
233 ""
234 "
235 {
236 /* One of the ops has to be in a register or 0 */
237 if (!register_operand (operand0, DFmode)
238 && !reg_or_0_operand (operand1, DFmode))
239 operands[1] = copy_to_mode_reg (DFmode, operand1);
240 }")
241
242 (define_insn "*movdf_internal"
243 [(set (match_operand:DF 0 "general_operand" "=r,r,r,r,r,m,m,r")
244 (match_operand:DF 1 "general_operand" "Jr,K,L,i,m,r,IG,iF"))]
245 "register_operand (operands[0], DFmode)
246 || reg_or_0_operand (operands[1], DFmode)"
247 "* return output_move_double (operands);"
248 [(set_attr "length" "4,8,8,16,8,8,8,16")
249 (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")
250 (set_attr "type" "other,other,other,other,load,other,other,other")])
251
252 \f
253 ;; ----------------------------------------------------------------------
254 ;; TEST INSTRUCTIONS
255 ;; ----------------------------------------------------------------------
256
257 (define_insn "*v850_tst1"
258 [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
259 (const_int 1)
260 (match_operand:QI 1 "const_int_operand" "n")))]
261 ""
262 "tst1 %1,%0"
263 [(set_attr "length" "4")
264 (set_attr "cc" "clobber")])
265
266 ;; This replaces ld.b;sar;andi with tst1;setf nz.
267
268 ;; ??? The zero_extract sets the Z bit to the opposite of what one would
269 ;; expect. This perhaps should be wrapped in a (eq: X (const_int 0)).
270
271 (define_split
272 [(set (match_operand:SI 0 "register_operand" "")
273 (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
274 (const_int 1)
275 (match_operand 2 "const_int_operand" "")))]
276 ""
277 [(set (cc0) (zero_extract:SI (match_dup 1)
278 (const_int 1)
279 (match_dup 2)))
280 (set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
281
282 (define_insn "tstsi"
283 [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
284 ""
285 "cmp %.,%0"
286 [(set_attr "length" "2")
287 (set_attr "cc" "set_znv")])
288
289 (define_insn "cmpsi"
290 [(set (cc0)
291 (compare (match_operand:SI 0 "register_operand" "r,r")
292 (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
293 ""
294 "@
295 cmp %1,%0
296 cmp %1,%0"
297 [(set_attr "length" "2,2")
298 (set_attr "cc" "compare")])
299 \f
300 ;; ----------------------------------------------------------------------
301 ;; ADD INSTRUCTIONS
302 ;; ----------------------------------------------------------------------
303
304 (define_insn "addsi3"
305 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
306 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,r")
307 (match_operand:SI 2 "nonmemory_operand" "rJ,K,U")))]
308 ""
309 "@
310 add %2,%0
311 addi %2,%1,%0
312 addi %O2(%P2),%1,%0"
313 [(set_attr "length" "2,4,4")
314 (set_attr "cc" "set_zn,set_zn,set_zn")])
315
316 ;; ----------------------------------------------------------------------
317 ;; SUBTRACT INSTRUCTIONS
318 ;; ----------------------------------------------------------------------
319
320 (define_insn "subsi3"
321 [(set (match_operand:SI 0 "register_operand" "=r,r")
322 (minus:SI (match_operand:SI 1 "register_operand" "0,r")
323 (match_operand:SI 2 "register_operand" "r,0")))]
324 ""
325 "@
326 sub %2,%0
327 subr %1,%0"
328 [(set_attr "length" "2,2")
329 (set_attr "cc" "set_zn")])
330
331 (define_insn "negsi2"
332 [(set (match_operand:SI 0 "register_operand" "=r")
333 (neg:SI (match_operand:SI 1 "register_operand" "0")))]
334 ""
335 "subr %.,%0"
336 [(set_attr "length" "2")
337 (set_attr "cc" "set_zn")])
338
339 ;; ----------------------------------------------------------------------
340 ;; MULTIPLY INSTRUCTIONS
341 ;; ----------------------------------------------------------------------
342
343 (define_expand "mulhisi3"
344 [(set (match_operand:SI 0 "register_operand" "")
345 (mult:SI
346 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
347 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
348 ""
349 "")
350
351 (define_insn "*mulhisi3_internal1"
352 [(set (match_operand:SI 0 "register_operand" "=r")
353 (mult:SI
354 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
355 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
356 ""
357 "mulh %2,%0"
358 [(set_attr "length" "2")
359 (set_attr "cc" "none_0hit")
360 (set_attr "type" "mult")])
361
362 ;; ??? Sign extending constants isn't valid. Fix?
363
364 (define_insn "*mulhisi3_internal2"
365 [(set (match_operand:SI 0 "register_operand" "=r,r")
366 (mult:SI
367 (sign_extend:SI (match_operand:HI 1 "register_operand" "%0,r"))
368 (sign_extend:SI (match_operand 2 "const_int_operand" "J,K"))))]
369 ""
370 "@
371 mulh %2,%0
372 mulhi %2,%1,%0"
373 [(set_attr "length" "2,4")
374 (set_attr "cc" "none_0hit,none_0hit")
375 (set_attr "type" "mult")])
376
377 \f
378 ;; ----------------------------------------------------------------------
379 ;; AND INSTRUCTIONS
380 ;; ----------------------------------------------------------------------
381
382 (define_insn "*v850_clr1_1"
383 [(set (match_operand:QI 0 "memory_operand" "=m")
384 (subreg:QI
385 (and:SI (subreg:SI (match_dup 0) 0)
386 (match_operand:QI 1 "not_power_of_two_operand" "")) 0))]
387 ""
388 "*
389 {
390 rtx xoperands[2];
391 xoperands[0] = operands[0];
392 xoperands[1] = GEN_INT (~INTVAL (operands[1]) & 0xff);
393 output_asm_insn (\"clr1 %M1,%0\", xoperands);
394 return \"\";
395 }"
396 [(set_attr "length" "4")
397 (set_attr "cc" "clobber")])
398
399 (define_insn "*v850_clr1_2"
400 [(set (match_operand:HI 0 "memory_operand" "=m")
401 (subreg:HI
402 (and:SI (subreg:SI (match_dup 0) 0)
403 (match_operand:HI 1 "not_power_of_two_operand" "")) 0))]
404 ""
405 "*
406 {
407 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffff);
408
409 rtx xoperands[2];
410 xoperands[0] = gen_rtx (MEM, QImode,
411 plus_constant (XEXP (operands[0], 0), log2 / 8));
412 xoperands[1] = GEN_INT (log2 % 8);
413 output_asm_insn (\"clr1 %1,%0\", xoperands);
414 return \"\";
415 }"
416 [(set_attr "length" "4")
417 (set_attr "cc" "clobber")])
418
419 (define_insn "*v850_clr1_3"
420 [(set (match_operand:SI 0 "memory_operand" "=m")
421 (and:SI (match_dup 0)
422 (match_operand:SI 1 "not_power_of_two_operand" "")))]
423 ""
424 "*
425 {
426 int log2 = exact_log2 (~INTVAL (operands[1]) & 0xffffffff);
427
428 rtx xoperands[2];
429 xoperands[0] = gen_rtx (MEM, QImode,
430 plus_constant (XEXP (operands[0], 0), log2 / 8));
431 xoperands[1] = GEN_INT (log2 % 8);
432 output_asm_insn (\"clr1 %1,%0\", xoperands);
433 return \"\";
434 }"
435 [(set_attr "length" "4")
436 (set_attr "cc" "clobber")])
437
438 (define_insn "andsi3"
439 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
440 (and:SI (match_operand:SI 1 "register_operand" "%0,0,r")
441 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
442 ""
443 "@
444 and %2,%0
445 and %.,%0
446 andi %2,%1,%0"
447 [(set_attr "length" "2,2,4")
448 (set_attr "cc" "set_znv")])
449
450 ;; ----------------------------------------------------------------------
451 ;; OR INSTRUCTIONS
452 ;; ----------------------------------------------------------------------
453
454 (define_insn "*v850_set1_1"
455 [(set (match_operand:QI 0 "memory_operand" "=m")
456 (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0)
457 (match_operand 1 "power_of_two_operand" "")) 0))]
458 ""
459 "set1 %M1,%0"
460 [(set_attr "length" "4")
461 (set_attr "cc" "clobber")])
462
463 (define_insn "*v850_set1_2"
464 [(set (match_operand:HI 0 "memory_operand" "=m")
465 (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0)
466 (match_operand 1 "power_of_two_operand" "")) 0))]
467 ""
468 "*
469 {
470 int log2 = exact_log2 (INTVAL (operands[1]));
471
472 if (log2 < 8)
473 return \"set1 %M1,%0\";
474 else
475 {
476 rtx xoperands[2];
477 xoperands[0] = gen_rtx (MEM, QImode,
478 plus_constant (XEXP (operands[0], 0), log2 / 8));
479 xoperands[1] = GEN_INT (log2 % 8);
480 output_asm_insn (\"set1 %1,%0\", xoperands);
481 }
482 return \"\";
483 }"
484 [(set_attr "length" "4")
485 (set_attr "cc" "clobber")])
486
487 (define_insn "*v850_set1_3"
488 [(set (match_operand:SI 0 "memory_operand" "=m")
489 (ior:SI (match_dup 0)
490 (match_operand 1 "power_of_two_operand" "")))]
491 ""
492 "*
493 {
494 int log2 = exact_log2 (INTVAL (operands[1]));
495
496 if (log2 < 8)
497 return \"set1 %M1,%0\";
498 else
499 {
500 rtx xoperands[2];
501 xoperands[0] = gen_rtx (MEM, QImode,
502 plus_constant (XEXP (operands[0], 0), log2 / 8));
503 xoperands[1] = GEN_INT (log2 % 8);
504 output_asm_insn (\"set1 %1,%0\", xoperands);
505 }
506 return \"\";
507 }"
508 [(set_attr "length" "4")
509 (set_attr "cc" "clobber")])
510
511 (define_insn "iorsi3"
512 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
513 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r")
514 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
515 ""
516 "@
517 or %2,%0
518 or %.,%0
519 ori %2,%1,%0"
520 [(set_attr "length" "2,2,4")
521 (set_attr "cc" "set_znv")])
522
523 ;; ----------------------------------------------------------------------
524 ;; XOR INSTRUCTIONS
525 ;; ----------------------------------------------------------------------
526
527 (define_insn "*v850_not1_1"
528 [(set (match_operand:QI 0 "memory_operand" "=m")
529 (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0)
530 (match_operand 1 "power_of_two_operand" "")) 0))]
531 ""
532 "not1 %M1,%0"
533 [(set_attr "length" "4")
534 (set_attr "cc" "clobber")])
535
536 (define_insn "*v850_not1_2"
537 [(set (match_operand:HI 0 "memory_operand" "=m")
538 (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0)
539 (match_operand 1 "power_of_two_operand" "")) 0))]
540 ""
541 "*
542 {
543 int log2 = exact_log2 (INTVAL (operands[1]));
544
545 if (log2 < 8)
546 return \"not1 %M1,%0\";
547 else
548 {
549 rtx xoperands[2];
550 xoperands[0] = gen_rtx (MEM, QImode,
551 plus_constant (XEXP (operands[0], 0), log2 / 8));
552 xoperands[1] = GEN_INT (log2 % 8);
553 output_asm_insn (\"not1 %1,%0\", xoperands);
554 }
555 return \"\";
556 }"
557 [(set_attr "length" "4")
558 (set_attr "cc" "clobber")])
559
560 (define_insn "*v850_not1_3"
561 [(set (match_operand:SI 0 "memory_operand" "=m")
562 (xor:SI (match_dup 0)
563 (match_operand 1 "power_of_two_operand" "")))]
564 ""
565 "*
566 {
567 int log2 = exact_log2 (INTVAL (operands[1]));
568
569 if (log2 < 8)
570 return \"not1 %M1,%0\";
571 else
572 {
573 rtx xoperands[2];
574 xoperands[0] = gen_rtx (MEM, QImode,
575 plus_constant (XEXP (operands[0], 0), log2 / 8));
576 xoperands[1] = GEN_INT (log2 % 8);
577 output_asm_insn (\"not1 %1,%0\", xoperands);
578 }
579 return \"\";
580 }"
581 [(set_attr "length" "4")
582 (set_attr "cc" "clobber")])
583
584 (define_insn "xorsi3"
585 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
586 (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r")
587 (match_operand:SI 2 "nonmemory_operand" "r,I,M")))]
588 ""
589 "@
590 xor %2,%0
591 xor %.,%0
592 xori %2,%1,%0"
593 [(set_attr "length" "2,2,4")
594 (set_attr "cc" "set_znv")])
595 \f
596 ;; ----------------------------------------------------------------------
597 ;; NOT INSTRUCTIONS
598 ;; ----------------------------------------------------------------------
599
600 (define_insn "one_cmplsi2"
601 [(set (match_operand:SI 0 "register_operand" "=r")
602 (not:SI (match_operand:SI 1 "register_operand" "r")))]
603 ""
604 "not %1,%0"
605 [(set_attr "length" "2")
606 (set_attr "cc" "set_znv")])
607 \f
608 ;; -----------------------------------------------------------------
609 ;; BIT FIELDS
610 ;; -----------------------------------------------------------------
611
612 ;; ??? Is it worth defining insv and extv for the V850 series?!?
613
614 ;; An insv pattern would be useful, but does not get used because
615 ;; store_bit_field never calls insv when storing a constant value into a
616 ;; single-bit bitfield.
617
618 ;; extv/extzv patterns would be useful, but do not get used because
619 ;; optimize_bitfield_compare in fold-const usually converts single
620 ;; bit extracts into an AND with a mask.
621
622 ;; -----------------------------------------------------------------
623 ;; Scc INSTRUCTIONS
624 ;; -----------------------------------------------------------------
625
626 (define_insn "sle"
627 [(set (match_operand:SI 0 "register_operand" "=r")
628 (le:SI (cc0) (const_int 0)))]
629 ""
630 "*
631 {
632 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
633 return 0;
634
635 return \"setf le,%0\";
636 }"
637 [(set_attr "length" "4")
638 (set_attr "cc" "none_0hit")])
639
640 (define_insn "sleu"
641 [(set (match_operand:SI 0 "register_operand" "=r")
642 (leu:SI (cc0) (const_int 0)))]
643 ""
644 "setf nh,%0"
645 [(set_attr "length" "4")
646 (set_attr "cc" "none_0hit")])
647
648 (define_insn "sge"
649 [(set (match_operand:SI 0 "register_operand" "=r")
650 (ge:SI (cc0) (const_int 0)))]
651 ""
652 "*
653 {
654 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
655 return 0;
656
657 return \"setf ge,%0\";
658 }"
659 [(set_attr "length" "4")
660 (set_attr "cc" "none_0hit")])
661
662 (define_insn "sgeu"
663 [(set (match_operand:SI 0 "register_operand" "=r")
664 (geu:SI (cc0) (const_int 0)))]
665 ""
666 "setf nl,%0"
667 [(set_attr "length" "4")
668 (set_attr "cc" "none_0hit")])
669
670 (define_insn "slt"
671 [(set (match_operand:SI 0 "register_operand" "=r")
672 (lt:SI (cc0) (const_int 0)))]
673 ""
674 "*
675 {
676 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
677 return 0;
678
679 return \"setf lt,%0\";
680 }"
681 [(set_attr "length" "4")
682 (set_attr "cc" "none_0hit")])
683
684 (define_insn "sltu"
685 [(set (match_operand:SI 0 "register_operand" "=r")
686 (ltu:SI (cc0) (const_int 0)))]
687 ""
688 "setf l,%0"
689 [(set_attr "length" "4")
690 (set_attr "cc" "none_0hit")])
691
692 (define_insn "sgt"
693 [(set (match_operand:SI 0 "register_operand" "=r")
694 (gt:SI (cc0) (const_int 0)))]
695 ""
696 "*
697 {
698 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
699 return 0;
700
701 return \"setf gt,%0\";
702 }"
703 [(set_attr "length" "4")
704 (set_attr "cc" "none_0hit")])
705
706 (define_insn "sgtu"
707 [(set (match_operand:SI 0 "register_operand" "=r")
708 (gtu:SI (cc0) (const_int 0)))]
709 ""
710 "setf h,%0"
711 [(set_attr "length" "4")
712 (set_attr "cc" "none_0hit")])
713
714 (define_insn "seq"
715 [(set (match_operand:SI 0 "register_operand" "=r")
716 (eq:SI (cc0) (const_int 0)))]
717 ""
718 "setf z,%0"
719 [(set_attr "length" "4")
720 (set_attr "cc" "none_0hit")])
721
722 (define_insn "sne"
723 [(set (match_operand:SI 0 "register_operand" "=r")
724 (ne:SI (cc0) (const_int 0)))]
725 ""
726 "setf nz,%0"
727 [(set_attr "length" "4")
728 (set_attr "cc" "none_0hit")])
729
730 \f
731 ;; ----------------------------------------------------------------------
732 ;; JUMP INSTRUCTIONS
733 ;; ----------------------------------------------------------------------
734
735 ;; Conditional jump instructions
736
737 (define_expand "ble"
738 [(set (pc)
739 (if_then_else (le (cc0)
740 (const_int 0))
741 (label_ref (match_operand 0 "" ""))
742 (pc)))]
743 ""
744 "")
745
746 (define_expand "bleu"
747 [(set (pc)
748 (if_then_else (leu (cc0)
749 (const_int 0))
750 (label_ref (match_operand 0 "" ""))
751 (pc)))]
752 ""
753 "")
754
755 (define_expand "bge"
756 [(set (pc)
757 (if_then_else (ge (cc0)
758 (const_int 0))
759 (label_ref (match_operand 0 "" ""))
760 (pc)))]
761 ""
762 "")
763
764 (define_expand "bgeu"
765 [(set (pc)
766 (if_then_else (geu (cc0)
767 (const_int 0))
768 (label_ref (match_operand 0 "" ""))
769 (pc)))]
770 ""
771 "")
772
773 (define_expand "blt"
774 [(set (pc)
775 (if_then_else (lt (cc0)
776 (const_int 0))
777 (label_ref (match_operand 0 "" ""))
778 (pc)))]
779 ""
780 "")
781
782 (define_expand "bltu"
783 [(set (pc)
784 (if_then_else (ltu (cc0)
785 (const_int 0))
786 (label_ref (match_operand 0 "" ""))
787 (pc)))]
788 ""
789 "")
790
791 (define_expand "bgt"
792 [(set (pc)
793 (if_then_else (gt (cc0)
794 (const_int 0))
795 (label_ref (match_operand 0 "" ""))
796 (pc)))]
797 ""
798 "")
799
800 (define_expand "bgtu"
801 [(set (pc)
802 (if_then_else (gtu (cc0)
803 (const_int 0))
804 (label_ref (match_operand 0 "" ""))
805 (pc)))]
806 ""
807 "")
808
809 (define_expand "beq"
810 [(set (pc)
811 (if_then_else (eq (cc0)
812 (const_int 0))
813 (label_ref (match_operand 0 "" ""))
814 (pc)))]
815 ""
816 "")
817
818 (define_expand "bne"
819 [(set (pc)
820 (if_then_else (ne (cc0)
821 (const_int 0))
822 (label_ref (match_operand 0 "" ""))
823 (pc)))]
824 ""
825 "")
826
827 (define_insn "*branch_normal"
828 [(set (pc)
829 (if_then_else (match_operator 1 "comparison_operator"
830 [(cc0) (const_int 0)])
831 (label_ref (match_operand 0 "" ""))
832 (pc)))]
833 ""
834 "*
835 {
836 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
837 && (GET_CODE (operands[1]) == GT
838 || GET_CODE (operands[1]) == GE
839 || GET_CODE (operands[1]) == LE
840 || GET_CODE (operands[1]) == LT))
841 return 0;
842
843 if (get_attr_length (insn) == 2)
844 return \"b%b1 %l0\";
845 else
846 return \"b%B1 .+6\;jr %l0\";
847 }"
848 [(set (attr "length")
849 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
850 (const_int 256))
851 (const_int 2)
852 (const_int 6)))
853 (set_attr "cc" "none")])
854
855 (define_insn "*branch_invert"
856 [(set (pc)
857 (if_then_else (match_operator 1 "comparison_operator"
858 [(cc0) (const_int 0)])
859 (pc)
860 (label_ref (match_operand 0 "" ""))))]
861 ""
862 "*
863 {
864 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
865 && (GET_CODE (operands[1]) == GT
866 || GET_CODE (operands[1]) == GE
867 || GET_CODE (operands[1]) == LE
868 || GET_CODE (operands[1]) == LT))
869 return 0;
870 if (get_attr_length (insn) == 2)
871 return \"b%B1 %l0\";
872 else
873 return \"b%b1 .+6\;jr %l0\";
874 }"
875 [(set (attr "length")
876 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
877 (const_int 256))
878 (const_int 2)
879 (const_int 6)))
880 (set_attr "cc" "none")])
881
882 ;; Unconditional and other jump instructions.
883
884 (define_insn "jump"
885 [(set (pc)
886 (label_ref (match_operand 0 "" "")))]
887 ""
888 "*
889 {
890 if (get_attr_length (insn) == 2)
891 return \"br %0\";
892 else
893 return \"jr %0\";
894 }"
895 [(set (attr "length")
896 (if_then_else (lt (abs (minus (match_dup 0) (pc)))
897 (const_int 256))
898 (const_int 2)
899 (const_int 4)))
900 (set_attr "cc" "none")])
901
902 (define_insn "indirect_jump"
903 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
904 ""
905 "jmp %0"
906 [(set_attr "length" "2")
907 (set_attr "cc" "none")])
908
909 (define_insn "tablejump"
910 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
911 (use (label_ref (match_operand 1 "" "")))]
912 ""
913 "jmp %0"
914 [(set_attr "length" "2")
915 (set_attr "cc" "none")])
916
917 (define_expand "casesi"
918 [(match_operand:SI 0 "register_operand" "")
919 (match_operand:SI 1 "register_operand" "")
920 (match_operand:SI 2 "register_operand" "")
921 (match_operand 3 "" "") (match_operand 4 "" "")]
922 ""
923 "
924 {
925 rtx reg = gen_reg_rtx (SImode);
926 rtx tableaddress = gen_reg_rtx (SImode);
927 rtx mem;
928
929 /* Subtract the lower bound from the index. */
930 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
931 /* Compare the result against the number of table entries. */
932 emit_insn (gen_cmpsi (reg, operands[2]));
933 /* Branch to the default label if out of range of the table. */
934 emit_jump_insn (gen_bgtu (operands[4]));
935
936 /* Shift index for the table array access. */
937 emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
938 /* Load the table address into a psuedo. */
939 emit_insn (gen_movsi (tableaddress,
940 gen_rtx (LABEL_REF, VOIDmode, operands[3])));
941 /* Add the table address to the index. */
942 emit_insn (gen_addsi3 (reg, reg, tableaddress));
943 /* Load the table entry. */
944 mem = gen_rtx (MEM, CASE_VECTOR_MODE, reg);
945 RTX_UNCHANGING_P (mem);
946 if (! TARGET_BIG_SWITCH)
947 {
948 rtx reg2 = gen_reg_rtx (HImode);
949 emit_insn (gen_movhi (reg2, mem));
950 emit_insn (gen_extendhisi2 (reg, reg2));
951 }
952 else
953 emit_insn (gen_movsi (reg, mem));
954 /* Add the table address. */
955 emit_insn (gen_addsi3 (reg, reg, tableaddress));
956 /* Branch to the switch label. */
957 emit_jump_insn (gen_tablejump (reg, operands[3]));
958 DONE;
959 }")
960
961 ;; Call subroutine with no return value.
962
963 (define_expand "call"
964 [(call (match_operand:QI 0 "general_operand" "")
965 (match_operand:SI 1 "general_operand" ""))]
966 ""
967 "
968 {
969 if (! call_address_operand (XEXP (operands[0], 0))
970 || TARGET_LONG_CALLS)
971 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
972 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
973 DONE;
974 }")
975
976 (define_insn "call_internal"
977 [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r"))
978 (match_operand:SI 1 "general_operand" "g,g"))
979 (clobber (reg:SI 31))]
980 ""
981 "@
982 jarl %0,r31
983 jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %0"
984 [(set_attr "length" "4,8")])
985
986 ;; Call subroutine, returning value in operand 0
987 ;; (which must be a hard register).
988
989 (define_expand "call_value"
990 [(set (match_operand 0 "" "")
991 (call (match_operand:QI 1 "general_operand" "")
992 (match_operand:SI 2 "general_operand" "")))]
993 ""
994 "
995 {
996 if (! call_address_operand (XEXP (operands[1], 0))
997 || TARGET_LONG_CALLS)
998 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
999 emit_call_insn (gen_call_value_internal (operands[0],
1000 XEXP (operands[1], 0),
1001 operands[2]));
1002 DONE;
1003 }")
1004
1005 (define_insn "call_value_internal"
1006 [(set (match_operand 0 "" "=r,r")
1007 (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r"))
1008 (match_operand:SI 2 "general_operand" "g,g")))
1009 (clobber (reg:SI 31))]
1010 ""
1011 "@
1012 jarl %1,r31
1013 jarl .+4,r31\\n\\tadd 4,r31\\n\\tjmp %1"
1014 [(set_attr "length" "4,8")])
1015
1016 (define_insn "nop"
1017 [(const_int 0)]
1018 ""
1019 "nop"
1020 [(set_attr "length" "2")
1021 (set_attr "cc" "none")])
1022 \f
1023 ;; ----------------------------------------------------------------------
1024 ;; EXTEND INSTRUCTIONS
1025 ;; ----------------------------------------------------------------------
1026
1027
1028 (define_insn "zero_extendhisi2"
1029 [(set (match_operand:SI 0 "register_operand" "=r")
1030 (zero_extend:SI
1031 (match_operand:HI 1 "register_operand" "r")))]
1032 ""
1033 "andi 65535,%1,%0"
1034 [(set_attr "length" "4")
1035 (set_attr "cc" "set_znv")])
1036
1037
1038 (define_insn "zero_extendqisi2"
1039 [(set (match_operand:SI 0 "register_operand" "=r")
1040 (zero_extend:SI
1041 (match_operand:QI 1 "register_operand" "r")))]
1042 ""
1043 "andi 255,%1,%0"
1044 [(set_attr "length" "4")
1045 (set_attr "cc" "set_znv")])
1046
1047 ;;- sign extension instructions
1048
1049
1050 ;; ??? This is missing a sign extend from memory pattern to match the ld.h
1051 ;; instruction.
1052
1053 (define_expand "extendhisi2"
1054 [(set (match_dup 2)
1055 (ashift:SI (match_operand:HI 1 "register_operand" "")
1056 (const_int 16)))
1057 (set (match_operand:SI 0 "register_operand" "")
1058 (ashiftrt:SI (match_dup 2)
1059 (const_int 16)))]
1060 ""
1061 "
1062 {
1063 operands[1] = gen_lowpart (SImode, operands[1]);
1064 operands[2] = gen_reg_rtx (SImode);
1065 }")
1066
1067
1068 ;; ??? This is missing a sign extend from memory pattern to match the ld.b
1069 ;; instruction.
1070
1071 (define_expand "extendqisi2"
1072 [(set (match_dup 2)
1073 (ashift:SI (match_operand:QI 1 "register_operand" "")
1074 (const_int 24)))
1075 (set (match_operand:SI 0 "register_operand" "")
1076 (ashiftrt:SI (match_dup 2)
1077 (const_int 24)))]
1078 ""
1079 "
1080 {
1081 operands[1] = gen_lowpart (SImode, operands[1]);
1082 operands[2] = gen_reg_rtx (SImode);
1083 }")
1084 \f
1085 ;; ----------------------------------------------------------------------
1086 ;; SHIFTS
1087 ;; ----------------------------------------------------------------------
1088
1089 (define_insn "ashlsi3"
1090 [(set (match_operand:SI 0 "register_operand" "=r,r")
1091 (ashift:SI
1092 (match_operand:SI 1 "register_operand" "0,0")
1093 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1094 ""
1095 "@
1096 shl %2,%0
1097 shl %2,%0"
1098 [(set_attr "length" "4,2")
1099 (set_attr "cc" "set_znv")])
1100
1101 (define_insn "lshrsi3"
1102 [(set (match_operand:SI 0 "register_operand" "=r,r")
1103 (lshiftrt:SI
1104 (match_operand:SI 1 "register_operand" "0,0")
1105 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1106 ""
1107 "@
1108 shr %2,%0
1109 shr %2,%0"
1110 [(set_attr "length" "4,2")
1111 (set_attr "cc" "set_znv")])
1112
1113 (define_insn "ashrsi3"
1114 [(set (match_operand:SI 0 "register_operand" "=r,r")
1115 (ashiftrt:SI
1116 (match_operand:SI 1 "register_operand" "0,0")
1117 (match_operand:SI 2 "nonmemory_operand" "r,N")))]
1118 ""
1119 "@
1120 sar %2,%0
1121 sar %2,%0"
1122 [(set_attr "length" "4,2")
1123 (set_attr "cc" "set_znv")])
1124
1125 ;; ----------------------------------------------------------------------
1126 ;; PROLOGUE/EPILOGUE
1127 ;; ----------------------------------------------------------------------
1128 (define_expand "prologue"
1129 [(const_int 0)]
1130 ""
1131 "expand_prologue (); DONE;")
1132
1133 (define_expand "epilogue"
1134 [(return)]
1135 ""
1136 "
1137 {
1138 /* Try to use the trivial return first. Else use the
1139 full epilogue. */
1140 if (0)
1141 emit_jump_insn (gen_return ());
1142 else
1143 expand_epilogue ();
1144 DONE;
1145 }")
1146
1147 (define_insn "return"
1148 [(return)]
1149 "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0"
1150 "jmp [r31]"
1151 [(set_attr "length" "2")
1152 (set_attr "cc" "none")])
1153
1154 (define_insn "return_internal"
1155 [(return)
1156 (use (reg:SI 31))]
1157 ""
1158 "jmp [r31]"
1159 [(set_attr "length" "2")
1160 (set_attr "cc" "none")])
1161
1162
1163 \f
1164 ;; ----------------------------------------------------------------------
1165 ;; HELPER INSTRUCTIONS for saving the prologue and epilog registers
1166 ;; ----------------------------------------------------------------------
1167
1168 ;; This pattern will match a stack adjust RTX followed by any number of push
1169 ;; RTXs. These RTXs will then be turned into a suitable call to a worker
1170 ;; function.
1171
1172
1173 (define_insn ""
1174 [(match_parallel 0 "pattern_is_ok_for_prologue"
1175 [(set (reg:SI 3)
1176 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1177 (set (mem:SI (plus:SI (reg:SI 3)
1178 (match_operand:SI 2 "immediate_operand" "i")))
1179 (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])]
1180 "TARGET_PROLOG_FUNCTION"
1181 "* return construct_save_jarl (operands[0]);
1182 "
1183 [(set_attr "length" "4")
1184 (set_attr "cc" "clobber")])
1185
1186
1187 ;; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.
1188 (define_insn "save_interrupt"
1189 [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16)))
1190 (set (mem:SI (reg:SI 3)) (reg:SI 30))
1191 (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))
1192 (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4))
1193 (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))]
1194 ""
1195 "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10"
1196 [(set_attr "length" "12")
1197 (set_attr "cc" "clobber")])
1198
1199
1200 ;; Save all registers except for the registers saved in save_interrupt when
1201 ;; an interrupt function makes a call.
1202 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1203 ;; all of memory. This blocks insns from being moved across this point.
1204 ;; This is needed because the rest of the compiler is not reading to handle
1205 ;; insns this compilcated
1206
1207 (define_insn "save_all_interrupt"
1208 [(unspec_volatile [(const_int 0)] 0)]
1209 ""
1210 "jarl __save_all_interrupt,r10"
1211 [(set_attr "length" "4")
1212 (set_attr "cc" "clobber")])
1213
1214
1215
1216
1217 ;; This pattern will match a return RTX followed by any number of pop RTXs
1218 ;; and possible a stack adjustment as well. These RTXs will be turned into
1219 ;; a suitable call to a worker function.
1220
1221
1222 (define_insn ""
1223 [(match_parallel 0 "pattern_is_ok_for_epilogue"
1224 [(return)
1225 (set (reg:SI 3)
1226 (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i")))
1227 (set (match_operand:SI 2 "register_is_ok_for_epilogue" "r")
1228 (mem:SI (plus:SI (reg:SI 3)
1229 (match_operand:SI 3 "immediate_operand" "i"))))])]
1230 "TARGET_PROLOG_FUNCTION && TARGET_V850"
1231 "* return construct_restore_jr (operands[0]);
1232 "
1233 [(set_attr "length" "4")
1234 (set_attr "cc" "clobber")])
1235
1236 ;; Restore r1, r4, r10, and return from the interrupt
1237 (define_insn "restore_interrupt"
1238 [(return)
1239 (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16)))
1240 (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12))))
1241 (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8))))
1242 (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4))))
1243 (set (reg:SI 1) (mem:SI (reg:SI 3)))]
1244 ""
1245 "jr __return_interrupt"
1246 [(set_attr "length" "4")
1247 (set_attr "cc" "clobber")])
1248
1249 ;; Restore all registers saved when an interrupt function makes a call.
1250 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1251 ;; all of memory. This blocks insns from being moved across this point.
1252 ;; This is needed because the rest of the compiler is not reading to handle
1253 ;; insns this compilcated
1254
1255 (define_insn "restore_all_interrupt"
1256 [(unspec_volatile [(const_int 0)] 1)]
1257 ""
1258 "jarl __restore_all_interrupt,r10"
1259 [(set_attr "length" "4")
1260 (set_attr "cc" "clobber")])
1261
1262 ;; Save r6-r9 for a variable argument function
1263 (define_insn "save_r6_r9"
1264 [(set (mem:SI (reg:SI 3)) (reg:SI 6))
1265 (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7))
1266 (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8))
1267 (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9))
1268 (clobber (reg:SI 10))]
1269 "TARGET_PROLOG_FUNCTION"
1270 "jarl __save_r6_r9,r10"
1271 [(set_attr "length" "4")
1272 (set_attr "cc" "clobber")])
1273