]> gcc.gnu.org Git - gcc.git/blame - gcc/config/mn10200/mn10200.md
alpha.md (call patterns): Revert Oct 16 change...
[gcc.git] / gcc / config / mn10200 / mn10200.md
CommitLineData
a1c8363d
JL
1;; GCC machine description for Matsushita MN10200
2;; Copyright (C) 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;; Condition code settings.
29;; none - insn does not affect cc
30;; none_0hit - insn does not affect cc but it does modify operand 0
31;; This attribute is used to keep track of when operand 0 changes.
32;; See the description of NOTICE_UPDATE_CC for more info.
33;; set_znv - sets z,n,v to useable values; c is unknown.
34;; set_zn - sets z,n to usable values; v,c is unknown.
35;; compare - compare instruction
36;; clobber - value of cc is unknown
37(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
38 (const_string "clobber"))
39\f
40;; ----------------------------------------------------------------------
41;; MOVE INSTRUCTIONS
42;; ----------------------------------------------------------------------
43;;
44;; Some general notes on move instructions.
45;;
46;; The hardware can't encode nop moves involving data registers, so
47;; we catch them and emit a nop instead.
48;;
49;; Loads/stores to/from address registers must be 16bit aligned,
50;; thus we avoid them for QImode.
51;;
52;; Stores from address registers always store 24bits, so avoid
53;; stores from address registers in HImode, SImode, and SFmode.
54;;
55;; As a result of the various problems using address registers in
56;; QImode, HImode, SImode, and SFmode, we discourage their use via
57;; '*' in their constraints. They're still allowed, but they're never
58;; the preferred class for for insns with those modes.
59
60;; movqi
61
62(define_expand "movqi"
63 [(set (match_operand:QI 0 "general_operand" "")
64 (match_operand:QI 1 "general_operand" ""))]
65 ""
66 "
67{
68 /* One of the ops has to be in a register */
69 if (!register_operand (operand0, QImode)
70 && !register_operand (operand1, QImode))
71 operands[1] = copy_to_mode_reg (QImode, operand1);
72}")
73
74;; We avoid memory operations involving address registers because we
75;; can't be sure they'll be suitably aligned.
76;;
77;; We also discourage holding QImode values in address registers.
78(define_insn ""
79 [(set (match_operand:QI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a")
80 (match_operand:QI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a"))]
81 "register_operand (operands[0], QImode)
82 || register_operand (operands[1], QImode)"
83 "@
84 nop
85 sub %0,%0
86 sub %0,%0
87 mov %S1,%0
88 movbu %1,%0
89 movb %1,%0
90 mov %1,%0
91 mov %1,%0
92 mov %1,%0"
93 [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
94
95;; movhi
96
97(define_expand "movhi"
98 [(set (match_operand:HI 0 "general_operand" "")
99 (match_operand:HI 1 "general_operand" ""))]
100 ""
101 "
102{
103 /* One of the ops has to be in a register */
104 if (!register_operand (operand1, HImode)
105 && !register_operand (operand0, HImode))
106 operands[1] = copy_to_mode_reg (HImode, operand1);
107}")
108
109(define_insn ""
110 [(set (match_operand:HI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a,*a")
111 (match_operand:HI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a,m"))]
112 "register_operand (operands[0], HImode)
113 || register_operand (operands[1], HImode)"
114 "@
115 nop
116 sub %0,%0
117 sub %0,%0
118 mov %s1,%0
119 mov %1,%0
120 mov %1,%0
121 mov %1,%0
122 mov %1,%0
123 mov %1,%0
124 mov %A1,%0"
125 [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
126
127;; movpsi and helpers
128
129(define_expand "movpsi"
130 [(set (match_operand:PSI 0 "general_operand" "")
131 (match_operand:PSI 1 "general_operand" ""))]
132 ""
133 "
134{
135 /* One of the ops has to be in a register */
136 if (!register_operand (operand1, PSImode)
137 && !register_operand (operand0, PSImode))
138 operands[1] = copy_to_mode_reg (PSImode, operand1);
139}")
140
141
142;; Constant and indexed addresses are not valid addresses for PSImode,
143;; therefore they won't be matched by the general movpsi pattern below.
144;; ??? We had patterns to handle indexed addresses, but they kept making
145;; us run out of regs, so they were eliminated.
146
147(define_insn ""
148 [(set (match_operand:PSI 0 "register_operand" "=a")
149 (match_operand:PSI 1 "constant_memory_operand" ""))]
150 ""
151 "mov %A1,%0"
152 [(set_attr "cc" "none_0hit")])
153
154(define_insn ""
155 [(set (match_operand:PSI 0 "constant_memory_operand" "=X")
156 (match_operand:PSI 1 "register_operand" "a"))]
157 ""
158 "mov %1,%A0"
159 [(set_attr "cc" "none_0hit")])
160
161;; We want to prefer address registers here because 24bit moves to/from
162;; memory are shorter and faster when done via address registers.
163(define_insn ""
164 [(set (match_operand:PSI 0 "general_operand" "=d,a?d,?da,a,m,?d,m")
165 (match_operand:PSI 1 "general_operand" "0,I,?dai,m,a,m,?d"))]
166 "register_operand (operands[0], PSImode)
167 || register_operand (operands[1], PSImode)"
168 "@
169 nop
170 sub %0,%0
171 mov %1,%0
172 mov %A1,%0
173 mov %1,%A0
174 movx %A1,%0
175 movx %1,%A0"
176 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
177
178(define_expand "movsi"
179 [(set (match_operand:SI 0 "general_operand" "")
180 (match_operand:SI 1 "general_operand" ""))]
181 ""
182 "
183{
184 /* One of the ops has to be in a register */
185 if (!register_operand (operand1, SImode)
186 && !register_operand (operand0, SImode))
187 operands[1] = copy_to_mode_reg (SImode, operand1);
188}")
189
190(define_insn ""
191 [(set (match_operand:SI 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a")
192 (match_operand:SI 1 "general_operand" "0,I,I,d,dim,*a,d,*a,i"))]
193 "register_operand (operands[0], SImode)
194 || register_operand (operands[1], SImode)"
195 "*
196{
197 switch (which_alternative)
198 {
199 case 0:
200 return \"nop\";
201 case 1:
202 case 2:
203 return \"sub %H0,%H0\;sub %L0,%L0\";
204 case 3:
205 case 5:
206 case 6:
207 case 7:
208 return \"mov %H1,%H0\;mov %L1,%L0\";
209
210 /* The next two cases try to optimize cases where one half
211 of the constant is all zeros, or when the two halves are
212 the same. */
213 case 4:
214 case 8:
215 if (REG_P (operands[0])
216 && GET_CODE (operands[1]) == CONST_INT
217 && (INTVAL (operands[1]) & 0xffff0000) == 0)
218 output_asm_insn (\"sub %H0,%H0\", operands);
219 else
220 output_asm_insn (\"mov %h1,%H0\", operands);
221
222 if (GET_CODE (operands[1]) == CONST_INT
223 && ((INTVAL (operands[1]) & 0xffff)
224 == ((INTVAL (operands[1]) >> 16) & 0xffff)))
225 output_asm_insn (\"mov %H0,%L0\", operands);
226 else if (GET_CODE (operands[1]) == CONST_INT
227 && (INTVAL (operands[1]) & 0xffff) == 0)
228 output_asm_insn (\"sub %L0,%L0\", operands);
229 else
230 output_asm_insn (\"mov %o1,%L0\", operands);
231 return \"\";
232 }
233}"
234 [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
235
236(define_expand "movsf"
237 [(set (match_operand:SF 0 "general_operand" "")
238 (match_operand:SF 1 "general_operand" ""))]
239 ""
240 "
241{
242 /* One of the ops has to be in a register */
243 if (!register_operand (operand1, SFmode)
244 && !register_operand (operand0, SFmode))
245 operands[1] = copy_to_mode_reg (SFmode, operand1);
246}")
247
248(define_insn ""
249 [(set (match_operand:SF 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a")
250 (match_operand:SF 1 "general_operand" "0,G,G,d,dim,*a,d,*a,i"))]
251 "register_operand (operands[0], SFmode)
252 || register_operand (operands[1], SFmode)"
253 "*
254{
255 switch (which_alternative)
256 {
257 case 0:
258 return \"nop\";
259
260 case 1:
261 case 2:
262 return \"sub %H0,%H0\;sub %L0,%L0\";
263
264 default:
265 {
266 long val;
267 REAL_VALUE_TYPE rv;
268
269 if (GET_CODE (operands[1]) == CONST_DOUBLE)
270 {
271 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
272 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
273 }
274
275 if (GET_CODE (operands[1]) == CONST_INT)
276 val = INTVAL (operands[1]);
277
278 if ((GET_CODE (operands[1]) == CONST_INT
279 || GET_CODE (operands[1]) == CONST_DOUBLE)
280 && (val & 0xffff0000) == 0)
281 output_asm_insn (\"sub %H0,%H0\", operands);
282 else
283 output_asm_insn (\"mov %h1,%H0\", operands);
284
285 if (GET_CODE (operands[1]) == CONST_INT
286 && ((INTVAL (operands[1]) & 0xffff)
287 == ((INTVAL (operands[1]) >> 16) & 0xffff)))
288 output_asm_insn (\"mov %H0,%L0\", operands);
289 else if ((GET_CODE (operands[1]) == CONST_INT
290 || GET_CODE (operands[1]) == CONST_DOUBLE)
291 && (val & 0x0000ffff) == 0)
292 output_asm_insn (\"sub %L0,%L0\", operands);
293 else
294 output_asm_insn (\"mov %o1,%L0\", operands);
295 return \"\";
296 }
297 }
298}"
299 [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
300
301\f
302;; ----------------------------------------------------------------------
303;; TEST INSTRUCTIONS
304;; ----------------------------------------------------------------------
305
306;; Go ahead and define tsthi and tstpsi so we can eliminate redundant tst insns
307;; when we start trying to optimize this port.
308(define_insn "tsthi"
309 [(set (cc0) (match_operand:HI 0 "general_operand" "da"))]
310 ""
311 "* return output_tst (operands[0], insn);"
312 [(set_attr "cc" "set_znv")])
313
314(define_insn "tstpsi"
315 [(set (cc0) (match_operand:PSI 0 "general_operand" "da"))]
316 ""
317 "* return output_tst (operands[0], insn);"
318 [(set_attr "cc" "set_znv")])
319
320(define_insn ""
321 [(set (cc0) (zero_extend:HI (match_operand:QI 0 "memory_operand" "d")))]
322 ""
323 "* return output_tst (operands[0], insn);"
324 [(set_attr "cc" "set_znv")])
325
326(define_insn ""
327 [(set (cc0) (zero_extend:PSI (match_operand:QI 0 "memory_operand" "d")))]
328 ""
329 "* return output_tst (operands[0], insn);"
330 [(set_attr "cc" "set_znv")])
331
332(define_insn "cmphi"
333 [(set (cc0)
334 (compare:HI (match_operand:HI 0 "general_operand" "da")
335 (match_operand:HI 1 "general_operand" "dai")))]
336 ""
337 "cmp %1,%0"
338 [(set_attr "cc" "compare")])
339
340(define_insn "cmppsi"
341 [(set (cc0)
342 (compare:PSI (match_operand:PSI 0 "general_operand" "da")
343 (match_operand:PSI 1 "general_operand" "dai")))]
344 ""
345 "cmp %1,%0"
346 [(set_attr "cc" "compare")])
347\f
348;; ----------------------------------------------------------------------
349;; ADD INSTRUCTIONS
350;; ----------------------------------------------------------------------
351
352(define_insn "addhi3"
353 [(set (match_operand:HI 0 "general_operand" "=d")
354 (plus:HI (match_operand:HI 1 "general_operand" "%0")
355 (match_operand:HI 2 "general_operand" "dai")))]
356 ""
357 "add %2,%0"
358 [(set_attr "cc" "set_zn")])
359
360(define_insn "addpsi3"
361 [(set (match_operand:PSI 0 "general_operand" "=da")
362 (plus:PSI (match_operand:PSI 1 "general_operand" "%0")
363 (match_operand:PSI 2 "general_operand" "dai")))]
364 ""
365 "add %2,%0"
366 [(set_attr "cc" "set_zn")])
367
368;; We want to avoid using explicit registers; reload won't tell us
369;; if it has to spill them and may generate incorrect code in such
370;; cases.
371;;
372;; So we call out to a library routine to perform 32bit add or
373;; subtract operations.
374(define_expand "addsi3"
375 [(set (match_operand:SI 0 "general_operand" "")
376 (plus:SI (match_operand:SI 1 "general_operand" "")
377 (match_operand:SI 2 "general_operand" "")))]
378 ""
379 "
380{
381 /* If adding a CONST_INT, we are better off generating code ourselves.
382
383 During RTL generation we call out to library routines.
384
385 After RTL generation we can not call the library routines as
386 they need to push arguments via virtual_outgoing_args_rtx which
387 has already been instantiated. So, after RTL generation we just
388 FAIL and open code the operation. */
389 if (GET_CODE (operands[2]) == CONST_INT)
390 {
391 if (!rtx_equal_p (operands[0], operands[1]))
392 emit_move_insn (operands[0], operands[1]);
393 emit_insn (gen_addsi3_const (operands[0], operands[0], operands[2]));
394 DONE;
395 }
396 else if (rtx_equal_function_value_matters)
397 {
398 rtx ret, insns;
399 extern rtx emit_library_call_value ();
400
401 start_sequence ();
402 ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__addsi3\"),
403 NULL_RTX, 1, SImode, 2, operands[1],
404 SImode, operands[2], SImode);
405 insns = get_insns ();
406 end_sequence ();
407 emit_libcall_block (insns, operands[0], ret,
408 gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
409 DONE;
410 }
411 else
412 FAIL;
413}")
414
415(define_insn "addsi3_const"
416 [(set (match_operand:SI 0 "general_operand" "=d")
417 (plus:SI (match_operand:SI 1 "general_operand" "0")
418 (match_operand:SI 2 "const_int_operand" "i")))
419 (clobber (match_scratch:SI 3 "=&d"))]
420 ""
421 "*
422{
423 unsigned long value = INTVAL (operands[2]);
424
425 /* If only the high bits are set in the constant, then we only
426 need a single add operation. It might be better to catch this
427 at RTL expansion time. */
428 if ((value & 0xffff) == 0)
429 return \"add %h2,%H0\";
430
431 value >>= 16;
432 value &= 0xffff;
433
434 if (value == 0)
435 return \"sub %3,%3\;add %o2,%L0\;addc %3,%H0\";
436 else
437 return \"mov %h2,%3\;add %o2,%L0\;addc %3,%H0\";
438}"
439 [(set_attr "cc" "clobber")])
440
441;; ----------------------------------------------------------------------
442;; SUBTRACT INSTRUCTIONS
443;; ----------------------------------------------------------------------
444
445(define_insn "subhi3"
446 [(set (match_operand:HI 0 "general_operand" "=d")
447 (minus:HI (match_operand:HI 1 "general_operand" "0")
448 (match_operand:HI 2 "general_operand" "dai")))]
449 ""
450 "sub %2,%0"
451 [(set_attr "cc" "set_zn")])
452
453(define_insn "subpsi3"
454 [(set (match_operand:PSI 0 "general_operand" "=da")
455 (minus:PSI (match_operand:PSI 1 "general_operand" "0")
456 (match_operand:PSI 2 "general_operand" "dai")))]
457 ""
458 "sub %2,%0"
459 [(set_attr "cc" "set_zn")])
460
461(define_expand "subsi3"
462 [(set (match_operand:SI 0 "general_operand" "")
463 (minus:SI (match_operand:SI 1 "general_operand" "")
464 (match_operand:SI 2 "general_operand" "")))]
465 ""
466 "
467{
468 /* During RTL generation we call out to library routines.
469
470 After RTL generation we can not call the library routines as
471 they need to push arguments via virtual_outgoing_args_rtx which
472 has already been instantiated. So, after RTL generation we just
473 FAIL and open code the operation. */
474 if (rtx_equal_function_value_matters)
475 {
476 rtx ret, insns;
477 extern rtx emit_library_call_value ();
478
479 start_sequence ();
480 ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__subsi3\"),
481 NULL_RTX, 1, SImode, 2, operands[1],
482 SImode, operands[2], SImode);
483 insns = get_insns ();
484 end_sequence ();
485 emit_libcall_block (insns, operands[0], ret,
486 gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
487 DONE;
488 }
489 else
490 FAIL;
491}")
492
493;; There isn't a negate instruction, so we fake it.
494;;
495;; We used to expand this into patterns, but a single pattern
496;; actually generates better overall code.
497;;
498;; We could do HImode negations with a "not;add" sequence, but
499;; generally it's generated slightly worse code.
e92f9bcf
JL
500;;
501;; The second alternative is not strictly necesasry, but helps
502;; when the register allocators start running short of registers.
a1c8363d 503(define_insn "neghi2"
e92f9bcf
JL
504 [(set (match_operand:HI 0 "general_operand" "=&d,d")
505 (neg:HI (match_operand:HI 1 "general_operand" "d,0")))]
a1c8363d 506 ""
e92f9bcf
JL
507 "@
508 sub %0,%0\;sub %1,%0
509 not %0\;add 1,%0"
a1c8363d
JL
510 [(set_attr "cc" "set_zn")])
511
e92f9bcf
JL
512;; The not/and sequence won't work here. It's not clear if we'll
513;; ever need to provide an alternate sequence since this should
514;; be used much less frequently than neghi2.
a1c8363d
JL
515(define_insn "negpsi2"
516 [(set (match_operand:PSI 0 "general_operand" "=&d")
517 (neg:PSI (match_operand:PSI 1 "general_operand" "d")))]
518 ""
519 "sub %0,%0\;sub %1,%0"
520 [(set_attr "cc" "set_zn")])
521
522;; Using a magic libcall that accepts its arguments in any
523;; data register pair has proven to be the most efficient
524;; and most compact way to represent negsi2.
525(define_insn "negsi2"
526 [(set (match_operand:SI 0 "general_operand" "=d")
527 (neg:SI (match_operand:SI 1 "general_operand" "0")))]
528 ""
529 "jsr ___negsi2_%0"
530 [(set_attr "cc" "clobber")])
531
532;; ----------------------------------------------------------------------
533;; MULTIPLY INSTRUCTIONS
534;; ----------------------------------------------------------------------
535;;
536;; The mn10200 has HIxHI->SI widening multiply, but we get _severe_
537;; code density regressions if we enable such a pattern.
538
539(define_insn "mulhi3"
540 [(set (match_operand:HI 0 "general_operand" "=d")
541 (mult:HI (match_operand:HI 1 "general_operand" "%0")
542 (match_operand:HI 2 "general_operand" "d")))]
543 ""
544 "mul %2,%0"
545 [(set_attr "cc" "set_zn")])
546
547(define_insn "udivmodhi4"
548 [(set (match_operand:HI 0 "general_operand" "=d")
549 (udiv:HI (match_operand:HI 1 "general_operand" "0")
550 (match_operand:HI 2 "general_operand" "d")))
551 (set (match_operand:HI 3 "general_operand" "=&d")
552 (umod:HI (match_dup 1) (match_dup 2)))]
553 ""
554 "*
555{
556 if (zero_dreg)
557 output_asm_insn (\"mov %0,mdr\", &zero_dreg);
558 else
559 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
560
561 if (find_reg_note (insn, REG_UNUSED, operands[3]))
562 return \"divu %2,%0\";
563 else
564 return \"divu %2,%0\;mov mdr,%3\";
565}"
566 [(set_attr "cc" "set_zn")])
567
568\f
569;; ----------------------------------------------------------------------
570;; AND INSTRUCTIONS
571;; ----------------------------------------------------------------------
572
573(define_insn "andhi3"
574 [(set (match_operand:HI 0 "general_operand" "=d,d")
575 (and:HI (match_operand:HI 1 "general_operand" "%0,0")
576 (match_operand:HI 2 "general_operand" "M,di")))]
577 ""
578 "*
579{
580 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
581 return \"extxbu %0\";
582 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fff)
583 return \"add %0,%0\;lsr %0\";
584 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffe)
585 return \"lsr %0\;add %0,%0\";
586 return \"and %2,%0\";
587}"
588 [(set_attr "cc" "none_0hit,set_znv")])
589
590;; This expander + pattern exist only to allow trampolines to be aligned
591;; in the stack.
592(define_expand "andpsi3"
593 [(set (match_operand:PSI 0 "general_operand" "")
594 (and:PSI (match_operand:PSI 1 "general_operand" "")
595 (match_operand:PSI 2 "const_int_operand" "")))]
596 ""
597 "
598{
599 if (GET_CODE (operands[2]) != CONST_INT
600 || (INTVAL (operands[2]) & 0xff0000) != 0xff0000)
601 FAIL;
602}")
603
604(define_insn ""
605 [(set (match_operand:PSI 0 "general_operand" "=d")
606 (and:PSI (match_operand:PSI 1 "general_operand" "%0")
607 (match_operand:PSI 2 "const_int_operand" "i")))]
608 "GET_CODE (operands[2]) == CONST_INT
609 && (INTVAL (operands[2]) & 0xff0000) == 0xff0000"
610 "and %2,%0"
611 [(set_attr "cc" "clobber")])
612
613;; ----------------------------------------------------------------------
614;; OR INSTRUCTIONS
615;; ----------------------------------------------------------------------
616
617(define_insn "iorhi3"
618 [(set (match_operand:HI 0 "general_operand" "=d")
619 (ior:HI (match_operand:HI 1 "general_operand" "%0")
620 (match_operand:HI 2 "general_operand" "di")))]
621 ""
622 "or %2,%0"
623 [(set_attr "cc" "set_znv")])
624
625;; ----------------------------------------------------------------------
626;; XOR INSTRUCTIONS
627;; ----------------------------------------------------------------------
628
629(define_insn "xorhi3"
630 [(set (match_operand:HI 0 "general_operand" "=d")
631 (xor:HI (match_operand:HI 1 "general_operand" "%0")
632 (match_operand:HI 2 "general_operand" "di")))]
633 ""
634 "xor %2,%0"
635 [(set_attr "cc" "set_znv")])
636
637;; ----------------------------------------------------------------------
638;; NOT INSTRUCTIONS
639;; ----------------------------------------------------------------------
640
641(define_insn "one_cmplhi2"
642 [(set (match_operand:HI 0 "general_operand" "=d")
643 (not:HI (match_operand:HI 1 "general_operand" "0")))]
644 ""
645 "not %0"
646 [(set_attr "cc" "set_znv")])
647
648\f
649;; -----------------------------------------------------------------
650;; BIT INSTRUCTIONS
651;; -----------------------------------------------------------------
652
653;; When clearing a set of bits in memory, we load the inverted bitmask into
654;; a register, then use bclr.
655(define_insn ""
656 [(set (match_operand:QI 0 "indirect_memory_operand" "")
657 (subreg:QI
658 (and:HI (subreg:HI (match_dup 0) 0)
659 (match_operand 1 "const_int_operand" "")) 0))
660 (clobber (match_scratch:HI 2 "=&d"))]
661 ""
662 "mov %N1,%2\;bclr %2,%0"
663 [(set_attr "cc" "clobber")])
664
665;; These clear a non-constant set of bits in memory.
666(define_insn ""
667 [(set (match_operand:QI 0 "indirect_memory_operand" "")
668 (subreg:QI
669 (and:HI (subreg:HI (match_dup 0) 0)
670 (not:HI (match_operand:HI 1 "general_operand" "d"))) 0))]
671 ""
672 "bclr %1,%0"
673 [(set_attr "cc" "clobber")])
674
675(define_insn ""
676 [(set (match_operand:QI 0 "indirect_memory_operand" "")
677 (subreg:QI
678 (and:HI (not:HI (match_operand:HI 1 "general_operand" "d"))
679 (subreg:HI (match_dup 0) 0)) 0))]
680 ""
681 "bclr %1,%0"
682 [(set_attr "cc" "clobber")])
683
684;; These set bits in memory.
685(define_insn ""
686 [(set (match_operand:QI 0 "indirect_memory_operand" "")
687 (subreg:QI
688 (ior:HI (subreg:HI (match_dup 0) 0)
689 (match_operand:HI 1 "general_operand" "d")) 0))]
690 ""
691 "bset %1,%0"
692 [(set_attr "cc" "clobber")])
693
694(define_insn ""
695 [(set (match_operand:QI 0 "indirect_memory_operand" "")
696 (subreg:QI
697 (ior:HI (match_operand:HI 1 "general_operand" "d")
698 (subreg:HI (match_dup 0) 0)) 0))]
699 ""
700 "bset %1,%0"
701 [(set_attr "cc" "clobber")])
702
703;; Not any shorter/faster than using cmp, but it might save a
704;; register if the result of the AND isn't ever used.
705
706(define_insn ""
707 [(set (cc0)
708 (zero_extract:HI (match_operand:HI 0 "general_operand" "d")
709 (match_operand 1 "const_int_operand" "")
710 (match_operand 2 "const_int_operand" "")))]
711 ""
712 "*
713{
714 int len = INTVAL (operands[1]);
715 int bit = INTVAL (operands[2]);
716 int mask = 0;
717 rtx xoperands[2];
718
719 while (len > 0)
720 {
721 mask |= (1 << bit);
722 bit++;
723 len--;
724 }
725
726 xoperands[0] = operands[0];
727 xoperands[1] = GEN_INT (mask);
728 output_asm_insn (\"btst %1,%0\", xoperands);
729 return \"\";
730}"
731 [(set_attr "cc" "set_znv")])
732
733(define_insn ""
734 [(set (cc0) (and:HI (match_operand:HI 0 "general_operand" "d")
735 (match_operand:HI 1 "const_int_operand" "i")))]
736 ""
737 "btst %1,%0"
738 [(set_attr "cc" "set_znv")])
739
740\f
741;; ----------------------------------------------------------------------
742;; JUMP INSTRUCTIONS
743;; ----------------------------------------------------------------------
744
745;; Conditional jump instructions
746
747(define_expand "ble"
748 [(set (pc)
749 (if_then_else (le (cc0)
750 (const_int 0))
751 (label_ref (match_operand 0 "" ""))
752 (pc)))]
753 ""
754 "")
755
756(define_expand "bleu"
757 [(set (pc)
758 (if_then_else (leu (cc0)
759 (const_int 0))
760 (label_ref (match_operand 0 "" ""))
761 (pc)))]
762 ""
763 "")
764
765(define_expand "bge"
766 [(set (pc)
767 (if_then_else (ge (cc0)
768 (const_int 0))
769 (label_ref (match_operand 0 "" ""))
770 (pc)))]
771 ""
772 "")
773
774(define_expand "bgeu"
775 [(set (pc)
776 (if_then_else (geu (cc0)
777 (const_int 0))
778 (label_ref (match_operand 0 "" ""))
779 (pc)))]
780 ""
781 "")
782
783(define_expand "blt"
784 [(set (pc)
785 (if_then_else (lt (cc0)
786 (const_int 0))
787 (label_ref (match_operand 0 "" ""))
788 (pc)))]
789 ""
790 "")
791
792(define_expand "bltu"
793 [(set (pc)
794 (if_then_else (ltu (cc0)
795 (const_int 0))
796 (label_ref (match_operand 0 "" ""))
797 (pc)))]
798 ""
799 "")
800
801(define_expand "bgt"
802 [(set (pc)
803 (if_then_else (gt (cc0)
804 (const_int 0))
805 (label_ref (match_operand 0 "" ""))
806 (pc)))]
807 ""
808 "")
809
810(define_expand "bgtu"
811 [(set (pc)
812 (if_then_else (gtu (cc0)
813 (const_int 0))
814 (label_ref (match_operand 0 "" ""))
815 (pc)))]
816 ""
817 "")
818
819(define_expand "beq"
820 [(set (pc)
821 (if_then_else (eq (cc0)
822 (const_int 0))
823 (label_ref (match_operand 0 "" ""))
824 (pc)))]
825 ""
826 "")
827
828(define_expand "bne"
829 [(set (pc)
830 (if_then_else (ne (cc0)
831 (const_int 0))
832 (label_ref (match_operand 0 "" ""))
833 (pc)))]
834 ""
835 "")
836
837(define_insn ""
838 [(set (pc)
839 (if_then_else (match_operator 1 "comparison_operator"
840 [(cc0) (const_int 0)])
841 (label_ref (match_operand 0 "" ""))
842 (pc)))]
843 ""
844 "*
845{
846 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
847 && (GET_CODE (operands[1]) == GT
848 || GET_CODE (operands[1]) == GE
849 || GET_CODE (operands[1]) == LE
850 || GET_CODE (operands[1]) == LT))
851 return 0;
852
853 if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode)
854 return \"b%b1x %0\";
855 else
856 return \"b%b1 %0\";
857}"
858 [(set_attr "cc" "none")])
859
860(define_insn ""
861 [(set (pc)
862 (if_then_else (match_operator 1 "comparison_operator"
863 [(cc0) (const_int 0)])
864 (pc)
865 (label_ref (match_operand 0 "" ""))))]
866 ""
867 "*
868{
869 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
870 && (GET_CODE (operands[1]) == GT
871 || GET_CODE (operands[1]) == GE
872 || GET_CODE (operands[1]) == LE
873 || GET_CODE (operands[1]) == LT))
874 return 0;
875
876 if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode)
877 return \"b%B1x %0\";
878 else
879 return \"b%B1 %0\";
880}"
881 [(set_attr "cc" "none")])
882
883(define_insn "jump"
884 [(set (pc)
885 (label_ref (match_operand 0 "" "")))]
886 ""
887 "jmp %l0"
888 [(set_attr "cc" "none")])
889
890(define_insn "indirect_jump"
891 [(set (pc) (match_operand:PSI 0 "general_operand" "a"))]
892 ""
893 "jmp (%0)"
894 [(set_attr "cc" "none")])
895
896(define_insn "tablejump"
897 [(set (pc) (match_operand:PSI 0 "general_operand" "a"))
898 (use (label_ref (match_operand 1 "" "")))]
899 ""
900 "jmp (%0)"
901 [(set_attr "cc" "none")])
902
903;; Call subroutine with no return value.
904
905(define_expand "call"
906 [(call (match_operand:QI 0 "general_operand" "")
907 (match_operand:HI 1 "general_operand" ""))]
908 ""
909 "
910{
911 if (! call_address_operand (XEXP (operands[0], 0)))
912 XEXP (operands[0], 0) = force_reg (PSImode, XEXP (operands[0], 0));
913 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
914 DONE;
915}")
916
917(define_insn "call_internal"
918 [(call (mem:QI (match_operand:PSI 0 "call_address_operand" "aS"))
919 (match_operand:HI 1 "general_operand" "g"))]
920 ""
921 "jsr %C0"
922 [(set_attr "cc" "clobber")])
923
924;; Call subroutine, returning value in operand 0
925;; (which must be a hard register).
926
927(define_expand "call_value"
928 [(set (match_operand 0 "" "")
929 (call (match_operand:QI 1 "general_operand" "")
930 (match_operand:HI 2 "general_operand" "")))]
931 ""
932 "
933{
934 if (! call_address_operand (XEXP (operands[1], 0)))
935 XEXP (operands[1], 0) = force_reg (PSImode, XEXP (operands[1], 0));
936 emit_call_insn (gen_call_value_internal (operands[0],
937 XEXP (operands[1], 0),
938 operands[2]));
939 DONE;
940}")
941
942(define_insn "call_value_internal"
943 [(set (match_operand 0 "" "=da")
944 (call (mem:QI (match_operand:PSI 1 "call_address_operand" "aS"))
945 (match_operand:HI 2 "general_operand" "g")))]
946 ""
947 "jsr %C1"
948 [(set_attr "cc" "clobber")])
949
950(define_expand "untyped_call"
951 [(parallel [(call (match_operand 0 "" "")
952 (const_int 0))
953 (match_operand 1 "" "")
954 (match_operand 2 "" "")])]
955 ""
956 "
957{
958 int i;
959
960 emit_call_insn (gen_call (operands[0], const0_rtx));
961
962 for (i = 0; i < XVECLEN (operands[2], 0); i++)
963 {
964 rtx set = XVECEXP (operands[2], 0, i);
965 emit_move_insn (SET_DEST (set), SET_SRC (set));
966 }
967 DONE;
968}")
969
970(define_insn "nop"
971 [(const_int 0)]
972 ""
973 "nop"
974 [(set_attr "cc" "none")])
975\f
976;; ----------------------------------------------------------------------
977;; EXTEND INSTRUCTIONS
978;; ----------------------------------------------------------------------
979
980(define_insn "zero_extendqihi2"
981 [(set (match_operand:HI 0 "general_operand" "=d,d,d")
982 (zero_extend:HI
983 (match_operand:QI 1 "general_operand" "0,di,m")))]
984 ""
985 "@
986 extxbu %0
987 mov %1,%0\;extxbu %0
988 movbu %1,%0"
989 [(set_attr "cc" "none_0hit")])
990
991(define_insn "zero_extendqipsi2"
992 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
993 (zero_extend:PSI
994 (match_operand:QI 1 "general_operand" "0,di,m")))]
995 ""
996 "@
997 extxbu %0
998 mov %1,%0\;extxbu %0
999 movbu %1,%0"
1000 [(set_attr "cc" "none_0hit")])
1001
1002(define_insn "zero_extendqisi2"
1003 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1004 (zero_extend:SI
1005 (match_operand:QI 1 "general_operand" "0,di,m")))]
1006 ""
1007 "@
1008 extxbu %L0\;sub %H0,%H0
1009 mov %1,%L0\;extxbu %L0\;sub %H0,%H0
1010 movbu %1,%L0\;sub %H0,%H0"
1011 [(set_attr "cc" "none_0hit")])
1012
1013(define_insn "zero_extendhipsi2"
1014 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1015 (zero_extend:PSI
1016 (match_operand:HI 1 "general_operand" "0,di,m")))]
1017 ""
1018 "@
1019 extxu %0
1020 mov %1,%0\;extxu %0
1021 mov %1,%0\;extxu %0"
1022 [(set_attr "cc" "none_0hit")])
1023
1024(define_insn "zero_extendhisi2"
1025 [(set (match_operand:SI 0 "general_operand" "=d,d")
1026 (zero_extend:SI
1027 (match_operand:HI 1 "general_operand" "0,dim")))]
1028 ""
1029 "@
1030 sub %H0,%H0
1031 mov %1,%L0\;sub %H0,%H0"
1032 [(set_attr "cc" "none_0hit")])
1033
1034;; The last alternative is necessary because the second operand might
1035;; have been the frame pointer. The frame pointer would get replaced
1036;; by (plus (stack_pointer) (const_int)).
1037;;
1038;; Reload would think that it only needed a PSImode register in
1039;; push_reload and at the start of allocate_reload_regs. However,
1040;; at the end of allocate_reload_reg it would realize that the
1041;; reload register must also be valid for SImode, and if it was
1042;; not valid reload would abort.
1043(define_insn "zero_extendpsisi2"
1044 [(set (match_operand:SI 0 "register_operand" "=d,?d,?*d,?*d")
1045 (zero_extend:SI (match_operand:PSI 1 "extendpsi_operand"
1046 "m,?0,?*dai,Q")))]
1047 ""
1048 "@
1049 mov %L1,%L0\;movbu %H1,%H0
1050 jsr ___zero_extendpsisi2_%0
1051 mov %1,%L0\;jsr ___zero_extendpsisi2_%0
1052 mov a3,%L0\;add %Z1,%L0\;jsr ___zero_extendpsisi2_%0"
1053 [(set_attr "cc" "clobber")])
1054
1055;;- sign extension instructions
1056
1057(define_insn "extendqihi2"
1058 [(set (match_operand:HI 0 "general_operand" "=d,d,d")
1059 (sign_extend:HI
1060 (match_operand:QI 1 "general_operand" "0,di,m")))]
1061 ""
1062 "*
1063{
1064 if (which_alternative == 0)
1065 return \"extxb %0\";
1066 else if (which_alternative == 1)
1067 return \"mov %1,%0\;extxb %0\";
1068 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1069 return \"movbu %1,%0\;extxb %0\";
1070 else
1071 return \"movb %1,%0\";
1072}"
1073 [(set_attr "cc" "none_0hit")])
1074
1075(define_insn "extendqipsi2"
1076 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1077 (sign_extend:PSI
1078 (match_operand:QI 1 "general_operand" "0,di,m")))]
1079 ""
1080 "*
1081{
1082 if (which_alternative == 0)
1083 return \"extxb %0\";
1084 else if (which_alternative == 1)
1085 return \"mov %1,%0\;extxb %0\";
1086 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1087 return \"movbu %1,%0\;extxb %0\";
1088 else
1089 return \"movb %1,%0\";
1090}"
1091 [(set_attr "cc" "none_0hit")])
1092
1093(define_insn "extendqisi2"
1094 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1095 (sign_extend:SI
1096 (match_operand:QI 1 "general_operand" "0,di,m")))]
1097 ""
1098 "*
1099{
1100 if (which_alternative == 0)
1101 return \"extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1102 else if (which_alternative == 1)
1103 return \"mov %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1104 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1105 return \"movbu %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1106 else
1107 return \"movb %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1108}"
1109 [(set_attr "cc" "none_0hit")])
1110
1111(define_insn "extendhipsi2"
1112 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1113 (sign_extend:PSI
1114 (match_operand:HI 1 "general_operand" "0,di,m")))]
1115 ""
1116 "@
1117 extx %0
1118 mov %1,%0\;extx %0
1119 mov %1,%0"
1120 [(set_attr "cc" "none_0hit")])
1121
1122(define_insn "extendhisi2"
1123 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1124 (sign_extend:SI
1125 (match_operand:HI 1 "general_operand" "0,di,m")))]
1126 ""
1127 "@
1128 mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0
1129 mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0
1130 mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0"
1131 [(set_attr "cc" "none_0hit")])
1132
1133;; The last alternative is necessary because the second operand might
1134;; have been the frame pointer. The frame pointer would get replaced
1135;; by (plus (stack_pointer) (const_int)).
1136;;
1137;; Reload would think that it only needed a PSImode register in
1138;; push_reload and at the start of allocate_reload_regs. However,
1139;; at the end of allocate_reload_reg it would realize that the
1140;; reload register must also be valid for SImode, and if it was
1141;; not valid reload would abort.
1142(define_insn "extendpsisi2"
1143 [(set (match_operand:SI 0 "general_operand" "=d,?d,?*d,?*d")
1144 (sign_extend:SI (match_operand:PSI 1 "extendpsi_operand"
1145 "m,?0,?*dai,Q")))]
1146 ""
1147 "@
1148 mov %L1,%L0\;movb %H1,%H0
1149 jsr ___sign_extendpsisi2_%0
1150 mov %1,%L0\;jsr ___sign_extendpsisi2_%0
1151 mov a3,%L0\;add %Z1,%L0\;jsr ___sign_extendpsisi2_%0"
1152 [(set_attr "cc" "clobber")])
1153
1154(define_insn "truncsipsi2"
1155 [(set (match_operand:PSI 0 "general_operand" "=a,?d,?*d,da")
1156 (truncate:PSI (match_operand:SI 1 "general_operand" "m,?m,?*d,i")))]
1157 ""
1158 "@
1159 mov %1,%0
1160 movx %A1,%0
1161 jsr ___truncsipsi2_%1_%0
1162 mov %1,%0"
1163 [(set_attr "cc" "clobber")])
1164
1165\f
1166;; Combine should be simplifying this stuff, but isn't.
1167;;
1168(define_insn ""
1169 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1170 (sign_extend:SI
1171 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1172 ""
1173 "@
1174 extxbu %L0\;sub %H0,%H0
1175 mov %1,%L0\;extxbu %L0\;sub %H0,%H0
1176 movbu %1,%L0\;sub %H0,%H0"
1177 [(set_attr "cc" "none_0hit")])
1178
1179(define_insn ""
1180 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1181 (truncate:PSI
1182 (sign_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1183 ""
1184 "*
1185{
1186 if (which_alternative == 0)
1187 return \"extxb %0\";
1188 else if (which_alternative == 1)
1189 return \"mov %1,%0\;extxb %0\";
1190 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1191 return \"movbu %1,%0\;extxb %0\";
1192 else
1193 return \"movb %1,%0\";
1194}"
1195 [(set_attr "cc" "none_0hit")])
1196
1197(define_insn ""
1198 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1199 (truncate:PSI
1200 (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))]
1201 ""
1202 "@
1203 extx %0
1204 mov %1,%0\;extx %0
1205 mov %1,%0"
1206 [(set_attr "cc" "none_0hit")])
1207
1208(define_insn ""
1209 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1210 (truncate:PSI
1211 (sign_extend:SI
1212 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))))]
1213 ""
1214 "@
1215 extxbu %0
1216 mov %1,%0\;extxbu %0
1217 movbu %1,%0"
1218 [(set_attr "cc" "none_0hit")])
1219
1220(define_insn ""
1221 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1222 (truncate:PSI
1223 (zero_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))]
1224 ""
1225 "@
1226 extxu %0
1227 mov %1,%0\;extxu %0
1228 mov %1,%0\;extxu %0"
1229 [(set_attr "cc" "none_0hit")])
1230
1231(define_insn ""
1232 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1233 (truncate:PSI
1234 (zero_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1235 ""
1236 "@
1237 extxbu %0
1238 mov %1,%0\;extxbu %0
1239 movbu %1,%0"
1240 [(set_attr "cc" "none_0hit")])
1241
1242;; ----------------------------------------------------------------------
1243;; SHIFTS
1244;; ----------------------------------------------------------------------
1245
1246;; If the shift count is small, we expand it into several single bit
1247;; shift insns. Otherwise we expand into a generic shift insn which
1248;; handles larger shift counts, shift by variable amounts, etc.
1249(define_expand "ashlhi3"
1250 [(set (match_operand:HI 0 "general_operand" "")
1251 (ashift:HI (match_operand:HI 1 "general_operand" "")
1252 (match_operand:HI 2 "general_operand" "")))]
1253 ""
1254 "
1255{
1256 /* This is an experiment to see if exposing more of the underlying
1257 operations results in better code. */
1258 if (GET_CODE (operands[2]) == CONST_INT
1259 && INTVAL (operands[2]) <= 4)
1260 {
1261 int count = INTVAL (operands[2]);
1262 emit_move_insn (operands[0], operands[1]);
1263 while (count > 0)
1264 {
1265 emit_insn (gen_rtx (SET, HImode, operands[0],
1266 gen_rtx (ASHIFT, HImode,
1267 operands[0], GEN_INT (1))));
1268 count--;
1269 }
1270 DONE;
1271 }
1272 else
1273 {
1274 expand_a_shift (HImode, ASHIFT, operands);
1275 DONE;
1276 }
1277}")
1278
1279;; ASHIFT one bit.
1280(define_insn ""
1281 [(set (match_operand:HI 0 "general_operand" "=d")
1282 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1283 (const_int 1)))]
1284 ""
1285 "add %0,%0"
1286 [(set_attr "cc" "set_zn")])
1287
1288(define_expand "lshrhi3"
1289 [(set (match_operand:HI 0 "general_operand" "")
1290 (lshiftrt:HI (match_operand:HI 1 "general_operand" "")
1291 (match_operand:HI 2 "general_operand" "")))]
1292 ""
1293 "
1294{
1295 /* This is an experiment to see if exposing more of the underlying
1296 operations results in better code. */
1297 if (GET_CODE (operands[2]) == CONST_INT
1298 && INTVAL (operands[2]) <= 4)
1299 {
1300 int count = INTVAL (operands[2]);
1301 emit_move_insn (operands[0], operands[1]);
1302 while (count > 0)
1303 {
1304 emit_insn (gen_rtx (SET, HImode, operands[0],
1305 gen_rtx (LSHIFTRT, HImode,
1306 operands[0], GEN_INT (1))));
1307 count--;
1308 }
1309 DONE;
1310 }
1311 else
1312 {
1313 expand_a_shift (HImode, LSHIFTRT, operands);
1314 DONE;
1315 }
1316}")
1317
1318;; LSHIFTRT one bit.
1319(define_insn ""
1320 [(set (match_operand:HI 0 "general_operand" "=d")
1321 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1322 (const_int 1)))]
1323 ""
1324 "lsr %0"
1325 [(set_attr "cc" "set_znv")])
1326
1327(define_expand "ashrhi3"
1328 [(set (match_operand:HI 0 "general_operand" "")
1329 (ashiftrt:HI (match_operand:HI 1 "general_operand" "")
1330 (match_operand:HI 2 "general_operand" "")))]
1331 ""
1332 "
1333{
1334 /* This is an experiment to see if exposing more of the underlying
1335 operations results in better code. */
1336 if (GET_CODE (operands[2]) == CONST_INT
1337 && INTVAL (operands[2]) <= 4)
1338 {
1339 int count = INTVAL (operands[2]);
1340 emit_move_insn (operands[0], operands[1]);
1341 while (count > 0)
1342 {
1343 emit_insn (gen_rtx (SET, HImode, operands[0],
1344 gen_rtx (ASHIFTRT, HImode,
1345 operands[0], GEN_INT (1))));
1346 count--;
1347 }
1348 DONE;
1349 }
1350 else
1351 {
1352 expand_a_shift (HImode, ASHIFTRT, operands);
1353 DONE;
1354 }
1355}")
1356
1357;; ASHIFTRT one bit.
1358(define_insn ""
1359 [(set (match_operand:HI 0 "general_operand" "=d")
1360 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1361 (const_int 1)))]
1362 ""
1363 "asr %0"
1364 [(set_attr "cc" "set_znv")])
1365
1366;; And the general HImode shift pattern. Handles both shift by constants
1367;; and shift by variable counts.
1368(define_insn ""
1369 [(set (match_operand:HI 0 "general_operand" "=d,d")
1370 (match_operator:HI 3 "nshift_operator"
1371 [ (match_operand:HI 1 "general_operand" "0,0")
1372 (match_operand:HI 2 "general_operand" "KL,dan")]))
1373 (clobber (match_scratch:HI 4 "=X,&d"))]
1374 ""
1375 "* return emit_a_shift (insn, operands);"
1376 [(set_attr "cc" "clobber")])
1377
1378;; We expect only ASHIFT with constant shift counts to be common for
1379;; PSImode, so we optimize just that case. For all other cases we
1380;; extend the value to SImode and perform the shift in SImode.
1381(define_expand "ashlpsi3"
1382 [(set (match_operand:PSI 0 "general_operand" "")
1383 (ashift:PSI (match_operand:PSI 1 "general_operand" "")
1384 (match_operand:HI 2 "general_operand" "")))]
1385 ""
1386 "
1387{
1388 /* This is an experiment to see if exposing more of the underlying
1389 operations results in better code. */
1390 if (GET_CODE (operands[2]) == CONST_INT
1391 && INTVAL (operands[2]) <= 7)
1392 {
1393 int count = INTVAL (operands[2]);
1394 emit_move_insn (operands[0], operands[1]);
1395 while (count > 0)
1396 {
1397 emit_insn (gen_rtx (SET, PSImode, operands[0],
1398 gen_rtx (ASHIFT, PSImode,
1399 operands[0], GEN_INT (1))));
1400 count--;
1401 }
1402 DONE;
1403 }
1404 else
1405 {
1406 expand_a_shift (PSImode, ASHIFT, operands);
1407 DONE;
1408 }
1409}")
1410
1411;; ASHIFT one bit.
1412(define_insn ""
1413 [(set (match_operand:PSI 0 "general_operand" "=d")
1414 (ashift:PSI (match_operand:PSI 1 "general_operand" "0")
1415 (const_int 1)))]
1416 ""
1417 "add %0,%0"
1418 [(set_attr "cc" "set_zn")])
1419
1420(define_expand "lshrpsi3"
1421 [(set (match_operand:PSI 0 "general_operand" "")
1422 (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "")
1423 (match_operand:HI 2 "general_operand" "")))]
1424 ""
1425 "
1426{
1427 rtx reg = gen_reg_rtx (SImode);
1428
1429 emit_insn (gen_zero_extendpsisi2 (reg, operands[1]));
1430 reg = expand_binop (SImode, lshr_optab, reg,
1431 operands[2], reg, 1, OPTAB_WIDEN);
1432 emit_insn (gen_truncsipsi2 (operands[0], reg));
1433 DONE;
1434}")
1435
1436(define_expand "ashrpsi3"
1437 [(set (match_operand:PSI 0 "general_operand" "")
1438 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "")
1439 (match_operand:HI 2 "general_operand" "")))]
1440 ""
1441 "
1442{
1443 rtx reg = gen_reg_rtx (SImode);
1444
1445 emit_insn (gen_extendpsisi2 (reg, operands[1]));
1446 reg = expand_binop (SImode, ashr_optab, reg,
1447 operands[2], reg, 0, OPTAB_WIDEN);
1448 emit_insn (gen_truncsipsi2 (operands[0], reg));
1449 DONE;
1450}")
1451
1452(define_expand "ashlsi3"
1453 [(set (match_operand:SI 0 "register_operand" "")
1454 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "")
1455 (match_operand:HI 2 "general_operand" "")))]
1456 ""
1457 "
1458{
1459 /* For small shifts, just emit a series of single bit shifts inline.
1460
1461 For other constant shift counts smaller than a word or non-constant
1462 shift counts we call out to a library call during RTL generation time;
1463 after RTL generation time we allow optabs.c to open code the operation.
1464 See comments in addsi3/subsi3 expanders.
1465
1466 Otherwise we allow optabs.c to open code the operation. */
1467 if (GET_CODE (operands[2]) == CONST_INT
1468 && (INTVAL (operands[2]) <= 3))
1469 {
1470 int count = INTVAL (operands[2]);
1471 emit_move_insn (operands[0], operands[1]);
1472 while (count > 0)
1473 {
1474 emit_insn (gen_rtx (SET, SImode, operands[0],
1475 gen_rtx (ASHIFT, SImode,
1476 operands[0], GEN_INT (1))));
1477 count--;
1478 }
1479 DONE;
1480 }
1481 else if (rtx_equal_function_value_matters
1482 && (GET_CODE (operands[2]) != CONST_INT
1483 || INTVAL (operands[2]) <= 15))
1484 {
1485 rtx ret, insns;
1486 extern rtx emit_library_call_value ();
1487
1488 start_sequence ();
1489 ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashlsi3\"),
1490 NULL_RTX, 1, SImode, 2, operands[1],
1491 SImode, operands[2], HImode);
1492 insns = get_insns ();
1493 end_sequence ();
1494 emit_libcall_block (insns, operands[0], ret,
1495 gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
1496 DONE;
1497 }
1498 else
1499 FAIL;
1500}")
1501
1502;; ASHIFT one bit.
1503(define_insn ""
1504 [(set (match_operand:SI 0 "general_operand" "=d")
1505 (ashift:SI (match_operand:SI 1 "general_operand" "0")
1506 (const_int 1)))]
1507 ""
1508 "add %L0,%L0\;addc %H0,%H0"
1509 [(set_attr "cc" "clobber")])
1510
1511(define_expand "lshrsi3"
1512 [(set (match_operand:SI 0 "register_operand" "")
1513 (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
1514 (match_operand:HI 2 "general_operand" "")))]
1515 ""
1516 "
1517{
1518 /* For small shifts, just emit a series of single bit shifts inline.
1519
1520 For other constant shift counts smaller than a word or non-constant
1521 shift counts we call out to a library call during RTL generation time;
1522 after RTL generation time we allow optabs.c to open code the operation.
1523 See comments in addsi3/subsi3 expanders.
1524
1525 Otherwise we allow optabs.c to open code the operation. */
1526 if (GET_CODE (operands[2]) == CONST_INT
1527 && (INTVAL (operands[2]) <= 2))
1528 {
1529 int count = INTVAL (operands[2]);
1530 emit_move_insn (operands[0], operands[1]);
1531 while (count > 0)
1532 {
1533 emit_insn (gen_rtx (SET, SImode, operands[0],
1534 gen_rtx (LSHIFTRT, SImode,
1535 operands[0], GEN_INT (1))));
1536 count--;
1537 }
1538 DONE;
1539 }
1540 else if (rtx_equal_function_value_matters
1541 && (GET_CODE (operands[2]) != CONST_INT
1542 || INTVAL (operands[2]) <= 15))
1543 {
1544 rtx ret, insns;
1545 extern rtx emit_library_call_value ();
1546
1547 start_sequence ();
1548 ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__lshrsi3\"),
1549 NULL_RTX, 1, SImode, 2, operands[1],
1550 SImode, operands[2], HImode);
1551 insns = get_insns ();
1552 end_sequence ();
1553 emit_libcall_block (insns, operands[0], ret,
1554 gen_rtx (LSHIFTRT, SImode, operands[1], operands[2]));
1555 DONE;
1556 }
1557 else
1558 FAIL;
1559}")
1560
1561;; LSHIFTRT one bit.
1562(define_insn ""
1563 [(set (match_operand:SI 0 "general_operand" "=d")
1564 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1565 (const_int 1)))]
1566 ""
1567 "lsr %H0\;ror %L0"
1568 [(set_attr "cc" "clobber")])
1569
1570(define_expand "ashrsi3"
1571 [(set (match_operand:SI 0 "register_operand" "")
1572 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1573 (match_operand:HI 2 "general_operand" "")))]
1574 ""
1575 "
1576{
1577 /* For small shifts, just emit a series of single bit shifts inline.
1578
1579 For other constant shift counts smaller than a word or non-constant
1580 shift counts we call out to a library call during RTL generation time;
1581 after RTL generation time we allow optabs.c to open code the operation.
1582 See comments in addsi3/subsi3 expanders.
1583
1584 Otherwise we allow optabs.c to open code the operation. */
1585 if (GET_CODE (operands[2]) == CONST_INT
1586 && (INTVAL (operands[2]) <= 2))
1587 {
1588 int count = INTVAL (operands[2]);
1589 emit_move_insn (operands[0], operands[1]);
1590 while (count > 0)
1591 {
1592 emit_insn (gen_rtx (SET, SImode, operands[0],
1593 gen_rtx (ASHIFTRT, SImode,
1594 operands[0], GEN_INT (1))));
1595 count--;
1596 }
1597 DONE;
1598 }
1599 else if (rtx_equal_function_value_matters
1600 && (GET_CODE (operands[2]) != CONST_INT
1601 || INTVAL (operands[2]) <= 15))
1602 {
1603 rtx ret, insns;
1604 extern rtx emit_library_call_value ();
1605
1606 start_sequence ();
1607 ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashrsi3\"),
1608 NULL_RTX, 1, SImode, 2, operands[1],
1609 SImode, operands[2], HImode);
1610 insns = get_insns ();
1611 end_sequence ();
1612 emit_libcall_block (insns, operands[0], ret,
1613 gen_rtx (ASHIFTRT, SImode, operands[1], operands[2]));
1614 DONE;
1615 }
1616 else
1617 FAIL;
1618}")
1619
1620;; ASHIFTRT one bit.
1621(define_insn ""
1622 [(set (match_operand:SI 0 "general_operand" "=d")
1623 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1624 (const_int 1)))]
1625 ""
1626 "asr %H0\;ror %L0"
1627 [(set_attr "cc" "clobber")])
1628
1629;; ----------------------------------------------------------------------
1630;; PROLOGUE/EPILOGUE
1631;; ----------------------------------------------------------------------
1632(define_expand "prologue"
1633 [(const_int 0)]
1634 ""
1635 "expand_prologue (); DONE;")
1636
1637(define_insn "outline_prologue_call"
1638 [(const_int 1)]
1639 ""
1640 "jsr ___prologue"
1641 [(set_attr "cc" "clobber")])
1642
1643(define_expand "epilogue"
1644 [(return)]
1645 ""
1646 "
1647{
1648 expand_epilogue ();
1649 DONE;
1650}")
1651
1652(define_insn "outline_epilogue_call_a0"
1653 [(const_int 2)]
1654 ""
1655 "jsr ___epilogue_a0"
1656 [(set_attr "cc" "clobber")])
1657
1658(define_insn "outline_epilogue_call_d0"
1659 [(const_int 3)]
1660 ""
1661 "jsr ___epilogue_d0"
1662 [(set_attr "cc" "clobber")])
1663
1664(define_insn "outline_epilogue_jump"
1665 [(const_int 4)]
1666 ""
1667 "jmp ___epilogue_noreturn"
1668 [(set_attr "cc" "clobber")])
1669
1670(define_insn "return"
1671 [(return)]
1672 "reload_completed && total_frame_size () == 0
1673 && !current_function_needs_context"
1674 "*
1675{
1676 rtx next = next_active_insn (insn);
1677
1678 if (next
1679 && GET_CODE (next) == JUMP_INSN
1680 && GET_CODE (PATTERN (next)) == RETURN)
1681 return \"\";
1682 return \"rts\";
1683}"
1684 [(set_attr "cc" "clobber")])
1685
1686(define_insn "return_internal"
1687 [(const_int 0)
1688 (return)]
1689 ""
1690 "rts"
1691 [(set_attr "cc" "clobber")])
1692
1693;; These are special combiner patterns to improve array/pointer accesses.
1694;;
1695;; A typical sequence involves extending an integer/char, shifting it left
1696;; a few times, then truncating the value to PSImode.
1697;;
1698;; This first pattern combines the shifting & truncation operations, by
1699;; itself it is a win because the shifts end up occuring in PSImode instead
1700;; of SImode. However, it has the secondary effect of giving us the
1701;; opportunity to match patterns which allow us to remove the initial
1702;; extension completely, which is a big win.
1703(define_insn ""
1704 [(set (match_operand:PSI 0 "general_operand" "=d,d,a")
1705 (truncate:PSI
1706 (ashift:SI (match_operand:SI 1 "general_operand" "d,m,m")
1707 (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1708 ""
1709 "*
1710{
1711 int count = INTVAL (operands[2]);
1712 if (which_alternative == 0)
1713 output_asm_insn (\"jsr ___truncsipsi2_%1_%0\", operands);
1714 else if (which_alternative == 1)
1715 output_asm_insn (\"movx %A1,%0\", operands);
1716 else
1717 output_asm_insn (\" mov %1,%0\", operands);
1718
1719 while (count)
1720 {
1721 output_asm_insn (\"add %0,%0\", operands);
1722 count--;
1723 }
1724 return \"\";
1725}"
1726 [(set_attr "cc" "clobber")])
1727
1728;; Similarly, except that we also have zero/sign extension of the
1729;; original operand. */
1730(define_insn ""
1731 [(set (match_operand:PSI 0 "general_operand" "=d,d")
1732 (truncate:PSI
1733 (ashift:SI
1734 (zero_extend:SI (match_operand:HI 1 "general_operand" "0,dim"))
1735 (match_operand:HI 2 "const_int_operand" "i,i"))))]
1736 ""
1737 "*
1738{
1739 int count = INTVAL (operands[2]);
1740
1741 /* First extend operand 1 to PSImode. */
1742 if (which_alternative == 0)
1743 output_asm_insn (\"extxu %0\", operands);
1744 else
1745 output_asm_insn (\"mov %1,%0\;extxu %0\", operands);
1746
1747 /* Now do the shifting. */
1748 while (count)
1749 {
1750 output_asm_insn (\"add %0,%0\", operands);
1751 count--;
1752 }
1753 return \"\";
1754}"
1755 [(set_attr "cc" "clobber")])
1756
1757(define_insn ""
1758 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1759 (truncate:PSI
1760 (ashift:SI
1761 (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))
1762 (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1763 ""
1764 "*
1765{
1766 int count = INTVAL (operands[2]);
1767
1768 /* First extend operand 1 to PSImode. */
1769 if (which_alternative == 0)
1770 output_asm_insn (\"extx %0\", operands);
1771 else if (which_alternative == 1)
1772 output_asm_insn (\"mov %1,%0\;extx %0\", operands);
1773 else
1774 output_asm_insn (\"mov %1,%0\", operands);
1775
1776 /* Now do the shifting. */
1777 while (count)
1778 {
1779 output_asm_insn (\"add %0,%0\", operands);
1780 count--;
1781 }
1782 return \"\";
1783}"
1784 [(set_attr "cc" "clobber")])
1785
1786(define_insn ""
1787 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1788 (truncate:PSI
1789 (ashift:SI
1790 (sign_extend:SI
1791 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))
1792 (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1793 ""
1794 "*
1795{
1796 int count = INTVAL (operands[2]);
1797
1798 /* First extend operand 1 to PSImode. */
1799 if (which_alternative == 0)
1800 output_asm_insn (\"extxbu %0\", operands);
1801 else if (which_alternative == 1)
1802 output_asm_insn (\"mov %1,%0\;extxbu %0\", operands);
1803 else
1804 output_asm_insn (\"movbu %1,%0\", operands);
1805
1806 /* Now do the shifting. */
1807 while (count)
1808 {
1809 output_asm_insn (\"add %0,%0\", operands);
1810 count--;
1811 }
1812 return \"\";
1813}"
1814 [(set_attr "cc" "clobber")])
1815
1816(define_insn ""
1817 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1818 (truncate:PSI
1819 (ashift:SI
1820 (sign_extend:SI
1821 (match_operand:QI 1 "general_operand" "0,di,m"))
1822 (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1823 ""
1824 "*
1825{
1826 int count = INTVAL (operands[2]);
1827
1828 /* First extend operand 1 to PSImode. */
1829 if (which_alternative == 0)
1830 output_asm_insn (\"extxb %0\", operands);
1831 else if (which_alternative == 1)
1832 output_asm_insn (\"mov %1,%0\;extxb %0\", operands);
1833 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1834 output_asm_insn (\"movbu %1,%0\;extxb %0\", operands);
1835 else
1836 output_asm_insn (\"movb %1,%0\", operands);
1837
1838 /* Now do the shifting. */
1839 while (count)
1840 {
1841 output_asm_insn (\"add %0,%0\", operands);
1842 count--;
1843 }
1844 return \"\";
1845}"
1846 [(set_attr "cc" "clobber")])
1847
1848;; Try to combine consecutive updates of the stack pointer (or any
1849;; other register for that matter).
1850(define_peephole
1851 [(set (match_operand:PSI 0 "register_operand" "=da")
1852 (plus:PSI (match_dup 0)
1853 (match_operand 1 "const_int_operand" "")))
1854 (set (match_dup 0)
1855 (plus:PSI (match_dup 0)
1856 (match_operand 2 "const_int_operand" "")))]
1857 ""
1858 "*
1859{
1860 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1861 return \"add %1,%0\";
1862}"
1863 [(set_attr "cc" "clobber")])
1864
1865;;
1866;; We had patterns to check eq/ne, but the they don't work because
1867;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1868;;
1869;; The Z flag and C flag would be set, and we have no way to
1870;; check for the Z flag set and C flag clear.
1871;;
1872;; This will work on the mn10200 because we can check the ZX flag
1873;; if the comparison is in HImode.
1874(define_peephole
1875 [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1876 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1877 (match_operand 1 "" "")
1878 (pc)))]
1879 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1880 "add %0,%0\;bcc %1"
1881 [(set_attr "cc" "clobber")])
1882
1883(define_peephole
1884 [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1885 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1886 (match_operand 1 "" "")
1887 (pc)))]
1888 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1889 "add %0,%0\;bcs %1"
1890 [(set_attr "cc" "clobber")])
1891
1892(define_peephole
1893 [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1894 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1895 (pc)
1896 (match_operand 1 "" "")))]
1897 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1898 "add %0,%0\;bcs %1"
1899 [(set_attr "cc" "clobber")])
1900
1901(define_peephole
1902 [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1903 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1904 (pc)
1905 (match_operand 1 "" "")))]
1906 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1907 "add %0,%0\;bcc %1"
1908 [(set_attr "cc" "clobber")])
1909
1910(define_peephole
1911 [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1912 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1913 (match_operand 1 "" "")
1914 (pc)))]
1915 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1916 "add %0,%0\;bccx %1"
1917 [(set_attr "cc" "clobber")])
1918
1919(define_peephole
1920 [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1921 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1922 (match_operand 1 "" "")
1923 (pc)))]
1924 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1925 "add %0,%0\;bcsx %1"
1926 [(set_attr "cc" "clobber")])
1927
1928(define_peephole
1929 [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1930 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1931 (pc)
1932 (match_operand 1 "" "")))]
1933 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1934 "add %0,%0\;bcsx %1"
1935 [(set_attr "cc" "clobber")])
1936
1937(define_peephole
1938 [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1939 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1940 (pc)
1941 (match_operand 1 "" "")))]
1942 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1943 "add %0,%0\;bccx %1"
1944 [(set_attr "cc" "clobber")])
1945
1946;; We call out to library routines to perform 32bit addition and subtraction
1947;; operations (see addsi3/subsi3 expanders for why). These peepholes catch
1948;; the trivial case where the operation could be done with an add;addc or
1949;; sub;subc sequence.
1950(define_peephole
1951 [(set (mem:SI (reg:PSI 7)) (reg:SI 2))
1952 (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")
1953 (match_operand:HI 2 "general_operand" "")))]
1954 "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1955 && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__addsi3\") == 0"
1956 "add d2,d0\;addc d3,d1"
1957 [(set_attr "cc" "clobber")])
1958
1959(define_peephole
1960 [(set (mem:SI (reg:PSI 7)) (reg:SI 2))
1961 (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")
1962 (match_operand:HI 2 "general_operand" "")))]
1963 "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1964 && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__subsi3\") == 0"
1965 "sub d2,d0\;subc d3,d1"
1966 [(set_attr "cc" "clobber")])
This page took 0.216777 seconds and 5 git commands to generate.