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