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