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