]> gcc.gnu.org Git - gcc.git/blame - gcc/config/mn10200/mn10200.md
mn10300.c (print_operand): Handle 'S'.
[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.
500(define_insn "neghi2"
501 [(set (match_operand:HI 0 "general_operand" "=&d")
502 (neg:HI (match_operand:HI 1 "general_operand" "d")))]
503 ""
504 "sub %0,%0\;sub %1,%0"
505 [(set_attr "cc" "set_zn")])
506
507(define_insn "negpsi2"
508 [(set (match_operand:PSI 0 "general_operand" "=&d")
509 (neg:PSI (match_operand:PSI 1 "general_operand" "d")))]
510 ""
511 "sub %0,%0\;sub %1,%0"
512 [(set_attr "cc" "set_zn")])
513
514;; Using a magic libcall that accepts its arguments in any
515;; data register pair has proven to be the most efficient
516;; and most compact way to represent negsi2.
517(define_insn "negsi2"
518 [(set (match_operand:SI 0 "general_operand" "=d")
519 (neg:SI (match_operand:SI 1 "general_operand" "0")))]
520 ""
521 "jsr ___negsi2_%0"
522 [(set_attr "cc" "clobber")])
523
524;; ----------------------------------------------------------------------
525;; MULTIPLY INSTRUCTIONS
526;; ----------------------------------------------------------------------
527;;
528;; The mn10200 has HIxHI->SI widening multiply, but we get _severe_
529;; code density regressions if we enable such a pattern.
530
531(define_insn "mulhi3"
532 [(set (match_operand:HI 0 "general_operand" "=d")
533 (mult:HI (match_operand:HI 1 "general_operand" "%0")
534 (match_operand:HI 2 "general_operand" "d")))]
535 ""
536 "mul %2,%0"
537 [(set_attr "cc" "set_zn")])
538
539(define_insn "udivmodhi4"
540 [(set (match_operand:HI 0 "general_operand" "=d")
541 (udiv:HI (match_operand:HI 1 "general_operand" "0")
542 (match_operand:HI 2 "general_operand" "d")))
543 (set (match_operand:HI 3 "general_operand" "=&d")
544 (umod:HI (match_dup 1) (match_dup 2)))]
545 ""
546 "*
547{
548 if (zero_dreg)
549 output_asm_insn (\"mov %0,mdr\", &zero_dreg);
550 else
551 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands);
552
553 if (find_reg_note (insn, REG_UNUSED, operands[3]))
554 return \"divu %2,%0\";
555 else
556 return \"divu %2,%0\;mov mdr,%3\";
557}"
558 [(set_attr "cc" "set_zn")])
559
560\f
561;; ----------------------------------------------------------------------
562;; AND INSTRUCTIONS
563;; ----------------------------------------------------------------------
564
565(define_insn "andhi3"
566 [(set (match_operand:HI 0 "general_operand" "=d,d")
567 (and:HI (match_operand:HI 1 "general_operand" "%0,0")
568 (match_operand:HI 2 "general_operand" "M,di")))]
569 ""
570 "*
571{
572 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff)
573 return \"extxbu %0\";
574 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fff)
575 return \"add %0,%0\;lsr %0\";
576 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffe)
577 return \"lsr %0\;add %0,%0\";
578 return \"and %2,%0\";
579}"
580 [(set_attr "cc" "none_0hit,set_znv")])
581
582;; This expander + pattern exist only to allow trampolines to be aligned
583;; in the stack.
584(define_expand "andpsi3"
585 [(set (match_operand:PSI 0 "general_operand" "")
586 (and:PSI (match_operand:PSI 1 "general_operand" "")
587 (match_operand:PSI 2 "const_int_operand" "")))]
588 ""
589 "
590{
591 if (GET_CODE (operands[2]) != CONST_INT
592 || (INTVAL (operands[2]) & 0xff0000) != 0xff0000)
593 FAIL;
594}")
595
596(define_insn ""
597 [(set (match_operand:PSI 0 "general_operand" "=d")
598 (and:PSI (match_operand:PSI 1 "general_operand" "%0")
599 (match_operand:PSI 2 "const_int_operand" "i")))]
600 "GET_CODE (operands[2]) == CONST_INT
601 && (INTVAL (operands[2]) & 0xff0000) == 0xff0000"
602 "and %2,%0"
603 [(set_attr "cc" "clobber")])
604
605;; ----------------------------------------------------------------------
606;; OR INSTRUCTIONS
607;; ----------------------------------------------------------------------
608
609(define_insn "iorhi3"
610 [(set (match_operand:HI 0 "general_operand" "=d")
611 (ior:HI (match_operand:HI 1 "general_operand" "%0")
612 (match_operand:HI 2 "general_operand" "di")))]
613 ""
614 "or %2,%0"
615 [(set_attr "cc" "set_znv")])
616
617;; ----------------------------------------------------------------------
618;; XOR INSTRUCTIONS
619;; ----------------------------------------------------------------------
620
621(define_insn "xorhi3"
622 [(set (match_operand:HI 0 "general_operand" "=d")
623 (xor:HI (match_operand:HI 1 "general_operand" "%0")
624 (match_operand:HI 2 "general_operand" "di")))]
625 ""
626 "xor %2,%0"
627 [(set_attr "cc" "set_znv")])
628
629;; ----------------------------------------------------------------------
630;; NOT INSTRUCTIONS
631;; ----------------------------------------------------------------------
632
633(define_insn "one_cmplhi2"
634 [(set (match_operand:HI 0 "general_operand" "=d")
635 (not:HI (match_operand:HI 1 "general_operand" "0")))]
636 ""
637 "not %0"
638 [(set_attr "cc" "set_znv")])
639
640\f
641;; -----------------------------------------------------------------
642;; BIT INSTRUCTIONS
643;; -----------------------------------------------------------------
644
645;; When clearing a set of bits in memory, we load the inverted bitmask into
646;; a register, then use bclr.
647(define_insn ""
648 [(set (match_operand:QI 0 "indirect_memory_operand" "")
649 (subreg:QI
650 (and:HI (subreg:HI (match_dup 0) 0)
651 (match_operand 1 "const_int_operand" "")) 0))
652 (clobber (match_scratch:HI 2 "=&d"))]
653 ""
654 "mov %N1,%2\;bclr %2,%0"
655 [(set_attr "cc" "clobber")])
656
657;; These clear a non-constant set of bits in memory.
658(define_insn ""
659 [(set (match_operand:QI 0 "indirect_memory_operand" "")
660 (subreg:QI
661 (and:HI (subreg:HI (match_dup 0) 0)
662 (not:HI (match_operand:HI 1 "general_operand" "d"))) 0))]
663 ""
664 "bclr %1,%0"
665 [(set_attr "cc" "clobber")])
666
667(define_insn ""
668 [(set (match_operand:QI 0 "indirect_memory_operand" "")
669 (subreg:QI
670 (and:HI (not:HI (match_operand:HI 1 "general_operand" "d"))
671 (subreg:HI (match_dup 0) 0)) 0))]
672 ""
673 "bclr %1,%0"
674 [(set_attr "cc" "clobber")])
675
676;; These set bits in memory.
677(define_insn ""
678 [(set (match_operand:QI 0 "indirect_memory_operand" "")
679 (subreg:QI
680 (ior:HI (subreg:HI (match_dup 0) 0)
681 (match_operand:HI 1 "general_operand" "d")) 0))]
682 ""
683 "bset %1,%0"
684 [(set_attr "cc" "clobber")])
685
686(define_insn ""
687 [(set (match_operand:QI 0 "indirect_memory_operand" "")
688 (subreg:QI
689 (ior:HI (match_operand:HI 1 "general_operand" "d")
690 (subreg:HI (match_dup 0) 0)) 0))]
691 ""
692 "bset %1,%0"
693 [(set_attr "cc" "clobber")])
694
695;; Not any shorter/faster than using cmp, but it might save a
696;; register if the result of the AND isn't ever used.
697
698(define_insn ""
699 [(set (cc0)
700 (zero_extract:HI (match_operand:HI 0 "general_operand" "d")
701 (match_operand 1 "const_int_operand" "")
702 (match_operand 2 "const_int_operand" "")))]
703 ""
704 "*
705{
706 int len = INTVAL (operands[1]);
707 int bit = INTVAL (operands[2]);
708 int mask = 0;
709 rtx xoperands[2];
710
711 while (len > 0)
712 {
713 mask |= (1 << bit);
714 bit++;
715 len--;
716 }
717
718 xoperands[0] = operands[0];
719 xoperands[1] = GEN_INT (mask);
720 output_asm_insn (\"btst %1,%0\", xoperands);
721 return \"\";
722}"
723 [(set_attr "cc" "set_znv")])
724
725(define_insn ""
726 [(set (cc0) (and:HI (match_operand:HI 0 "general_operand" "d")
727 (match_operand:HI 1 "const_int_operand" "i")))]
728 ""
729 "btst %1,%0"
730 [(set_attr "cc" "set_znv")])
731
732\f
733;; ----------------------------------------------------------------------
734;; JUMP INSTRUCTIONS
735;; ----------------------------------------------------------------------
736
737;; Conditional jump instructions
738
739(define_expand "ble"
740 [(set (pc)
741 (if_then_else (le (cc0)
742 (const_int 0))
743 (label_ref (match_operand 0 "" ""))
744 (pc)))]
745 ""
746 "")
747
748(define_expand "bleu"
749 [(set (pc)
750 (if_then_else (leu (cc0)
751 (const_int 0))
752 (label_ref (match_operand 0 "" ""))
753 (pc)))]
754 ""
755 "")
756
757(define_expand "bge"
758 [(set (pc)
759 (if_then_else (ge (cc0)
760 (const_int 0))
761 (label_ref (match_operand 0 "" ""))
762 (pc)))]
763 ""
764 "")
765
766(define_expand "bgeu"
767 [(set (pc)
768 (if_then_else (geu (cc0)
769 (const_int 0))
770 (label_ref (match_operand 0 "" ""))
771 (pc)))]
772 ""
773 "")
774
775(define_expand "blt"
776 [(set (pc)
777 (if_then_else (lt (cc0)
778 (const_int 0))
779 (label_ref (match_operand 0 "" ""))
780 (pc)))]
781 ""
782 "")
783
784(define_expand "bltu"
785 [(set (pc)
786 (if_then_else (ltu (cc0)
787 (const_int 0))
788 (label_ref (match_operand 0 "" ""))
789 (pc)))]
790 ""
791 "")
792
793(define_expand "bgt"
794 [(set (pc)
795 (if_then_else (gt (cc0)
796 (const_int 0))
797 (label_ref (match_operand 0 "" ""))
798 (pc)))]
799 ""
800 "")
801
802(define_expand "bgtu"
803 [(set (pc)
804 (if_then_else (gtu (cc0)
805 (const_int 0))
806 (label_ref (match_operand 0 "" ""))
807 (pc)))]
808 ""
809 "")
810
811(define_expand "beq"
812 [(set (pc)
813 (if_then_else (eq (cc0)
814 (const_int 0))
815 (label_ref (match_operand 0 "" ""))
816 (pc)))]
817 ""
818 "")
819
820(define_expand "bne"
821 [(set (pc)
822 (if_then_else (ne (cc0)
823 (const_int 0))
824 (label_ref (match_operand 0 "" ""))
825 (pc)))]
826 ""
827 "")
828
829(define_insn ""
830 [(set (pc)
831 (if_then_else (match_operator 1 "comparison_operator"
832 [(cc0) (const_int 0)])
833 (label_ref (match_operand 0 "" ""))
834 (pc)))]
835 ""
836 "*
837{
838 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
839 && (GET_CODE (operands[1]) == GT
840 || GET_CODE (operands[1]) == GE
841 || GET_CODE (operands[1]) == LE
842 || GET_CODE (operands[1]) == LT))
843 return 0;
844
845 if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode)
846 return \"b%b1x %0\";
847 else
848 return \"b%b1 %0\";
849}"
850 [(set_attr "cc" "none")])
851
852(define_insn ""
853 [(set (pc)
854 (if_then_else (match_operator 1 "comparison_operator"
855 [(cc0) (const_int 0)])
856 (pc)
857 (label_ref (match_operand 0 "" ""))))]
858 ""
859 "*
860{
861 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
862 && (GET_CODE (operands[1]) == GT
863 || GET_CODE (operands[1]) == GE
864 || GET_CODE (operands[1]) == LE
865 || GET_CODE (operands[1]) == LT))
866 return 0;
867
868 if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode)
869 return \"b%B1x %0\";
870 else
871 return \"b%B1 %0\";
872}"
873 [(set_attr "cc" "none")])
874
875(define_insn "jump"
876 [(set (pc)
877 (label_ref (match_operand 0 "" "")))]
878 ""
879 "jmp %l0"
880 [(set_attr "cc" "none")])
881
882(define_insn "indirect_jump"
883 [(set (pc) (match_operand:PSI 0 "general_operand" "a"))]
884 ""
885 "jmp (%0)"
886 [(set_attr "cc" "none")])
887
888(define_insn "tablejump"
889 [(set (pc) (match_operand:PSI 0 "general_operand" "a"))
890 (use (label_ref (match_operand 1 "" "")))]
891 ""
892 "jmp (%0)"
893 [(set_attr "cc" "none")])
894
895;; Call subroutine with no return value.
896
897(define_expand "call"
898 [(call (match_operand:QI 0 "general_operand" "")
899 (match_operand:HI 1 "general_operand" ""))]
900 ""
901 "
902{
903 if (! call_address_operand (XEXP (operands[0], 0)))
904 XEXP (operands[0], 0) = force_reg (PSImode, XEXP (operands[0], 0));
905 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1]));
906 DONE;
907}")
908
909(define_insn "call_internal"
910 [(call (mem:QI (match_operand:PSI 0 "call_address_operand" "aS"))
911 (match_operand:HI 1 "general_operand" "g"))]
912 ""
913 "jsr %C0"
914 [(set_attr "cc" "clobber")])
915
916;; Call subroutine, returning value in operand 0
917;; (which must be a hard register).
918
919(define_expand "call_value"
920 [(set (match_operand 0 "" "")
921 (call (match_operand:QI 1 "general_operand" "")
922 (match_operand:HI 2 "general_operand" "")))]
923 ""
924 "
925{
926 if (! call_address_operand (XEXP (operands[1], 0)))
927 XEXP (operands[1], 0) = force_reg (PSImode, XEXP (operands[1], 0));
928 emit_call_insn (gen_call_value_internal (operands[0],
929 XEXP (operands[1], 0),
930 operands[2]));
931 DONE;
932}")
933
934(define_insn "call_value_internal"
935 [(set (match_operand 0 "" "=da")
936 (call (mem:QI (match_operand:PSI 1 "call_address_operand" "aS"))
937 (match_operand:HI 2 "general_operand" "g")))]
938 ""
939 "jsr %C1"
940 [(set_attr "cc" "clobber")])
941
942(define_expand "untyped_call"
943 [(parallel [(call (match_operand 0 "" "")
944 (const_int 0))
945 (match_operand 1 "" "")
946 (match_operand 2 "" "")])]
947 ""
948 "
949{
950 int i;
951
952 emit_call_insn (gen_call (operands[0], const0_rtx));
953
954 for (i = 0; i < XVECLEN (operands[2], 0); i++)
955 {
956 rtx set = XVECEXP (operands[2], 0, i);
957 emit_move_insn (SET_DEST (set), SET_SRC (set));
958 }
959 DONE;
960}")
961
962(define_insn "nop"
963 [(const_int 0)]
964 ""
965 "nop"
966 [(set_attr "cc" "none")])
967\f
968;; ----------------------------------------------------------------------
969;; EXTEND INSTRUCTIONS
970;; ----------------------------------------------------------------------
971
972(define_insn "zero_extendqihi2"
973 [(set (match_operand:HI 0 "general_operand" "=d,d,d")
974 (zero_extend:HI
975 (match_operand:QI 1 "general_operand" "0,di,m")))]
976 ""
977 "@
978 extxbu %0
979 mov %1,%0\;extxbu %0
980 movbu %1,%0"
981 [(set_attr "cc" "none_0hit")])
982
983(define_insn "zero_extendqipsi2"
984 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
985 (zero_extend:PSI
986 (match_operand:QI 1 "general_operand" "0,di,m")))]
987 ""
988 "@
989 extxbu %0
990 mov %1,%0\;extxbu %0
991 movbu %1,%0"
992 [(set_attr "cc" "none_0hit")])
993
994(define_insn "zero_extendqisi2"
995 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
996 (zero_extend:SI
997 (match_operand:QI 1 "general_operand" "0,di,m")))]
998 ""
999 "@
1000 extxbu %L0\;sub %H0,%H0
1001 mov %1,%L0\;extxbu %L0\;sub %H0,%H0
1002 movbu %1,%L0\;sub %H0,%H0"
1003 [(set_attr "cc" "none_0hit")])
1004
1005(define_insn "zero_extendhipsi2"
1006 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1007 (zero_extend:PSI
1008 (match_operand:HI 1 "general_operand" "0,di,m")))]
1009 ""
1010 "@
1011 extxu %0
1012 mov %1,%0\;extxu %0
1013 mov %1,%0\;extxu %0"
1014 [(set_attr "cc" "none_0hit")])
1015
1016(define_insn "zero_extendhisi2"
1017 [(set (match_operand:SI 0 "general_operand" "=d,d")
1018 (zero_extend:SI
1019 (match_operand:HI 1 "general_operand" "0,dim")))]
1020 ""
1021 "@
1022 sub %H0,%H0
1023 mov %1,%L0\;sub %H0,%H0"
1024 [(set_attr "cc" "none_0hit")])
1025
1026;; The last alternative is necessary because the second operand might
1027;; have been the frame pointer. The frame pointer would get replaced
1028;; by (plus (stack_pointer) (const_int)).
1029;;
1030;; Reload would think that it only needed a PSImode register in
1031;; push_reload and at the start of allocate_reload_regs. However,
1032;; at the end of allocate_reload_reg it would realize that the
1033;; reload register must also be valid for SImode, and if it was
1034;; not valid reload would abort.
1035(define_insn "zero_extendpsisi2"
1036 [(set (match_operand:SI 0 "register_operand" "=d,?d,?*d,?*d")
1037 (zero_extend:SI (match_operand:PSI 1 "extendpsi_operand"
1038 "m,?0,?*dai,Q")))]
1039 ""
1040 "@
1041 mov %L1,%L0\;movbu %H1,%H0
1042 jsr ___zero_extendpsisi2_%0
1043 mov %1,%L0\;jsr ___zero_extendpsisi2_%0
1044 mov a3,%L0\;add %Z1,%L0\;jsr ___zero_extendpsisi2_%0"
1045 [(set_attr "cc" "clobber")])
1046
1047;;- sign extension instructions
1048
1049(define_insn "extendqihi2"
1050 [(set (match_operand:HI 0 "general_operand" "=d,d,d")
1051 (sign_extend:HI
1052 (match_operand:QI 1 "general_operand" "0,di,m")))]
1053 ""
1054 "*
1055{
1056 if (which_alternative == 0)
1057 return \"extxb %0\";
1058 else if (which_alternative == 1)
1059 return \"mov %1,%0\;extxb %0\";
1060 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1061 return \"movbu %1,%0\;extxb %0\";
1062 else
1063 return \"movb %1,%0\";
1064}"
1065 [(set_attr "cc" "none_0hit")])
1066
1067(define_insn "extendqipsi2"
1068 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1069 (sign_extend:PSI
1070 (match_operand:QI 1 "general_operand" "0,di,m")))]
1071 ""
1072 "*
1073{
1074 if (which_alternative == 0)
1075 return \"extxb %0\";
1076 else if (which_alternative == 1)
1077 return \"mov %1,%0\;extxb %0\";
1078 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1079 return \"movbu %1,%0\;extxb %0\";
1080 else
1081 return \"movb %1,%0\";
1082}"
1083 [(set_attr "cc" "none_0hit")])
1084
1085(define_insn "extendqisi2"
1086 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1087 (sign_extend:SI
1088 (match_operand:QI 1 "general_operand" "0,di,m")))]
1089 ""
1090 "*
1091{
1092 if (which_alternative == 0)
1093 return \"extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1094 else if (which_alternative == 1)
1095 return \"mov %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1096 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1097 return \"movbu %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1098 else
1099 return \"movb %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\";
1100}"
1101 [(set_attr "cc" "none_0hit")])
1102
1103(define_insn "extendhipsi2"
1104 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1105 (sign_extend:PSI
1106 (match_operand:HI 1 "general_operand" "0,di,m")))]
1107 ""
1108 "@
1109 extx %0
1110 mov %1,%0\;extx %0
1111 mov %1,%0"
1112 [(set_attr "cc" "none_0hit")])
1113
1114(define_insn "extendhisi2"
1115 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1116 (sign_extend:SI
1117 (match_operand:HI 1 "general_operand" "0,di,m")))]
1118 ""
1119 "@
1120 mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0
1121 mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0
1122 mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0"
1123 [(set_attr "cc" "none_0hit")])
1124
1125;; The last alternative is necessary because the second operand might
1126;; have been the frame pointer. The frame pointer would get replaced
1127;; by (plus (stack_pointer) (const_int)).
1128;;
1129;; Reload would think that it only needed a PSImode register in
1130;; push_reload and at the start of allocate_reload_regs. However,
1131;; at the end of allocate_reload_reg it would realize that the
1132;; reload register must also be valid for SImode, and if it was
1133;; not valid reload would abort.
1134(define_insn "extendpsisi2"
1135 [(set (match_operand:SI 0 "general_operand" "=d,?d,?*d,?*d")
1136 (sign_extend:SI (match_operand:PSI 1 "extendpsi_operand"
1137 "m,?0,?*dai,Q")))]
1138 ""
1139 "@
1140 mov %L1,%L0\;movb %H1,%H0
1141 jsr ___sign_extendpsisi2_%0
1142 mov %1,%L0\;jsr ___sign_extendpsisi2_%0
1143 mov a3,%L0\;add %Z1,%L0\;jsr ___sign_extendpsisi2_%0"
1144 [(set_attr "cc" "clobber")])
1145
1146(define_insn "truncsipsi2"
1147 [(set (match_operand:PSI 0 "general_operand" "=a,?d,?*d,da")
1148 (truncate:PSI (match_operand:SI 1 "general_operand" "m,?m,?*d,i")))]
1149 ""
1150 "@
1151 mov %1,%0
1152 movx %A1,%0
1153 jsr ___truncsipsi2_%1_%0
1154 mov %1,%0"
1155 [(set_attr "cc" "clobber")])
1156
1157\f
1158;; Combine should be simplifying this stuff, but isn't.
1159;;
1160(define_insn ""
1161 [(set (match_operand:SI 0 "general_operand" "=d,d,d")
1162 (sign_extend:SI
1163 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1164 ""
1165 "@
1166 extxbu %L0\;sub %H0,%H0
1167 mov %1,%L0\;extxbu %L0\;sub %H0,%H0
1168 movbu %1,%L0\;sub %H0,%H0"
1169 [(set_attr "cc" "none_0hit")])
1170
1171(define_insn ""
1172 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1173 (truncate:PSI
1174 (sign_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1175 ""
1176 "*
1177{
1178 if (which_alternative == 0)
1179 return \"extxb %0\";
1180 else if (which_alternative == 1)
1181 return \"mov %1,%0\;extxb %0\";
1182 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1183 return \"movbu %1,%0\;extxb %0\";
1184 else
1185 return \"movb %1,%0\";
1186}"
1187 [(set_attr "cc" "none_0hit")])
1188
1189(define_insn ""
1190 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1191 (truncate:PSI
1192 (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))]
1193 ""
1194 "@
1195 extx %0
1196 mov %1,%0\;extx %0
1197 mov %1,%0"
1198 [(set_attr "cc" "none_0hit")])
1199
1200(define_insn ""
1201 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1202 (truncate:PSI
1203 (sign_extend:SI
1204 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))))]
1205 ""
1206 "@
1207 extxbu %0
1208 mov %1,%0\;extxbu %0
1209 movbu %1,%0"
1210 [(set_attr "cc" "none_0hit")])
1211
1212(define_insn ""
1213 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1214 (truncate:PSI
1215 (zero_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))]
1216 ""
1217 "@
1218 extxu %0
1219 mov %1,%0\;extxu %0
1220 mov %1,%0\;extxu %0"
1221 [(set_attr "cc" "none_0hit")])
1222
1223(define_insn ""
1224 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1225 (truncate:PSI
1226 (zero_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))]
1227 ""
1228 "@
1229 extxbu %0
1230 mov %1,%0\;extxbu %0
1231 movbu %1,%0"
1232 [(set_attr "cc" "none_0hit")])
1233
1234;; ----------------------------------------------------------------------
1235;; SHIFTS
1236;; ----------------------------------------------------------------------
1237
1238;; If the shift count is small, we expand it into several single bit
1239;; shift insns. Otherwise we expand into a generic shift insn which
1240;; handles larger shift counts, shift by variable amounts, etc.
1241(define_expand "ashlhi3"
1242 [(set (match_operand:HI 0 "general_operand" "")
1243 (ashift:HI (match_operand:HI 1 "general_operand" "")
1244 (match_operand:HI 2 "general_operand" "")))]
1245 ""
1246 "
1247{
1248 /* This is an experiment to see if exposing more of the underlying
1249 operations results in better code. */
1250 if (GET_CODE (operands[2]) == CONST_INT
1251 && INTVAL (operands[2]) <= 4)
1252 {
1253 int count = INTVAL (operands[2]);
1254 emit_move_insn (operands[0], operands[1]);
1255 while (count > 0)
1256 {
1257 emit_insn (gen_rtx (SET, HImode, operands[0],
1258 gen_rtx (ASHIFT, HImode,
1259 operands[0], GEN_INT (1))));
1260 count--;
1261 }
1262 DONE;
1263 }
1264 else
1265 {
1266 expand_a_shift (HImode, ASHIFT, operands);
1267 DONE;
1268 }
1269}")
1270
1271;; ASHIFT one bit.
1272(define_insn ""
1273 [(set (match_operand:HI 0 "general_operand" "=d")
1274 (ashift:HI (match_operand:HI 1 "general_operand" "0")
1275 (const_int 1)))]
1276 ""
1277 "add %0,%0"
1278 [(set_attr "cc" "set_zn")])
1279
1280(define_expand "lshrhi3"
1281 [(set (match_operand:HI 0 "general_operand" "")
1282 (lshiftrt:HI (match_operand:HI 1 "general_operand" "")
1283 (match_operand:HI 2 "general_operand" "")))]
1284 ""
1285 "
1286{
1287 /* This is an experiment to see if exposing more of the underlying
1288 operations results in better code. */
1289 if (GET_CODE (operands[2]) == CONST_INT
1290 && INTVAL (operands[2]) <= 4)
1291 {
1292 int count = INTVAL (operands[2]);
1293 emit_move_insn (operands[0], operands[1]);
1294 while (count > 0)
1295 {
1296 emit_insn (gen_rtx (SET, HImode, operands[0],
1297 gen_rtx (LSHIFTRT, HImode,
1298 operands[0], GEN_INT (1))));
1299 count--;
1300 }
1301 DONE;
1302 }
1303 else
1304 {
1305 expand_a_shift (HImode, LSHIFTRT, operands);
1306 DONE;
1307 }
1308}")
1309
1310;; LSHIFTRT one bit.
1311(define_insn ""
1312 [(set (match_operand:HI 0 "general_operand" "=d")
1313 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
1314 (const_int 1)))]
1315 ""
1316 "lsr %0"
1317 [(set_attr "cc" "set_znv")])
1318
1319(define_expand "ashrhi3"
1320 [(set (match_operand:HI 0 "general_operand" "")
1321 (ashiftrt:HI (match_operand:HI 1 "general_operand" "")
1322 (match_operand:HI 2 "general_operand" "")))]
1323 ""
1324 "
1325{
1326 /* This is an experiment to see if exposing more of the underlying
1327 operations results in better code. */
1328 if (GET_CODE (operands[2]) == CONST_INT
1329 && INTVAL (operands[2]) <= 4)
1330 {
1331 int count = INTVAL (operands[2]);
1332 emit_move_insn (operands[0], operands[1]);
1333 while (count > 0)
1334 {
1335 emit_insn (gen_rtx (SET, HImode, operands[0],
1336 gen_rtx (ASHIFTRT, HImode,
1337 operands[0], GEN_INT (1))));
1338 count--;
1339 }
1340 DONE;
1341 }
1342 else
1343 {
1344 expand_a_shift (HImode, ASHIFTRT, operands);
1345 DONE;
1346 }
1347}")
1348
1349;; ASHIFTRT one bit.
1350(define_insn ""
1351 [(set (match_operand:HI 0 "general_operand" "=d")
1352 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
1353 (const_int 1)))]
1354 ""
1355 "asr %0"
1356 [(set_attr "cc" "set_znv")])
1357
1358;; And the general HImode shift pattern. Handles both shift by constants
1359;; and shift by variable counts.
1360(define_insn ""
1361 [(set (match_operand:HI 0 "general_operand" "=d,d")
1362 (match_operator:HI 3 "nshift_operator"
1363 [ (match_operand:HI 1 "general_operand" "0,0")
1364 (match_operand:HI 2 "general_operand" "KL,dan")]))
1365 (clobber (match_scratch:HI 4 "=X,&d"))]
1366 ""
1367 "* return emit_a_shift (insn, operands);"
1368 [(set_attr "cc" "clobber")])
1369
1370;; We expect only ASHIFT with constant shift counts to be common for
1371;; PSImode, so we optimize just that case. For all other cases we
1372;; extend the value to SImode and perform the shift in SImode.
1373(define_expand "ashlpsi3"
1374 [(set (match_operand:PSI 0 "general_operand" "")
1375 (ashift:PSI (match_operand:PSI 1 "general_operand" "")
1376 (match_operand:HI 2 "general_operand" "")))]
1377 ""
1378 "
1379{
1380 /* This is an experiment to see if exposing more of the underlying
1381 operations results in better code. */
1382 if (GET_CODE (operands[2]) == CONST_INT
1383 && INTVAL (operands[2]) <= 7)
1384 {
1385 int count = INTVAL (operands[2]);
1386 emit_move_insn (operands[0], operands[1]);
1387 while (count > 0)
1388 {
1389 emit_insn (gen_rtx (SET, PSImode, operands[0],
1390 gen_rtx (ASHIFT, PSImode,
1391 operands[0], GEN_INT (1))));
1392 count--;
1393 }
1394 DONE;
1395 }
1396 else
1397 {
1398 expand_a_shift (PSImode, ASHIFT, operands);
1399 DONE;
1400 }
1401}")
1402
1403;; ASHIFT one bit.
1404(define_insn ""
1405 [(set (match_operand:PSI 0 "general_operand" "=d")
1406 (ashift:PSI (match_operand:PSI 1 "general_operand" "0")
1407 (const_int 1)))]
1408 ""
1409 "add %0,%0"
1410 [(set_attr "cc" "set_zn")])
1411
1412(define_expand "lshrpsi3"
1413 [(set (match_operand:PSI 0 "general_operand" "")
1414 (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "")
1415 (match_operand:HI 2 "general_operand" "")))]
1416 ""
1417 "
1418{
1419 rtx reg = gen_reg_rtx (SImode);
1420
1421 emit_insn (gen_zero_extendpsisi2 (reg, operands[1]));
1422 reg = expand_binop (SImode, lshr_optab, reg,
1423 operands[2], reg, 1, OPTAB_WIDEN);
1424 emit_insn (gen_truncsipsi2 (operands[0], reg));
1425 DONE;
1426}")
1427
1428(define_expand "ashrpsi3"
1429 [(set (match_operand:PSI 0 "general_operand" "")
1430 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "")
1431 (match_operand:HI 2 "general_operand" "")))]
1432 ""
1433 "
1434{
1435 rtx reg = gen_reg_rtx (SImode);
1436
1437 emit_insn (gen_extendpsisi2 (reg, operands[1]));
1438 reg = expand_binop (SImode, ashr_optab, reg,
1439 operands[2], reg, 0, OPTAB_WIDEN);
1440 emit_insn (gen_truncsipsi2 (operands[0], reg));
1441 DONE;
1442}")
1443
1444(define_expand "ashlsi3"
1445 [(set (match_operand:SI 0 "register_operand" "")
1446 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "")
1447 (match_operand:HI 2 "general_operand" "")))]
1448 ""
1449 "
1450{
1451 /* For small shifts, just emit a series of single bit shifts inline.
1452
1453 For other constant shift counts smaller than a word or non-constant
1454 shift counts we call out to a library call during RTL generation time;
1455 after RTL generation time we allow optabs.c to open code the operation.
1456 See comments in addsi3/subsi3 expanders.
1457
1458 Otherwise we allow optabs.c to open code the operation. */
1459 if (GET_CODE (operands[2]) == CONST_INT
1460 && (INTVAL (operands[2]) <= 3))
1461 {
1462 int count = INTVAL (operands[2]);
1463 emit_move_insn (operands[0], operands[1]);
1464 while (count > 0)
1465 {
1466 emit_insn (gen_rtx (SET, SImode, operands[0],
1467 gen_rtx (ASHIFT, SImode,
1468 operands[0], GEN_INT (1))));
1469 count--;
1470 }
1471 DONE;
1472 }
1473 else if (rtx_equal_function_value_matters
1474 && (GET_CODE (operands[2]) != CONST_INT
1475 || INTVAL (operands[2]) <= 15))
1476 {
1477 rtx ret, insns;
1478 extern rtx emit_library_call_value ();
1479
1480 start_sequence ();
1481 ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashlsi3\"),
1482 NULL_RTX, 1, SImode, 2, operands[1],
1483 SImode, operands[2], HImode);
1484 insns = get_insns ();
1485 end_sequence ();
1486 emit_libcall_block (insns, operands[0], ret,
1487 gen_rtx (ASHIFT, SImode, operands[1], operands[2]));
1488 DONE;
1489 }
1490 else
1491 FAIL;
1492}")
1493
1494;; ASHIFT one bit.
1495(define_insn ""
1496 [(set (match_operand:SI 0 "general_operand" "=d")
1497 (ashift:SI (match_operand:SI 1 "general_operand" "0")
1498 (const_int 1)))]
1499 ""
1500 "add %L0,%L0\;addc %H0,%H0"
1501 [(set_attr "cc" "clobber")])
1502
1503(define_expand "lshrsi3"
1504 [(set (match_operand:SI 0 "register_operand" "")
1505 (lshiftrt:SI (match_operand:SI 1 "general_operand" "")
1506 (match_operand:HI 2 "general_operand" "")))]
1507 ""
1508 "
1509{
1510 /* For small shifts, just emit a series of single bit shifts inline.
1511
1512 For other constant shift counts smaller than a word or non-constant
1513 shift counts we call out to a library call during RTL generation time;
1514 after RTL generation time we allow optabs.c to open code the operation.
1515 See comments in addsi3/subsi3 expanders.
1516
1517 Otherwise we allow optabs.c to open code the operation. */
1518 if (GET_CODE (operands[2]) == CONST_INT
1519 && (INTVAL (operands[2]) <= 2))
1520 {
1521 int count = INTVAL (operands[2]);
1522 emit_move_insn (operands[0], operands[1]);
1523 while (count > 0)
1524 {
1525 emit_insn (gen_rtx (SET, SImode, operands[0],
1526 gen_rtx (LSHIFTRT, SImode,
1527 operands[0], GEN_INT (1))));
1528 count--;
1529 }
1530 DONE;
1531 }
1532 else if (rtx_equal_function_value_matters
1533 && (GET_CODE (operands[2]) != CONST_INT
1534 || INTVAL (operands[2]) <= 15))
1535 {
1536 rtx ret, insns;
1537 extern rtx emit_library_call_value ();
1538
1539 start_sequence ();
1540 ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__lshrsi3\"),
1541 NULL_RTX, 1, SImode, 2, operands[1],
1542 SImode, operands[2], HImode);
1543 insns = get_insns ();
1544 end_sequence ();
1545 emit_libcall_block (insns, operands[0], ret,
1546 gen_rtx (LSHIFTRT, SImode, operands[1], operands[2]));
1547 DONE;
1548 }
1549 else
1550 FAIL;
1551}")
1552
1553;; LSHIFTRT one bit.
1554(define_insn ""
1555 [(set (match_operand:SI 0 "general_operand" "=d")
1556 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
1557 (const_int 1)))]
1558 ""
1559 "lsr %H0\;ror %L0"
1560 [(set_attr "cc" "clobber")])
1561
1562(define_expand "ashrsi3"
1563 [(set (match_operand:SI 0 "register_operand" "")
1564 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1565 (match_operand:HI 2 "general_operand" "")))]
1566 ""
1567 "
1568{
1569 /* For small shifts, just emit a series of single bit shifts inline.
1570
1571 For other constant shift counts smaller than a word or non-constant
1572 shift counts we call out to a library call during RTL generation time;
1573 after RTL generation time we allow optabs.c to open code the operation.
1574 See comments in addsi3/subsi3 expanders.
1575
1576 Otherwise we allow optabs.c to open code the operation. */
1577 if (GET_CODE (operands[2]) == CONST_INT
1578 && (INTVAL (operands[2]) <= 2))
1579 {
1580 int count = INTVAL (operands[2]);
1581 emit_move_insn (operands[0], operands[1]);
1582 while (count > 0)
1583 {
1584 emit_insn (gen_rtx (SET, SImode, operands[0],
1585 gen_rtx (ASHIFTRT, SImode,
1586 operands[0], GEN_INT (1))));
1587 count--;
1588 }
1589 DONE;
1590 }
1591 else if (rtx_equal_function_value_matters
1592 && (GET_CODE (operands[2]) != CONST_INT
1593 || INTVAL (operands[2]) <= 15))
1594 {
1595 rtx ret, insns;
1596 extern rtx emit_library_call_value ();
1597
1598 start_sequence ();
1599 ret = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"__ashrsi3\"),
1600 NULL_RTX, 1, SImode, 2, operands[1],
1601 SImode, operands[2], HImode);
1602 insns = get_insns ();
1603 end_sequence ();
1604 emit_libcall_block (insns, operands[0], ret,
1605 gen_rtx (ASHIFTRT, SImode, operands[1], operands[2]));
1606 DONE;
1607 }
1608 else
1609 FAIL;
1610}")
1611
1612;; ASHIFTRT one bit.
1613(define_insn ""
1614 [(set (match_operand:SI 0 "general_operand" "=d")
1615 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
1616 (const_int 1)))]
1617 ""
1618 "asr %H0\;ror %L0"
1619 [(set_attr "cc" "clobber")])
1620
1621;; ----------------------------------------------------------------------
1622;; PROLOGUE/EPILOGUE
1623;; ----------------------------------------------------------------------
1624(define_expand "prologue"
1625 [(const_int 0)]
1626 ""
1627 "expand_prologue (); DONE;")
1628
1629(define_insn "outline_prologue_call"
1630 [(const_int 1)]
1631 ""
1632 "jsr ___prologue"
1633 [(set_attr "cc" "clobber")])
1634
1635(define_expand "epilogue"
1636 [(return)]
1637 ""
1638 "
1639{
1640 expand_epilogue ();
1641 DONE;
1642}")
1643
1644(define_insn "outline_epilogue_call_a0"
1645 [(const_int 2)]
1646 ""
1647 "jsr ___epilogue_a0"
1648 [(set_attr "cc" "clobber")])
1649
1650(define_insn "outline_epilogue_call_d0"
1651 [(const_int 3)]
1652 ""
1653 "jsr ___epilogue_d0"
1654 [(set_attr "cc" "clobber")])
1655
1656(define_insn "outline_epilogue_jump"
1657 [(const_int 4)]
1658 ""
1659 "jmp ___epilogue_noreturn"
1660 [(set_attr "cc" "clobber")])
1661
1662(define_insn "return"
1663 [(return)]
1664 "reload_completed && total_frame_size () == 0
1665 && !current_function_needs_context"
1666 "*
1667{
1668 rtx next = next_active_insn (insn);
1669
1670 if (next
1671 && GET_CODE (next) == JUMP_INSN
1672 && GET_CODE (PATTERN (next)) == RETURN)
1673 return \"\";
1674 return \"rts\";
1675}"
1676 [(set_attr "cc" "clobber")])
1677
1678(define_insn "return_internal"
1679 [(const_int 0)
1680 (return)]
1681 ""
1682 "rts"
1683 [(set_attr "cc" "clobber")])
1684
1685;; These are special combiner patterns to improve array/pointer accesses.
1686;;
1687;; A typical sequence involves extending an integer/char, shifting it left
1688;; a few times, then truncating the value to PSImode.
1689;;
1690;; This first pattern combines the shifting & truncation operations, by
1691;; itself it is a win because the shifts end up occuring in PSImode instead
1692;; of SImode. However, it has the secondary effect of giving us the
1693;; opportunity to match patterns which allow us to remove the initial
1694;; extension completely, which is a big win.
1695(define_insn ""
1696 [(set (match_operand:PSI 0 "general_operand" "=d,d,a")
1697 (truncate:PSI
1698 (ashift:SI (match_operand:SI 1 "general_operand" "d,m,m")
1699 (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1700 ""
1701 "*
1702{
1703 int count = INTVAL (operands[2]);
1704 if (which_alternative == 0)
1705 output_asm_insn (\"jsr ___truncsipsi2_%1_%0\", operands);
1706 else if (which_alternative == 1)
1707 output_asm_insn (\"movx %A1,%0\", operands);
1708 else
1709 output_asm_insn (\" mov %1,%0\", operands);
1710
1711 while (count)
1712 {
1713 output_asm_insn (\"add %0,%0\", operands);
1714 count--;
1715 }
1716 return \"\";
1717}"
1718 [(set_attr "cc" "clobber")])
1719
1720;; Similarly, except that we also have zero/sign extension of the
1721;; original operand. */
1722(define_insn ""
1723 [(set (match_operand:PSI 0 "general_operand" "=d,d")
1724 (truncate:PSI
1725 (ashift:SI
1726 (zero_extend:SI (match_operand:HI 1 "general_operand" "0,dim"))
1727 (match_operand:HI 2 "const_int_operand" "i,i"))))]
1728 ""
1729 "*
1730{
1731 int count = INTVAL (operands[2]);
1732
1733 /* First extend operand 1 to PSImode. */
1734 if (which_alternative == 0)
1735 output_asm_insn (\"extxu %0\", operands);
1736 else
1737 output_asm_insn (\"mov %1,%0\;extxu %0\", operands);
1738
1739 /* Now do the shifting. */
1740 while (count)
1741 {
1742 output_asm_insn (\"add %0,%0\", operands);
1743 count--;
1744 }
1745 return \"\";
1746}"
1747 [(set_attr "cc" "clobber")])
1748
1749(define_insn ""
1750 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1751 (truncate:PSI
1752 (ashift:SI
1753 (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))
1754 (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1755 ""
1756 "*
1757{
1758 int count = INTVAL (operands[2]);
1759
1760 /* First extend operand 1 to PSImode. */
1761 if (which_alternative == 0)
1762 output_asm_insn (\"extx %0\", operands);
1763 else if (which_alternative == 1)
1764 output_asm_insn (\"mov %1,%0\;extx %0\", operands);
1765 else
1766 output_asm_insn (\"mov %1,%0\", operands);
1767
1768 /* Now do the shifting. */
1769 while (count)
1770 {
1771 output_asm_insn (\"add %0,%0\", operands);
1772 count--;
1773 }
1774 return \"\";
1775}"
1776 [(set_attr "cc" "clobber")])
1777
1778(define_insn ""
1779 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1780 (truncate:PSI
1781 (ashift:SI
1782 (sign_extend:SI
1783 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))
1784 (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1785 ""
1786 "*
1787{
1788 int count = INTVAL (operands[2]);
1789
1790 /* First extend operand 1 to PSImode. */
1791 if (which_alternative == 0)
1792 output_asm_insn (\"extxbu %0\", operands);
1793 else if (which_alternative == 1)
1794 output_asm_insn (\"mov %1,%0\;extxbu %0\", operands);
1795 else
1796 output_asm_insn (\"movbu %1,%0\", operands);
1797
1798 /* Now do the shifting. */
1799 while (count)
1800 {
1801 output_asm_insn (\"add %0,%0\", operands);
1802 count--;
1803 }
1804 return \"\";
1805}"
1806 [(set_attr "cc" "clobber")])
1807
1808(define_insn ""
1809 [(set (match_operand:PSI 0 "general_operand" "=d,d,d")
1810 (truncate:PSI
1811 (ashift:SI
1812 (sign_extend:SI
1813 (match_operand:QI 1 "general_operand" "0,di,m"))
1814 (match_operand:HI 2 "const_int_operand" "i,i,i"))))]
1815 ""
1816 "*
1817{
1818 int count = INTVAL (operands[2]);
1819
1820 /* First extend operand 1 to PSImode. */
1821 if (which_alternative == 0)
1822 output_asm_insn (\"extxb %0\", operands);
1823 else if (which_alternative == 1)
1824 output_asm_insn (\"mov %1,%0\;extxb %0\", operands);
1825 else if (GET_CODE (XEXP (operands[1], 0)) == REG)
1826 output_asm_insn (\"movbu %1,%0\;extxb %0\", operands);
1827 else
1828 output_asm_insn (\"movb %1,%0\", operands);
1829
1830 /* Now do the shifting. */
1831 while (count)
1832 {
1833 output_asm_insn (\"add %0,%0\", operands);
1834 count--;
1835 }
1836 return \"\";
1837}"
1838 [(set_attr "cc" "clobber")])
1839
1840;; Try to combine consecutive updates of the stack pointer (or any
1841;; other register for that matter).
1842(define_peephole
1843 [(set (match_operand:PSI 0 "register_operand" "=da")
1844 (plus:PSI (match_dup 0)
1845 (match_operand 1 "const_int_operand" "")))
1846 (set (match_dup 0)
1847 (plus:PSI (match_dup 0)
1848 (match_operand 2 "const_int_operand" "")))]
1849 ""
1850 "*
1851{
1852 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
1853 return \"add %1,%0\";
1854}"
1855 [(set_attr "cc" "clobber")])
1856
1857;;
1858;; We had patterns to check eq/ne, but the they don't work because
1859;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
1860;;
1861;; The Z flag and C flag would be set, and we have no way to
1862;; check for the Z flag set and C flag clear.
1863;;
1864;; This will work on the mn10200 because we can check the ZX flag
1865;; if the comparison is in HImode.
1866(define_peephole
1867 [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1868 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1869 (match_operand 1 "" "")
1870 (pc)))]
1871 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1872 "add %0,%0\;bcc %1"
1873 [(set_attr "cc" "clobber")])
1874
1875(define_peephole
1876 [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1877 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1878 (match_operand 1 "" "")
1879 (pc)))]
1880 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1881 "add %0,%0\;bcs %1"
1882 [(set_attr "cc" "clobber")])
1883
1884(define_peephole
1885 [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1886 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1887 (pc)
1888 (match_operand 1 "" "")))]
1889 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1890 "add %0,%0\;bcs %1"
1891 [(set_attr "cc" "clobber")])
1892
1893(define_peephole
1894 [(set (cc0) (match_operand:HI 0 "register_operand" "d"))
1895 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1896 (pc)
1897 (match_operand 1 "" "")))]
1898 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1899 "add %0,%0\;bcc %1"
1900 [(set_attr "cc" "clobber")])
1901
1902(define_peephole
1903 [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1904 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1905 (match_operand 1 "" "")
1906 (pc)))]
1907 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1908 "add %0,%0\;bccx %1"
1909 [(set_attr "cc" "clobber")])
1910
1911(define_peephole
1912 [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1913 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1914 (match_operand 1 "" "")
1915 (pc)))]
1916 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1917 "add %0,%0\;bcsx %1"
1918 [(set_attr "cc" "clobber")])
1919
1920(define_peephole
1921 [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1922 (set (pc) (if_then_else (ge (cc0) (const_int 0))
1923 (pc)
1924 (match_operand 1 "" "")))]
1925 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1926 "add %0,%0\;bcsx %1"
1927 [(set_attr "cc" "clobber")])
1928
1929(define_peephole
1930 [(set (cc0) (match_operand:PSI 0 "register_operand" "d"))
1931 (set (pc) (if_then_else (lt (cc0) (const_int 0))
1932 (pc)
1933 (match_operand 1 "" "")))]
1934 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
1935 "add %0,%0\;bccx %1"
1936 [(set_attr "cc" "clobber")])
1937
1938;; We call out to library routines to perform 32bit addition and subtraction
1939;; operations (see addsi3/subsi3 expanders for why). These peepholes catch
1940;; the trivial case where the operation could be done with an add;addc or
1941;; sub;subc sequence.
1942(define_peephole
1943 [(set (mem:SI (reg:PSI 7)) (reg:SI 2))
1944 (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")
1945 (match_operand:HI 2 "general_operand" "")))]
1946 "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1947 && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__addsi3\") == 0"
1948 "add d2,d0\;addc d3,d1"
1949 [(set_attr "cc" "clobber")])
1950
1951(define_peephole
1952 [(set (mem:SI (reg:PSI 7)) (reg:SI 2))
1953 (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "")
1954 (match_operand:HI 2 "general_operand" "")))]
1955 "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1956 && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__subsi3\") == 0"
1957 "sub d2,d0\;subc d3,d1"
1958 [(set_attr "cc" "clobber")])
This page took 0.23999 seconds and 5 git commands to generate.