]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.c
(INITIAL_ELIMINATION_OFFSET): Subtract
[gcc.git] / gcc / config / i386 / i386.c
CommitLineData
2a2ab3f9 1/* Subroutines for insn-output.c for Intel 80386.
d3414ccb 2 Copyright (C) 1988, 1992 Free Software Foundation, Inc.
2a2ab3f9
JVA
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include <stdio.h>
21#include "config.h"
22#include "rtl.h"
23#include "regs.h"
24#include "hard-reg-set.h"
25#include "real.h"
26#include "insn-config.h"
27#include "conditions.h"
28#include "insn-flags.h"
29#include "output.h"
30#include "insn-attr.h"
31#include "tree.h"
32#include "flags.h"
33
997de79c
JVA
34#ifdef EXTRA_CONSTRAINT
35/* If EXTRA_CONSTRAINT is defined, then the 'S'
36 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
37 asm statements that need 'S' for class SIREG will break. */
ad5a6adc
RS
38 error EXTRA_CONSTRAINT conflicts with S constraint letter
39/* The previous line used to be #error, but some compilers barf
40 even if the conditional was untrue. */
997de79c
JVA
41#endif
42
2a2ab3f9
JVA
43#define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
44
45extern FILE *asm_out_file;
46extern char *strcat ();
47
48char *singlemove_string ();
49char *output_move_const_single ();
c572e5ba 50char *output_fp_cc0_set ();
2a2ab3f9 51
35b63115
RS
52char *hi_reg_name[] = HI_REGISTER_NAMES;
53char *qi_reg_name[] = QI_REGISTER_NAMES;
54char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
4c0d89b5
RS
55
56/* Array of the smallest class containing reg number REGNO, indexed by
57 REGNO. Used by REGNO_REG_CLASS in i386.h. */
58
59enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
60{
61 /* ax, dx, cx, bx */
ab408a86 62 AREG, DREG, CREG, BREG,
4c0d89b5
RS
63 /* si, di, bp, sp */
64 SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
65 /* FP registers */
66 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
67 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
68 /* arg pointer */
69 INDEX_REGS
70};
c572e5ba
JVA
71
72/* Test and compare insns in i386.md store the information needed to
73 generate branch and scc insns here. */
74
75struct rtx_def *i386_compare_op0, *i386_compare_op1;
76struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
2a2ab3f9
JVA
77\f
78/* Output an insn whose source is a 386 integer register. SRC is the
79 rtx for the register, and TEMPLATE is the op-code template. SRC may
80 be either SImode or DImode.
81
82 The template will be output with operands[0] as SRC, and operands[1]
83 as a pointer to the top of the 386 stack. So a call from floatsidf2
84 would look like this:
85
86 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
87
88 where %z0 corresponds to the caller's operands[1], and is used to
89 emit the proper size suffix.
90
91 ??? Extend this to handle HImode - a 387 can load and store HImode
92 values directly. */
93
94void
95output_op_from_reg (src, template)
96 rtx src;
97 char *template;
98{
99 rtx xops[4];
100
101 xops[0] = src;
102 xops[1] = AT_SP (Pmode);
435defd1 103 xops[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (src)));
2a2ab3f9
JVA
104 xops[3] = stack_pointer_rtx;
105
106 if (GET_MODE_SIZE (GET_MODE (src)) > UNITS_PER_WORD)
107 {
108 rtx high = gen_rtx (REG, SImode, REGNO (src) + 1);
109 output_asm_insn (AS1 (push%L0,%0), &high);
110 }
111 output_asm_insn (AS1 (push%L0,%0), &src);
112
113 output_asm_insn (template, xops);
114
115 output_asm_insn (AS2 (add%L3,%2,%3), xops);
116}
117\f
118/* Output an insn to pop an value from the 387 top-of-stack to 386
119 register DEST. The 387 register stack is popped if DIES is true. If
120 the mode of DEST is an integer mode, a `fist' integer store is done,
121 otherwise a `fst' float store is done. */
122
123void
124output_to_reg (dest, dies)
125 rtx dest;
126 int dies;
127{
128 rtx xops[4];
129
130 xops[0] = AT_SP (Pmode);
131 xops[1] = stack_pointer_rtx;
435defd1 132 xops[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (dest)));
2a2ab3f9
JVA
133 xops[3] = dest;
134
135 output_asm_insn (AS2 (sub%L1,%2,%1), xops);
136
137 if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
138 {
139 if (dies)
140 output_asm_insn (AS1 (fistp%z3,%y0), xops);
141 else
142 output_asm_insn (AS1 (fist%z3,%y0), xops);
143 }
144 else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
145 {
146 if (dies)
147 output_asm_insn (AS1 (fstp%z3,%y0), xops);
148 else
149 output_asm_insn (AS1 (fst%z3,%y0), xops);
150 }
151 else
152 abort ();
153
154 output_asm_insn (AS1 (pop%L0,%0), &dest);
155
156 if (GET_MODE_SIZE (GET_MODE (dest)) > UNITS_PER_WORD)
157 {
158 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
159 output_asm_insn (AS1 (pop%L0,%0), &dest);
160 }
161}
162\f
163char *
164singlemove_string (operands)
165 rtx *operands;
166{
167 rtx x;
168 if (GET_CODE (operands[0]) == MEM
169 && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
170 {
171 if (XEXP (x, 0) != stack_pointer_rtx)
172 abort ();
173 return "push%L1 %1";
174 }
175 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
176 {
177 return output_move_const_single (operands);
178 }
179 else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
180 return AS2 (mov%L0,%1,%0);
181 else if (CONSTANT_P (operands[1]))
182 return AS2 (mov%L0,%1,%0);
183 else
184 {
185 output_asm_insn ("push%L1 %1", operands);
186 return "pop%L0 %0";
187 }
188}
189\f
190/* Return a REG that occurs in ADDR with coefficient 1.
191 ADDR can be effectively incremented by incrementing REG. */
192
193static rtx
194find_addr_reg (addr)
195 rtx addr;
196{
197 while (GET_CODE (addr) == PLUS)
198 {
199 if (GET_CODE (XEXP (addr, 0)) == REG)
200 addr = XEXP (addr, 0);
201 else if (GET_CODE (XEXP (addr, 1)) == REG)
202 addr = XEXP (addr, 1);
203 else if (CONSTANT_P (XEXP (addr, 0)))
204 addr = XEXP (addr, 1);
205 else if (CONSTANT_P (XEXP (addr, 1)))
206 addr = XEXP (addr, 0);
207 else
208 abort ();
209 }
210 if (GET_CODE (addr) == REG)
211 return addr;
212 abort ();
213}
214
215/* Output an insn to add the constant N to the register X. */
216
217static void
218asm_add (n, x)
219 int n;
220 rtx x;
221{
222 rtx xops[2];
223 xops[1] = x;
224 if (n < 0)
225 {
435defd1 226 xops[0] = GEN_INT (-n);
2a2ab3f9
JVA
227 output_asm_insn (AS2 (sub%L0,%0,%1), xops);
228 }
229 else if (n > 0)
230 {
435defd1 231 xops[0] = GEN_INT (n);
2a2ab3f9
JVA
232 output_asm_insn (AS2 (add%L0,%0,%1), xops);
233 }
234}
235
236/* Output assembler code to perform a doubleword move insn
237 with operands OPERANDS. */
238
239char *
240output_move_double (operands)
241 rtx *operands;
242{
243 enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
244 rtx latehalf[2];
245 rtx addreg0 = 0, addreg1 = 0;
85ddb399 246 int dest_overlapped_low = 0;
2a2ab3f9
JVA
247
248 /* First classify both operands. */
249
250 if (REG_P (operands[0]))
251 optype0 = REGOP;
252 else if (offsettable_memref_p (operands[0]))
253 optype0 = OFFSOP;
254 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
255 optype0 = POPOP;
256 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
257 optype0 = PUSHOP;
258 else if (GET_CODE (operands[0]) == MEM)
259 optype0 = MEMOP;
260 else
261 optype0 = RNDOP;
262
263 if (REG_P (operands[1]))
264 optype1 = REGOP;
265 else if (CONSTANT_P (operands[1]))
266 optype1 = CNSTOP;
267 else if (offsettable_memref_p (operands[1]))
268 optype1 = OFFSOP;
269 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
270 optype1 = POPOP;
271 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
272 optype1 = PUSHOP;
273 else if (GET_CODE (operands[1]) == MEM)
274 optype1 = MEMOP;
275 else
276 optype1 = RNDOP;
277
278 /* Check for the cases that the operand constraints are not
279 supposed to allow to happen. Abort if we get one,
280 because generating code for these cases is painful. */
281
282 if (optype0 == RNDOP || optype1 == RNDOP)
283 abort ();
284
285 /* If one operand is decrementing and one is incrementing
286 decrement the former register explicitly
287 and change that operand into ordinary indexing. */
288
289 if (optype0 == PUSHOP && optype1 == POPOP)
290 {
291 operands[0] = XEXP (XEXP (operands[0], 0), 0);
292 asm_add (-8, operands[0]);
293 operands[0] = gen_rtx (MEM, DImode, operands[0]);
294 optype0 = OFFSOP;
295 }
296 if (optype0 == POPOP && optype1 == PUSHOP)
297 {
298 operands[1] = XEXP (XEXP (operands[1], 0), 0);
299 asm_add (-8, operands[1]);
300 operands[1] = gen_rtx (MEM, DImode, operands[1]);
301 optype1 = OFFSOP;
302 }
303
304 /* If an operand is an unoffsettable memory ref, find a register
305 we can increment temporarily to make it refer to the second word. */
306
307 if (optype0 == MEMOP)
308 addreg0 = find_addr_reg (XEXP (operands[0], 0));
309
310 if (optype1 == MEMOP)
311 addreg1 = find_addr_reg (XEXP (operands[1], 0));
312
313 /* Ok, we can do one word at a time.
314 Normally we do the low-numbered word first,
315 but if either operand is autodecrementing then we
316 do the high-numbered word first.
317
318 In either case, set up in LATEHALF the operands to use
319 for the high-numbered word and in some cases alter the
320 operands in OPERANDS to be suitable for the low-numbered word. */
321
322 if (optype0 == REGOP)
323 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
324 else if (optype0 == OFFSOP)
325 latehalf[0] = adj_offsettable_operand (operands[0], 4);
326 else
327 latehalf[0] = operands[0];
328
329 if (optype1 == REGOP)
330 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
331 else if (optype1 == OFFSOP)
332 latehalf[1] = adj_offsettable_operand (operands[1], 4);
333 else if (optype1 == CNSTOP)
334 {
335 if (GET_CODE (operands[1]) == CONST_DOUBLE)
336 split_double (operands[1], &operands[1], &latehalf[1]);
337 else if (CONSTANT_P (operands[1]))
997de79c
JVA
338 {
339 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
340 latehalf[1] = constm1_rtx;
341 else
342 latehalf[1] = const0_rtx;
343 }
2a2ab3f9
JVA
344 }
345 else
346 latehalf[1] = operands[1];
347
348 /* If insn is effectively movd N (sp),-(sp) then we will do the
349 high word first. We should use the adjusted operand 1 (which is N+4 (sp))
350 for the low word as well, to compensate for the first decrement of sp. */
351 if (optype0 == PUSHOP
352 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
353 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
354 operands[1] = latehalf[1];
355
81fd0956 356 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
85ddb399
RS
357 if the upper part of reg N does not appear in the MEM, arrange to
358 emit the move late-half first. Otherwise, compute the MEM address
359 into the upper part of N and use that as a pointer to the memory
360 operand. */
81fd0956 361 if (optype0 == REGOP
85ddb399 362 && (optype1 == OFFSOP || optype1 == MEMOP))
81fd0956 363 {
85ddb399
RS
364 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
365 && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
366 {
367 /* If both halves of dest are used in the src memory address,
368 compute the address into latehalf of dest. */
369 rtx xops[2];
370 xops[0] = latehalf[0];
371 xops[1] = XEXP (operands[1], 0);
372 output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
373 operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
374 latehalf[1] = adj_offsettable_operand (operands[1], 4);
375 }
376 else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
377 /* If the low half of dest is mentioned in the source memory
378 address, the arrange to emit the move late half first. */
379 dest_overlapped_low = 1;
81fd0956
RS
380 }
381
2a2ab3f9
JVA
382 /* If one or both operands autodecrementing,
383 do the two words, high-numbered first. */
384
385 /* Likewise, the first move would clobber the source of the second one,
386 do them in the other order. This happens only for registers;
387 such overlap can't happen in memory unless the user explicitly
388 sets it up, and that is an undefined circumstance. */
389
390 if (optype0 == PUSHOP || optype1 == PUSHOP
391 || (optype0 == REGOP && optype1 == REGOP
85ddb399
RS
392 && REGNO (operands[0]) == REGNO (latehalf[1]))
393 || dest_overlapped_low)
2a2ab3f9
JVA
394 {
395 /* Make any unoffsettable addresses point at high-numbered word. */
396 if (addreg0)
397 asm_add (4, addreg0);
398 if (addreg1)
399 asm_add (4, addreg1);
400
401 /* Do that word. */
402 output_asm_insn (singlemove_string (latehalf), latehalf);
403
404 /* Undo the adds we just did. */
405 if (addreg0)
406 asm_add (-4, addreg0);
407 if (addreg1)
408 asm_add (-4, addreg1);
409
410 /* Do low-numbered word. */
411 return singlemove_string (operands);
412 }
413
414 /* Normal case: do the two words, low-numbered first. */
415
416 output_asm_insn (singlemove_string (operands), operands);
417
418 /* Make any unoffsettable addresses point at high-numbered word. */
419 if (addreg0)
420 asm_add (4, addreg0);
421 if (addreg1)
422 asm_add (4, addreg1);
423
424 /* Do that word. */
425 output_asm_insn (singlemove_string (latehalf), latehalf);
426
427 /* Undo the adds we just did. */
428 if (addreg0)
429 asm_add (-4, addreg0);
430 if (addreg1)
431 asm_add (-4, addreg1);
432
433 return "";
434}
435\f
436int
437standard_80387_constant_p (x)
438 rtx x;
439{
440 union real_extract u;
441 register double d;
442
443 bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
444 d = u.d;
445
446 if (d == 0)
447 return 1;
448
449 if (d == 1)
450 return 2;
451
452 /* Note that on the 80387, other constants, such as pi,
453 are much slower to load as standard constants
454 than to load from doubles in memory! */
455
456 return 0;
457}
458
459char *
460output_move_const_single (operands)
461 rtx *operands;
462{
463 if (FP_REG_P (operands[0]))
464 {
465 int conval = standard_80387_constant_p (operands[1]);
466
467 if (conval == 1)
468 return "fldz";
469
470 if (conval == 2)
471 return "fld1";
472 }
473 if (GET_CODE (operands[1]) == CONST_DOUBLE)
474 {
475 union { int i[2]; double d;} u1;
476 union { int i; float f;} u2;
477 u1.i[0] = CONST_DOUBLE_LOW (operands[1]);
478 u1.i[1] = CONST_DOUBLE_HIGH (operands[1]);
479 u2.f = u1.d;
435defd1 480 operands[1] = GEN_INT (u2.i);
2a2ab3f9
JVA
481 }
482 return singlemove_string (operands);
483}
484\f
485/* Returns 1 if OP is either a symbol reference or a sum of a symbol
486 reference and a constant. */
487
488int
489symbolic_operand (op, mode)
490 register rtx op;
491 enum machine_mode mode;
492{
493 switch (GET_CODE (op))
494 {
495 case SYMBOL_REF:
496 case LABEL_REF:
497 return 1;
498 case CONST:
499 op = XEXP (op, 0);
500 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
501 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
502 && GET_CODE (XEXP (op, 1)) == CONST_INT);
503 default:
504 return 0;
505 }
506}
507\f
508/* Returns 1 if OP contains a symbol reference */
509
510int
511symbolic_reference_mentioned_p (op)
512 rtx op;
513{
514 register char *fmt;
515 register int i;
516
517 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
518 return 1;
519
520 fmt = GET_RTX_FORMAT (GET_CODE (op));
521 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
522 {
523 if (fmt[i] == 'E')
524 {
525 register int j;
526
527 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
528 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
529 return 1;
530 }
531 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
532 return 1;
533 }
534
535 return 0;
536}
537\f
538/* Return a legitimate reference for ORIG (an address) using the
539 register REG. If REG is 0, a new pseudo is generated.
540
541 There are three types of references that must be handled:
542
543 1. Global data references must load the address from the GOT, via
544 the PIC reg. An insn is emitted to do this load, and the reg is
545 returned.
546
547 2. Static data references must compute the address as an offset
548 from the GOT, whose base is in the PIC reg. An insn is emitted to
549 compute the address into a reg, and the reg is returned. Static
550 data objects have SYMBOL_REF_FLAG set to differentiate them from
551 global data objects.
552
553 3. Constant pool addresses must be handled special. They are
554 considered legitimate addresses, but only if not used with regs.
555 When printed, the output routines know to print the reference with the
556 PIC reg, even though the PIC reg doesn't appear in the RTL.
557
558 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
559 reg also appears in the address (except for constant pool references,
560 noted above).
561
562 "switch" statements also require special handling when generating
563 PIC code. See comments by the `casesi' insn in i386.md for details. */
564
565rtx
566legitimize_pic_address (orig, reg)
567 rtx orig;
568 rtx reg;
569{
570 rtx addr = orig;
571 rtx new = orig;
572
573 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
574 {
575 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
576 reg = new = orig;
577 else
578 {
579 if (reg == 0)
580 reg = gen_reg_rtx (Pmode);
581
582 if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
583 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
584 else
585 new = gen_rtx (MEM, Pmode,
586 gen_rtx (PLUS, Pmode,
587 pic_offset_table_rtx, orig));
588
589 emit_move_insn (reg, new);
590 }
591 current_function_uses_pic_offset_table = 1;
592 return reg;
593 }
594 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
595 {
596 rtx base;
597
598 if (GET_CODE (addr) == CONST)
599 {
600 addr = XEXP (addr, 0);
601 if (GET_CODE (addr) != PLUS)
602 abort ();
603 }
604
605 if (XEXP (addr, 0) == pic_offset_table_rtx)
606 return orig;
607
608 if (reg == 0)
609 reg = gen_reg_rtx (Pmode);
610
611 base = legitimize_pic_address (XEXP (addr, 0), reg);
435defd1
JVA
612 addr = legitimize_pic_address (XEXP (addr, 1),
613 base == reg ? NULL_RTX : reg);
2a2ab3f9
JVA
614
615 if (GET_CODE (addr) == CONST_INT)
616 return plus_constant (base, INTVAL (addr));
617
618 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
619 {
620 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
621 addr = XEXP (addr, 1);
622 }
623 return gen_rtx (PLUS, Pmode, base, addr);
624 }
625 return new;
626}
627\f
628/* Emit insns to move operands[1] into operands[0]. */
629
630void
631emit_pic_move (operands, mode)
632 rtx *operands;
633 enum machine_mode mode;
634{
635 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
636
637 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
638 operands[1] = (rtx) force_reg (SImode, operands[1]);
639 else
640 operands[1] = legitimize_pic_address (operands[1], temp);
641}
642\f
643/* This function generates the assembly code for function entry.
644 FILE is an stdio stream to output the code to.
645 SIZE is an int: how many units of temporary storage to allocate. */
646
647void
648function_prologue (file, size)
649 FILE *file;
650 int size;
651{
652 register int regno;
653 int limit;
654 rtx xops[4];
aae75261
JVA
655 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
656 || current_function_uses_const_pool);
2a2ab3f9
JVA
657
658 xops[0] = stack_pointer_rtx;
659 xops[1] = frame_pointer_rtx;
435defd1 660 xops[2] = GEN_INT (size);
2a2ab3f9
JVA
661 if (frame_pointer_needed)
662 {
663 output_asm_insn ("push%L1 %1", xops);
664 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
665 }
666
667 if (size)
668 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
669
670 /* Note If use enter it is NOT reversed args.
671 This one is not reversed from intel!!
672 I think enter is slower. Also sdb doesn't like it.
673 But if you want it the code is:
674 {
675 xops[3] = const0_rtx;
676 output_asm_insn ("enter %2,%3", xops);
677 }
678 */
679 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
680 for (regno = limit - 1; regno >= 0; regno--)
681 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 682 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9
JVA
683 {
684 xops[0] = gen_rtx (REG, SImode, regno);
685 output_asm_insn ("push%L0 %0", xops);
686 }
687
aae75261 688 if (pic_reg_used)
2a2ab3f9
JVA
689 {
690 xops[0] = pic_offset_table_rtx;
691 xops[1] = (rtx) gen_label_rtx ();
692
693 output_asm_insn (AS1 (call,%P1), xops);
694 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
695 output_asm_insn (AS1 (pop%L0,%0), xops);
696 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
697 }
698}
699
700/* Return 1 if it is appropriate to emit `ret' instructions in the
701 body of a function. Do this only if the epilogue is simple, needing a
702 couple of insns. Prior to reloading, we can't tell how many registers
703 must be saved, so return 0 then.
704
705 If NON_SAVING_SETJMP is defined and true, then it is not possible
706 for the epilogue to be simple, so return 0. This is a special case
707 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
708 final, but jump_optimize may need to know sooner if a `return' is OK. */
709
710int
711simple_386_epilogue ()
712{
713 int regno;
714 int nregs = 0;
715 int reglimit = (frame_pointer_needed
716 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
aae75261
JVA
717 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
718 || current_function_uses_const_pool);
2a2ab3f9
JVA
719
720#ifdef NON_SAVING_SETJMP
721 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
722 return 0;
723#endif
724
725 if (! reload_completed)
726 return 0;
727
728 for (regno = reglimit - 1; regno >= 0; regno--)
729 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 730 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9
JVA
731 nregs++;
732
733 return nregs == 0 || ! frame_pointer_needed;
734}
735
736/* This function generates the assembly code for function exit.
737 FILE is an stdio stream to output the code to.
738 SIZE is an int: how many units of temporary storage to deallocate. */
739
740void
741function_epilogue (file, size)
742 FILE *file;
743 int size;
744{
745 register int regno;
746 register int nregs, limit;
747 int offset;
748 rtx xops[3];
aae75261
JVA
749 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
750 || current_function_uses_const_pool);
2a2ab3f9
JVA
751
752 /* Compute the number of registers to pop */
753
754 limit = (frame_pointer_needed
755 ? FRAME_POINTER_REGNUM
756 : STACK_POINTER_REGNUM);
757
758 nregs = 0;
759
760 for (regno = limit - 1; regno >= 0; regno--)
761 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 762 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9
JVA
763 nregs++;
764
765 /* sp is often unreliable so we must go off the frame pointer,
766 */
767
768 /* In reality, we may not care if sp is unreliable, because we can
769 restore the register relative to the frame pointer. In theory,
770 since each move is the same speed as a pop, and we don't need the
771 leal, this is faster. For now restore multiple registers the old
772 way. */
773
774 offset = -size - (nregs * UNITS_PER_WORD);
775
776 xops[2] = stack_pointer_rtx;
777
778 if (nregs > 1 || ! frame_pointer_needed)
779 {
780 if (frame_pointer_needed)
781 {
782 xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
783 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
784 }
785
786 for (regno = 0; regno < limit; regno++)
787 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 788 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9
JVA
789 {
790 xops[0] = gen_rtx (REG, SImode, regno);
791 output_asm_insn ("pop%L0 %0", xops);
792 }
793 }
794 else
795 for (regno = 0; regno < limit; regno++)
796 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 797 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9
JVA
798 {
799 xops[0] = gen_rtx (REG, SImode, regno);
800 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
801 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
802 offset += 4;
803 }
804
805 if (frame_pointer_needed)
806 {
807 /* On i486, mov & pop is faster than "leave". */
808
809 if (TARGET_486)
810 {
811 xops[0] = frame_pointer_rtx;
812 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
813 output_asm_insn ("pop%L0 %0", xops);
814 }
815 else
816 output_asm_insn ("leave", xops);
817 }
818 else if (size)
819 {
820 /* If there is no frame pointer, we must still release the frame. */
821
435defd1 822 xops[0] = GEN_INT (size);
2a2ab3f9
JVA
823 output_asm_insn (AS2 (add%L2,%0,%2), xops);
824 }
825
826 if (current_function_pops_args && current_function_args_size)
827 {
435defd1 828 xops[1] = GEN_INT (current_function_pops_args);
2a2ab3f9
JVA
829
830 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
831 asked to pop more, pop return address, do explicit add, and jump
832 indirectly to the caller. */
833
834 if (current_function_pops_args >= 32768)
835 {
836 /* ??? Which register to use here? */
837 xops[0] = gen_rtx (REG, SImode, 2);
838 output_asm_insn ("pop%L0 %0", xops);
839 output_asm_insn (AS2 (add%L2,%1,%2), xops);
840 output_asm_insn ("jmp %*%0", xops);
841 }
842 else
843 output_asm_insn ("ret %1", xops);
844 }
2a2ab3f9
JVA
845 else
846 output_asm_insn ("ret", xops);
847}
848\f
849/* Print an integer constant expression in assembler syntax. Addition
850 and subtraction are the only arithmetic that may appear in these
851 expressions. FILE is the stdio stream to write to, X is the rtx, and
852 CODE is the operand print code from the output string. */
853
854static void
855output_pic_addr_const (file, x, code)
856 FILE *file;
857 rtx x;
858 int code;
859{
860 char buf[256];
861
862 switch (GET_CODE (x))
863 {
864 case PC:
865 if (flag_pic)
866 putc ('.', file);
867 else
868 abort ();
869 break;
870
871 case SYMBOL_REF:
872 case LABEL_REF:
873 if (GET_CODE (x) == SYMBOL_REF)
874 assemble_name (file, XSTR (x, 0));
875 else
876 {
877 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
878 CODE_LABEL_NUMBER (XEXP (x, 0)));
879 assemble_name (asm_out_file, buf);
880 }
881
882 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
883 fprintf (file, "@GOTOFF(%%ebx)");
884 else if (code == 'P')
885 fprintf (file, "@PLT");
886 else if (GET_CODE (x) == LABEL_REF || ! SYMBOL_REF_FLAG (x))
887 fprintf (file, "@GOT");
888 else
889 fprintf (file, "@GOTOFF");
890
891 break;
892
893 case CODE_LABEL:
894 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
895 assemble_name (asm_out_file, buf);
896 break;
897
898 case CONST_INT:
899 fprintf (file, "%d", INTVAL (x));
900 break;
901
902 case CONST:
903 /* This used to output parentheses around the expression,
904 but that does not work on the 386 (either ATT or BSD assembler). */
905 output_pic_addr_const (file, XEXP (x, 0), code);
906 break;
907
908 case CONST_DOUBLE:
909 if (GET_MODE (x) == VOIDmode)
910 {
911 /* We can use %d if the number is <32 bits and positive. */
912 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
913 fprintf (file, "0x%x%08x",
914 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
915 else
916 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
917 }
918 else
919 /* We can't handle floating point constants;
920 PRINT_OPERAND must handle them. */
921 output_operand_lossage ("floating constant misused");
922 break;
923
924 case PLUS:
925 /* Some assemblers need integer constants to appear last (eg masm). */
926 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
927 {
928 output_pic_addr_const (file, XEXP (x, 1), code);
929 if (INTVAL (XEXP (x, 0)) >= 0)
930 fprintf (file, "+");
931 output_pic_addr_const (file, XEXP (x, 0), code);
932 }
933 else
934 {
935 output_pic_addr_const (file, XEXP (x, 0), code);
936 if (INTVAL (XEXP (x, 1)) >= 0)
937 fprintf (file, "+");
938 output_pic_addr_const (file, XEXP (x, 1), code);
939 }
940 break;
941
942 case MINUS:
943 output_pic_addr_const (file, XEXP (x, 0), code);
944 fprintf (file, "-");
945 output_pic_addr_const (file, XEXP (x, 1), code);
946 break;
947
948 default:
949 output_operand_lossage ("invalid expression as operand");
950 }
951}
952\f
2a2ab3f9
JVA
953/* Meaning of CODE:
954 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
955 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
956 R -- print the prefix for register names.
957 z -- print the opcode suffix for the size of the current operand.
958 * -- print a star (in certain assembler syntax)
959 w -- print the operand as if it's a "word" (HImode) even if it isn't.
960 c -- don't print special prefixes before constant operands.
961*/
962
963void
964print_operand (file, x, code)
965 FILE *file;
966 rtx x;
967 int code;
968{
969 if (code)
970 {
971 switch (code)
972 {
973 case '*':
974 if (USE_STAR)
975 putc ('*', file);
976 return;
977
2a2ab3f9
JVA
978 case 'L':
979 PUT_OP_SIZE (code, 'l', file);
980 return;
981
982 case 'W':
983 PUT_OP_SIZE (code, 'w', file);
984 return;
985
986 case 'B':
987 PUT_OP_SIZE (code, 'b', file);
988 return;
989
990 case 'Q':
991 PUT_OP_SIZE (code, 'l', file);
992 return;
993
994 case 'S':
995 PUT_OP_SIZE (code, 's', file);
996 return;
997
2a2ab3f9
JVA
998 case 'z':
999 /* 387 opcodes don't get size suffixes if the operands are
1000 registers. */
1001
1002 if (STACK_REG_P (x))
1003 return;
1004
1005 /* this is the size of op from size of operand */
1006 switch (GET_MODE_SIZE (GET_MODE (x)))
1007 {
1008 case 1:
1009 PUT_OP_SIZE ('B', 'b', file);
1010 return;
1011
1012 case 2:
1013 PUT_OP_SIZE ('W', 'w', file);
1014 return;
1015
1016 case 4:
1017 if (GET_MODE (x) == SFmode)
1018 {
1019 PUT_OP_SIZE ('S', 's', file);
1020 return;
1021 }
1022 else
1023 PUT_OP_SIZE ('L', 'l', file);
1024 return;
1025
1026 case 8:
1027 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
56c0e8fa
JVA
1028 {
1029#ifdef GAS_MNEMONICS
1030 PUT_OP_SIZE ('Q', 'q', file);
1031 return;
1032#else
1033 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
1034#endif
1035 }
2a2ab3f9
JVA
1036
1037 PUT_OP_SIZE ('Q', 'l', file);
1038 return;
1039 }
4af3895e
JVA
1040
1041 case 'b':
1042 case 'w':
1043 case 'k':
1044 case 'h':
1045 case 'y':
1046 case 'P':
1047 break;
1048
1049 default:
68daafd4
JVA
1050 {
1051 char str[50];
1052
1053 sprintf (str, "invalid operand code `%c'", code);
1054 output_operand_lossage (str);
1055 }
2a2ab3f9
JVA
1056 }
1057 }
1058 if (GET_CODE (x) == REG)
1059 {
1060 PRINT_REG (x, code, file);
1061 }
1062 else if (GET_CODE (x) == MEM)
1063 {
1064 PRINT_PTR (x, file);
1065 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
1066 {
1067 if (flag_pic)
1068 output_pic_addr_const (file, XEXP (x, 0), code);
1069 else
1070 output_addr_const (file, XEXP (x, 0));
1071 }
1072 else
1073 output_address (XEXP (x, 0));
1074 }
1075 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
1076 {
1077 union { double d; int i[2]; } u;
1078 union { float f; int i; } u1;
1079 u.i[0] = CONST_DOUBLE_LOW (x);
1080 u.i[1] = CONST_DOUBLE_HIGH (x);
1081 u1.f = u.d;
4af3895e
JVA
1082 PRINT_IMMED_PREFIX (file);
1083 fprintf (file, "0x%x", u1.i);
2a2ab3f9
JVA
1084 }
1085 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
1086 {
1087 union { double d; int i[2]; } u;
1088 u.i[0] = CONST_DOUBLE_LOW (x);
1089 u.i[1] = CONST_DOUBLE_HIGH (x);
1090 fprintf (file, "%.22e", u.d);
1091 }
1092 else
1093 {
4af3895e 1094 if (code != 'P')
2a2ab3f9 1095 {
695dac07 1096 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2a2ab3f9
JVA
1097 PRINT_IMMED_PREFIX (file);
1098 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
1099 || GET_CODE (x) == LABEL_REF)
1100 PRINT_OFFSET_PREFIX (file);
1101 }
1102 if (flag_pic)
1103 output_pic_addr_const (file, x, code);
1104 else
1105 output_addr_const (file, x);
1106 }
1107}
1108\f
1109/* Print a memory operand whose address is ADDR. */
1110
1111void
1112print_operand_address (file, addr)
1113 FILE *file;
1114 register rtx addr;
1115{
1116 register rtx reg1, reg2, breg, ireg;
1117 rtx offset;
1118
1119 switch (GET_CODE (addr))
1120 {
1121 case REG:
1122 ADDR_BEG (file);
1123 fprintf (file, "%se", RP);
1124 fputs (hi_reg_name[REGNO (addr)], file);
1125 ADDR_END (file);
1126 break;
1127
1128 case PLUS:
1129 reg1 = 0;
1130 reg2 = 0;
1131 ireg = 0;
1132 breg = 0;
1133 offset = 0;
1134 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
1135 {
1136 offset = XEXP (addr, 0);
1137 addr = XEXP (addr, 1);
1138 }
1139 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
1140 {
1141 offset = XEXP (addr, 1);
1142 addr = XEXP (addr, 0);
1143 }
1144 if (GET_CODE (addr) != PLUS) ;
1145 else if (GET_CODE (XEXP (addr, 0)) == MULT)
1146 {
1147 reg1 = XEXP (addr, 0);
1148 addr = XEXP (addr, 1);
1149 }
1150 else if (GET_CODE (XEXP (addr, 1)) == MULT)
1151 {
1152 reg1 = XEXP (addr, 1);
1153 addr = XEXP (addr, 0);
1154 }
1155 else if (GET_CODE (XEXP (addr, 0)) == REG)
1156 {
1157 reg1 = XEXP (addr, 0);
1158 addr = XEXP (addr, 1);
1159 }
1160 else if (GET_CODE (XEXP (addr, 1)) == REG)
1161 {
1162 reg1 = XEXP (addr, 1);
1163 addr = XEXP (addr, 0);
1164 }
1165 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
1166 {
1167 if (reg1 == 0) reg1 = addr;
1168 else reg2 = addr;
1169 addr = 0;
1170 }
1171 if (offset != 0)
1172 {
1173 if (addr != 0) abort ();
1174 addr = offset;
1175 }
1176 if ((reg1 && GET_CODE (reg1) == MULT)
1177 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
1178 {
1179 breg = reg2;
1180 ireg = reg1;
1181 }
1182 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
1183 {
1184 breg = reg1;
1185 ireg = reg2;
1186 }
1187
1188 if (ireg != 0 || breg != 0)
1189 {
1190 int scale = 1;
1191
1192 if (addr != 0)
1193 {
1194 if (GET_CODE (addr) == LABEL_REF)
1195 output_asm_label (addr);
1196 else
1197 {
1198 if (flag_pic)
1199 output_pic_addr_const (file, addr, 0);
1200 else
1201 output_addr_const (file, addr);
1202 }
1203 }
1204
1205 if (ireg != 0 && GET_CODE (ireg) == MULT)
1206 {
1207 scale = INTVAL (XEXP (ireg, 1));
1208 ireg = XEXP (ireg, 0);
1209 }
1210
1211 /* The stack pointer can only appear as a base register,
1212 never an index register, so exchange the regs if it is wrong. */
1213
1214 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
1215 {
1216 rtx tmp;
1217
1218 tmp = breg;
1219 breg = ireg;
1220 ireg = tmp;
1221 }
1222
1223 /* output breg+ireg*scale */
1224 PRINT_B_I_S (breg, ireg, scale, file);
1225 break;
1226 }
1227
1228 case MULT:
1229 {
1230 int scale;
1231 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
1232 {
1233 scale = INTVAL (XEXP (addr, 0));
1234 ireg = XEXP (addr, 1);
1235 }
1236 else
1237 {
1238 scale = INTVAL (XEXP (addr, 1));
1239 ireg = XEXP (addr, 0);
1240 }
1241 output_addr_const (file, const0_rtx);
1242 PRINT_B_I_S ((rtx) 0, ireg, scale, file);
1243 }
1244 break;
1245
1246 default:
1247 if (GET_CODE (addr) == CONST_INT
1248 && INTVAL (addr) < 0x8000
1249 && INTVAL (addr) >= -0x8000)
1250 fprintf (file, "%d", INTVAL (addr));
1251 else
1252 {
1253 if (flag_pic)
1254 output_pic_addr_const (file, addr, 0);
1255 else
1256 output_addr_const (file, addr);
1257 }
1258 }
1259}
1260\f
1261/* Set the cc_status for the results of an insn whose pattern is EXP.
1262 On the 80386, we assume that only test and compare insns, as well
1263 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, LSHIFT,
1264 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
4c0d89b5
RS
1265 Also, we assume that jumps, moves and sCOND don't affect the condition
1266 codes. All else clobbers the condition codes, by assumption.
1267
1268 We assume that ALL integer add, minus, etc. instructions effect the
1269 condition codes. This MUST be consistent with i386.md.
2a2ab3f9 1270
4c0d89b5
RS
1271 We don't record any float test or compare - the redundant test &
1272 compare check in final.c does not handle stack-like regs correctly. */
2a2ab3f9
JVA
1273
1274void
1275notice_update_cc (exp)
1276 rtx exp;
1277{
1278 if (GET_CODE (exp) == SET)
1279 {
1280 /* Jumps do not alter the cc's. */
1281 if (SET_DEST (exp) == pc_rtx)
1282 return;
1283 /* Moving register or memory into a register:
1284 it doesn't alter the cc's, but it might invalidate
1285 the RTX's which we remember the cc's came from.
1286 (Note that moving a constant 0 or 1 MAY set the cc's). */
1287 if (REG_P (SET_DEST (exp))
4c0d89b5
RS
1288 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
1289 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2a2ab3f9
JVA
1290 {
1291 if (cc_status.value1
1292 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1293 cc_status.value1 = 0;
1294 if (cc_status.value2
1295 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1296 cc_status.value2 = 0;
1297 return;
1298 }
1299 /* Moving register into memory doesn't alter the cc's.
1300 It may invalidate the RTX's which we remember the cc's came from. */
4c0d89b5
RS
1301 if (GET_CODE (SET_DEST (exp)) == MEM
1302 && (REG_P (SET_SRC (exp))
1303 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2a2ab3f9
JVA
1304 {
1305 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1306 cc_status.value1 = 0;
1307 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1308 cc_status.value2 = 0;
1309 return;
1310 }
1311 /* Function calls clobber the cc's. */
1312 else if (GET_CODE (SET_SRC (exp)) == CALL)
1313 {
1314 CC_STATUS_INIT;
1315 return;
1316 }
1317 /* Tests and compares set the cc's in predictable ways. */
1318 else if (SET_DEST (exp) == cc0_rtx)
1319 {
1320 CC_STATUS_INIT;
1321 cc_status.value1 = SET_SRC (exp);
1322 return;
1323 }
1324 /* Certain instructions effect the condition codes. */
1325 else if (GET_MODE (SET_SRC (exp)) == SImode
1326 || GET_MODE (SET_SRC (exp)) == HImode
1327 || GET_MODE (SET_SRC (exp)) == QImode)
1328 switch (GET_CODE (SET_SRC (exp)))
1329 {
1330 case ASHIFTRT: case LSHIFTRT:
1331 case ASHIFT: case LSHIFT:
1332 /* Shifts on the 386 don't set the condition codes if the
1333 shift count is zero. */
1334 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
1335 {
1336 CC_STATUS_INIT;
1337 break;
1338 }
1339 /* We assume that the CONST_INT is non-zero (this rtx would
1340 have been deleted if it were zero. */
1341
1342 case PLUS: case MINUS: case NEG:
1343 case AND: case IOR: case XOR:
1344 cc_status.flags = CC_NO_OVERFLOW;
1345 cc_status.value1 = SET_SRC (exp);
1346 cc_status.value2 = SET_DEST (exp);
1347 break;
1348
1349 default:
1350 CC_STATUS_INIT;
1351 }
1352 else
1353 {
1354 CC_STATUS_INIT;
1355 }
1356 }
1357 else if (GET_CODE (exp) == PARALLEL
1358 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1359 {
1360 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1361 return;
1362 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1363 {
1364 CC_STATUS_INIT;
2247a58c
JVA
1365 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
1366 cc_status.flags |= CC_IN_80387;
1367 else
4c0d89b5 1368 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2a2ab3f9
JVA
1369 return;
1370 }
1371 CC_STATUS_INIT;
1372 }
1373 else
1374 {
1375 CC_STATUS_INIT;
1376 }
1377}
1378\f
1379/* Split one or more DImode RTL references into pairs of SImode
1380 references. The RTL can be REG, offsettable MEM, integer constant, or
1381 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
1382 split and "num" is its length. lo_half and hi_half are output arrays
1383 that parallel "operands". */
1384
1385void
1386split_di (operands, num, lo_half, hi_half)
1387 rtx operands[];
1388 int num;
1389 rtx lo_half[], hi_half[];
1390{
1391 while (num--)
1392 {
1393 if (GET_CODE (operands[num]) == REG)
1394 {
1395 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
1396 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
1397 }
1398 else if (CONSTANT_P (operands[num]))
1399 {
1400 split_double (operands[num], &lo_half[num], &hi_half[num]);
1401 }
1402 else if (offsettable_memref_p (operands[num]))
1403 {
1404 lo_half[num] = operands[num];
1405 hi_half[num] = adj_offsettable_operand (operands[num], 4);
1406 }
1407 else
1408 abort();
1409 }
1410}
1411\f
1412/* Return 1 if this is a valid binary operation on a 387.
1413 OP is the expression matched, and MODE is its mode. */
1414
1415int
1416binary_387_op (op, mode)
1417 register rtx op;
1418 enum machine_mode mode;
1419{
1420 if (mode != VOIDmode && mode != GET_MODE (op))
1421 return 0;
1422
1423 switch (GET_CODE (op))
1424 {
1425 case PLUS:
1426 case MINUS:
1427 case MULT:
1428 case DIV:
1429 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
1430
1431 default:
1432 return 0;
1433 }
1434}
1435
1436/* Return 1 if this is a valid conversion operation on a 387.
1437 OP is the expression matched, and MODE is its mode. */
1438
1439int
1440convert_387_op (op, mode)
1441 register rtx op;
1442 enum machine_mode mode;
1443{
1444 if (mode != VOIDmode && mode != GET_MODE (op))
1445 return 0;
1446
1447 switch (GET_CODE (op))
1448 {
1449 case FLOAT:
1450 return GET_MODE (XEXP (op, 0)) == SImode;
1451
1452 case FLOAT_EXTEND:
1453 return mode == DFmode && GET_MODE (XEXP (op, 0)) == SFmode;
1454
1455 default:
1456 return 0;
1457 }
1458}
1459
2a2ab3f9
JVA
1460/* Return 1 if this is a valid shift or rotate operation on a 386.
1461 OP is the expression matched, and MODE is its mode. */
1462
1463int
1464shift_op (op, mode)
1465 register rtx op;
1466 enum machine_mode mode;
1467{
1468 rtx operand = XEXP (op, 0);
1469
1470 if (mode != VOIDmode && mode != GET_MODE (op))
1471 return 0;
1472
1473 if (GET_MODE (operand) != GET_MODE (op)
1474 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
1475 return 0;
1476
1477 return (GET_CODE (op) == ASHIFT
1478 || GET_CODE (op) == ASHIFTRT
1479 || GET_CODE (op) == LSHIFTRT
1480 || GET_CODE (op) == ROTATE
1481 || GET_CODE (op) == ROTATERT);
1482}
ac2afb64
JVA
1483
1484/* Return 1 if OP is COMPARE rtx with mode VOIDmode.
1485 MODE is not used. */
1486
1487int
1488VOIDmode_compare_op (op, mode)
1489 register rtx op;
1490 enum machine_mode mode;
1491{
1492 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
1493}
2a2ab3f9
JVA
1494\f
1495/* Output code to perform a 387 binary operation in INSN, one of PLUS,
1496 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
1497 is the expression of the binary operation. The output may either be
1498 emitted here, or returned to the caller, like all output_* functions.
1499
1500 There is no guarantee that the operands are the same mode, as they
1501 might be within FLOAT or FLOAT_EXTEND expressions. */
1502
1503char *
1504output_387_binary_op (insn, operands)
1505 rtx insn;
1506 rtx *operands;
1507{
1508 rtx temp;
1509 char *base_op;
1510 static char buf[100];
1511
1512 switch (GET_CODE (operands[3]))
1513 {
1514 case PLUS:
1515 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1516 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1517 base_op = "fiadd";
1518 else
1519 base_op = "fadd";
1520 break;
1521
1522 case MINUS:
1523 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1524 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1525 base_op = "fisub";
1526 else
1527 base_op = "fsub";
1528 break;
1529
1530 case MULT:
1531 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1532 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1533 base_op = "fimul";
1534 else
1535 base_op = "fmul";
1536 break;
1537
1538 case DIV:
1539 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1540 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1541 base_op = "fidiv";
1542 else
1543 base_op = "fdiv";
1544 break;
1545
1546 default:
1547 abort ();
1548 }
1549
1550 strcpy (buf, base_op);
1551
1552 switch (GET_CODE (operands[3]))
1553 {
1554 case MULT:
1555 case PLUS:
1556 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
1557 {
1558 temp = operands[2];
1559 operands[2] = operands[1];
1560 operands[1] = temp;
1561 }
1562
1563 if (GET_CODE (operands[2]) == MEM)
1564 return strcat (buf, AS1 (%z2,%2));
1565
1566 if (NON_STACK_REG_P (operands[1]))
1567 {
1568 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
1569 RET;
1570 }
1571 else if (NON_STACK_REG_P (operands[2]))
1572 {
1573 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
1574 RET;
1575 }
1576
1577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
1578 return strcat (buf, AS2 (p,%2,%0));
1579
1580 if (STACK_TOP_P (operands[0]))
1581 return strcat (buf, AS2 (,%y2,%0));
1582 else
1583 return strcat (buf, AS2 (,%2,%0));
1584
1585 case MINUS:
1586 case DIV:
1587 if (GET_CODE (operands[1]) == MEM)
1588 return strcat (buf, AS1 (r%z1,%1));
1589
1590 if (GET_CODE (operands[2]) == MEM)
1591 return strcat (buf, AS1 (%z2,%2));
1592
1593 if (NON_STACK_REG_P (operands[1]))
1594 {
1595 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
1596 RET;
1597 }
1598 else if (NON_STACK_REG_P (operands[2]))
1599 {
1600 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
1601 RET;
1602 }
1603
1604 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
1605 abort ();
1606
1607 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
1608 return strcat (buf, AS2 (rp,%2,%0));
1609
1610 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1611 return strcat (buf, AS2 (p,%1,%0));
1612
1613 if (STACK_TOP_P (operands[0]))
1614 {
1615 if (STACK_TOP_P (operands[1]))
1616 return strcat (buf, AS2 (,%y2,%0));
1617 else
1618 return strcat (buf, AS2 (r,%y1,%0));
1619 }
1620 else if (STACK_TOP_P (operands[1]))
1621 return strcat (buf, AS2 (,%1,%0));
1622 else
1623 return strcat (buf, AS2 (r,%2,%0));
1624
1625 default:
1626 abort ();
1627 }
1628}
1629\f
1630/* Output code for INSN to convert a float to a signed int. OPERANDS
1631 are the insn operands. The output may be SFmode or DFmode and the
1632 input operand may be SImode or DImode. As a special case, make sure
1633 that the 387 stack top dies if the output mode is DImode, because the
1634 hardware requires this. */
1635
1636char *
1637output_fix_trunc (insn, operands)
1638 rtx insn;
1639 rtx *operands;
1640{
1641 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
305f097e 1642 rtx xops[2];
2a2ab3f9
JVA
1643
1644 if (! STACK_TOP_P (operands[1]) ||
1645 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
1646 abort ();
1647
305f097e
JVA
1648 xops[0] = GEN_INT (12);
1649 xops[1] = operands[4];
1650
1651 output_asm_insn (AS1 (fnstc%W2,%2), operands);
1652 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
1653 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
1654 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
1655 output_asm_insn (AS1 (fldc%W3,%3), operands);
2a2ab3f9
JVA
1656
1657 if (NON_STACK_REG_P (operands[0]))
1658 output_to_reg (operands[0], stack_top_dies);
1659 else if (GET_CODE (operands[0]) == MEM)
1660 {
2a2ab3f9
JVA
1661 if (stack_top_dies)
1662 output_asm_insn (AS1 (fistp%z0,%0), operands);
1663 else
1664 output_asm_insn (AS1 (fist%z0,%0), operands);
1665 }
1666 else
1667 abort ();
1668
305f097e 1669 return AS1 (fldc%W2,%2);
2a2ab3f9
JVA
1670}
1671\f
1672/* Output code for INSN to compare OPERANDS. The two operands might
1673 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
c572e5ba
JVA
1674 expression. If the compare is in mode CCFPEQmode, use an opcode that
1675 will not fault if a qNaN is present. */
2a2ab3f9
JVA
1676
1677char *
1678output_float_compare (insn, operands)
1679 rtx insn;
1680 rtx *operands;
1681{
1682 int stack_top_dies;
c572e5ba
JVA
1683 rtx body = XVECEXP (PATTERN (insn), 0, 0);
1684 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
2a2ab3f9
JVA
1685
1686 if (! STACK_TOP_P (operands[0]))
1687 abort ();
1688
1689 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1690
1691 if (STACK_REG_P (operands[1])
1692 && stack_top_dies
1693 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
1694 && REGNO (operands[1]) != FIRST_STACK_REG)
1695 {
1696 /* If both the top of the 387 stack dies, and the other operand
1697 is also a stack register that dies, then this must be a
1698 `fcompp' float compare */
1699
c572e5ba
JVA
1700 if (unordered_compare)
1701 output_asm_insn ("fucompp", operands);
1702 else
1703 output_asm_insn ("fcompp", operands);
2a2ab3f9
JVA
1704 }
1705 else
1706 {
1707 static char buf[100];
1708
c572e5ba
JVA
1709 /* Decide if this is the integer or float compare opcode, or the
1710 unordered float compare. */
2a2ab3f9 1711
c572e5ba
JVA
1712 if (unordered_compare)
1713 strcpy (buf, "fucom");
1714 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
2a2ab3f9
JVA
1715 strcpy (buf, "fcom");
1716 else
1717 strcpy (buf, "ficom");
1718
1719 /* Modify the opcode if the 387 stack is to be popped. */
1720
1721 if (stack_top_dies)
1722 strcat (buf, "p");
1723
1724 if (NON_STACK_REG_P (operands[1]))
1725 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
1726 else
1727 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
1728 }
1729
1730 /* Now retrieve the condition code. */
1731
c572e5ba
JVA
1732 return output_fp_cc0_set (insn);
1733}
1734\f
1735/* Output opcodes to transfer the results of FP compare or test INSN
1736 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
1737 result of the compare or test is unordered, no comparison operator
1738 succeeds except NE. Return an output template, if any. */
1739
1740char *
1741output_fp_cc0_set (insn)
1742 rtx insn;
1743{
1744 rtx xops[3];
1745 rtx unordered_label;
1746 rtx next;
1747 enum rtx_code code;
1748
1749 xops[0] = gen_rtx (REG, HImode, 0);
1750 output_asm_insn (AS1 (fnsts%W0,%0), xops);
1751
1752 if (! TARGET_IEEE_FP)
1753 return "sahf";
2a2ab3f9 1754
c572e5ba 1755 next = next_cc0_user (insn);
dd9611dc
JVA
1756 if (next == NULL_RTX)
1757 abort ();
c572e5ba
JVA
1758
1759 if (GET_CODE (next) == JUMP_INSN
1760 && GET_CODE (PATTERN (next)) == SET
1761 && SET_DEST (PATTERN (next)) == pc_rtx
1762 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
1763 {
1764 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
1765 }
1766 else if (GET_CODE (PATTERN (next)) == SET)
1767 {
1768 code = GET_CODE (SET_SRC (PATTERN (next)));
1769 }
1770 else
1771 abort ();
1772
1773 xops[0] = gen_rtx (REG, QImode, 0);
1774
1775 switch (code)
1776 {
1777 case GT:
435defd1 1778 xops[1] = GEN_INT (0x45);
c572e5ba
JVA
1779 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1780 /* je label */
1781 break;
1782
1783 case LT:
435defd1
JVA
1784 xops[1] = GEN_INT (0x45);
1785 xops[2] = GEN_INT (0x01);
c572e5ba
JVA
1786 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1787 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1788 /* je label */
1789 break;
1790
1791 case GE:
435defd1 1792 xops[1] = GEN_INT (0x05);
c572e5ba
JVA
1793 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1794 /* je label */
1795 break;
1796
1797 case LE:
435defd1
JVA
1798 xops[1] = GEN_INT (0x45);
1799 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
1800 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1801 output_asm_insn (AS1 (dec%B0,%h0), xops);
1802 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1803 /* jb label */
1804 break;
1805
1806 case EQ:
435defd1
JVA
1807 xops[1] = GEN_INT (0x45);
1808 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
1809 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1810 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1811 /* je label */
1812 break;
1813
1814 case NE:
435defd1
JVA
1815 xops[1] = GEN_INT (0x44);
1816 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
1817 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1818 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
1819 /* jne label */
1820 break;
1821
1822 case GTU:
1823 case LTU:
1824 case GEU:
1825 case LEU:
1826 default:
1827 abort ();
1828 }
1829 RET;
2a2ab3f9 1830}
305f097e
JVA
1831\f
1832#define MAX_386_STACK_LOCALS 2
1833
1834static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
1835
1836/* Clear stack slot assignments remembered from previous functions.
1837 This is called from INIT_EXPANDERS once before RTL is emitted for each
1838 function. */
1839
1840void
1841clear_386_stack_locals ()
1842{
1843 enum machine_mode mode;
1844 int n;
1845
1846 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
1847 mode = (enum machine_mode) ((int) mode + 1))
1848 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
1849 i386_stack_locals[(int) mode][n] = NULL_RTX;
1850}
1851
1852/* Return a MEM corresponding to a stack slot with mode MODE.
1853 Allocate a new slot if necessary.
1854
1855 The RTL for a function can have several slots available: N is
1856 which slot to use. */
1857
1858rtx
1859assign_386_stack_local (mode, n)
1860 enum machine_mode mode;
1861 int n;
1862{
1863 if (n < 0 || n >= MAX_386_STACK_LOCALS)
1864 abort ();
1865
1866 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
1867 i386_stack_locals[(int) mode][n]
1868 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
1869
1870 return i386_stack_locals[(int) mode][n];
1871}
This page took 0.277368 seconds and 5 git commands to generate.