]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.c
Add -mno-wide-multiply, -mno-move, make addresses more compatible with other parts...
[gcc.git] / gcc / config / i386 / i386.c
1 /* Subroutines for insn-output.c for Intel X86.
2 Copyright (C) 1988, 1992, 1994 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include <stdio.h>
21 #include <setjmp.h>
22 #include "config.h"
23 #include "rtl.h"
24 #include "regs.h"
25 #include "hard-reg-set.h"
26 #include "real.h"
27 #include "insn-config.h"
28 #include "conditions.h"
29 #include "insn-flags.h"
30 #include "output.h"
31 #include "insn-attr.h"
32 #include "tree.h"
33 #include "flags.h"
34 #include "function.h"
35
36 #ifdef EXTRA_CONSTRAINT
37 /* If EXTRA_CONSTRAINT is defined, then the 'S'
38 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
39 asm statements that need 'S' for class SIREG will break. */
40 error EXTRA_CONSTRAINT conflicts with S constraint letter
41 /* The previous line used to be #error, but some compilers barf
42 even if the conditional was untrue. */
43 #endif
44
45 #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
46
47 extern FILE *asm_out_file;
48 extern char *strcat ();
49
50 char *singlemove_string ();
51 char *output_move_const_single ();
52 char *output_fp_cc0_set ();
53
54 char *hi_reg_name[] = HI_REGISTER_NAMES;
55 char *qi_reg_name[] = QI_REGISTER_NAMES;
56 char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
57
58 /* Array of the smallest class containing reg number REGNO, indexed by
59 REGNO. Used by REGNO_REG_CLASS in i386.h. */
60
61 enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
62 {
63 /* ax, dx, cx, bx */
64 AREG, DREG, CREG, BREG,
65 /* si, di, bp, sp */
66 SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
67 /* FP registers */
68 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
69 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
70 /* arg pointer */
71 INDEX_REGS
72 };
73
74 /* Test and compare insns in i386.md store the information needed to
75 generate branch and scc insns here. */
76
77 struct rtx_def *i386_compare_op0, *i386_compare_op1;
78 struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
79 \f
80 /* Output an insn whose source is a 386 integer register. SRC is the
81 rtx for the register, and TEMPLATE is the op-code template. SRC may
82 be either SImode or DImode.
83
84 The template will be output with operands[0] as SRC, and operands[1]
85 as a pointer to the top of the 386 stack. So a call from floatsidf2
86 would look like this:
87
88 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
89
90 where %z0 corresponds to the caller's operands[1], and is used to
91 emit the proper size suffix.
92
93 ??? Extend this to handle HImode - a 387 can load and store HImode
94 values directly. */
95
96 void
97 output_op_from_reg (src, template)
98 rtx src;
99 char *template;
100 {
101 rtx xops[4];
102 int size = GET_MODE_SIZE (GET_MODE (src));
103
104 xops[0] = src;
105 xops[1] = AT_SP (Pmode);
106 xops[2] = GEN_INT (size);
107 xops[3] = stack_pointer_rtx;
108
109 if (size > UNITS_PER_WORD)
110 {
111 rtx high;
112 if (size > 2 * UNITS_PER_WORD)
113 {
114 high = gen_rtx (REG, SImode, REGNO (src) + 2);
115 output_asm_insn (AS1 (push%L0,%0), &high);
116 }
117 high = gen_rtx (REG, SImode, REGNO (src) + 1);
118 output_asm_insn (AS1 (push%L0,%0), &high);
119 }
120 output_asm_insn (AS1 (push%L0,%0), &src);
121
122 output_asm_insn (template, xops);
123
124 output_asm_insn (AS2 (add%L3,%2,%3), xops);
125 }
126 \f
127 /* Output an insn to pop an value from the 387 top-of-stack to 386
128 register DEST. The 387 register stack is popped if DIES is true. If
129 the mode of DEST is an integer mode, a `fist' integer store is done,
130 otherwise a `fst' float store is done. */
131
132 void
133 output_to_reg (dest, dies)
134 rtx dest;
135 int dies;
136 {
137 rtx xops[4];
138 int size = GET_MODE_SIZE (GET_MODE (dest));
139
140 xops[0] = AT_SP (Pmode);
141 xops[1] = stack_pointer_rtx;
142 xops[2] = GEN_INT (size);
143 xops[3] = dest;
144
145 output_asm_insn (AS2 (sub%L1,%2,%1), xops);
146
147 if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
148 {
149 if (dies)
150 output_asm_insn (AS1 (fistp%z3,%y0), xops);
151 else
152 output_asm_insn (AS1 (fist%z3,%y0), xops);
153 }
154 else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
155 {
156 if (dies)
157 output_asm_insn (AS1 (fstp%z3,%y0), xops);
158 else
159 {
160 if (GET_MODE (dest) == XFmode)
161 {
162 output_asm_insn (AS1 (fstp%z3,%y0), xops);
163 output_asm_insn (AS1 (fld%z3,%y0), xops);
164 }
165 else
166 output_asm_insn (AS1 (fst%z3,%y0), xops);
167 }
168 }
169 else
170 abort ();
171
172 output_asm_insn (AS1 (pop%L0,%0), &dest);
173
174 if (size > UNITS_PER_WORD)
175 {
176 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
177 output_asm_insn (AS1 (pop%L0,%0), &dest);
178 if (size > 2 * UNITS_PER_WORD)
179 {
180 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
181 output_asm_insn (AS1 (pop%L0,%0), &dest);
182 }
183 }
184 }
185 \f
186 char *
187 singlemove_string (operands)
188 rtx *operands;
189 {
190 rtx x;
191 if (GET_CODE (operands[0]) == MEM
192 && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
193 {
194 if (XEXP (x, 0) != stack_pointer_rtx)
195 abort ();
196 return "push%L1 %1";
197 }
198 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
199 {
200 return output_move_const_single (operands);
201 }
202 else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
203 return AS2 (mov%L0,%1,%0);
204 else if (CONSTANT_P (operands[1]))
205 return AS2 (mov%L0,%1,%0);
206 else
207 {
208 output_asm_insn ("push%L1 %1", operands);
209 return "pop%L0 %0";
210 }
211 }
212 \f
213 /* Return a REG that occurs in ADDR with coefficient 1.
214 ADDR can be effectively incremented by incrementing REG. */
215
216 static rtx
217 find_addr_reg (addr)
218 rtx addr;
219 {
220 while (GET_CODE (addr) == PLUS)
221 {
222 if (GET_CODE (XEXP (addr, 0)) == REG)
223 addr = XEXP (addr, 0);
224 else if (GET_CODE (XEXP (addr, 1)) == REG)
225 addr = XEXP (addr, 1);
226 else if (CONSTANT_P (XEXP (addr, 0)))
227 addr = XEXP (addr, 1);
228 else if (CONSTANT_P (XEXP (addr, 1)))
229 addr = XEXP (addr, 0);
230 else
231 abort ();
232 }
233 if (GET_CODE (addr) == REG)
234 return addr;
235 abort ();
236 }
237
238 /* Output an insn to add the constant N to the register X. */
239
240 static void
241 asm_add (n, x)
242 int n;
243 rtx x;
244 {
245 rtx xops[2];
246 xops[0] = x;
247
248 if (n == -1)
249 output_asm_insn (AS1 (dec%L0,%0), xops);
250 else if (n == 1)
251 output_asm_insn (AS1 (inc%L0,%0), xops);
252 else if (n < 0)
253 {
254 xops[1] = GEN_INT (-n);
255 output_asm_insn (AS2 (sub%L0,%1,%0), xops);
256 }
257 else if (n > 0)
258 {
259 xops[1] = GEN_INT (n);
260 output_asm_insn (AS2 (add%L0,%1,%0), xops);
261 }
262 }
263
264 /* Output assembler code to perform a doubleword move insn
265 with operands OPERANDS. */
266
267 char *
268 output_move_double (operands)
269 rtx *operands;
270 {
271 enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
272 rtx latehalf[2];
273 rtx middlehalf[2];
274 rtx xops[2];
275 rtx addreg0 = 0, addreg1 = 0;
276 int dest_overlapped_low = 0;
277 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
278
279 middlehalf[0] = 0;
280 middlehalf[1] = 0;
281
282 /* First classify both operands. */
283
284 if (REG_P (operands[0]))
285 optype0 = REGOP;
286 else if (offsettable_memref_p (operands[0]))
287 optype0 = OFFSOP;
288 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
289 optype0 = POPOP;
290 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
291 optype0 = PUSHOP;
292 else if (GET_CODE (operands[0]) == MEM)
293 optype0 = MEMOP;
294 else
295 optype0 = RNDOP;
296
297 if (REG_P (operands[1]))
298 optype1 = REGOP;
299 else if (CONSTANT_P (operands[1]))
300 optype1 = CNSTOP;
301 else if (offsettable_memref_p (operands[1]))
302 optype1 = OFFSOP;
303 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
304 optype1 = POPOP;
305 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
306 optype1 = PUSHOP;
307 else if (GET_CODE (operands[1]) == MEM)
308 optype1 = MEMOP;
309 else
310 optype1 = RNDOP;
311
312 /* Check for the cases that the operand constraints are not
313 supposed to allow to happen. Abort if we get one,
314 because generating code for these cases is painful. */
315
316 if (optype0 == RNDOP || optype1 == RNDOP)
317 abort ();
318
319 /* If one operand is decrementing and one is incrementing
320 decrement the former register explicitly
321 and change that operand into ordinary indexing. */
322
323 if (optype0 == PUSHOP && optype1 == POPOP)
324 {
325 /* ??? Can this ever happen on i386? */
326 operands[0] = XEXP (XEXP (operands[0], 0), 0);
327 asm_add (-size, operands[0]);
328 if (GET_MODE (operands[1]) == XFmode)
329 operands[0] = gen_rtx (MEM, XFmode, operands[0]);
330 else if (GET_MODE (operands[0]) == DFmode)
331 operands[0] = gen_rtx (MEM, DFmode, operands[0]);
332 else
333 operands[0] = gen_rtx (MEM, DImode, operands[0]);
334 optype0 = OFFSOP;
335 }
336
337 if (optype0 == POPOP && optype1 == PUSHOP)
338 {
339 /* ??? Can this ever happen on i386? */
340 operands[1] = XEXP (XEXP (operands[1], 0), 0);
341 asm_add (-size, operands[1]);
342 if (GET_MODE (operands[1]) == XFmode)
343 operands[1] = gen_rtx (MEM, XFmode, operands[1]);
344 else if (GET_MODE (operands[1]) == DFmode)
345 operands[1] = gen_rtx (MEM, DFmode, operands[1]);
346 else
347 operands[1] = gen_rtx (MEM, DImode, operands[1]);
348 optype1 = OFFSOP;
349 }
350
351 /* If an operand is an unoffsettable memory ref, find a register
352 we can increment temporarily to make it refer to the second word. */
353
354 if (optype0 == MEMOP)
355 addreg0 = find_addr_reg (XEXP (operands[0], 0));
356
357 if (optype1 == MEMOP)
358 addreg1 = find_addr_reg (XEXP (operands[1], 0));
359
360 /* Ok, we can do one word at a time.
361 Normally we do the low-numbered word first,
362 but if either operand is autodecrementing then we
363 do the high-numbered word first.
364
365 In either case, set up in LATEHALF the operands to use
366 for the high-numbered word and in some cases alter the
367 operands in OPERANDS to be suitable for the low-numbered word. */
368
369 if (size == 12)
370 {
371 if (optype0 == REGOP)
372 {
373 middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
374 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
375 }
376 else if (optype0 == OFFSOP)
377 {
378 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
379 latehalf[0] = adj_offsettable_operand (operands[0], 8);
380 }
381 else
382 {
383 middlehalf[0] = operands[0];
384 latehalf[0] = operands[0];
385 }
386
387 if (optype1 == REGOP)
388 {
389 middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
390 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
391 }
392 else if (optype1 == OFFSOP)
393 {
394 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
395 latehalf[1] = adj_offsettable_operand (operands[1], 8);
396 }
397 else if (optype1 == CNSTOP)
398 {
399 if (GET_CODE (operands[1]) == CONST_DOUBLE)
400 {
401 REAL_VALUE_TYPE r; long l[3];
402
403 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
404 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
405 operands[1] = GEN_INT (l[0]);
406 middlehalf[1] = GEN_INT (l[1]);
407 latehalf[1] = GEN_INT (l[2]);
408 }
409 else if (CONSTANT_P (operands[1]))
410 /* No non-CONST_DOUBLE constant should ever appear here. */
411 abort ();
412 }
413 else
414 {
415 middlehalf[1] = operands[1];
416 latehalf[1] = operands[1];
417 }
418 }
419 else /* size is not 12: */
420 {
421 if (optype0 == REGOP)
422 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
423 else if (optype0 == OFFSOP)
424 latehalf[0] = adj_offsettable_operand (operands[0], 4);
425 else
426 latehalf[0] = operands[0];
427
428 if (optype1 == REGOP)
429 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
430 else if (optype1 == OFFSOP)
431 latehalf[1] = adj_offsettable_operand (operands[1], 4);
432 else if (optype1 == CNSTOP)
433 {
434 if (GET_CODE (operands[1]) == CONST_DOUBLE)
435 split_double (operands[1], &operands[1], &latehalf[1]);
436 else if (CONSTANT_P (operands[1]))
437 {
438 /* ??? jrv: Can this really happen? A DImode constant
439 that isn't a CONST_DOUBLE? */
440 if (GET_CODE (operands[1]) == CONST_INT
441 && INTVAL (operands[1]) < 0)
442 latehalf[1] = constm1_rtx;
443 else
444 latehalf[1] = const0_rtx;
445 }
446 }
447 else
448 latehalf[1] = operands[1];
449 }
450
451 /* If insn is effectively movd N (sp),-(sp) then we will do the
452 high word first. We should use the adjusted operand 1
453 (which is N+4 (sp) or N+8 (sp))
454 for the low word and middle word as well,
455 to compensate for the first decrement of sp. */
456 if (optype0 == PUSHOP
457 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
458 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
459 middlehalf[1] = operands[1] = latehalf[1];
460
461 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
462 if the upper part of reg N does not appear in the MEM, arrange to
463 emit the move late-half first. Otherwise, compute the MEM address
464 into the upper part of N and use that as a pointer to the memory
465 operand. */
466 if (optype0 == REGOP
467 && (optype1 == OFFSOP || optype1 == MEMOP))
468 {
469 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
470 && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
471 {
472 /* If both halves of dest are used in the src memory address,
473 compute the address into latehalf of dest. */
474 compadr:
475 xops[0] = latehalf[0];
476 xops[1] = XEXP (operands[1], 0);
477 output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
478 if( GET_MODE (operands[1]) == XFmode )
479 {
480 /* abort (); */
481 operands[1] = gen_rtx (MEM, XFmode, latehalf[0]);
482 middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
483 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
484 }
485 else
486 {
487 operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
488 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
489 }
490 }
491 else if (size == 12
492 && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0)))
493 {
494 /* Check for two regs used by both source and dest. */
495 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
496 || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
497 goto compadr;
498
499 /* JRV says this can't happen: */
500 if (addreg0 || addreg1)
501 abort();
502
503 /* Only the middle reg conflicts; simply put it last. */
504 output_asm_insn (singlemove_string (operands), operands);
505 output_asm_insn (singlemove_string (latehalf), latehalf);
506 output_asm_insn (singlemove_string (middlehalf), middlehalf);
507 return "";
508 }
509 else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
510 /* If the low half of dest is mentioned in the source memory
511 address, the arrange to emit the move late half first. */
512 dest_overlapped_low = 1;
513 }
514
515 /* If one or both operands autodecrementing,
516 do the two words, high-numbered first. */
517
518 /* Likewise, the first move would clobber the source of the second one,
519 do them in the other order. This happens only for registers;
520 such overlap can't happen in memory unless the user explicitly
521 sets it up, and that is an undefined circumstance. */
522
523 /*
524 if (optype0 == PUSHOP || optype1 == PUSHOP
525 || (optype0 == REGOP && optype1 == REGOP
526 && REGNO (operands[0]) == REGNO (latehalf[1]))
527 || dest_overlapped_low)
528 */
529 if (optype0 == PUSHOP || optype1 == PUSHOP
530 || (optype0 == REGOP && optype1 == REGOP
531 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
532 || REGNO (operands[0]) == REGNO (latehalf[1])))
533 || dest_overlapped_low)
534 {
535 /* Make any unoffsettable addresses point at high-numbered word. */
536 if (addreg0)
537 asm_add (size-4, addreg0);
538 if (addreg1)
539 asm_add (size-4, addreg1);
540
541 /* Do that word. */
542 output_asm_insn (singlemove_string (latehalf), latehalf);
543
544 /* Undo the adds we just did. */
545 if (addreg0)
546 asm_add (-4, addreg0);
547 if (addreg1)
548 asm_add (-4, addreg1);
549
550 if (size == 12)
551 {
552 output_asm_insn (singlemove_string (middlehalf), middlehalf);
553 if (addreg0)
554 asm_add (-4, addreg0);
555 if (addreg1)
556 asm_add (-4, addreg1);
557 }
558
559 /* Do low-numbered word. */
560 return singlemove_string (operands);
561 }
562
563 /* Normal case: do the two words, low-numbered first. */
564
565 output_asm_insn (singlemove_string (operands), operands);
566
567 /* Do the middle one of the three words for long double */
568 if (size == 12)
569 {
570 if (addreg0)
571 asm_add (4, addreg0);
572 if (addreg1)
573 asm_add (4, addreg1);
574
575 output_asm_insn (singlemove_string (middlehalf), middlehalf);
576 }
577
578 /* Make any unoffsettable addresses point at high-numbered word. */
579 if (addreg0)
580 asm_add (4, addreg0);
581 if (addreg1)
582 asm_add (4, addreg1);
583
584 /* Do that word. */
585 output_asm_insn (singlemove_string (latehalf), latehalf);
586
587 /* Undo the adds we just did. */
588 if (addreg0)
589 asm_add (4-size, addreg0);
590 if (addreg1)
591 asm_add (4-size, addreg1);
592
593 return "";
594 }
595 \f
596 int
597 standard_80387_constant_p (x)
598 rtx x;
599 {
600 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
601 REAL_VALUE_TYPE d;
602 jmp_buf handler;
603 int is0, is1;
604
605 if (setjmp (handler))
606 return 0;
607
608 set_float_handler (handler);
609 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
610 is0 = REAL_VALUES_EQUAL (d, dconst0);
611 is1 = REAL_VALUES_EQUAL (d, dconst1);
612 set_float_handler (NULL_PTR);
613
614 if (is0)
615 return 1;
616
617 if (is1)
618 return 2;
619
620 /* Note that on the 80387, other constants, such as pi,
621 are much slower to load as standard constants
622 than to load from doubles in memory! */
623 #endif
624
625 return 0;
626 }
627
628 char *
629 output_move_const_single (operands)
630 rtx *operands;
631 {
632 if (FP_REG_P (operands[0]))
633 {
634 int conval = standard_80387_constant_p (operands[1]);
635
636 if (conval == 1)
637 return "fldz";
638
639 if (conval == 2)
640 return "fld1";
641 }
642 if (GET_CODE (operands[1]) == CONST_DOUBLE)
643 {
644 REAL_VALUE_TYPE r; long l;
645
646 if (GET_MODE (operands[1]) == XFmode)
647 abort ();
648
649 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
650 REAL_VALUE_TO_TARGET_SINGLE (r, l);
651 operands[1] = GEN_INT (l);
652 }
653 return singlemove_string (operands);
654 }
655 \f
656 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
657 reference and a constant. */
658
659 int
660 symbolic_operand (op, mode)
661 register rtx op;
662 enum machine_mode mode;
663 {
664 switch (GET_CODE (op))
665 {
666 case SYMBOL_REF:
667 case LABEL_REF:
668 return 1;
669 case CONST:
670 op = XEXP (op, 0);
671 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
672 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
673 && GET_CODE (XEXP (op, 1)) == CONST_INT);
674 default:
675 return 0;
676 }
677 }
678
679 /* Test for a valid operand for a call instruction.
680 Don't allow the arg pointer register or virtual regs
681 since they may change into reg + const, which the patterns
682 can't handle yet. */
683
684 int
685 call_insn_operand (op, mode)
686 rtx op;
687 enum machine_mode mode;
688 {
689 if (GET_CODE (op) == MEM
690 && ((CONSTANT_ADDRESS_P (XEXP (op, 0))
691 /* This makes a difference for PIC. */
692 && general_operand (XEXP (op, 0), Pmode))
693 || (GET_CODE (XEXP (op, 0)) == REG
694 && XEXP (op, 0) != arg_pointer_rtx
695 && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
696 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
697 return 1;
698 return 0;
699 }
700
701 /* Like call_insn_operand but allow (mem (symbol_ref ...))
702 even if pic. */
703
704 int
705 expander_call_insn_operand (op, mode)
706 rtx op;
707 enum machine_mode mode;
708 {
709 if (GET_CODE (op) == MEM
710 && (CONSTANT_ADDRESS_P (XEXP (op, 0))
711 || (GET_CODE (XEXP (op, 0)) == REG
712 && XEXP (op, 0) != arg_pointer_rtx
713 && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
714 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
715 return 1;
716 return 0;
717 }
718 \f
719 /* Returns 1 if OP contains a symbol reference */
720
721 int
722 symbolic_reference_mentioned_p (op)
723 rtx op;
724 {
725 register char *fmt;
726 register int i;
727
728 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
729 return 1;
730
731 fmt = GET_RTX_FORMAT (GET_CODE (op));
732 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
733 {
734 if (fmt[i] == 'E')
735 {
736 register int j;
737
738 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
739 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
740 return 1;
741 }
742 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
743 return 1;
744 }
745
746 return 0;
747 }
748 \f
749 /* This function generates the assembly code for function entry.
750 FILE is an stdio stream to output the code to.
751 SIZE is an int: how many units of temporary storage to allocate. */
752
753 void
754 function_prologue (file, size)
755 FILE *file;
756 int size;
757 {
758 register int regno;
759 int limit;
760 rtx xops[4];
761 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
762 || current_function_uses_const_pool);
763
764 xops[0] = stack_pointer_rtx;
765 xops[1] = frame_pointer_rtx;
766 xops[2] = GEN_INT (size);
767 if (frame_pointer_needed)
768 {
769 output_asm_insn ("push%L1 %1", xops);
770 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
771 }
772
773 if (size)
774 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
775
776 /* Note If use enter it is NOT reversed args.
777 This one is not reversed from intel!!
778 I think enter is slower. Also sdb doesn't like it.
779 But if you want it the code is:
780 {
781 xops[3] = const0_rtx;
782 output_asm_insn ("enter %2,%3", xops);
783 }
784 */
785 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
786 for (regno = limit - 1; regno >= 0; regno--)
787 if ((regs_ever_live[regno] && ! call_used_regs[regno])
788 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
789 {
790 xops[0] = gen_rtx (REG, SImode, regno);
791 output_asm_insn ("push%L0 %0", xops);
792 }
793
794 if (pic_reg_used)
795 {
796 xops[0] = pic_offset_table_rtx;
797 xops[1] = (rtx) gen_label_rtx ();
798
799 output_asm_insn (AS1 (call,%P1), xops);
800 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
801 output_asm_insn (AS1 (pop%L0,%0), xops);
802 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
803 }
804 }
805
806 /* Return 1 if it is appropriate to emit `ret' instructions in the
807 body of a function. Do this only if the epilogue is simple, needing a
808 couple of insns. Prior to reloading, we can't tell how many registers
809 must be saved, so return 0 then.
810
811 If NON_SAVING_SETJMP is defined and true, then it is not possible
812 for the epilogue to be simple, so return 0. This is a special case
813 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
814 final, but jump_optimize may need to know sooner if a `return' is OK. */
815
816 int
817 simple_386_epilogue ()
818 {
819 int regno;
820 int nregs = 0;
821 int reglimit = (frame_pointer_needed
822 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
823 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
824 || current_function_uses_const_pool);
825
826 #ifdef NON_SAVING_SETJMP
827 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
828 return 0;
829 #endif
830
831 if (! reload_completed)
832 return 0;
833
834 for (regno = reglimit - 1; regno >= 0; regno--)
835 if ((regs_ever_live[regno] && ! call_used_regs[regno])
836 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
837 nregs++;
838
839 return nregs == 0 || ! frame_pointer_needed;
840 }
841
842 \f
843 /* This function generates the assembly code for function exit.
844 FILE is an stdio stream to output the code to.
845 SIZE is an int: how many units of temporary storage to deallocate. */
846
847 void
848 function_epilogue (file, size)
849 FILE *file;
850 int size;
851 {
852 register int regno;
853 register int nregs, limit;
854 int offset;
855 rtx xops[3];
856 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
857 || current_function_uses_const_pool);
858
859 /* Compute the number of registers to pop */
860
861 limit = (frame_pointer_needed
862 ? FRAME_POINTER_REGNUM
863 : STACK_POINTER_REGNUM);
864
865 nregs = 0;
866
867 for (regno = limit - 1; regno >= 0; regno--)
868 if ((regs_ever_live[regno] && ! call_used_regs[regno])
869 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
870 nregs++;
871
872 /* sp is often unreliable so we must go off the frame pointer,
873 */
874
875 /* In reality, we may not care if sp is unreliable, because we can
876 restore the register relative to the frame pointer. In theory,
877 since each move is the same speed as a pop, and we don't need the
878 leal, this is faster. For now restore multiple registers the old
879 way. */
880
881 offset = -size - (nregs * UNITS_PER_WORD);
882
883 xops[2] = stack_pointer_rtx;
884
885 if (nregs > 1 || ! frame_pointer_needed)
886 {
887 if (frame_pointer_needed)
888 {
889 xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
890 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
891 }
892
893 for (regno = 0; regno < limit; regno++)
894 if ((regs_ever_live[regno] && ! call_used_regs[regno])
895 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
896 {
897 xops[0] = gen_rtx (REG, SImode, regno);
898 output_asm_insn ("pop%L0 %0", xops);
899 }
900 }
901 else
902 for (regno = 0; regno < limit; regno++)
903 if ((regs_ever_live[regno] && ! call_used_regs[regno])
904 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
905 {
906 xops[0] = gen_rtx (REG, SImode, regno);
907 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
908 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
909 offset += 4;
910 }
911
912 if (frame_pointer_needed)
913 {
914 /* On i486, mov & pop is faster than "leave". */
915
916 if (!TARGET_386)
917 {
918 xops[0] = frame_pointer_rtx;
919 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
920 output_asm_insn ("pop%L0 %0", xops);
921 }
922 else
923 output_asm_insn ("leave", xops);
924 }
925 else if (size)
926 {
927 /* If there is no frame pointer, we must still release the frame. */
928
929 xops[0] = GEN_INT (size);
930 output_asm_insn (AS2 (add%L2,%0,%2), xops);
931 }
932
933 if (current_function_pops_args && current_function_args_size)
934 {
935 xops[1] = GEN_INT (current_function_pops_args);
936
937 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
938 asked to pop more, pop return address, do explicit add, and jump
939 indirectly to the caller. */
940
941 if (current_function_pops_args >= 32768)
942 {
943 /* ??? Which register to use here? */
944 xops[0] = gen_rtx (REG, SImode, 2);
945 output_asm_insn ("pop%L0 %0", xops);
946 output_asm_insn (AS2 (add%L2,%1,%2), xops);
947 output_asm_insn ("jmp %*%0", xops);
948 }
949 else
950 output_asm_insn ("ret %1", xops);
951 }
952 else
953 output_asm_insn ("ret", xops);
954 }
955
956 \f
957 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
958 that is a valid memory address for an instruction.
959 The MODE argument is the machine mode for the MEM expression
960 that wants to use this address.
961
962 On x86, legitimate addresses are:
963 base movl (base),reg
964 displacement movl disp,reg
965 base + displacement movl disp(base),reg
966 index + base movl (base,index),reg
967 (index + base) + displacement movl disp(base,index),reg
968 index*scale movl (,index,scale),reg
969 index*scale + disp movl disp(,index,scale),reg
970 index*scale + base movl (base,index,scale),reg
971 (index*scale + base) + disp movl disp(base,index,scale),reg
972
973 In each case, scale can be 1, 2, 4, 8. */
974
975 /* This is exactly the same as print_operand_addr, except that
976 it recognizes addresses instead of printing them.
977
978 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
979 convert common non-canonical forms to canonical form so that they will
980 be recognized. */
981
982 #define ADDR_INVALID(msg,insn) \
983 do { \
984 if (TARGET_DEBUG_ADDR) \
985 { \
986 fprintf (stderr, msg); \
987 debug_rtx (insn); \
988 } \
989 } while (0)
990
991 int
992 legitimate_address_p (mode, addr, strict)
993 enum machine_mode mode;
994 register rtx addr;
995 int strict;
996 {
997 rtx base = NULL_RTX;
998 rtx indx = NULL_RTX;
999 rtx scale = NULL_RTX;
1000 rtx disp = NULL_RTX;
1001
1002 if (TARGET_DEBUG_ADDR)
1003 {
1004 fprintf (stderr,
1005 "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
1006 GET_MODE_NAME (mode), strict);
1007
1008 debug_rtx (addr);
1009 }
1010
1011 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
1012 base = addr; /* base reg */
1013
1014 else if (GET_CODE (addr) == PLUS)
1015 {
1016 rtx op0 = XEXP (addr, 0);
1017 rtx op1 = XEXP (addr, 1);
1018 enum rtx_code code0 = GET_CODE (op0);
1019 enum rtx_code code1 = GET_CODE (op1);
1020
1021 if (code0 == REG || code0 == SUBREG)
1022 {
1023 if (code1 == REG || code1 == SUBREG)
1024 {
1025 indx = op0; /* index + base */
1026 base = op1;
1027 }
1028
1029 else
1030 {
1031 base = op0; /* base + displacement */
1032 disp = op1;
1033 }
1034 }
1035
1036 else if (code0 == MULT)
1037 {
1038 indx = XEXP (op0, 0);
1039 scale = XEXP (op0, 1);
1040
1041 if (code1 == REG || code1 == SUBREG)
1042 base = op1; /* index*scale + base */
1043
1044 else
1045 disp = op1; /* index*scale + disp */
1046 }
1047
1048 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
1049 {
1050 indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
1051 scale = XEXP (XEXP (op0, 0), 1);
1052 base = XEXP (op0, 1);
1053 disp = op1;
1054 }
1055
1056 else if (code0 == PLUS)
1057 {
1058 indx = XEXP (op0, 0); /* index + base + disp */
1059 base = XEXP (op0, 1);
1060 disp = op1;
1061 }
1062
1063 else
1064 {
1065 ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
1066 return FALSE;
1067 }
1068 }
1069
1070 else if (GET_CODE (addr) == MULT)
1071 {
1072 indx = XEXP (addr, 0); /* index*scale */
1073 scale = XEXP (addr, 1);
1074 }
1075
1076 else
1077 disp = addr; /* displacement */
1078
1079 /* Validate base register */
1080 if (base)
1081 {
1082 if (GET_CODE (base) == SUBREG)
1083 {
1084 if (GET_CODE (SUBREG_REG (base)) != REG || SUBREG_WORD (base) != 0)
1085 {
1086 ADDR_INVALID ("Base SUBREG is not of a REG.\n", base);
1087 return FALSE;
1088 }
1089
1090 base = SUBREG_REG (base);
1091 }
1092
1093 if (GET_CODE (base) != REG
1094 || ( strict && !REG_OK_FOR_BASE_STRICT_P (base))
1095 || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
1096 {
1097 ADDR_INVALID ("Base is not valid.\n", base);
1098 return FALSE;
1099 }
1100 }
1101
1102 /* Validate index register */
1103 if (indx)
1104 {
1105 if (GET_CODE (indx) == SUBREG)
1106 {
1107 if (GET_CODE (SUBREG_REG (indx)) != REG || SUBREG_WORD (indx) != 0)
1108 {
1109 ADDR_INVALID ("Index SUBREG is not of a REG.", indx);
1110 return FALSE;
1111 }
1112
1113 indx = SUBREG_REG (indx);
1114 }
1115
1116 if (GET_CODE (indx) != REG
1117 || ( strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
1118 || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
1119 {
1120 ADDR_INVALID ("Index is not valid.\n", indx);
1121 return FALSE;
1122 }
1123 }
1124 else if (scale)
1125 abort (); /* scale w/o index illegal */
1126
1127 /* Validate scale factor */
1128 if (scale)
1129 {
1130 HOST_WIDE_INT value;
1131
1132 if (GET_CODE (scale) != CONST_INT)
1133 {
1134 ADDR_INVALID ("Scale is not valid.\n", scale);
1135 return FALSE;
1136 }
1137
1138 value = INTVAL (scale);
1139 if (value != 1 && value != 2 && value != 4 && value != 8)
1140 {
1141 ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
1142 return FALSE;
1143 }
1144 }
1145
1146 /* Validate displacement */
1147 if (disp)
1148 {
1149 if (!CONSTANT_ADDRESS_P (disp))
1150 {
1151 ADDR_INVALID ("Displacement is not valid.\n", disp);
1152 return FALSE;
1153 }
1154
1155 if (GET_CODE (disp) == CONST_DOUBLE)
1156 {
1157 ADDR_INVALID ("Displacement is a const_double.\n", disp);
1158 return FALSE;
1159 }
1160
1161 if (flag_pic && SYMBOLIC_CONST (disp) && base != pic_offset_table_rtx
1162 && (indx != pic_offset_table_rtx || scale != NULL_RTX))
1163 {
1164 ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
1165 return FALSE;
1166 }
1167
1168 if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
1169 && (base != NULL_RTX || indx != NULL_RTX))
1170 {
1171 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
1172 return FALSE;
1173 }
1174 }
1175
1176 if (TARGET_DEBUG_ADDR)
1177 fprintf (stderr, "Address is valid.\n");
1178
1179 /* Everything looks valid, return true */
1180 return TRUE;
1181 }
1182
1183 \f
1184 /* Return a legitimate reference for ORIG (an address) using the
1185 register REG. If REG is 0, a new pseudo is generated.
1186
1187 There are three types of references that must be handled:
1188
1189 1. Global data references must load the address from the GOT, via
1190 the PIC reg. An insn is emitted to do this load, and the reg is
1191 returned.
1192
1193 2. Static data references must compute the address as an offset
1194 from the GOT, whose base is in the PIC reg. An insn is emitted to
1195 compute the address into a reg, and the reg is returned. Static
1196 data objects have SYMBOL_REF_FLAG set to differentiate them from
1197 global data objects.
1198
1199 3. Constant pool addresses must be handled special. They are
1200 considered legitimate addresses, but only if not used with regs.
1201 When printed, the output routines know to print the reference with the
1202 PIC reg, even though the PIC reg doesn't appear in the RTL.
1203
1204 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
1205 reg also appears in the address (except for constant pool references,
1206 noted above).
1207
1208 "switch" statements also require special handling when generating
1209 PIC code. See comments by the `casesi' insn in i386.md for details. */
1210
1211 rtx
1212 legitimize_pic_address (orig, reg)
1213 rtx orig;
1214 rtx reg;
1215 {
1216 rtx addr = orig;
1217 rtx new = orig;
1218
1219 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
1220 {
1221 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
1222 reg = new = orig;
1223 else
1224 {
1225 if (reg == 0)
1226 reg = gen_reg_rtx (Pmode);
1227
1228 if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
1229 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
1230 else
1231 new = gen_rtx (MEM, Pmode,
1232 gen_rtx (PLUS, Pmode,
1233 pic_offset_table_rtx, orig));
1234
1235 emit_move_insn (reg, new);
1236 }
1237 current_function_uses_pic_offset_table = 1;
1238 return reg;
1239 }
1240 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1241 {
1242 rtx base;
1243
1244 if (GET_CODE (addr) == CONST)
1245 {
1246 addr = XEXP (addr, 0);
1247 if (GET_CODE (addr) != PLUS)
1248 abort ();
1249 }
1250
1251 if (XEXP (addr, 0) == pic_offset_table_rtx)
1252 return orig;
1253
1254 if (reg == 0)
1255 reg = gen_reg_rtx (Pmode);
1256
1257 base = legitimize_pic_address (XEXP (addr, 0), reg);
1258 addr = legitimize_pic_address (XEXP (addr, 1),
1259 base == reg ? NULL_RTX : reg);
1260
1261 if (GET_CODE (addr) == CONST_INT)
1262 return plus_constant (base, INTVAL (addr));
1263
1264 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
1265 {
1266 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
1267 addr = XEXP (addr, 1);
1268 }
1269 return gen_rtx (PLUS, Pmode, base, addr);
1270 }
1271 return new;
1272 }
1273 \f
1274
1275 /* Emit insns to move operands[1] into operands[0]. */
1276
1277 void
1278 emit_pic_move (operands, mode)
1279 rtx *operands;
1280 enum machine_mode mode;
1281 {
1282 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
1283
1284 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
1285 operands[1] = (rtx) force_reg (SImode, operands[1]);
1286 else
1287 operands[1] = legitimize_pic_address (operands[1], temp);
1288 }
1289
1290 \f
1291 /* Try machine-dependent ways of modifying an illegitimate address
1292 to be legitimate. If we find one, return the new, valid address.
1293 This macro is used in only one place: `memory_address' in explow.c.
1294
1295 OLDX is the address as it was before break_out_memory_refs was called.
1296 In some cases it is useful to look at this to decide what needs to be done.
1297
1298 MODE and WIN are passed so that this macro can use
1299 GO_IF_LEGITIMATE_ADDRESS.
1300
1301 It is always safe for this macro to do nothing. It exists to recognize
1302 opportunities to optimize the output.
1303
1304 For the 80386, we handle X+REG by loading X into a register R and
1305 using R+REG. R will go in a general reg and indexing will be used.
1306 However, if REG is a broken-out memory address or multiplication,
1307 nothing needs to be done because REG can certainly go in a general reg.
1308
1309 When -fpic is used, special handling is needed for symbolic references.
1310 See comments by legitimize_pic_address in i386.c for details. */
1311
1312 rtx
1313 legitimize_address (x, oldx, mode)
1314 register rtx x;
1315 register rtx oldx;
1316 enum machine_mode mode;
1317 {
1318 int changed = 0;
1319 unsigned log;
1320
1321 if (TARGET_DEBUG_ADDR)
1322 {
1323 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
1324 debug_rtx (x);
1325 }
1326
1327 if (flag_pic && SYMBOLIC_CONST (x))
1328 return legitimize_pic_address (x, 0);
1329
1330 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
1331 if (GET_CODE (x) == ASHIFT
1332 && GET_CODE (XEXP (x, 1)) == CONST_INT
1333 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
1334 {
1335 changed = 1;
1336 x = gen_rtx (MULT, Pmode,
1337 force_reg (Pmode, XEXP (x, 0)),
1338 GEN_INT (1 << log));
1339 }
1340
1341 if (GET_CODE (x) == PLUS)
1342 {
1343 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
1344 if (GET_CODE (XEXP (x, 0)) == ASHIFT
1345 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1346 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
1347 {
1348 changed = 1;
1349 XEXP (x, 0) = gen_rtx (MULT, Pmode,
1350 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
1351 GEN_INT (1 << log));
1352 }
1353
1354 if (GET_CODE (XEXP (x, 1)) == ASHIFT
1355 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
1356 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
1357 {
1358 changed = 1;
1359 XEXP (x, 1) = gen_rtx (MULT, Pmode,
1360 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
1361 GEN_INT (1 << log));
1362 }
1363
1364 /* Put multiply first if it isn't already */
1365 if (GET_CODE (XEXP (x, 1)) == MULT)
1366 {
1367 rtx tmp = XEXP (x, 0);
1368 XEXP (x, 0) = XEXP (x, 1);
1369 XEXP (x, 1) = tmp;
1370 changed = 1;
1371 }
1372
1373 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
1374 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
1375 created by virtual register instantiation, register elimination, and
1376 similar optimizations. */
1377 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
1378 {
1379 changed = 1;
1380 x = gen_rtx (PLUS, Pmode,
1381 gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
1382 XEXP (XEXP (x, 1), 1));
1383 }
1384
1385 /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
1386 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
1387 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
1388 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
1389 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
1390 && CONSTANT_P (XEXP (x, 1)))
1391 {
1392 rtx constant, other;
1393
1394 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1395 {
1396 constant = XEXP (x, 1);
1397 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
1398 }
1399 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
1400 {
1401 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
1402 other = XEXP (x, 1);
1403 }
1404 else
1405 constant = 0;
1406
1407 if (constant)
1408 {
1409 changed = 1;
1410 x = gen_rtx (PLUS, Pmode,
1411 gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
1412 XEXP (XEXP (XEXP (x, 0), 1), 0)),
1413 plus_constant (other, INTVAL (constant)));
1414 }
1415 }
1416
1417 if (changed && legitimate_address_p (mode, x, FALSE))
1418 return x;
1419
1420 if (GET_CODE (XEXP (x, 0)) == MULT)
1421 {
1422 changed = 1;
1423 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
1424 }
1425
1426 if (GET_CODE (XEXP (x, 1)) == MULT)
1427 {
1428 changed = 1;
1429 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
1430 }
1431
1432 if (changed
1433 && GET_CODE (XEXP (x, 1)) == REG
1434 && GET_CODE (XEXP (x, 0)) == REG)
1435 return x;
1436
1437 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
1438 {
1439 changed = 1;
1440 x = legitimize_pic_address (x, 0);
1441 }
1442
1443 if (changed && legitimate_address_p (mode, x, FALSE))
1444 return x;
1445
1446 if (GET_CODE (XEXP (x, 0)) == REG)
1447 {
1448 register rtx temp = gen_reg_rtx (Pmode);
1449 register rtx val = force_operand (XEXP (x, 1), temp);
1450 if (val != temp)
1451 emit_move_insn (temp, val);
1452
1453 XEXP (x, 1) = temp;
1454 return x;
1455 }
1456
1457 else if (GET_CODE (XEXP (x, 1)) == REG)
1458 {
1459 register rtx temp = gen_reg_rtx (Pmode);
1460 register rtx val = force_operand (XEXP (x, 0), temp);
1461 if (val != temp)
1462 emit_move_insn (temp, val);
1463
1464 XEXP (x, 0) = temp;
1465 return x;
1466 }
1467 }
1468
1469 return x;
1470 }
1471
1472 \f
1473 /* Print an integer constant expression in assembler syntax. Addition
1474 and subtraction are the only arithmetic that may appear in these
1475 expressions. FILE is the stdio stream to write to, X is the rtx, and
1476 CODE is the operand print code from the output string. */
1477
1478 static void
1479 output_pic_addr_const (file, x, code)
1480 FILE *file;
1481 rtx x;
1482 int code;
1483 {
1484 char buf[256];
1485
1486 switch (GET_CODE (x))
1487 {
1488 case PC:
1489 if (flag_pic)
1490 putc ('.', file);
1491 else
1492 abort ();
1493 break;
1494
1495 case SYMBOL_REF:
1496 case LABEL_REF:
1497 if (GET_CODE (x) == SYMBOL_REF)
1498 assemble_name (file, XSTR (x, 0));
1499 else
1500 {
1501 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
1502 CODE_LABEL_NUMBER (XEXP (x, 0)));
1503 assemble_name (asm_out_file, buf);
1504 }
1505
1506 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
1507 fprintf (file, "@GOTOFF(%%ebx)");
1508 else if (code == 'P')
1509 fprintf (file, "@PLT");
1510 else if (GET_CODE (x) == LABEL_REF || ! SYMBOL_REF_FLAG (x))
1511 fprintf (file, "@GOT");
1512 else
1513 fprintf (file, "@GOTOFF");
1514
1515 break;
1516
1517 case CODE_LABEL:
1518 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1519 assemble_name (asm_out_file, buf);
1520 break;
1521
1522 case CONST_INT:
1523 fprintf (file, "%d", INTVAL (x));
1524 break;
1525
1526 case CONST:
1527 /* This used to output parentheses around the expression,
1528 but that does not work on the 386 (either ATT or BSD assembler). */
1529 output_pic_addr_const (file, XEXP (x, 0), code);
1530 break;
1531
1532 case CONST_DOUBLE:
1533 if (GET_MODE (x) == VOIDmode)
1534 {
1535 /* We can use %d if the number is <32 bits and positive. */
1536 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
1537 fprintf (file, "0x%x%08x",
1538 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
1539 else
1540 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
1541 }
1542 else
1543 /* We can't handle floating point constants;
1544 PRINT_OPERAND must handle them. */
1545 output_operand_lossage ("floating constant misused");
1546 break;
1547
1548 case PLUS:
1549 /* Some assemblers need integer constants to appear last (eg masm). */
1550 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1551 {
1552 output_pic_addr_const (file, XEXP (x, 1), code);
1553 if (INTVAL (XEXP (x, 0)) >= 0)
1554 fprintf (file, "+");
1555 output_pic_addr_const (file, XEXP (x, 0), code);
1556 }
1557 else
1558 {
1559 output_pic_addr_const (file, XEXP (x, 0), code);
1560 if (INTVAL (XEXP (x, 1)) >= 0)
1561 fprintf (file, "+");
1562 output_pic_addr_const (file, XEXP (x, 1), code);
1563 }
1564 break;
1565
1566 case MINUS:
1567 output_pic_addr_const (file, XEXP (x, 0), code);
1568 fprintf (file, "-");
1569 output_pic_addr_const (file, XEXP (x, 1), code);
1570 break;
1571
1572 default:
1573 output_operand_lossage ("invalid expression as operand");
1574 }
1575 }
1576 \f
1577 /* Meaning of CODE:
1578 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
1579 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
1580 R -- print the prefix for register names.
1581 z -- print the opcode suffix for the size of the current operand.
1582 * -- print a star (in certain assembler syntax)
1583 w -- print the operand as if it's a "word" (HImode) even if it isn't.
1584 c -- don't print special prefixes before constant operands.
1585 */
1586
1587 void
1588 print_operand (file, x, code)
1589 FILE *file;
1590 rtx x;
1591 int code;
1592 {
1593 if (code)
1594 {
1595 switch (code)
1596 {
1597 case '*':
1598 if (USE_STAR)
1599 putc ('*', file);
1600 return;
1601
1602 case 'L':
1603 PUT_OP_SIZE (code, 'l', file);
1604 return;
1605
1606 case 'W':
1607 PUT_OP_SIZE (code, 'w', file);
1608 return;
1609
1610 case 'B':
1611 PUT_OP_SIZE (code, 'b', file);
1612 return;
1613
1614 case 'Q':
1615 PUT_OP_SIZE (code, 'l', file);
1616 return;
1617
1618 case 'S':
1619 PUT_OP_SIZE (code, 's', file);
1620 return;
1621
1622 case 'T':
1623 PUT_OP_SIZE (code, 't', file);
1624 return;
1625
1626 case 'z':
1627 /* 387 opcodes don't get size suffixes if the operands are
1628 registers. */
1629
1630 if (STACK_REG_P (x))
1631 return;
1632
1633 /* this is the size of op from size of operand */
1634 switch (GET_MODE_SIZE (GET_MODE (x)))
1635 {
1636 case 1:
1637 PUT_OP_SIZE ('B', 'b', file);
1638 return;
1639
1640 case 2:
1641 PUT_OP_SIZE ('W', 'w', file);
1642 return;
1643
1644 case 4:
1645 if (GET_MODE (x) == SFmode)
1646 {
1647 PUT_OP_SIZE ('S', 's', file);
1648 return;
1649 }
1650 else
1651 PUT_OP_SIZE ('L', 'l', file);
1652 return;
1653
1654 case 12:
1655 PUT_OP_SIZE ('T', 't', file);
1656 return;
1657
1658 case 8:
1659 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
1660 {
1661 #ifdef GAS_MNEMONICS
1662 PUT_OP_SIZE ('Q', 'q', file);
1663 return;
1664 #else
1665 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
1666 #endif
1667 }
1668
1669 PUT_OP_SIZE ('Q', 'l', file);
1670 return;
1671 }
1672
1673 case 'b':
1674 case 'w':
1675 case 'k':
1676 case 'h':
1677 case 'y':
1678 case 'P':
1679 break;
1680
1681 default:
1682 {
1683 char str[50];
1684
1685 sprintf (str, "invalid operand code `%c'", code);
1686 output_operand_lossage (str);
1687 }
1688 }
1689 }
1690 if (GET_CODE (x) == REG)
1691 {
1692 PRINT_REG (x, code, file);
1693 }
1694 else if (GET_CODE (x) == MEM)
1695 {
1696 PRINT_PTR (x, file);
1697 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
1698 {
1699 if (flag_pic)
1700 output_pic_addr_const (file, XEXP (x, 0), code);
1701 else
1702 output_addr_const (file, XEXP (x, 0));
1703 }
1704 else
1705 output_address (XEXP (x, 0));
1706 }
1707 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
1708 {
1709 REAL_VALUE_TYPE r; long l;
1710 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1711 REAL_VALUE_TO_TARGET_SINGLE (r, l);
1712 PRINT_IMMED_PREFIX (file);
1713 fprintf (file, "0x%x", l);
1714 }
1715 /* These float cases don't actually occur as immediate operands. */
1716 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
1717 {
1718 REAL_VALUE_TYPE r; char dstr[30];
1719 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1720 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
1721 fprintf (file, "%s", dstr);
1722 }
1723 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
1724 {
1725 REAL_VALUE_TYPE r; char dstr[30];
1726 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1727 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
1728 fprintf (file, "%s", dstr);
1729 }
1730 else
1731 {
1732 if (code != 'P')
1733 {
1734 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
1735 PRINT_IMMED_PREFIX (file);
1736 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
1737 || GET_CODE (x) == LABEL_REF)
1738 PRINT_OFFSET_PREFIX (file);
1739 }
1740 if (flag_pic)
1741 output_pic_addr_const (file, x, code);
1742 else
1743 output_addr_const (file, x);
1744 }
1745 }
1746 \f
1747 /* Print a memory operand whose address is ADDR. */
1748
1749 void
1750 print_operand_address (file, addr)
1751 FILE *file;
1752 register rtx addr;
1753 {
1754 register rtx reg1, reg2, breg, ireg;
1755 rtx offset;
1756
1757 switch (GET_CODE (addr))
1758 {
1759 case REG:
1760 ADDR_BEG (file);
1761 fprintf (file, "%se", RP);
1762 fputs (hi_reg_name[REGNO (addr)], file);
1763 ADDR_END (file);
1764 break;
1765
1766 case PLUS:
1767 reg1 = 0;
1768 reg2 = 0;
1769 ireg = 0;
1770 breg = 0;
1771 offset = 0;
1772 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
1773 {
1774 offset = XEXP (addr, 0);
1775 addr = XEXP (addr, 1);
1776 }
1777 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
1778 {
1779 offset = XEXP (addr, 1);
1780 addr = XEXP (addr, 0);
1781 }
1782 if (GET_CODE (addr) != PLUS) ;
1783 else if (GET_CODE (XEXP (addr, 0)) == MULT)
1784 {
1785 reg1 = XEXP (addr, 0);
1786 addr = XEXP (addr, 1);
1787 }
1788 else if (GET_CODE (XEXP (addr, 1)) == MULT)
1789 {
1790 reg1 = XEXP (addr, 1);
1791 addr = XEXP (addr, 0);
1792 }
1793 else if (GET_CODE (XEXP (addr, 0)) == REG)
1794 {
1795 reg1 = XEXP (addr, 0);
1796 addr = XEXP (addr, 1);
1797 }
1798 else if (GET_CODE (XEXP (addr, 1)) == REG)
1799 {
1800 reg1 = XEXP (addr, 1);
1801 addr = XEXP (addr, 0);
1802 }
1803 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
1804 {
1805 if (reg1 == 0) reg1 = addr;
1806 else reg2 = addr;
1807 addr = 0;
1808 }
1809 if (offset != 0)
1810 {
1811 if (addr != 0) abort ();
1812 addr = offset;
1813 }
1814 if ((reg1 && GET_CODE (reg1) == MULT)
1815 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
1816 {
1817 breg = reg2;
1818 ireg = reg1;
1819 }
1820 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
1821 {
1822 breg = reg1;
1823 ireg = reg2;
1824 }
1825
1826 if (ireg != 0 || breg != 0)
1827 {
1828 int scale = 1;
1829
1830 if (addr != 0)
1831 {
1832 if (GET_CODE (addr) == LABEL_REF)
1833 output_asm_label (addr);
1834 else
1835 {
1836 if (flag_pic)
1837 output_pic_addr_const (file, addr, 0);
1838 else
1839 output_addr_const (file, addr);
1840 }
1841 }
1842
1843 if (ireg != 0 && GET_CODE (ireg) == MULT)
1844 {
1845 scale = INTVAL (XEXP (ireg, 1));
1846 ireg = XEXP (ireg, 0);
1847 }
1848
1849 /* The stack pointer can only appear as a base register,
1850 never an index register, so exchange the regs if it is wrong. */
1851
1852 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
1853 {
1854 rtx tmp;
1855
1856 tmp = breg;
1857 breg = ireg;
1858 ireg = tmp;
1859 }
1860
1861 /* output breg+ireg*scale */
1862 PRINT_B_I_S (breg, ireg, scale, file);
1863 break;
1864 }
1865
1866 case MULT:
1867 {
1868 int scale;
1869 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
1870 {
1871 scale = INTVAL (XEXP (addr, 0));
1872 ireg = XEXP (addr, 1);
1873 }
1874 else
1875 {
1876 scale = INTVAL (XEXP (addr, 1));
1877 ireg = XEXP (addr, 0);
1878 }
1879 output_addr_const (file, const0_rtx);
1880 PRINT_B_I_S ((rtx) 0, ireg, scale, file);
1881 }
1882 break;
1883
1884 default:
1885 if (GET_CODE (addr) == CONST_INT
1886 && INTVAL (addr) < 0x8000
1887 && INTVAL (addr) >= -0x8000)
1888 fprintf (file, "%d", INTVAL (addr));
1889 else
1890 {
1891 if (flag_pic)
1892 output_pic_addr_const (file, addr, 0);
1893 else
1894 output_addr_const (file, addr);
1895 }
1896 }
1897 }
1898 \f
1899 /* Set the cc_status for the results of an insn whose pattern is EXP.
1900 On the 80386, we assume that only test and compare insns, as well
1901 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
1902 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
1903 Also, we assume that jumps, moves and sCOND don't affect the condition
1904 codes. All else clobbers the condition codes, by assumption.
1905
1906 We assume that ALL integer add, minus, etc. instructions effect the
1907 condition codes. This MUST be consistent with i386.md.
1908
1909 We don't record any float test or compare - the redundant test &
1910 compare check in final.c does not handle stack-like regs correctly. */
1911
1912 void
1913 notice_update_cc (exp)
1914 rtx exp;
1915 {
1916 if (GET_CODE (exp) == SET)
1917 {
1918 /* Jumps do not alter the cc's. */
1919 if (SET_DEST (exp) == pc_rtx)
1920 return;
1921 /* Moving register or memory into a register:
1922 it doesn't alter the cc's, but it might invalidate
1923 the RTX's which we remember the cc's came from.
1924 (Note that moving a constant 0 or 1 MAY set the cc's). */
1925 if (REG_P (SET_DEST (exp))
1926 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
1927 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
1928 {
1929 if (cc_status.value1
1930 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1931 cc_status.value1 = 0;
1932 if (cc_status.value2
1933 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1934 cc_status.value2 = 0;
1935 return;
1936 }
1937 /* Moving register into memory doesn't alter the cc's.
1938 It may invalidate the RTX's which we remember the cc's came from. */
1939 if (GET_CODE (SET_DEST (exp)) == MEM
1940 && (REG_P (SET_SRC (exp))
1941 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
1942 {
1943 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1944 cc_status.value1 = 0;
1945 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1946 cc_status.value2 = 0;
1947 return;
1948 }
1949 /* Function calls clobber the cc's. */
1950 else if (GET_CODE (SET_SRC (exp)) == CALL)
1951 {
1952 CC_STATUS_INIT;
1953 return;
1954 }
1955 /* Tests and compares set the cc's in predictable ways. */
1956 else if (SET_DEST (exp) == cc0_rtx)
1957 {
1958 CC_STATUS_INIT;
1959 cc_status.value1 = SET_SRC (exp);
1960 return;
1961 }
1962 /* Certain instructions effect the condition codes. */
1963 else if (GET_MODE (SET_SRC (exp)) == SImode
1964 || GET_MODE (SET_SRC (exp)) == HImode
1965 || GET_MODE (SET_SRC (exp)) == QImode)
1966 switch (GET_CODE (SET_SRC (exp)))
1967 {
1968 case ASHIFTRT: case LSHIFTRT:
1969 case ASHIFT:
1970 /* Shifts on the 386 don't set the condition codes if the
1971 shift count is zero. */
1972 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
1973 {
1974 CC_STATUS_INIT;
1975 break;
1976 }
1977 /* We assume that the CONST_INT is non-zero (this rtx would
1978 have been deleted if it were zero. */
1979
1980 case PLUS: case MINUS: case NEG:
1981 case AND: case IOR: case XOR:
1982 cc_status.flags = CC_NO_OVERFLOW;
1983 cc_status.value1 = SET_SRC (exp);
1984 cc_status.value2 = SET_DEST (exp);
1985 break;
1986
1987 default:
1988 CC_STATUS_INIT;
1989 }
1990 else
1991 {
1992 CC_STATUS_INIT;
1993 }
1994 }
1995 else if (GET_CODE (exp) == PARALLEL
1996 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1997 {
1998 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1999 return;
2000 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
2001 {
2002 CC_STATUS_INIT;
2003 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
2004 cc_status.flags |= CC_IN_80387;
2005 else
2006 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2007 return;
2008 }
2009 CC_STATUS_INIT;
2010 }
2011 else
2012 {
2013 CC_STATUS_INIT;
2014 }
2015 }
2016 \f
2017 /* Split one or more DImode RTL references into pairs of SImode
2018 references. The RTL can be REG, offsettable MEM, integer constant, or
2019 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
2020 split and "num" is its length. lo_half and hi_half are output arrays
2021 that parallel "operands". */
2022
2023 void
2024 split_di (operands, num, lo_half, hi_half)
2025 rtx operands[];
2026 int num;
2027 rtx lo_half[], hi_half[];
2028 {
2029 while (num--)
2030 {
2031 if (GET_CODE (operands[num]) == REG)
2032 {
2033 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
2034 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
2035 }
2036 else if (CONSTANT_P (operands[num]))
2037 {
2038 split_double (operands[num], &lo_half[num], &hi_half[num]);
2039 }
2040 else if (offsettable_memref_p (operands[num]))
2041 {
2042 lo_half[num] = operands[num];
2043 hi_half[num] = adj_offsettable_operand (operands[num], 4);
2044 }
2045 else
2046 abort();
2047 }
2048 }
2049 \f
2050 /* Return 1 if this is a valid binary operation on a 387.
2051 OP is the expression matched, and MODE is its mode. */
2052
2053 int
2054 binary_387_op (op, mode)
2055 register rtx op;
2056 enum machine_mode mode;
2057 {
2058 if (mode != VOIDmode && mode != GET_MODE (op))
2059 return 0;
2060
2061 switch (GET_CODE (op))
2062 {
2063 case PLUS:
2064 case MINUS:
2065 case MULT:
2066 case DIV:
2067 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
2068
2069 default:
2070 return 0;
2071 }
2072 }
2073
2074 \f
2075 /* Return 1 if this is a valid shift or rotate operation on a 386.
2076 OP is the expression matched, and MODE is its mode. */
2077
2078 int
2079 shift_op (op, mode)
2080 register rtx op;
2081 enum machine_mode mode;
2082 {
2083 rtx operand = XEXP (op, 0);
2084
2085 if (mode != VOIDmode && mode != GET_MODE (op))
2086 return 0;
2087
2088 if (GET_MODE (operand) != GET_MODE (op)
2089 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
2090 return 0;
2091
2092 return (GET_CODE (op) == ASHIFT
2093 || GET_CODE (op) == ASHIFTRT
2094 || GET_CODE (op) == LSHIFTRT
2095 || GET_CODE (op) == ROTATE
2096 || GET_CODE (op) == ROTATERT);
2097 }
2098
2099 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
2100 MODE is not used. */
2101
2102 int
2103 VOIDmode_compare_op (op, mode)
2104 register rtx op;
2105 enum machine_mode mode;
2106 {
2107 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
2108 }
2109 \f
2110 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
2111 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
2112 is the expression of the binary operation. The output may either be
2113 emitted here, or returned to the caller, like all output_* functions.
2114
2115 There is no guarantee that the operands are the same mode, as they
2116 might be within FLOAT or FLOAT_EXTEND expressions. */
2117
2118 char *
2119 output_387_binary_op (insn, operands)
2120 rtx insn;
2121 rtx *operands;
2122 {
2123 rtx temp;
2124 char *base_op;
2125 static char buf[100];
2126
2127 switch (GET_CODE (operands[3]))
2128 {
2129 case PLUS:
2130 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2131 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2132 base_op = "fiadd";
2133 else
2134 base_op = "fadd";
2135 break;
2136
2137 case MINUS:
2138 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2139 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2140 base_op = "fisub";
2141 else
2142 base_op = "fsub";
2143 break;
2144
2145 case MULT:
2146 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2147 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2148 base_op = "fimul";
2149 else
2150 base_op = "fmul";
2151 break;
2152
2153 case DIV:
2154 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2155 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2156 base_op = "fidiv";
2157 else
2158 base_op = "fdiv";
2159 break;
2160
2161 default:
2162 abort ();
2163 }
2164
2165 strcpy (buf, base_op);
2166
2167 switch (GET_CODE (operands[3]))
2168 {
2169 case MULT:
2170 case PLUS:
2171 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2172 {
2173 temp = operands[2];
2174 operands[2] = operands[1];
2175 operands[1] = temp;
2176 }
2177
2178 if (GET_CODE (operands[2]) == MEM)
2179 return strcat (buf, AS1 (%z2,%2));
2180
2181 if (NON_STACK_REG_P (operands[1]))
2182 {
2183 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
2184 RET;
2185 }
2186 else if (NON_STACK_REG_P (operands[2]))
2187 {
2188 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
2189 RET;
2190 }
2191
2192 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
2193 return strcat (buf, AS2 (p,%2,%0));
2194
2195 if (STACK_TOP_P (operands[0]))
2196 return strcat (buf, AS2 (,%y2,%0));
2197 else
2198 return strcat (buf, AS2 (,%2,%0));
2199
2200 case MINUS:
2201 case DIV:
2202 if (GET_CODE (operands[1]) == MEM)
2203 return strcat (buf, AS1 (r%z1,%1));
2204
2205 if (GET_CODE (operands[2]) == MEM)
2206 return strcat (buf, AS1 (%z2,%2));
2207
2208 if (NON_STACK_REG_P (operands[1]))
2209 {
2210 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
2211 RET;
2212 }
2213 else if (NON_STACK_REG_P (operands[2]))
2214 {
2215 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
2216 RET;
2217 }
2218
2219 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
2220 abort ();
2221
2222 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
2223 return strcat (buf, AS2 (rp,%2,%0));
2224
2225 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2226 return strcat (buf, AS2 (p,%1,%0));
2227
2228 if (STACK_TOP_P (operands[0]))
2229 {
2230 if (STACK_TOP_P (operands[1]))
2231 return strcat (buf, AS2 (,%y2,%0));
2232 else
2233 return strcat (buf, AS2 (r,%y1,%0));
2234 }
2235 else if (STACK_TOP_P (operands[1]))
2236 return strcat (buf, AS2 (,%1,%0));
2237 else
2238 return strcat (buf, AS2 (r,%2,%0));
2239
2240 default:
2241 abort ();
2242 }
2243 }
2244 \f
2245 /* Output code for INSN to convert a float to a signed int. OPERANDS
2246 are the insn operands. The output may be SFmode or DFmode and the
2247 input operand may be SImode or DImode. As a special case, make sure
2248 that the 387 stack top dies if the output mode is DImode, because the
2249 hardware requires this. */
2250
2251 char *
2252 output_fix_trunc (insn, operands)
2253 rtx insn;
2254 rtx *operands;
2255 {
2256 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2257 rtx xops[2];
2258
2259 if (! STACK_TOP_P (operands[1]) ||
2260 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
2261 abort ();
2262
2263 xops[0] = GEN_INT (12);
2264 xops[1] = operands[4];
2265
2266 output_asm_insn (AS1 (fnstc%W2,%2), operands);
2267 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
2268 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
2269 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
2270 output_asm_insn (AS1 (fldc%W3,%3), operands);
2271
2272 if (NON_STACK_REG_P (operands[0]))
2273 output_to_reg (operands[0], stack_top_dies);
2274 else if (GET_CODE (operands[0]) == MEM)
2275 {
2276 if (stack_top_dies)
2277 output_asm_insn (AS1 (fistp%z0,%0), operands);
2278 else
2279 output_asm_insn (AS1 (fist%z0,%0), operands);
2280 }
2281 else
2282 abort ();
2283
2284 return AS1 (fldc%W2,%2);
2285 }
2286 \f
2287 /* Output code for INSN to compare OPERANDS. The two operands might
2288 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
2289 expression. If the compare is in mode CCFPEQmode, use an opcode that
2290 will not fault if a qNaN is present. */
2291
2292 char *
2293 output_float_compare (insn, operands)
2294 rtx insn;
2295 rtx *operands;
2296 {
2297 int stack_top_dies;
2298 rtx body = XVECEXP (PATTERN (insn), 0, 0);
2299 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
2300
2301 if (! STACK_TOP_P (operands[0]))
2302 abort ();
2303
2304 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2305
2306 if (STACK_REG_P (operands[1])
2307 && stack_top_dies
2308 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
2309 && REGNO (operands[1]) != FIRST_STACK_REG)
2310 {
2311 /* If both the top of the 387 stack dies, and the other operand
2312 is also a stack register that dies, then this must be a
2313 `fcompp' float compare */
2314
2315 if (unordered_compare)
2316 output_asm_insn ("fucompp", operands);
2317 else
2318 output_asm_insn ("fcompp", operands);
2319 }
2320 else
2321 {
2322 static char buf[100];
2323
2324 /* Decide if this is the integer or float compare opcode, or the
2325 unordered float compare. */
2326
2327 if (unordered_compare)
2328 strcpy (buf, "fucom");
2329 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
2330 strcpy (buf, "fcom");
2331 else
2332 strcpy (buf, "ficom");
2333
2334 /* Modify the opcode if the 387 stack is to be popped. */
2335
2336 if (stack_top_dies)
2337 strcat (buf, "p");
2338
2339 if (NON_STACK_REG_P (operands[1]))
2340 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
2341 else
2342 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
2343 }
2344
2345 /* Now retrieve the condition code. */
2346
2347 return output_fp_cc0_set (insn);
2348 }
2349 \f
2350 /* Output opcodes to transfer the results of FP compare or test INSN
2351 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
2352 result of the compare or test is unordered, no comparison operator
2353 succeeds except NE. Return an output template, if any. */
2354
2355 char *
2356 output_fp_cc0_set (insn)
2357 rtx insn;
2358 {
2359 rtx xops[3];
2360 rtx unordered_label;
2361 rtx next;
2362 enum rtx_code code;
2363
2364 xops[0] = gen_rtx (REG, HImode, 0);
2365 output_asm_insn (AS1 (fnsts%W0,%0), xops);
2366
2367 if (! TARGET_IEEE_FP)
2368 return "sahf";
2369
2370 next = next_cc0_user (insn);
2371 if (next == NULL_RTX)
2372 abort ();
2373
2374 if (GET_CODE (next) == JUMP_INSN
2375 && GET_CODE (PATTERN (next)) == SET
2376 && SET_DEST (PATTERN (next)) == pc_rtx
2377 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
2378 {
2379 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
2380 }
2381 else if (GET_CODE (PATTERN (next)) == SET)
2382 {
2383 code = GET_CODE (SET_SRC (PATTERN (next)));
2384 }
2385 else
2386 abort ();
2387
2388 xops[0] = gen_rtx (REG, QImode, 0);
2389
2390 switch (code)
2391 {
2392 case GT:
2393 xops[1] = GEN_INT (0x45);
2394 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2395 /* je label */
2396 break;
2397
2398 case LT:
2399 xops[1] = GEN_INT (0x45);
2400 xops[2] = GEN_INT (0x01);
2401 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2402 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
2403 /* je label */
2404 break;
2405
2406 case GE:
2407 xops[1] = GEN_INT (0x05);
2408 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2409 /* je label */
2410 break;
2411
2412 case LE:
2413 xops[1] = GEN_INT (0x45);
2414 xops[2] = GEN_INT (0x40);
2415 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2416 output_asm_insn (AS1 (dec%B0,%h0), xops);
2417 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
2418 /* jb label */
2419 break;
2420
2421 case EQ:
2422 xops[1] = GEN_INT (0x45);
2423 xops[2] = GEN_INT (0x40);
2424 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2425 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
2426 /* je label */
2427 break;
2428
2429 case NE:
2430 xops[1] = GEN_INT (0x44);
2431 xops[2] = GEN_INT (0x40);
2432 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
2433 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
2434 /* jne label */
2435 break;
2436
2437 case GTU:
2438 case LTU:
2439 case GEU:
2440 case LEU:
2441 default:
2442 abort ();
2443 }
2444 RET;
2445 }
2446 \f
2447 #define MAX_386_STACK_LOCALS 2
2448
2449 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
2450
2451 /* Define the structure for the machine field in struct function. */
2452 struct machine_function
2453 {
2454 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
2455 };
2456
2457 /* Functions to save and restore i386_stack_locals.
2458 These will be called, via pointer variables,
2459 from push_function_context and pop_function_context. */
2460
2461 void
2462 save_386_machine_status (p)
2463 struct function *p;
2464 {
2465 p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
2466 bcopy (i386_stack_locals, p->machine->i386_stack_locals,
2467 sizeof i386_stack_locals);
2468 }
2469
2470 void
2471 restore_386_machine_status (p)
2472 struct function *p;
2473 {
2474 bcopy (p->machine->i386_stack_locals, i386_stack_locals,
2475 sizeof i386_stack_locals);
2476 free (p->machine);
2477 }
2478
2479 /* Clear stack slot assignments remembered from previous functions.
2480 This is called from INIT_EXPANDERS once before RTL is emitted for each
2481 function. */
2482
2483 void
2484 clear_386_stack_locals ()
2485 {
2486 enum machine_mode mode;
2487 int n;
2488
2489 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
2490 mode = (enum machine_mode) ((int) mode + 1))
2491 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
2492 i386_stack_locals[(int) mode][n] = NULL_RTX;
2493
2494 /* Arrange to save and restore i386_stack_locals around nested functions. */
2495 save_machine_status = save_386_machine_status;
2496 restore_machine_status = restore_386_machine_status;
2497 }
2498
2499 /* Return a MEM corresponding to a stack slot with mode MODE.
2500 Allocate a new slot if necessary.
2501
2502 The RTL for a function can have several slots available: N is
2503 which slot to use. */
2504
2505 rtx
2506 assign_386_stack_local (mode, n)
2507 enum machine_mode mode;
2508 int n;
2509 {
2510 if (n < 0 || n >= MAX_386_STACK_LOCALS)
2511 abort ();
2512
2513 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
2514 i386_stack_locals[(int) mode][n]
2515 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
2516
2517 return i386_stack_locals[(int) mode][n];
2518 }
This page took 0.155371 seconds and 6 git commands to generate.