]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.c
Daily bump.
[gcc.git] / gcc / config / i386 / i386.c
CommitLineData
3b3c6a3f 1/* Subroutines for insn-output.c for Intel X86.
3aeae608 2 Copyright (C) 1988, 92, 94-98, 1999 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
97aadbb9 18the Free Software Foundation, 59 Temple Place - Suite 330,
32b5b1aa 19Boston, MA 02111-1307, USA. */
2a2ab3f9 20
0b6b2900 21#include <setjmp.h>
2a2ab3f9 22#include "config.h"
bb5177ac 23#include "system.h"
2a2ab3f9
JVA
24#include "rtl.h"
25#include "regs.h"
26#include "hard-reg-set.h"
27#include "real.h"
28#include "insn-config.h"
29#include "conditions.h"
30#include "insn-flags.h"
31#include "output.h"
32#include "insn-attr.h"
33#include "tree.h"
34#include "flags.h"
a8ffcc81 35#include "except.h"
ecbc4695 36#include "function.h"
00c79232 37#include "recog.h"
ced8dd8c 38#include "expr.h"
f103890b 39#include "toplev.h"
2a2ab3f9 40
997de79c
JVA
41#ifdef EXTRA_CONSTRAINT
42/* If EXTRA_CONSTRAINT is defined, then the 'S'
43 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
44 asm statements that need 'S' for class SIREG will break. */
ad5a6adc
RS
45 error EXTRA_CONSTRAINT conflicts with S constraint letter
46/* The previous line used to be #error, but some compilers barf
47 even if the conditional was untrue. */
997de79c
JVA
48#endif
49
8dfe5673
RK
50#ifndef CHECK_STACK_LIMIT
51#define CHECK_STACK_LIMIT -1
52#endif
53
e9a25f70
JL
54/* Type of an operand for ix86_{binary,unary}_operator_ok */
55enum reg_mem
32b5b1aa
SC
56{
57 reg_p,
58 mem_p,
59 imm_p
60};
61
62/* Processor costs (relative to an add) */
63struct processor_costs i386_cost = { /* 386 specific costs */
e9a25f70 64 1, /* cost of an add instruction */
32b5b1aa
SC
65 1, /* cost of a lea instruction */
66 3, /* variable shift costs */
67 2, /* constant shift costs */
68 6, /* cost of starting a multiply */
69 1, /* cost of multiply per each bit set */
70 23 /* cost of a divide/mod */
71};
72
73struct processor_costs i486_cost = { /* 486 specific costs */
74 1, /* cost of an add instruction */
75 1, /* cost of a lea instruction */
76 3, /* variable shift costs */
77 2, /* constant shift costs */
78 12, /* cost of starting a multiply */
79 1, /* cost of multiply per each bit set */
80 40 /* cost of a divide/mod */
81};
82
e5cb57e8 83struct processor_costs pentium_cost = {
32b5b1aa
SC
84 1, /* cost of an add instruction */
85 1, /* cost of a lea instruction */
856b07a1 86 4, /* variable shift costs */
e5cb57e8 87 1, /* constant shift costs */
856b07a1
SC
88 11, /* cost of starting a multiply */
89 0, /* cost of multiply per each bit set */
e5cb57e8 90 25 /* cost of a divide/mod */
32b5b1aa
SC
91};
92
856b07a1
SC
93struct processor_costs pentiumpro_cost = {
94 1, /* cost of an add instruction */
95 1, /* cost of a lea instruction */
96 3, /* variable shift costs */
97 1, /* constant shift costs */
98 4, /* cost of starting a multiply */
99 0, /* cost of multiply per each bit set */
100 17 /* cost of a divide/mod */
101};
102
73fe76e4
JH
103/* We use decoding time together with execution time.
104 To get correct vale add 1 for short decodable, 2 for long decodable
105 and 4 for vector decodable instruction to execution time and divide
106 by two (because CPU is able to do two insns at a time). */
107
a269a03c
JC
108struct processor_costs k6_cost = {
109 1, /* cost of an add instruction */
110 1, /* cost of a lea instruction */
111 1, /* variable shift costs */
112 1, /* constant shift costs */
73fe76e4 113 3, /* cost of starting a multiply */
a269a03c 114 0, /* cost of multiply per each bit set */
73fe76e4 115 20 /* cost of a divide/mod */
a269a03c
JC
116};
117
32b5b1aa
SC
118struct processor_costs *ix86_cost = &pentium_cost;
119
a269a03c
JC
120/* Processor feature/optimization bitmasks. */
121#define m_386 (1<<PROCESSOR_I386)
122#define m_486 (1<<PROCESSOR_I486)
123#define m_PENT (1<<PROCESSOR_PENTIUM)
124#define m_PPRO (1<<PROCESSOR_PENTIUMPRO)
125#define m_K6 (1<<PROCESSOR_K6)
126
127const int x86_use_leave = m_386 | m_K6;
128const int x86_push_memory = m_386 | m_K6;
129const int x86_zero_extend_with_and = m_486 | m_PENT;
130const int x86_movx = m_386 | m_PPRO | m_K6;
0a726ef1 131const int x86_double_with_add = ~(m_386 | m_PENT | m_PPRO);
a269a03c
JC
132const int x86_use_bit_test = m_386;
133const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO;
134const int x86_use_q_reg = m_PENT | m_PPRO | m_K6;
135const int x86_use_any_reg = m_486;
136const int x86_cmove = m_PPRO;
137const int x86_deep_branch = m_PPRO| m_K6;
138
f64cecad 139#define AT_BP(mode) (gen_rtx_MEM ((mode), frame_pointer_rtx))
2a2ab3f9
JVA
140
141extern FILE *asm_out_file;
142extern char *strcat ();
143
e9a25f70
JL
144static void ix86_epilogue PROTO((int));
145static void ix86_prologue PROTO((int));
146
2a2ab3f9
JVA
147char *singlemove_string ();
148char *output_move_const_single ();
c572e5ba 149char *output_fp_cc0_set ();
2a2ab3f9 150
35b63115
RS
151char *hi_reg_name[] = HI_REGISTER_NAMES;
152char *qi_reg_name[] = QI_REGISTER_NAMES;
153char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
4c0d89b5
RS
154
155/* Array of the smallest class containing reg number REGNO, indexed by
156 REGNO. Used by REGNO_REG_CLASS in i386.h. */
157
158enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
159{
160 /* ax, dx, cx, bx */
ab408a86 161 AREG, DREG, CREG, BREG,
4c0d89b5
RS
162 /* si, di, bp, sp */
163 SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
164 /* FP registers */
165 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
79325812 166 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
4c0d89b5
RS
167 /* arg pointer */
168 INDEX_REGS
169};
c572e5ba
JVA
170
171/* Test and compare insns in i386.md store the information needed to
172 generate branch and scc insns here. */
173
f5316dfe
MM
174struct rtx_def *i386_compare_op0 = NULL_RTX;
175struct rtx_def *i386_compare_op1 = NULL_RTX;
c572e5ba 176struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
f5316dfe 177
c8c5cb99
SC
178/* which cpu are we scheduling for */
179enum processor_type ix86_cpu;
180
181/* which instruction set architecture to use. */
c942177e 182int ix86_arch;
c8c5cb99
SC
183
184/* Strings to hold which cpu and instruction set architecture to use. */
185char *ix86_cpu_string; /* for -mcpu=<xxx> */
c942177e 186char *ix86_arch_string; /* for -march=<xxx> */
c8c5cb99 187
f5316dfe 188/* Register allocation order */
b08de47e 189char *i386_reg_alloc_order;
f5316dfe
MM
190static char regs_allocated[FIRST_PSEUDO_REGISTER];
191
b08de47e 192/* # of registers to use to pass arguments. */
e9a25f70
JL
193char *i386_regparm_string;
194
195/* i386_regparm_string as a number */
196int i386_regparm;
197
198/* Alignment to use for loops and jumps: */
199
200/* Power of two alignment for loops. */
201char *i386_align_loops_string;
202
203/* Power of two alignment for non-loop jumps. */
204char *i386_align_jumps_string;
205
3af4bd89
JH
206/* Power of two alignment for stack boundary in bytes. */
207char *i386_preferred_stack_boundary_string;
208
209/* Preferred alignment for stack boundary in bits. */
210int i386_preferred_stack_boundary;
211
e9a25f70
JL
212/* Values 1-5: see jump.c */
213int i386_branch_cost;
214char *i386_branch_cost_string;
215
216/* Power of two alignment for functions. */
217int i386_align_funcs;
218char *i386_align_funcs_string;
b08de47e 219
e9a25f70
JL
220/* Power of two alignment for loops. */
221int i386_align_loops;
b08de47e 222
e9a25f70
JL
223/* Power of two alignment for non-loop jumps. */
224int i386_align_jumps;
b08de47e 225
f5316dfe
MM
226/* Sometimes certain combinations of command options do not make
227 sense on a particular target machine. You can define a macro
228 `OVERRIDE_OPTIONS' to take account of this. This macro, if
229 defined, is executed once just after all the command options have
230 been parsed.
231
232 Don't use this macro to turn on various extra optimizations for
233 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
234
235void
236override_options ()
237{
00c79232 238 int ch, i, j;
b08de47e 239 int def_align;
f5316dfe 240
c8c5cb99
SC
241 static struct ptt
242 {
243 char *name; /* Canonical processor name. */
244 enum processor_type processor; /* Processor type enum value. */
32b5b1aa 245 struct processor_costs *cost; /* Processor costs */
c8c5cb99
SC
246 int target_enable; /* Target flags to enable. */
247 int target_disable; /* Target flags to disable. */
3af4bd89
JH
248 } processor_target_table[] = {
249 {PROCESSOR_I386_STRING, PROCESSOR_I386, &i386_cost, 0, 0},
250 {PROCESSOR_I486_STRING, PROCESSOR_I486, &i486_cost, 0, 0},
251 {PROCESSOR_I586_STRING, PROCESSOR_PENTIUM, &pentium_cost, 0, 0},
252 {PROCESSOR_PENTIUM_STRING, PROCESSOR_PENTIUM, &pentium_cost, 0, 0},
253 {PROCESSOR_I686_STRING, PROCESSOR_PENTIUMPRO, &pentiumpro_cost, 0, 0},
254 {PROCESSOR_PENTIUMPRO_STRING, PROCESSOR_PENTIUMPRO,
255 &pentiumpro_cost, 0, 0},
256 {PROCESSOR_K6_STRING, PROCESSOR_K6, &k6_cost, 0, 0}
257 };
c8c5cb99
SC
258
259 int ptt_size = sizeof (processor_target_table) / sizeof (struct ptt);
260
f5316dfe
MM
261#ifdef SUBTARGET_OVERRIDE_OPTIONS
262 SUBTARGET_OVERRIDE_OPTIONS;
263#endif
264
e9a25f70 265 /* Validate registers in register allocation order. */
f5316dfe
MM
266 if (i386_reg_alloc_order)
267 {
268 for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
269 {
00c79232 270 int regno = 0;
79325812 271
f5316dfe
MM
272 switch (ch)
273 {
274 case 'a': regno = 0; break;
275 case 'd': regno = 1; break;
276 case 'c': regno = 2; break;
277 case 'b': regno = 3; break;
278 case 'S': regno = 4; break;
279 case 'D': regno = 5; break;
280 case 'B': regno = 6; break;
281
282 default: fatal ("Register '%c' is unknown", ch);
283 }
284
285 if (regs_allocated[regno])
e9a25f70 286 fatal ("Register '%c' already specified in allocation order", ch);
f5316dfe
MM
287
288 regs_allocated[regno] = 1;
289 }
290 }
b08de47e 291
e9a25f70 292 if (ix86_arch_string == 0)
7cae778a 293 {
c942177e 294 ix86_arch_string = PROCESSOR_PENTIUM_STRING;
e9a25f70 295 if (ix86_cpu_string == 0)
7cae778a
SC
296 ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
297 }
79325812 298
c8c5cb99 299 for (i = 0; i < ptt_size; i++)
c942177e 300 if (! strcmp (ix86_arch_string, processor_target_table[i].name))
c8c5cb99 301 {
c942177e 302 ix86_arch = processor_target_table[i].processor;
e9a25f70 303 if (ix86_cpu_string == 0)
77a989d1 304 ix86_cpu_string = processor_target_table[i].name;
c8c5cb99
SC
305 break;
306 }
307
308 if (i == ptt_size)
309 {
c942177e 310 error ("bad value (%s) for -march= switch", ix86_arch_string);
4f74d15b 311 ix86_arch_string = PROCESSOR_PENTIUM_STRING;
c942177e 312 ix86_arch = PROCESSOR_DEFAULT;
c8c5cb99
SC
313 }
314
e9a25f70
JL
315 if (ix86_cpu_string == 0)
316 ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
4f74d15b 317
c8c5cb99
SC
318 for (j = 0; j < ptt_size; j++)
319 if (! strcmp (ix86_cpu_string, processor_target_table[j].name))
320 {
321 ix86_cpu = processor_target_table[j].processor;
856b07a1 322 ix86_cost = processor_target_table[j].cost;
a269a03c 323 if (i > j && (int) ix86_arch >= (int) PROCESSOR_K6)
e9a25f70
JL
324 error ("-mcpu=%s does not support -march=%s",
325 ix86_cpu_string, ix86_arch_string);
c8c5cb99
SC
326
327 target_flags |= processor_target_table[j].target_enable;
328 target_flags &= ~processor_target_table[j].target_disable;
329 break;
330 }
331
332 if (j == ptt_size)
333 {
334 error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
335 ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
336 ix86_cpu = PROCESSOR_DEFAULT;
337 }
e9a25f70
JL
338
339 /* Validate -mregparm= value. */
b08de47e
MM
340 if (i386_regparm_string)
341 {
342 i386_regparm = atoi (i386_regparm_string);
343 if (i386_regparm < 0 || i386_regparm > REGPARM_MAX)
e9a25f70
JL
344 fatal ("-mregparm=%d is not between 0 and %d",
345 i386_regparm, REGPARM_MAX);
b08de47e
MM
346 }
347
e9a25f70
JL
348 /* The 486 suffers more from non-aligned cache line fills, and the
349 larger code size results in a larger cache foot-print and more misses.
350 The 486 has a 16 byte cache line, pentium and pentiumpro have a 32 byte
351 cache line. */
d4e2f547 352 def_align = (TARGET_486) ? 4 : 2;
b08de47e 353
e9a25f70 354 /* Validate -malign-loops= value, or provide default. */
3af4bd89
JH
355#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
356 i386_align_loops = 4;
357#else
358 i386_align_loops = 2;
359#endif
b08de47e
MM
360 if (i386_align_loops_string)
361 {
362 i386_align_loops = atoi (i386_align_loops_string);
363 if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN)
364 fatal ("-malign-loops=%d is not between 0 and %d",
365 i386_align_loops, MAX_CODE_ALIGN);
366 }
3af4bd89
JH
367
368 /* Validate -malign-jumps= value, or provide default. */
9e423e6d 369#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
3af4bd89 370 i386_align_jumps = 4;
9e423e6d 371#else
3af4bd89 372 i386_align_jumps = def_align;
9e423e6d 373#endif
b08de47e
MM
374 if (i386_align_jumps_string)
375 {
376 i386_align_jumps = atoi (i386_align_jumps_string);
377 if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN)
378 fatal ("-malign-jumps=%d is not between 0 and %d",
379 i386_align_jumps, MAX_CODE_ALIGN);
380 }
b08de47e 381
e9a25f70 382 /* Validate -malign-functions= value, or provide default. */
3af4bd89 383 i386_align_funcs = def_align;
b08de47e
MM
384 if (i386_align_funcs_string)
385 {
386 i386_align_funcs = atoi (i386_align_funcs_string);
387 if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN)
388 fatal ("-malign-functions=%d is not between 0 and %d",
389 i386_align_funcs, MAX_CODE_ALIGN);
390 }
3af4bd89
JH
391
392 /* Validate -mpreferred_stack_boundary= value, or provide default.
393 The default of 128 bits is for Pentium III's SSE __m128. */
394 i386_preferred_stack_boundary = 128;
395 if (i386_preferred_stack_boundary_string)
396 {
397 i = atoi (i386_preferred_stack_boundary_string);
398 if (i < 2 || i > 31)
399 fatal ("-mpreferred_stack_boundary=%d is not between 2 and 31", i);
400 i386_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
401 }
77a989d1 402
e9a25f70 403 /* Validate -mbranch-cost= value, or provide default. */
3af4bd89 404 i386_branch_cost = 1;
804a8ee0
SC
405 if (i386_branch_cost_string)
406 {
407 i386_branch_cost = atoi (i386_branch_cost_string);
408 if (i386_branch_cost < 0 || i386_branch_cost > 5)
3af4bd89 409 fatal ("-mbranch-cost=%d is not between 0 and 5", i386_branch_cost);
804a8ee0 410 }
804a8ee0 411
e9a25f70
JL
412 /* Keep nonleaf frame pointers. */
413 if (TARGET_OMIT_LEAF_FRAME_POINTER)
77a989d1 414 flag_omit_frame_pointer = 1;
f5316dfe
MM
415}
416\f
417/* A C statement (sans semicolon) to choose the order in which to
418 allocate hard registers for pseudo-registers local to a basic
419 block.
420
421 Store the desired register order in the array `reg_alloc_order'.
422 Element 0 should be the register to allocate first; element 1, the
423 next register; and so on.
424
425 The macro body should not assume anything about the contents of
426 `reg_alloc_order' before execution of the macro.
427
428 On most machines, it is not necessary to define this macro. */
429
430void
431order_regs_for_local_alloc ()
432{
00c79232 433 int i, ch, order;
f5316dfe 434
e9a25f70
JL
435 /* User specified the register allocation order. */
436
f5316dfe
MM
437 if (i386_reg_alloc_order)
438 {
439 for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
440 {
00c79232 441 int regno = 0;
79325812 442
f5316dfe
MM
443 switch (ch)
444 {
445 case 'a': regno = 0; break;
446 case 'd': regno = 1; break;
447 case 'c': regno = 2; break;
448 case 'b': regno = 3; break;
449 case 'S': regno = 4; break;
450 case 'D': regno = 5; break;
451 case 'B': regno = 6; break;
452 }
453
454 reg_alloc_order[order++] = regno;
455 }
456
457 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
458 {
e9a25f70 459 if (! regs_allocated[i])
f5316dfe
MM
460 reg_alloc_order[order++] = i;
461 }
462 }
463
e9a25f70 464 /* If user did not specify a register allocation order, use natural order. */
f5316dfe
MM
465 else
466 {
467 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
468 reg_alloc_order[i] = i;
f5316dfe
MM
469 }
470}
32b5b1aa
SC
471\f
472void
c6aded7c 473optimization_options (level, size)
32b5b1aa 474 int level;
bb5177ac 475 int size ATTRIBUTE_UNUSED;
32b5b1aa 476{
e9a25f70
JL
477 /* For -O2 and beyond, turn off -fschedule-insns by default. It tends to
478 make the problem with not enough registers even worse. */
32b5b1aa
SC
479#ifdef INSN_SCHEDULING
480 if (level > 1)
481 flag_schedule_insns = 0;
482#endif
483}
b08de47e 484\f
5bc7cd8e
SC
485/* Sign-extend a 16-bit constant */
486
487struct rtx_def *
488i386_sext16_if_const (op)
489 struct rtx_def *op;
490{
491 if (GET_CODE (op) == CONST_INT)
492 {
493 HOST_WIDE_INT val = INTVAL (op);
494 HOST_WIDE_INT sext_val;
495 if (val & 0x8000)
496 sext_val = val | ~0xffff;
497 else
498 sext_val = val & 0xffff;
499 if (sext_val != val)
500 op = GEN_INT (sext_val);
501 }
502 return op;
503}
504\f
505/* Return nonzero if the rtx is aligned */
506
507static int
508i386_aligned_reg_p (regno)
509 int regno;
510{
511 return (regno == STACK_POINTER_REGNUM
e9a25f70 512 || (! flag_omit_frame_pointer && regno == FRAME_POINTER_REGNUM));
5bc7cd8e
SC
513}
514
515int
516i386_aligned_p (op)
517 rtx op;
518{
e9a25f70 519 /* Registers and immediate operands are always "aligned". */
5bc7cd8e
SC
520 if (GET_CODE (op) != MEM)
521 return 1;
522
e9a25f70 523 /* Don't even try to do any aligned optimizations with volatiles. */
5bc7cd8e
SC
524 if (MEM_VOLATILE_P (op))
525 return 0;
526
e9a25f70 527 /* Get address of memory operand. */
5bc7cd8e
SC
528 op = XEXP (op, 0);
529
530 switch (GET_CODE (op))
531 {
532 case CONST_INT:
e9a25f70
JL
533 if (INTVAL (op) & 3)
534 break;
535 return 1;
5bc7cd8e 536
e9a25f70 537 /* Match "reg + offset" */
5bc7cd8e 538 case PLUS:
e9a25f70
JL
539 if (GET_CODE (XEXP (op, 1)) != CONST_INT)
540 break;
541 if (INTVAL (XEXP (op, 1)) & 3)
542 break;
543
544 op = XEXP (op, 0);
545 if (GET_CODE (op) != REG)
546 break;
547
548 /* ... fall through ... */
549
5bc7cd8e 550 case REG:
e9a25f70 551 return i386_aligned_reg_p (REGNO (op));
79325812 552
00c79232 553 default:
53949fac 554 break;
5bc7cd8e 555 }
e9a25f70 556
5bc7cd8e
SC
557 return 0;
558}
559\f
560/* Return nonzero if INSN looks like it won't compute useful cc bits
561 as a side effect. This information is only a hint. */
562
563int
564i386_cc_probably_useless_p (insn)
565 rtx insn;
566{
e9a25f70 567 return ! next_cc0_user (insn);
5bc7cd8e
SC
568}
569\f
b08de47e
MM
570/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
571 attribute for DECL. The attributes in ATTRIBUTES have previously been
572 assigned to DECL. */
573
574int
575i386_valid_decl_attribute_p (decl, attributes, identifier, args)
bb5177ac
RL
576 tree decl ATTRIBUTE_UNUSED;
577 tree attributes ATTRIBUTE_UNUSED;
578 tree identifier ATTRIBUTE_UNUSED;
579 tree args ATTRIBUTE_UNUSED;
b08de47e
MM
580{
581 return 0;
582}
583
584/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
585 attribute for TYPE. The attributes in ATTRIBUTES have previously been
586 assigned to TYPE. */
587
588int
589i386_valid_type_attribute_p (type, attributes, identifier, args)
590 tree type;
bb5177ac 591 tree attributes ATTRIBUTE_UNUSED;
b08de47e
MM
592 tree identifier;
593 tree args;
594{
595 if (TREE_CODE (type) != FUNCTION_TYPE
ac478ac0 596 && TREE_CODE (type) != METHOD_TYPE
b08de47e
MM
597 && TREE_CODE (type) != FIELD_DECL
598 && TREE_CODE (type) != TYPE_DECL)
599 return 0;
600
601 /* Stdcall attribute says callee is responsible for popping arguments
602 if they are not variable. */
603 if (is_attribute_p ("stdcall", identifier))
604 return (args == NULL_TREE);
605
e9a25f70 606 /* Cdecl attribute says the callee is a normal C declaration. */
b08de47e
MM
607 if (is_attribute_p ("cdecl", identifier))
608 return (args == NULL_TREE);
609
610 /* Regparm attribute specifies how many integer arguments are to be
e9a25f70 611 passed in registers. */
b08de47e
MM
612 if (is_attribute_p ("regparm", identifier))
613 {
614 tree cst;
615
e9a25f70 616 if (! args || TREE_CODE (args) != TREE_LIST
b08de47e
MM
617 || TREE_CHAIN (args) != NULL_TREE
618 || TREE_VALUE (args) == NULL_TREE)
619 return 0;
620
621 cst = TREE_VALUE (args);
622 if (TREE_CODE (cst) != INTEGER_CST)
623 return 0;
624
625 if (TREE_INT_CST_HIGH (cst) != 0
626 || TREE_INT_CST_LOW (cst) < 0
627 || TREE_INT_CST_LOW (cst) > REGPARM_MAX)
628 return 0;
629
630 return 1;
631 }
632
633 return 0;
634}
635
636/* Return 0 if the attributes for two types are incompatible, 1 if they
637 are compatible, and 2 if they are nearly compatible (which causes a
638 warning to be generated). */
639
640int
641i386_comp_type_attributes (type1, type2)
afcfe58c
MM
642 tree type1;
643 tree type2;
b08de47e 644{
afcfe58c
MM
645 /* Check for mismatch of non-default calling convention. */
646 char *rtdstr = TARGET_RTD ? "cdecl" : "stdcall";
647
648 if (TREE_CODE (type1) != FUNCTION_TYPE)
649 return 1;
650
651 /* Check for mismatched return types (cdecl vs stdcall). */
6093f019
RH
652 if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
653 != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
afcfe58c 654 return 0;
b08de47e
MM
655 return 1;
656}
657
658\f
659/* Value is the number of bytes of arguments automatically
660 popped when returning from a subroutine call.
661 FUNDECL is the declaration node of the function (as a tree),
662 FUNTYPE is the data type of the function (as a tree),
663 or for a library call it is an identifier node for the subroutine name.
664 SIZE is the number of bytes of arguments passed on the stack.
665
666 On the 80386, the RTD insn may be used to pop them if the number
667 of args is fixed, but if the number is variable then the caller
668 must pop them all. RTD can't be used for library calls now
669 because the library is compiled with the Unix compiler.
670 Use of RTD is a selectable option, since it is incompatible with
671 standard Unix calling sequences. If the option is not selected,
672 the caller must always pop the args.
673
674 The attribute stdcall is equivalent to RTD on a per module basis. */
675
676int
677i386_return_pops_args (fundecl, funtype, size)
678 tree fundecl;
679 tree funtype;
680 int size;
79325812 681{
3345ee7d 682 int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
b08de47e 683
e9a25f70
JL
684 /* Cdecl functions override -mrtd, and never pop the stack. */
685 if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
79325812 686
e9a25f70 687 /* Stdcall functions will pop the stack if not variable args. */
698cdd84
SC
688 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
689 rtd = 1;
79325812 690
698cdd84
SC
691 if (rtd
692 && (TYPE_ARG_TYPES (funtype) == NULL_TREE
e9a25f70
JL
693 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype)))
694 == void_type_node)))
698cdd84
SC
695 return size;
696 }
79325812 697
e9a25f70 698 /* Lose any fake structure return argument. */
698cdd84
SC
699 if (aggregate_value_p (TREE_TYPE (funtype)))
700 return GET_MODE_SIZE (Pmode);
79325812 701
2614aac6 702 return 0;
b08de47e
MM
703}
704
705\f
706/* Argument support functions. */
707
708/* Initialize a variable CUM of type CUMULATIVE_ARGS
709 for a call to a function whose data type is FNTYPE.
710 For a library call, FNTYPE is 0. */
711
712void
713init_cumulative_args (cum, fntype, libname)
e9a25f70 714 CUMULATIVE_ARGS *cum; /* Argument info to initialize */
b08de47e
MM
715 tree fntype; /* tree ptr for function decl */
716 rtx libname; /* SYMBOL_REF of library name or 0 */
717{
718 static CUMULATIVE_ARGS zero_cum;
719 tree param, next_param;
720
721 if (TARGET_DEBUG_ARG)
722 {
723 fprintf (stderr, "\ninit_cumulative_args (");
724 if (fntype)
e9a25f70
JL
725 fprintf (stderr, "fntype code = %s, ret code = %s",
726 tree_code_name[(int) TREE_CODE (fntype)],
727 tree_code_name[(int) TREE_CODE (TREE_TYPE (fntype))]);
b08de47e
MM
728 else
729 fprintf (stderr, "no fntype");
730
731 if (libname)
732 fprintf (stderr, ", libname = %s", XSTR (libname, 0));
733 }
734
735 *cum = zero_cum;
736
737 /* Set up the number of registers to use for passing arguments. */
738 cum->nregs = i386_regparm;
739 if (fntype)
740 {
741 tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
e9a25f70 742
b08de47e
MM
743 if (attr)
744 cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
745 }
746
747 /* Determine if this function has variable arguments. This is
748 indicated by the last argument being 'void_type_mode' if there
749 are no variable arguments. If there are variable arguments, then
750 we won't pass anything in registers */
751
752 if (cum->nregs)
753 {
754 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
e9a25f70 755 param != 0; param = next_param)
b08de47e
MM
756 {
757 next_param = TREE_CHAIN (param);
e9a25f70 758 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
b08de47e
MM
759 cum->nregs = 0;
760 }
761 }
762
763 if (TARGET_DEBUG_ARG)
764 fprintf (stderr, ", nregs=%d )\n", cum->nregs);
765
766 return;
767}
768
769/* Update the data in CUM to advance over an argument
770 of mode MODE and data type TYPE.
771 (TYPE is null for libcalls where that information may not be available.) */
772
773void
774function_arg_advance (cum, mode, type, named)
775 CUMULATIVE_ARGS *cum; /* current arg information */
776 enum machine_mode mode; /* current arg mode */
777 tree type; /* type of the argument or 0 if lib support */
778 int named; /* whether or not the argument was named */
779{
e9a25f70
JL
780 int bytes
781 = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
b08de47e
MM
782 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
783
784 if (TARGET_DEBUG_ARG)
785 fprintf (stderr,
e9a25f70 786 "function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
b08de47e
MM
787 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
788
789 cum->words += words;
790 cum->nregs -= words;
791 cum->regno += words;
792
793 if (cum->nregs <= 0)
794 {
795 cum->nregs = 0;
796 cum->regno = 0;
797 }
798
799 return;
800}
801
802/* Define where to put the arguments to a function.
803 Value is zero to push the argument on the stack,
804 or a hard register in which to store the argument.
805
806 MODE is the argument's machine mode.
807 TYPE is the data type of the argument (as a tree).
808 This is null for libcalls where that information may
809 not be available.
810 CUM is a variable of type CUMULATIVE_ARGS which gives info about
811 the preceding args and about the function being called.
812 NAMED is nonzero if this argument is a named parameter
813 (otherwise it is an extra parameter matching an ellipsis). */
814
815struct rtx_def *
816function_arg (cum, mode, type, named)
817 CUMULATIVE_ARGS *cum; /* current arg information */
818 enum machine_mode mode; /* current arg mode */
819 tree type; /* type of the argument or 0 if lib support */
820 int named; /* != 0 for normal args, == 0 for ... args */
821{
822 rtx ret = NULL_RTX;
e9a25f70
JL
823 int bytes
824 = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
b08de47e
MM
825 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
826
827 switch (mode)
828 {
e9a25f70
JL
829 /* For now, pass fp/complex values on the stack. */
830 default:
b08de47e
MM
831 break;
832
833 case BLKmode:
834 case DImode:
835 case SImode:
836 case HImode:
837 case QImode:
838 if (words <= cum->nregs)
f64cecad 839 ret = gen_rtx_REG (mode, cum->regno);
b08de47e
MM
840 break;
841 }
842
843 if (TARGET_DEBUG_ARG)
844 {
845 fprintf (stderr,
e9a25f70 846 "function_arg (size=%d, wds=%2d, nregs=%d, mode=%4s, named=%d",
b08de47e
MM
847 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
848
849 if (ret)
850 fprintf (stderr, ", reg=%%e%s", reg_names[ REGNO(ret) ]);
851 else
852 fprintf (stderr, ", stack");
853
854 fprintf (stderr, " )\n");
855 }
856
857 return ret;
858}
859
860/* For an arg passed partly in registers and partly in memory,
861 this is the number of registers used.
862 For args passed entirely in registers or entirely in memory, zero. */
863
864int
865function_arg_partial_nregs (cum, mode, type, named)
bb5177ac
RL
866 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED; /* current arg information */
867 enum machine_mode mode ATTRIBUTE_UNUSED; /* current arg mode */
868 tree type ATTRIBUTE_UNUSED; /* type of the argument or 0 if lib support */
869 int named ATTRIBUTE_UNUSED; /* != 0 for normal args, == 0 for ... args */
b08de47e
MM
870{
871 return 0;
872}
2a2ab3f9 873\f
2a2ab3f9
JVA
874/* Output an insn to pop an value from the 387 top-of-stack to 386
875 register DEST. The 387 register stack is popped if DIES is true. If
876 the mode of DEST is an integer mode, a `fist' integer store is done,
877 otherwise a `fst' float store is done. */
878
879void
c27d9c3b 880output_to_reg (dest, dies, scratch_mem)
2a2ab3f9
JVA
881 rtx dest;
882 int dies;
c27d9c3b 883 rtx scratch_mem;
2a2ab3f9
JVA
884{
885 rtx xops[4];
5f1ec3e6 886 int size = GET_MODE_SIZE (GET_MODE (dest));
2a2ab3f9 887
c27d9c3b
SC
888 if (! scratch_mem)
889 xops[0] = AT_SP (Pmode);
890 else
891 xops[0] = scratch_mem;
e9a25f70 892
2a2ab3f9 893 xops[1] = stack_pointer_rtx;
5f1ec3e6 894 xops[2] = GEN_INT (size);
2a2ab3f9
JVA
895 xops[3] = dest;
896
c27d9c3b
SC
897 if (! scratch_mem)
898 output_asm_insn (AS2 (sub%L1,%2,%1), xops);
2a2ab3f9
JVA
899
900 if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
901 {
902 if (dies)
903 output_asm_insn (AS1 (fistp%z3,%y0), xops);
60aeab7f
L
904 else if (GET_MODE (xops[3]) == DImode && ! dies)
905 {
906 /* There is no DImode version of this without a stack pop, so
907 we must emulate it. It doesn't matter much what the second
908 instruction is, because the value being pushed on the FP stack
909 is not used except for the following stack popping store.
910 This case can only happen without optimization, so it doesn't
911 matter that it is inefficient. */
912 output_asm_insn (AS1 (fistp%z3,%0), xops);
913 output_asm_insn (AS1 (fild%z3,%0), xops);
914 }
2a2ab3f9
JVA
915 else
916 output_asm_insn (AS1 (fist%z3,%y0), xops);
917 }
e9a25f70 918
2a2ab3f9
JVA
919 else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
920 {
921 if (dies)
922 output_asm_insn (AS1 (fstp%z3,%y0), xops);
923 else
5f1ec3e6
JVA
924 {
925 if (GET_MODE (dest) == XFmode)
30387275
JVA
926 {
927 output_asm_insn (AS1 (fstp%z3,%y0), xops);
928 output_asm_insn (AS1 (fld%z3,%y0), xops);
929 }
5f1ec3e6
JVA
930 else
931 output_asm_insn (AS1 (fst%z3,%y0), xops);
932 }
2a2ab3f9 933 }
e9a25f70 934
2a2ab3f9
JVA
935 else
936 abort ();
937
c27d9c3b
SC
938 if (! scratch_mem)
939 output_asm_insn (AS1 (pop%L0,%0), &dest);
940 else
941 output_asm_insn (AS2 (mov%L0,%0,%3), xops);
942
2a2ab3f9 943
5f1ec3e6 944 if (size > UNITS_PER_WORD)
2a2ab3f9 945 {
f64cecad 946 dest = gen_rtx_REG (SImode, REGNO (dest) + 1);
c27d9c3b
SC
947 if (! scratch_mem)
948 output_asm_insn (AS1 (pop%L0,%0), &dest);
949 else
950 {
79325812 951 xops[0] = adj_offsettable_operand (xops[0], 4);
c27d9c3b
SC
952 xops[3] = dest;
953 output_asm_insn (AS2 (mov%L0,%0,%3), xops);
954 }
e9a25f70 955
5f1ec3e6
JVA
956 if (size > 2 * UNITS_PER_WORD)
957 {
f64cecad 958 dest = gen_rtx_REG (SImode, REGNO (dest) + 1);
c27d9c3b
SC
959 if (! scratch_mem)
960 output_asm_insn (AS1 (pop%L0,%0), &dest);
961 else
962 {
79325812 963 xops[0] = adj_offsettable_operand (xops[0], 4);
c27d9c3b
SC
964 output_asm_insn (AS2 (mov%L0,%0,%3), xops);
965 }
5f1ec3e6 966 }
2a2ab3f9
JVA
967 }
968}
969\f
970char *
971singlemove_string (operands)
972 rtx *operands;
973{
974 rtx x;
975 if (GET_CODE (operands[0]) == MEM
976 && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
977 {
978 if (XEXP (x, 0) != stack_pointer_rtx)
979 abort ();
980 return "push%L1 %1";
981 }
982 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
e9a25f70 983 return output_move_const_single (operands);
2a2ab3f9
JVA
984 else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
985 return AS2 (mov%L0,%1,%0);
986 else if (CONSTANT_P (operands[1]))
987 return AS2 (mov%L0,%1,%0);
988 else
989 {
990 output_asm_insn ("push%L1 %1", operands);
991 return "pop%L0 %0";
992 }
993}
994\f
2a2ab3f9
JVA
995/* Output an insn to add the constant N to the register X. */
996
997static void
998asm_add (n, x)
999 int n;
1000 rtx x;
1001{
1002 rtx xops[2];
3b3c6a3f
MM
1003 xops[0] = x;
1004
1005 if (n == -1)
1006 output_asm_insn (AS1 (dec%L0,%0), xops);
1007 else if (n == 1)
1008 output_asm_insn (AS1 (inc%L0,%0), xops);
5bc7cd8e 1009 else if (n < 0 || n == 128)
2a2ab3f9 1010 {
3b3c6a3f
MM
1011 xops[1] = GEN_INT (-n);
1012 output_asm_insn (AS2 (sub%L0,%1,%0), xops);
2a2ab3f9
JVA
1013 }
1014 else if (n > 0)
1015 {
3b3c6a3f
MM
1016 xops[1] = GEN_INT (n);
1017 output_asm_insn (AS2 (add%L0,%1,%0), xops);
2a2ab3f9
JVA
1018 }
1019}
b840bfb0 1020\f
2a2ab3f9
JVA
1021/* Output assembler code to perform a doubleword move insn
1022 with operands OPERANDS. */
1023
1024char *
1025output_move_double (operands)
1026 rtx *operands;
1027{
1028 enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
1029 rtx latehalf[2];
5f1ec3e6
JVA
1030 rtx middlehalf[2];
1031 rtx xops[2];
85ddb399 1032 int dest_overlapped_low = 0;
57e1b65c 1033 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
5f1ec3e6
JVA
1034
1035 middlehalf[0] = 0;
1036 middlehalf[1] = 0;
2a2ab3f9
JVA
1037
1038 /* First classify both operands. */
1039
1040 if (REG_P (operands[0]))
1041 optype0 = REGOP;
1042 else if (offsettable_memref_p (operands[0]))
1043 optype0 = OFFSOP;
1044 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1045 optype0 = POPOP;
1046 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1047 optype0 = PUSHOP;
1048 else if (GET_CODE (operands[0]) == MEM)
1049 optype0 = MEMOP;
1050 else
1051 optype0 = RNDOP;
1052
1053 if (REG_P (operands[1]))
1054 optype1 = REGOP;
1055 else if (CONSTANT_P (operands[1]))
1056 optype1 = CNSTOP;
1057 else if (offsettable_memref_p (operands[1]))
1058 optype1 = OFFSOP;
1059 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
1060 optype1 = POPOP;
1061 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
1062 optype1 = PUSHOP;
1063 else if (GET_CODE (operands[1]) == MEM)
1064 optype1 = MEMOP;
1065 else
1066 optype1 = RNDOP;
1067
296967fe
JW
1068 /* Check for the cases that are not supposed to happen
1069 either due to the operand constraints or the fact
1070 that all memory operands on the x86 are offsettable.
1071 Abort if we get one, because generating code for these
1072 cases is painful. */
2a2ab3f9 1073
296967fe
JW
1074 if (optype0 == RNDOP || optype1 == RNDOP
1075 || optype0 == MEMOP || optype1 == MEMOP)
2a2ab3f9
JVA
1076 abort ();
1077
1078 /* If one operand is decrementing and one is incrementing
1079 decrement the former register explicitly
1080 and change that operand into ordinary indexing. */
1081
1082 if (optype0 == PUSHOP && optype1 == POPOP)
1083 {
5f1ec3e6 1084 /* ??? Can this ever happen on i386? */
2a2ab3f9 1085 operands[0] = XEXP (XEXP (operands[0], 0), 0);
5f1ec3e6
JVA
1086 asm_add (-size, operands[0]);
1087 if (GET_MODE (operands[1]) == XFmode)
f64cecad 1088 operands[0] = gen_rtx_MEM (XFmode, operands[0]);
5f1ec3e6 1089 else if (GET_MODE (operands[0]) == DFmode)
f64cecad 1090 operands[0] = gen_rtx_MEM (DFmode, operands[0]);
5f1ec3e6 1091 else
f64cecad 1092 operands[0] = gen_rtx_MEM (DImode, operands[0]);
2a2ab3f9
JVA
1093 optype0 = OFFSOP;
1094 }
5f1ec3e6 1095
2a2ab3f9
JVA
1096 if (optype0 == POPOP && optype1 == PUSHOP)
1097 {
5f1ec3e6 1098 /* ??? Can this ever happen on i386? */
2a2ab3f9 1099 operands[1] = XEXP (XEXP (operands[1], 0), 0);
5f1ec3e6
JVA
1100 asm_add (-size, operands[1]);
1101 if (GET_MODE (operands[1]) == XFmode)
f64cecad 1102 operands[1] = gen_rtx_MEM (XFmode, operands[1]);
5f1ec3e6 1103 else if (GET_MODE (operands[1]) == DFmode)
f64cecad 1104 operands[1] = gen_rtx_MEM (DFmode, operands[1]);
5f1ec3e6 1105 else
f64cecad 1106 operands[1] = gen_rtx_MEM (DImode, operands[1]);
2a2ab3f9
JVA
1107 optype1 = OFFSOP;
1108 }
1109
2a2ab3f9
JVA
1110 /* Ok, we can do one word at a time.
1111 Normally we do the low-numbered word first,
1112 but if either operand is autodecrementing then we
1113 do the high-numbered word first.
1114
1115 In either case, set up in LATEHALF the operands to use
1116 for the high-numbered word and in some cases alter the
1117 operands in OPERANDS to be suitable for the low-numbered word. */
1118
5f1ec3e6
JVA
1119 if (size == 12)
1120 {
1121 if (optype0 == REGOP)
1122 {
f64cecad
JC
1123 middlehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
1124 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
5f1ec3e6
JVA
1125 }
1126 else if (optype0 == OFFSOP)
1127 {
1128 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
1129 latehalf[0] = adj_offsettable_operand (operands[0], 8);
1130 }
1131 else
1132 {
1133 middlehalf[0] = operands[0];
1134 latehalf[0] = operands[0];
1135 }
79325812 1136
5f1ec3e6
JVA
1137 if (optype1 == REGOP)
1138 {
f64cecad
JC
1139 middlehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
1140 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
5f1ec3e6
JVA
1141 }
1142 else if (optype1 == OFFSOP)
1143 {
1144 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
1145 latehalf[1] = adj_offsettable_operand (operands[1], 8);
1146 }
1147 else if (optype1 == CNSTOP)
1148 {
1149 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1150 {
1151 REAL_VALUE_TYPE r; long l[3];
2a2ab3f9 1152
5f1ec3e6
JVA
1153 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1154 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
1155 operands[1] = GEN_INT (l[0]);
1156 middlehalf[1] = GEN_INT (l[1]);
1157 latehalf[1] = GEN_INT (l[2]);
1158 }
1159 else if (CONSTANT_P (operands[1]))
1160 /* No non-CONST_DOUBLE constant should ever appear here. */
1161 abort ();
1162 }
1163 else
1164 {
1165 middlehalf[1] = operands[1];
1166 latehalf[1] = operands[1];
1167 }
1168 }
e9a25f70
JL
1169
1170 else
2a2ab3f9 1171 {
e9a25f70
JL
1172 /* Size is not 12. */
1173
5f1ec3e6 1174 if (optype0 == REGOP)
f64cecad 1175 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
5f1ec3e6
JVA
1176 else if (optype0 == OFFSOP)
1177 latehalf[0] = adj_offsettable_operand (operands[0], 4);
1178 else
1179 latehalf[0] = operands[0];
1180
1181 if (optype1 == REGOP)
f64cecad 1182 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
5f1ec3e6
JVA
1183 else if (optype1 == OFFSOP)
1184 latehalf[1] = adj_offsettable_operand (operands[1], 4);
1185 else if (optype1 == CNSTOP)
57e1b65c 1186 split_double (operands[1], &operands[1], &latehalf[1]);
5f1ec3e6
JVA
1187 else
1188 latehalf[1] = operands[1];
2a2ab3f9 1189 }
2a2ab3f9
JVA
1190
1191 /* If insn is effectively movd N (sp),-(sp) then we will do the
e7c2087c
RS
1192 high word first. We should use the adjusted operand 1
1193 (which is N+4 (sp) or N+8 (sp))
1194 for the low word and middle word as well,
1195 to compensate for the first decrement of sp. */
2a2ab3f9
JVA
1196 if (optype0 == PUSHOP
1197 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
1198 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
e7c2087c 1199 middlehalf[1] = operands[1] = latehalf[1];
2a2ab3f9 1200
81fd0956 1201 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
85ddb399
RS
1202 if the upper part of reg N does not appear in the MEM, arrange to
1203 emit the move late-half first. Otherwise, compute the MEM address
1204 into the upper part of N and use that as a pointer to the memory
1205 operand. */
296967fe 1206 if (optype0 == REGOP && optype1 == OFFSOP)
81fd0956 1207 {
85ddb399
RS
1208 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
1209 && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
1210 {
1211 /* If both halves of dest are used in the src memory address,
1212 compute the address into latehalf of dest. */
e9a25f70 1213 compadr:
85ddb399
RS
1214 xops[0] = latehalf[0];
1215 xops[1] = XEXP (operands[1], 0);
1216 output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
e9a25f70 1217 if (GET_MODE (operands[1]) == XFmode)
5f1ec3e6 1218 {
f64cecad 1219 operands[1] = gen_rtx_MEM (XFmode, latehalf[0]);
5f1ec3e6
JVA
1220 middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
1221 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1222 }
1223 else
1224 {
f64cecad 1225 operands[1] = gen_rtx_MEM (DImode, latehalf[0]);
5f1ec3e6
JVA
1226 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
1227 }
1228 }
e9a25f70 1229
5f1ec3e6
JVA
1230 else if (size == 12
1231 && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0)))
1232 {
1233 /* Check for two regs used by both source and dest. */
1234 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
1235 || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
e9a25f70 1236 goto compadr;
5f1ec3e6 1237
5f1ec3e6
JVA
1238 /* Only the middle reg conflicts; simply put it last. */
1239 output_asm_insn (singlemove_string (operands), operands);
1240 output_asm_insn (singlemove_string (latehalf), latehalf);
1241 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1242 return "";
85ddb399 1243 }
e9a25f70 1244
85ddb399
RS
1245 else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
1246 /* If the low half of dest is mentioned in the source memory
1247 address, the arrange to emit the move late half first. */
1248 dest_overlapped_low = 1;
81fd0956
RS
1249 }
1250
2a2ab3f9
JVA
1251 /* If one or both operands autodecrementing,
1252 do the two words, high-numbered first. */
1253
1254 /* Likewise, the first move would clobber the source of the second one,
1255 do them in the other order. This happens only for registers;
1256 such overlap can't happen in memory unless the user explicitly
1257 sets it up, and that is an undefined circumstance. */
1258
e9a25f70 1259#if 0
2a2ab3f9
JVA
1260 if (optype0 == PUSHOP || optype1 == PUSHOP
1261 || (optype0 == REGOP && optype1 == REGOP
85ddb399
RS
1262 && REGNO (operands[0]) == REGNO (latehalf[1]))
1263 || dest_overlapped_low)
e9a25f70
JL
1264#endif
1265
5f1ec3e6
JVA
1266 if (optype0 == PUSHOP || optype1 == PUSHOP
1267 || (optype0 == REGOP && optype1 == REGOP
1268 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
1269 || REGNO (operands[0]) == REGNO (latehalf[1])))
1270 || dest_overlapped_low)
2a2ab3f9 1271 {
296967fe 1272 /* Do the high-numbered word. */
2a2ab3f9
JVA
1273 output_asm_insn (singlemove_string (latehalf), latehalf);
1274
5f1ec3e6 1275 if (size == 12)
296967fe 1276 output_asm_insn (singlemove_string (middlehalf), middlehalf);
5f1ec3e6 1277
2a2ab3f9
JVA
1278 /* Do low-numbered word. */
1279 return singlemove_string (operands);
1280 }
1281
1282 /* Normal case: do the two words, low-numbered first. */
1283
1284 output_asm_insn (singlemove_string (operands), operands);
1285
5f1ec3e6
JVA
1286 /* Do the middle one of the three words for long double */
1287 if (size == 12)
296967fe 1288 output_asm_insn (singlemove_string (middlehalf), middlehalf);
5f1ec3e6 1289
296967fe 1290 /* Do the high-numbered word. */
2a2ab3f9
JVA
1291 output_asm_insn (singlemove_string (latehalf), latehalf);
1292
2a2ab3f9
JVA
1293 return "";
1294}
b840bfb0
MM
1295\f
1296#define MAX_TMPS 2 /* max temporary registers used */
1297
1298/* Output the appropriate code to move push memory on the stack */
1299
1300char *
1301output_move_pushmem (operands, insn, length, tmp_start, n_operands)
1302 rtx operands[];
1303 rtx insn;
1304 int length;
1305 int tmp_start;
1306 int n_operands;
1307{
e9a25f70
JL
1308 struct
1309 {
1310 char *load;
1311 char *push;
1312 rtx xops[2];
1313 } tmp_info[MAX_TMPS];
79325812 1314
b840bfb0
MM
1315 rtx src = operands[1];
1316 int max_tmps = 0;
1317 int offset = 0;
1318 int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src);
1319 int stack_offset = 0;
1320 int i, num_tmps;
1321 rtx xops[1];
1322
e9a25f70 1323 if (! offsettable_memref_p (src))
b840bfb0
MM
1324 fatal_insn ("Source is not offsettable", insn);
1325
1326 if ((length & 3) != 0)
1327 fatal_insn ("Pushing non-word aligned size", insn);
1328
1329 /* Figure out which temporary registers we have available */
1330 for (i = tmp_start; i < n_operands; i++)
1331 {
1332 if (GET_CODE (operands[i]) == REG)
1333 {
1334 if (reg_overlap_mentioned_p (operands[i], src))
1335 continue;
1336
1337 tmp_info[ max_tmps++ ].xops[1] = operands[i];
1338 if (max_tmps == MAX_TMPS)
1339 break;
1340 }
1341 }
1342
1343 if (max_tmps == 0)
1344 for (offset = length - 4; offset >= 0; offset -= 4)
1345 {
1346 xops[0] = adj_offsettable_operand (src, offset + stack_offset);
1347 output_asm_insn (AS1(push%L0,%0), xops);
1348 if (stack_p)
1349 stack_offset += 4;
1350 }
1351
1352 else
1353 for (offset = length - 4; offset >= 0; )
1354 {
1355 for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++)
1356 {
1357 tmp_info[num_tmps].load = AS2(mov%L0,%0,%1);
1358 tmp_info[num_tmps].push = AS1(push%L0,%1);
e9a25f70
JL
1359 tmp_info[num_tmps].xops[0]
1360 = adj_offsettable_operand (src, offset + stack_offset);
b840bfb0
MM
1361 offset -= 4;
1362 }
1363
1364 for (i = 0; i < num_tmps; i++)
1365 output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1366
1367 for (i = 0; i < num_tmps; i++)
1368 output_asm_insn (tmp_info[i].push, tmp_info[i].xops);
1369
1370 if (stack_p)
1371 stack_offset += 4*num_tmps;
1372 }
1373
1374 return "";
1375}
b840bfb0 1376\f
2a2ab3f9
JVA
1377int
1378standard_80387_constant_p (x)
1379 rtx x;
1380{
0b6b2900
RK
1381#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1382 REAL_VALUE_TYPE d;
1383 jmp_buf handler;
1384 int is0, is1;
2a2ab3f9 1385
0b6b2900
RK
1386 if (setjmp (handler))
1387 return 0;
2a2ab3f9 1388
0b6b2900
RK
1389 set_float_handler (handler);
1390 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
8ab92e4e 1391 is0 = REAL_VALUES_EQUAL (d, dconst0) && !REAL_VALUE_MINUS_ZERO (d);
0b6b2900
RK
1392 is1 = REAL_VALUES_EQUAL (d, dconst1);
1393 set_float_handler (NULL_PTR);
1394
1395 if (is0)
2a2ab3f9
JVA
1396 return 1;
1397
0b6b2900 1398 if (is1)
2a2ab3f9
JVA
1399 return 2;
1400
1401 /* Note that on the 80387, other constants, such as pi,
1402 are much slower to load as standard constants
1403 than to load from doubles in memory! */
a269a03c 1404 /* ??? Not true on K6: all constants are equal cost. */
0b6b2900 1405#endif
2a2ab3f9
JVA
1406
1407 return 0;
1408}
1409
1410char *
1411output_move_const_single (operands)
1412 rtx *operands;
1413{
1414 if (FP_REG_P (operands[0]))
1415 {
1416 int conval = standard_80387_constant_p (operands[1]);
1417
1418 if (conval == 1)
1419 return "fldz";
1420
1421 if (conval == 2)
1422 return "fld1";
1423 }
e9a25f70 1424
2a2ab3f9
JVA
1425 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1426 {
5f1ec3e6
JVA
1427 REAL_VALUE_TYPE r; long l;
1428
1429 if (GET_MODE (operands[1]) == XFmode)
1430 abort ();
1431
1432 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1433 REAL_VALUE_TO_TARGET_SINGLE (r, l);
1434 operands[1] = GEN_INT (l);
2a2ab3f9 1435 }
e9a25f70 1436
2a2ab3f9
JVA
1437 return singlemove_string (operands);
1438}
1439\f
1440/* Returns 1 if OP is either a symbol reference or a sum of a symbol
1441 reference and a constant. */
1442
1443int
1444symbolic_operand (op, mode)
1445 register rtx op;
bb5177ac 1446 enum machine_mode mode ATTRIBUTE_UNUSED;
2a2ab3f9
JVA
1447{
1448 switch (GET_CODE (op))
1449 {
1450 case SYMBOL_REF:
1451 case LABEL_REF:
1452 return 1;
e9a25f70 1453
2a2ab3f9
JVA
1454 case CONST:
1455 op = XEXP (op, 0);
1456 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1457 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1458 && GET_CODE (XEXP (op, 1)) == CONST_INT);
e9a25f70 1459
2a2ab3f9
JVA
1460 default:
1461 return 0;
1462 }
1463}
fee2770d 1464
0a726ef1
JL
1465/* Return nonzero if OP is a constant shift count small enough to
1466 encode into an lea instruction. */
1467
1468int
1469small_shift_operand (op, mode)
1470 rtx op;
1471 enum machine_mode mode ATTRIBUTE_UNUSED;
1472{
1473 return (GET_CODE (op) == CONST_INT && INTVAL (op) > 0 && INTVAL (op) < 4);
1474}
1475
fee2770d
RS
1476/* Test for a valid operand for a call instruction.
1477 Don't allow the arg pointer register or virtual regs
1478 since they may change into reg + const, which the patterns
1479 can't handle yet. */
1480
1481int
1482call_insn_operand (op, mode)
1483 rtx op;
bb5177ac 1484 enum machine_mode mode ATTRIBUTE_UNUSED;
4f2c8ebb
RS
1485{
1486 if (GET_CODE (op) == MEM
1487 && ((CONSTANT_ADDRESS_P (XEXP (op, 0))
1488 /* This makes a difference for PIC. */
1489 && general_operand (XEXP (op, 0), Pmode))
1490 || (GET_CODE (XEXP (op, 0)) == REG
1491 && XEXP (op, 0) != arg_pointer_rtx
e9a25f70
JL
1492 && ! (REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1493 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
4f2c8ebb 1494 return 1;
e9a25f70 1495
4f2c8ebb
RS
1496 return 0;
1497}
1498
1499/* Like call_insn_operand but allow (mem (symbol_ref ...))
1500 even if pic. */
1501
1502int
1503expander_call_insn_operand (op, mode)
1504 rtx op;
bb5177ac 1505 enum machine_mode mode ATTRIBUTE_UNUSED;
fee2770d
RS
1506{
1507 if (GET_CODE (op) == MEM
1508 && (CONSTANT_ADDRESS_P (XEXP (op, 0))
1509 || (GET_CODE (XEXP (op, 0)) == REG
1510 && XEXP (op, 0) != arg_pointer_rtx
e9a25f70
JL
1511 && ! (REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1512 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
fee2770d 1513 return 1;
e9a25f70 1514
fee2770d
RS
1515 return 0;
1516}
d784886d
RK
1517
1518/* Return 1 if OP is a comparison operator that can use the condition code
1519 generated by an arithmetic operation. */
1520
1521int
1522arithmetic_comparison_operator (op, mode)
1523 register rtx op;
1524 enum machine_mode mode;
1525{
1526 enum rtx_code code;
1527
1528 if (mode != VOIDmode && mode != GET_MODE (op))
1529 return 0;
e9a25f70 1530
d784886d
RK
1531 code = GET_CODE (op);
1532 if (GET_RTX_CLASS (code) != '<')
1533 return 0;
1534
1535 return (code != GT && code != LE);
1536}
57dbca5e
BS
1537
1538int
1539ix86_logical_operator (op, mode)
1540 register rtx op;
bb5177ac 1541 enum machine_mode mode ATTRIBUTE_UNUSED;
57dbca5e
BS
1542{
1543 return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR;
1544}
1545
2a2ab3f9
JVA
1546\f
1547/* Returns 1 if OP contains a symbol reference */
1548
1549int
1550symbolic_reference_mentioned_p (op)
1551 rtx op;
1552{
1553 register char *fmt;
1554 register int i;
1555
1556 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1557 return 1;
1558
1559 fmt = GET_RTX_FORMAT (GET_CODE (op));
1560 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1561 {
1562 if (fmt[i] == 'E')
1563 {
1564 register int j;
1565
1566 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1567 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1568 return 1;
1569 }
e9a25f70 1570
2a2ab3f9
JVA
1571 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1572 return 1;
1573 }
1574
1575 return 0;
1576}
32b5b1aa
SC
1577\f
1578/* Attempt to expand a binary operator. Make the expansion closer to the
1579 actual machine, then just general_operand, which will allow 3 separate
1580 memory references (one output, two input) in a single insn. Return
1581 whether the insn fails, or succeeds. */
1582
1583int
1584ix86_expand_binary_operator (code, mode, operands)
1585 enum rtx_code code;
1586 enum machine_mode mode;
1587 rtx operands[];
1588{
32b5b1aa
SC
1589 int modified;
1590
1591 /* Recognize <var1> = <value> <op> <var1> for commutative operators */
1592 if (GET_RTX_CLASS (code) == 'c'
1593 && (rtx_equal_p (operands[0], operands[2])
1594 || immediate_operand (operands[1], mode)))
1595 {
1596 rtx temp = operands[1];
1597 operands[1] = operands[2];
1598 operands[2] = temp;
1599 }
1600
1601 /* If optimizing, copy to regs to improve CSE */
e9a25f70
JL
1602 if (TARGET_PSEUDO && optimize
1603 && ((reload_in_progress | reload_completed) == 0))
32b5b1aa 1604 {
e9a25f70
JL
1605 if (GET_CODE (operands[1]) == MEM
1606 && ! rtx_equal_p (operands[0], operands[1]))
32b5b1aa
SC
1607 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1608
1609 if (GET_CODE (operands[2]) == MEM)
1610 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
0afeb08a
SC
1611
1612 if (GET_CODE (operands[1]) == CONST_INT && code == MINUS)
1613 {
1614 rtx temp = gen_reg_rtx (GET_MODE (operands[0]));
e9a25f70 1615
0afeb08a
SC
1616 emit_move_insn (temp, operands[1]);
1617 operands[1] = temp;
1618 return TRUE;
79325812 1619 }
32b5b1aa
SC
1620 }
1621
1622 if (!ix86_binary_operator_ok (code, mode, operands))
1623 {
e9a25f70
JL
1624 /* If not optimizing, try to make a valid insn (optimize code
1625 previously did this above to improve chances of CSE) */
32b5b1aa 1626
e9a25f70 1627 if ((! TARGET_PSEUDO || !optimize)
32b5b1aa
SC
1628 && ((reload_in_progress | reload_completed) == 0)
1629 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM))
1630 {
1631 modified = FALSE;
e9a25f70
JL
1632 if (GET_CODE (operands[1]) == MEM
1633 && ! rtx_equal_p (operands[0], operands[1]))
32b5b1aa
SC
1634 {
1635 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
1636 modified = TRUE;
1637 }
1638
1639 if (GET_CODE (operands[2]) == MEM)
1640 {
1641 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
1642 modified = TRUE;
1643 }
1644
0afeb08a
SC
1645 if (GET_CODE (operands[1]) == CONST_INT && code == MINUS)
1646 {
1647 rtx temp = gen_reg_rtx (GET_MODE (operands[0]));
e9a25f70 1648
0afeb08a
SC
1649 emit_move_insn (temp, operands[1]);
1650 operands[1] = temp;
1651 return TRUE;
79325812 1652 }
0afeb08a 1653
e9a25f70 1654 if (modified && ! ix86_binary_operator_ok (code, mode, operands))
32b5b1aa
SC
1655 return FALSE;
1656 }
1657 else
1658 return FALSE;
1659 }
1660
1661 return TRUE;
1662}
1663\f
1664/* Return TRUE or FALSE depending on whether the binary operator meets the
1665 appropriate constraints. */
1666
1667int
1668ix86_binary_operator_ok (code, mode, operands)
1669 enum rtx_code code;
bb5177ac 1670 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
1671 rtx operands[3];
1672{
29e8f73f
SC
1673 return (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
1674 && (GET_CODE (operands[1]) != CONST_INT || GET_RTX_CLASS (code) == 'c');
32b5b1aa
SC
1675}
1676\f
1677/* Attempt to expand a unary operator. Make the expansion closer to the
1678 actual machine, then just general_operand, which will allow 2 separate
1679 memory references (one output, one input) in a single insn. Return
1680 whether the insn fails, or succeeds. */
1681
1682int
1683ix86_expand_unary_operator (code, mode, operands)
1684 enum rtx_code code;
1685 enum machine_mode mode;
1686 rtx operands[];
1687{
32b5b1aa
SC
1688 /* If optimizing, copy to regs to improve CSE */
1689 if (TARGET_PSEUDO
1690 && optimize
1691 && ((reload_in_progress | reload_completed) == 0)
1692 && GET_CODE (operands[1]) == MEM)
e9a25f70 1693 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
32b5b1aa 1694
e9a25f70 1695 if (! ix86_unary_operator_ok (code, mode, operands))
32b5b1aa 1696 {
e9a25f70 1697 if ((! TARGET_PSEUDO || optimize == 0)
32b5b1aa
SC
1698 && ((reload_in_progress | reload_completed) == 0)
1699 && GET_CODE (operands[1]) == MEM)
1700 {
1701 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
e9a25f70 1702 if (! ix86_unary_operator_ok (code, mode, operands))
32b5b1aa
SC
1703 return FALSE;
1704 }
1705 else
1706 return FALSE;
1707 }
1708
1709 return TRUE;
1710}
1711\f
1712/* Return TRUE or FALSE depending on whether the unary operator meets the
1713 appropriate constraints. */
1714
1715int
1716ix86_unary_operator_ok (code, mode, operands)
bb5177ac
RL
1717 enum rtx_code code ATTRIBUTE_UNUSED;
1718 enum machine_mode mode ATTRIBUTE_UNUSED;
1719 rtx operands[2] ATTRIBUTE_UNUSED;
32b5b1aa
SC
1720{
1721 return TRUE;
1722}
2a2ab3f9 1723\f
e5cb57e8 1724static rtx pic_label_rtx;
c942177e
SC
1725static char pic_label_name [256];
1726static int pic_label_no = 0;
e5cb57e8
SC
1727
1728/* This function generates code for -fpic that loads %ebx with
38e01259 1729 the return address of the caller and then returns. */
e9a25f70 1730
e5cb57e8
SC
1731void
1732asm_output_function_prefix (file, name)
e9a25f70 1733 FILE *file;
bb5177ac 1734 char *name ATTRIBUTE_UNUSED;
e5cb57e8
SC
1735{
1736 rtx xops[2];
1737 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1738 || current_function_uses_const_pool);
1739 xops[0] = pic_offset_table_rtx;
1740 xops[1] = stack_pointer_rtx;
1741
e9a25f70 1742 /* Deep branch prediction favors having a return for every call. */
e5cb57e8
SC
1743 if (pic_reg_used && TARGET_DEEP_BRANCH_PREDICTION)
1744 {
c942177e
SC
1745 tree prologue_node;
1746
77a989d1 1747 if (pic_label_rtx == 0)
c942177e 1748 {
e9a25f70 1749 pic_label_rtx = gen_label_rtx ();
5cb6195d 1750 ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", pic_label_no++);
c942177e
SC
1751 LABEL_NAME (pic_label_rtx) = pic_label_name;
1752 }
e9a25f70 1753
c942177e
SC
1754 prologue_node = make_node (FUNCTION_DECL);
1755 DECL_RESULT (prologue_node) = 0;
e06c10eb
RL
1756
1757 /* This used to call ASM_DECLARE_FUNCTION_NAME() but since it's an
1758 internal (non-global) label that's being emitted, it didn't make
1759 sense to have .type information for local labels. This caused
1760 the SCO OpenServer 5.0.4 ELF assembler grief (why are you giving
1761 me debug info for a label that you're declaring non-global?) this
1762 was changed to call ASM_OUTPUT_LABEL() instead. */
1763
1764
1765 ASM_OUTPUT_LABEL (file, pic_label_name);
e5cb57e8
SC
1766 output_asm_insn ("movl (%1),%0", xops);
1767 output_asm_insn ("ret", xops);
1768 }
1769}
1770
e9a25f70
JL
1771/* Generate the assembly code for function entry.
1772 FILE is an stdio stream to output the code to.
1773 SIZE is an int: how many units of temporary storage to allocate. */
2a2ab3f9
JVA
1774
1775void
1776function_prologue (file, size)
bb5177ac
RL
1777 FILE *file ATTRIBUTE_UNUSED;
1778 int size ATTRIBUTE_UNUSED;
77a989d1 1779{
983f1685 1780 if (TARGET_SCHEDULE_PROLOGUE)
c942177e
SC
1781 {
1782 pic_label_rtx = 0;
1783 return;
1784 }
79325812 1785
e9a25f70
JL
1786 ix86_prologue (0);
1787}
8dfe5673 1788
e9a25f70
JL
1789/* Expand the prologue into a bunch of separate insns. */
1790
1791void
1792ix86_expand_prologue ()
1793{
1794 if (! TARGET_SCHEDULE_PROLOGUE)
1795 return;
79325812 1796
e9a25f70
JL
1797 ix86_prologue (1);
1798}
1799
1800void
1801load_pic_register (do_rtl)
1802 int do_rtl;
1803{
1804 rtx xops[4];
1805
1806 if (TARGET_DEEP_BRANCH_PREDICTION)
983f1685 1807 {
e9a25f70
JL
1808 xops[0] = pic_offset_table_rtx;
1809 if (pic_label_rtx == 0)
0021b564 1810 {
e9a25f70 1811 pic_label_rtx = gen_label_rtx ();
5cb6195d 1812 ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", pic_label_no++);
e9a25f70 1813 LABEL_NAME (pic_label_rtx) = pic_label_name;
0021b564 1814 }
983f1685 1815
f64cecad 1816 xops[1] = gen_rtx_MEM (QImode,
e9a25f70
JL
1817 gen_rtx (SYMBOL_REF, Pmode,
1818 LABEL_NAME (pic_label_rtx)));
1819
1820 if (do_rtl)
0021b564 1821 {
e9a25f70 1822 emit_insn (gen_prologue_get_pc (xops[0], xops[1]));
79325812 1823 emit_insn (gen_prologue_set_got (xops[0],
d119f84c
RH
1824#ifdef YES_UNDERSCORES
1825 gen_rtx_SYMBOL_REF (Pmode,
1826 "$__GLOBAL_OFFSET_TABLE_"),
1827#else
1828 gen_rtx_SYMBOL_REF (Pmode,
1829 "$_GLOBAL_OFFSET_TABLE_"),
1830#endif
e9a25f70
JL
1831 xops[1]));
1832 }
1833 else
1834 {
5cb6195d 1835 output_asm_insn (AS1 (call,%X1), xops);
d119f84c 1836 output_asm_insn ("addl $%__GLOBAL_OFFSET_TABLE_,%0", xops);
e9a25f70 1837 pic_label_rtx = 0;
0021b564
JM
1838 }
1839 }
983f1685 1840
e9a25f70 1841 else
983f1685
SC
1842 {
1843 xops[0] = pic_offset_table_rtx;
e9a25f70 1844 xops[1] = gen_label_rtx ();
79325812 1845
e9a25f70
JL
1846 if (do_rtl)
1847 {
4f9ca067
JW
1848 /* We can't put a raw CODE_LABEL into the RTL, and we can't emit
1849 a new CODE_LABEL after reload, so we need a single pattern to
1850 emit the 3 necessary instructions. */
1851 emit_insn (gen_prologue_get_pc_and_set_got (xops[0]));
e9a25f70
JL
1852 }
1853 else
1854 {
1855 output_asm_insn (AS1 (call,%P1), xops);
79325812 1856 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
e9a25f70
JL
1857 CODE_LABEL_NUMBER (xops[1]));
1858 output_asm_insn (AS1 (pop%L0,%0), xops);
d119f84c 1859 output_asm_insn ("addl $%__GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
e9a25f70 1860 }
79325812 1861 }
77a989d1 1862
e9a25f70
JL
1863 /* When -fpic, we must emit a scheduling barrier, so that the instruction
1864 that restores %ebx (which is PIC_OFFSET_TABLE_REGNUM), does not get
1865 moved before any instruction which implicitly uses the got. */
77a989d1 1866
e9a25f70
JL
1867 if (do_rtl)
1868 emit_insn (gen_blockage ());
1869}
1870
65954bd8
JL
1871/* Compute the size of local storage taking into consideration the
1872 desired stack alignment which is to be maintained. Also determine
1873 the number of registers saved below the local storage. */
1874
1875HOST_WIDE_INT
1876ix86_compute_frame_size (size, nregs_on_stack)
1877 HOST_WIDE_INT size;
1878 int *nregs_on_stack;
1879{
1880 int limit;
1881 int nregs;
1882 int regno;
1883 int padding;
1884 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1885 || current_function_uses_const_pool);
1886 HOST_WIDE_INT total_size;
1887
1888 limit = frame_pointer_needed
1889 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
1890
1891 nregs = 0;
1892
1893 for (regno = limit - 1; regno >= 0; regno--)
1894 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1895 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1896 nregs++;
1897
1898 padding = 0;
1899 total_size = size + (nregs * UNITS_PER_WORD);
1900
1901#ifdef PREFERRED_STACK_BOUNDARY
1902 {
1903 int offset;
1904 int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
1905
1906 offset = 4;
1907 if (frame_pointer_needed)
1908 offset += UNITS_PER_WORD;
1909
1910 total_size += offset;
1911
1912 padding = ((total_size + preferred_alignment - 1)
1913 & -preferred_alignment) - total_size;
1914
1915 if (padding < (((offset + preferred_alignment - 1)
1916 & -preferred_alignment) - offset))
1917 padding += preferred_alignment;
54ff41b7
JW
1918
1919 /* Don't bother aligning the stack of a leaf function
1920 which doesn't allocate any stack slots. */
1921 if (size == 0 && current_function_is_leaf)
1922 padding = 0;
65954bd8
JL
1923 }
1924#endif
1925
1926 if (nregs_on_stack)
1927 *nregs_on_stack = nregs;
1928
1929 return size + padding;
1930}
1931
e9a25f70
JL
1932static void
1933ix86_prologue (do_rtl)
1934 int do_rtl;
2a2ab3f9
JVA
1935{
1936 register int regno;
1937 int limit;
1938 rtx xops[4];
aae75261
JVA
1939 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1940 || current_function_uses_const_pool);
65954bd8 1941 HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), (int *)0);
469ac993 1942 rtx insn;
e9a25f70 1943 int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
79325812 1944
2a2ab3f9
JVA
1945 xops[0] = stack_pointer_rtx;
1946 xops[1] = frame_pointer_rtx;
77a989d1 1947 xops[2] = GEN_INT (tsize);
e9a25f70 1948
2a2ab3f9
JVA
1949 if (frame_pointer_needed)
1950 {
e9a25f70
JL
1951 if (do_rtl)
1952 {
1953 insn = emit_insn (gen_rtx (SET, VOIDmode,
f64cecad 1954 gen_rtx_MEM (SImode,
e9a25f70
JL
1955 gen_rtx (PRE_DEC, SImode,
1956 stack_pointer_rtx)),
1957 frame_pointer_rtx));
1958
1959 RTX_FRAME_RELATED_P (insn) = 1;
1960 insn = emit_move_insn (xops[1], xops[0]);
1961 RTX_FRAME_RELATED_P (insn) = 1;
1962 }
1963
1964 else
1965 {
79325812 1966 output_asm_insn ("push%L1 %1", xops);
e9a25f70
JL
1967#ifdef INCOMING_RETURN_ADDR_RTX
1968 if (dwarf2out_do_frame ())
1969 {
1970 char *l = dwarf2out_cfi_label ();
1971
1972 cfa_store_offset += 4;
1973 cfa_offset = cfa_store_offset;
1974 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
1975 dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, - cfa_store_offset);
1976 }
1977#endif
1978
79325812 1979 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
e9a25f70
JL
1980#ifdef INCOMING_RETURN_ADDR_RTX
1981 if (dwarf2out_do_frame ())
1982 dwarf2out_def_cfa ("", FRAME_POINTER_REGNUM, cfa_offset);
1983#endif
1984 }
2a2ab3f9
JVA
1985 }
1986
8dfe5673
RK
1987 if (tsize == 0)
1988 ;
1989 else if (! TARGET_STACK_PROBE || tsize < CHECK_STACK_LIMIT)
469ac993 1990 {
e9a25f70
JL
1991 if (do_rtl)
1992 {
1993 insn = emit_insn (gen_prologue_set_stack_ptr (xops[2]));
1994 RTX_FRAME_RELATED_P (insn) = 1;
1995 }
79325812 1996 else
e9a25f70
JL
1997 {
1998 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
1999#ifdef INCOMING_RETURN_ADDR_RTX
2000 if (dwarf2out_do_frame ())
2001 {
2002 cfa_store_offset += tsize;
2003 if (! frame_pointer_needed)
2004 {
2005 cfa_offset = cfa_store_offset;
2006 dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, cfa_offset);
2007 }
2008 }
2009#endif
2010 }
469ac993 2011 }
79325812 2012 else
8dfe5673 2013 {
f64cecad 2014 xops[3] = gen_rtx_REG (SImode, 0);
e9a25f70 2015 if (do_rtl)
8dfe5673 2016 emit_move_insn (xops[3], xops[2]);
e9a25f70
JL
2017 else
2018 output_asm_insn (AS2 (mov%L0,%2,%3), xops);
2019
f64cecad 2020 xops[3] = gen_rtx_MEM (FUNCTION_MODE,
8dfe5673 2021 gen_rtx (SYMBOL_REF, Pmode, "_alloca"));
e9a25f70
JL
2022
2023 if (do_rtl)
2024 emit_call_insn (gen_rtx (CALL, VOIDmode, xops[3], const0_rtx));
2025 else
2026 output_asm_insn (AS1 (call,%P3), xops);
8dfe5673 2027 }
77a989d1 2028
2a2ab3f9
JVA
2029 /* Note If use enter it is NOT reversed args.
2030 This one is not reversed from intel!!
2031 I think enter is slower. Also sdb doesn't like it.
2032 But if you want it the code is:
2033 {
2034 xops[3] = const0_rtx;
2035 output_asm_insn ("enter %2,%3", xops);
2036 }
2037 */
e9a25f70 2038
2a2ab3f9
JVA
2039 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
2040 for (regno = limit - 1; regno >= 0; regno--)
2041 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 2042 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9 2043 {
f64cecad 2044 xops[0] = gen_rtx_REG (SImode, regno);
e9a25f70
JL
2045 if (do_rtl)
2046 {
2047 insn = emit_insn (gen_rtx (SET, VOIDmode,
f64cecad 2048 gen_rtx_MEM (SImode,
e9a25f70
JL
2049 gen_rtx (PRE_DEC, SImode,
2050 stack_pointer_rtx)),
2051 xops[0]));
2a2ab3f9 2052
e9a25f70
JL
2053 RTX_FRAME_RELATED_P (insn) = 1;
2054 }
2055 else
2056 {
2057 output_asm_insn ("push%L0 %0", xops);
2058#ifdef INCOMING_RETURN_ADDR_RTX
2059 if (dwarf2out_do_frame ())
2060 {
2061 char *l = dwarf2out_cfi_label ();
2062
2063 cfa_store_offset += 4;
2064 if (! frame_pointer_needed)
2065 {
2066 cfa_offset = cfa_store_offset;
2067 dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, cfa_offset);
2068 }
2069
2070 dwarf2out_reg_save (l, regno, - cfa_store_offset);
2071 }
2072#endif
2073 }
2074 }
2a2ab3f9 2075
84530511
SC
2076#ifdef SUBTARGET_PROLOGUE
2077 SUBTARGET_PROLOGUE;
2078#endif
2079
e9a25f70
JL
2080 if (pic_reg_used)
2081 load_pic_register (do_rtl);
77a989d1 2082
e9a25f70
JL
2083 /* If we are profiling, make sure no instructions are scheduled before
2084 the call to mcount. However, if -fpic, the above call will have
2085 done that. */
2086 if ((profile_flag || profile_block_flag)
2087 && ! pic_reg_used && do_rtl)
2088 emit_insn (gen_blockage ());
77a989d1
SC
2089}
2090
2a2ab3f9
JVA
2091/* Return 1 if it is appropriate to emit `ret' instructions in the
2092 body of a function. Do this only if the epilogue is simple, needing a
2093 couple of insns. Prior to reloading, we can't tell how many registers
79325812 2094 must be saved, so return 0 then. Return 0 if there is no frame
77a989d1 2095 marker to de-allocate.
2a2ab3f9
JVA
2096
2097 If NON_SAVING_SETJMP is defined and true, then it is not possible
2098 for the epilogue to be simple, so return 0. This is a special case
77a989d1
SC
2099 since NON_SAVING_SETJMP will not cause regs_ever_live to change
2100 until final, but jump_optimize may need to know sooner if a
2101 `return' is OK. */
2a2ab3f9
JVA
2102
2103int
77a989d1 2104ix86_can_use_return_insn_p ()
2a2ab3f9
JVA
2105{
2106 int regno;
2107 int nregs = 0;
2108 int reglimit = (frame_pointer_needed
2109 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
aae75261
JVA
2110 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
2111 || current_function_uses_const_pool);
2a2ab3f9
JVA
2112
2113#ifdef NON_SAVING_SETJMP
2114 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
2115 return 0;
2116#endif
2117
2118 if (! reload_completed)
2119 return 0;
2120
2121 for (regno = reglimit - 1; regno >= 0; regno--)
2122 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 2123 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9
JVA
2124 nregs++;
2125
2126 return nregs == 0 || ! frame_pointer_needed;
2127}
2128
2129/* This function generates the assembly code for function exit.
2130 FILE is an stdio stream to output the code to.
2131 SIZE is an int: how many units of temporary storage to deallocate. */
2132
e9a25f70
JL
2133void
2134function_epilogue (file, size)
bb5177ac
RL
2135 FILE *file ATTRIBUTE_UNUSED;
2136 int size ATTRIBUTE_UNUSED;
e9a25f70
JL
2137{
2138 return;
2139}
2140
79325812 2141/* Restore function stack, frame, and registers. */
e9a25f70 2142
2a2ab3f9 2143void
77a989d1 2144ix86_expand_epilogue ()
e9a25f70
JL
2145{
2146 ix86_epilogue (1);
2147}
2148
2149static void
2150ix86_epilogue (do_rtl)
2151 int do_rtl;
2a2ab3f9
JVA
2152{
2153 register int regno;
65954bd8
JL
2154 register int limit;
2155 int nregs;
2a2ab3f9 2156 rtx xops[3];
aae75261
JVA
2157 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
2158 || current_function_uses_const_pool);
fdb8a883 2159 int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
65954bd8
JL
2160 HOST_WIDE_INT offset;
2161 HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), &nregs);
2a2ab3f9 2162
fdb8a883 2163 /* sp is often unreliable so we may have to go off the frame pointer. */
2a2ab3f9 2164
65954bd8 2165 offset = -(tsize + nregs * UNITS_PER_WORD);
2a2ab3f9
JVA
2166
2167 xops[2] = stack_pointer_rtx;
2168
00fc09e1
JW
2169 /* When -fpic, we must emit a scheduling barrier, so that the instruction
2170 that restores %ebx (which is PIC_OFFSET_TABLE_REGNUM), does not get
2171 moved before any instruction which implicitly uses the got. This
2172 includes any instruction which uses a SYMBOL_REF or a LABEL_REF.
2173
2174 Alternatively, this could be fixed by making the dependence on the
2175 PIC_OFFSET_TABLE_REGNUM explicit in the RTL. */
e9a25f70
JL
2176
2177 if (flag_pic || profile_flag || profile_block_flag)
00fc09e1
JW
2178 emit_insn (gen_blockage ());
2179
fdb8a883
JW
2180 /* If we're only restoring one register and sp is not valid then
2181 using a move instruction to restore the register since it's
2182 less work than reloading sp and popping the register. Otherwise,
2183 restore sp (if necessary) and pop the registers. */
2184
65954bd8
JL
2185 limit = frame_pointer_needed
2186 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
2187
fdb8a883 2188 if (nregs > 1 || sp_valid)
2a2ab3f9 2189 {
fdb8a883 2190 if ( !sp_valid )
2a2ab3f9 2191 {
77a989d1 2192 xops[0] = adj_offsettable_operand (AT_BP (QImode), offset);
e9a25f70
JL
2193 if (do_rtl)
2194 emit_insn (gen_movsi_lea (xops[2], XEXP (xops[0], 0)));
2195 else
2196 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
2a2ab3f9
JVA
2197 }
2198
2199 for (regno = 0; regno < limit; regno++)
2200 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 2201 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9 2202 {
f64cecad 2203 xops[0] = gen_rtx_REG (SImode, regno);
e9a25f70
JL
2204
2205 if (do_rtl)
2206 emit_insn (gen_pop (xops[0]));
2207 else
2208 output_asm_insn ("pop%L0 %0", xops);
2a2ab3f9
JVA
2209 }
2210 }
e9a25f70 2211
2a2ab3f9
JVA
2212 else
2213 for (regno = 0; regno < limit; regno++)
2214 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 2215 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9 2216 {
f64cecad 2217 xops[0] = gen_rtx_REG (SImode, regno);
2a2ab3f9 2218 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
e9a25f70
JL
2219
2220 if (do_rtl)
2221 emit_move_insn (xops[0], xops[1]);
2222 else
2223 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2224
2a2ab3f9
JVA
2225 offset += 4;
2226 }
2227
2228 if (frame_pointer_needed)
2229 {
c8c5cb99 2230 /* If not an i386, mov & pop is faster than "leave". */
2a2ab3f9 2231
3f803cd9 2232 if (TARGET_USE_LEAVE)
e9a25f70
JL
2233 {
2234 if (do_rtl)
2235 emit_insn (gen_leave());
2236 else
2237 output_asm_insn ("leave", xops);
2238 }
c8c5cb99 2239 else
2a2ab3f9
JVA
2240 {
2241 xops[0] = frame_pointer_rtx;
77a989d1 2242 xops[1] = stack_pointer_rtx;
e9a25f70
JL
2243
2244 if (do_rtl)
2245 {
2246 emit_insn (gen_epilogue_set_stack_ptr());
2247 emit_insn (gen_pop (xops[0]));
2248 }
2249 else
2250 {
2251 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
2252 output_asm_insn ("pop%L0 %0", xops);
2253 }
2254 }
2255 }
2256
77a989d1 2257 else if (tsize)
2a2ab3f9 2258 {
3403c6ca
UD
2259 /* Intel's docs say that for 4 or 8 bytes of stack frame one should
2260 use `pop' and not `add'. */
2261 int use_pop = tsize == 4;
e9a25f70 2262
3403c6ca
UD
2263 /* Use two pops only for the Pentium processors. */
2264 if (tsize == 8 && !TARGET_386 && !TARGET_486)
2265 {
2266 rtx retval = current_function_return_rtx;
2267
2268 xops[1] = gen_rtx_REG (SImode, 1); /* %edx */
2269
2270 /* This case is a bit more complex. Since we cannot pop into
2271 %ecx twice we need a second register. But this is only
2272 available if the return value is not of DImode in which
2273 case the %edx register is not available. */
2274 use_pop = (retval == NULL
2275 || ! reg_overlap_mentioned_p (xops[1], retval));
2276 }
2277
2278 if (use_pop)
2279 {
2280 xops[0] = gen_rtx_REG (SImode, 2); /* %ecx */
2281
2282 if (do_rtl)
2283 {
2284 /* We have to prevent the two pops here from being scheduled.
2285 GCC otherwise would try in some situation to put other
2286 instructions in between them which has a bad effect. */
2287 emit_insn (gen_blockage ());
2288 emit_insn (gen_pop (xops[0]));
2289 if (tsize == 8)
2290 emit_insn (gen_pop (xops[1]));
2291 }
2292 else
2293 {
2294 output_asm_insn ("pop%L0 %0", xops);
2295 if (tsize == 8)
2296 output_asm_insn ("pop%L1 %1", xops);
2297 }
2298 }
e9a25f70 2299 else
3403c6ca
UD
2300 {
2301 /* If there is no frame pointer, we must still release the frame. */
2302 xops[0] = GEN_INT (tsize);
2303
2304 if (do_rtl)
2305 emit_insn (gen_rtx (SET, VOIDmode, xops[2],
2306 gen_rtx (PLUS, SImode, xops[2], xops[0])));
2307 else
2308 output_asm_insn (AS2 (add%L2,%0,%2), xops);
2309 }
2a2ab3f9
JVA
2310 }
2311
68f654ec
RK
2312#ifdef FUNCTION_BLOCK_PROFILER_EXIT
2313 if (profile_block_flag == 2)
2314 {
2315 FUNCTION_BLOCK_PROFILER_EXIT(file);
2316 }
2317#endif
2318
2a2ab3f9
JVA
2319 if (current_function_pops_args && current_function_args_size)
2320 {
435defd1 2321 xops[1] = GEN_INT (current_function_pops_args);
2a2ab3f9
JVA
2322
2323 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
2324 asked to pop more, pop return address, do explicit add, and jump
2325 indirectly to the caller. */
2326
2327 if (current_function_pops_args >= 32768)
2328 {
2329 /* ??? Which register to use here? */
f64cecad 2330 xops[0] = gen_rtx_REG (SImode, 2);
e9a25f70
JL
2331
2332 if (do_rtl)
2333 {
2334 emit_insn (gen_pop (xops[0]));
2335 emit_insn (gen_rtx (SET, VOIDmode, xops[2],
2336 gen_rtx (PLUS, SImode, xops[1], xops[2])));
2337 emit_jump_insn (xops[0]);
2338 }
2339 else
2340 {
2341 output_asm_insn ("pop%L0 %0", xops);
2342 output_asm_insn (AS2 (add%L2,%1,%2), xops);
2343 output_asm_insn ("jmp %*%0", xops);
2344 }
2345 }
79325812 2346 else
e9a25f70
JL
2347 {
2348 if (do_rtl)
2349 emit_jump_insn (gen_return_pop_internal (xops[1]));
2350 else
2351 output_asm_insn ("ret %1", xops);
2a2ab3f9 2352 }
2a2ab3f9 2353 }
2a2ab3f9 2354 else
e9a25f70
JL
2355 {
2356 if (do_rtl)
2357 emit_jump_insn (gen_return_internal ());
2358 else
2359 output_asm_insn ("ret", xops);
2360 }
2a2ab3f9 2361}
3b3c6a3f
MM
2362\f
2363/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2364 that is a valid memory address for an instruction.
2365 The MODE argument is the machine mode for the MEM expression
2366 that wants to use this address.
2367
2368 On x86, legitimate addresses are:
2369 base movl (base),reg
2370 displacement movl disp,reg
2371 base + displacement movl disp(base),reg
2372 index + base movl (base,index),reg
2373 (index + base) + displacement movl disp(base,index),reg
2374 index*scale movl (,index,scale),reg
2375 index*scale + disp movl disp(,index,scale),reg
2376 index*scale + base movl (base,index,scale),reg
2377 (index*scale + base) + disp movl disp(base,index,scale),reg
2378
2379 In each case, scale can be 1, 2, 4, 8. */
2380
2381/* This is exactly the same as print_operand_addr, except that
2382 it recognizes addresses instead of printing them.
2383
2384 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
2385 convert common non-canonical forms to canonical form so that they will
2386 be recognized. */
2387
2388#define ADDR_INVALID(msg,insn) \
2389do { \
2390 if (TARGET_DEBUG_ADDR) \
2391 { \
2392 fprintf (stderr, msg); \
2393 debug_rtx (insn); \
2394 } \
2395} while (0)
2396
59be65f6 2397int
91bb873f
RH
2398legitimate_pic_address_disp_p (disp)
2399 register rtx disp;
2400{
2401 if (GET_CODE (disp) != CONST)
2402 return 0;
2403 disp = XEXP (disp, 0);
2404
2405 if (GET_CODE (disp) == PLUS)
2406 {
2407 if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
2408 return 0;
2409 disp = XEXP (disp, 0);
2410 }
2411
2412 if (GET_CODE (disp) != UNSPEC
2413 || XVECLEN (disp, 0) != 1)
2414 return 0;
2415
2416 /* Must be @GOT or @GOTOFF. */
2417 if (XINT (disp, 1) != 6
2418 && XINT (disp, 1) != 7)
2419 return 0;
2420
2421 if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
2422 && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
2423 return 0;
2424
2425 return 1;
2426}
2427
3b3c6a3f
MM
2428int
2429legitimate_address_p (mode, addr, strict)
2430 enum machine_mode mode;
2431 register rtx addr;
2432 int strict;
2433{
2434 rtx base = NULL_RTX;
2435 rtx indx = NULL_RTX;
2436 rtx scale = NULL_RTX;
2437 rtx disp = NULL_RTX;
2438
2439 if (TARGET_DEBUG_ADDR)
2440 {
2441 fprintf (stderr,
e9a25f70 2442 "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
3b3c6a3f
MM
2443 GET_MODE_NAME (mode), strict);
2444
2445 debug_rtx (addr);
2446 }
2447
2448 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
c954bd01 2449 base = addr;
3b3c6a3f
MM
2450
2451 else if (GET_CODE (addr) == PLUS)
2452 {
2453 rtx op0 = XEXP (addr, 0);
2454 rtx op1 = XEXP (addr, 1);
2455 enum rtx_code code0 = GET_CODE (op0);
2456 enum rtx_code code1 = GET_CODE (op1);
2457
2458 if (code0 == REG || code0 == SUBREG)
2459 {
2460 if (code1 == REG || code1 == SUBREG)
2461 {
e9a25f70 2462 indx = op0; /* index + base */
3b3c6a3f
MM
2463 base = op1;
2464 }
2465
2466 else
2467 {
e9a25f70 2468 base = op0; /* base + displacement */
3b3c6a3f
MM
2469 disp = op1;
2470 }
2471 }
2472
2473 else if (code0 == MULT)
2474 {
2475 indx = XEXP (op0, 0);
2476 scale = XEXP (op0, 1);
2477
2478 if (code1 == REG || code1 == SUBREG)
e9a25f70 2479 base = op1; /* index*scale + base */
3b3c6a3f
MM
2480
2481 else
e9a25f70 2482 disp = op1; /* index*scale + disp */
3b3c6a3f
MM
2483 }
2484
2485 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
2486 {
2487 indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
2488 scale = XEXP (XEXP (op0, 0), 1);
2489 base = XEXP (op0, 1);
2490 disp = op1;
2491 }
2492
2493 else if (code0 == PLUS)
2494 {
e9a25f70 2495 indx = XEXP (op0, 0); /* index + base + disp */
3b3c6a3f
MM
2496 base = XEXP (op0, 1);
2497 disp = op1;
2498 }
2499
2500 else
2501 {
2502 ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
2503 return FALSE;
2504 }
2505 }
2506
2507 else if (GET_CODE (addr) == MULT)
2508 {
e9a25f70 2509 indx = XEXP (addr, 0); /* index*scale */
3b3c6a3f
MM
2510 scale = XEXP (addr, 1);
2511 }
2512
2513 else
e9a25f70 2514 disp = addr; /* displacement */
3b3c6a3f 2515
91f0226f
MM
2516 /* Allow arg pointer and stack pointer as index if there is not scaling */
2517 if (base && indx && !scale
2518 && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
2519 {
2520 rtx tmp = base;
2521 base = indx;
2522 indx = tmp;
2523 }
2524
e9a25f70
JL
2525 /* Validate base register:
2526
2527 Don't allow SUBREG's here, it can lead to spill failures when the base
3d771dfd
MM
2528 is one word out of a two word structure, which is represented internally
2529 as a DImode int. */
e9a25f70 2530
3b3c6a3f
MM
2531 if (base)
2532 {
3d771dfd 2533 if (GET_CODE (base) != REG)
3b3c6a3f 2534 {
3d771dfd
MM
2535 ADDR_INVALID ("Base is not a register.\n", base);
2536 return FALSE;
3b3c6a3f
MM
2537 }
2538
c954bd01
RH
2539 if (GET_MODE (base) != Pmode)
2540 {
2541 ADDR_INVALID ("Base is not in Pmode.\n", base);
2542 return FALSE;
2543 }
2544
e9a25f70
JL
2545 if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
2546 || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
3b3c6a3f
MM
2547 {
2548 ADDR_INVALID ("Base is not valid.\n", base);
2549 return FALSE;
2550 }
2551 }
2552
e9a25f70
JL
2553 /* Validate index register:
2554
2555 Don't allow SUBREG's here, it can lead to spill failures when the index
3d771dfd
MM
2556 is one word out of a two word structure, which is represented internally
2557 as a DImode int. */
3b3c6a3f
MM
2558 if (indx)
2559 {
3d771dfd 2560 if (GET_CODE (indx) != REG)
3b3c6a3f 2561 {
3d771dfd
MM
2562 ADDR_INVALID ("Index is not a register.\n", indx);
2563 return FALSE;
3b3c6a3f
MM
2564 }
2565
c954bd01
RH
2566 if (GET_MODE (indx) != Pmode)
2567 {
2568 ADDR_INVALID ("Index is not in Pmode.\n", indx);
2569 return FALSE;
2570 }
2571
e9a25f70
JL
2572 if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (indx))
2573 || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
3b3c6a3f
MM
2574 {
2575 ADDR_INVALID ("Index is not valid.\n", indx);
2576 return FALSE;
2577 }
2578 }
2579 else if (scale)
e9a25f70 2580 abort (); /* scale w/o index invalid */
3b3c6a3f 2581
e9a25f70 2582 /* Validate scale factor: */
3b3c6a3f
MM
2583 if (scale)
2584 {
2585 HOST_WIDE_INT value;
2586
2587 if (GET_CODE (scale) != CONST_INT)
2588 {
2589 ADDR_INVALID ("Scale is not valid.\n", scale);
2590 return FALSE;
2591 }
2592
2593 value = INTVAL (scale);
2594 if (value != 1 && value != 2 && value != 4 && value != 8)
2595 {
2596 ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
2597 return FALSE;
2598 }
2599 }
2600
91bb873f 2601 /* Validate displacement. */
3b3c6a3f
MM
2602 if (disp)
2603 {
91bb873f 2604 if (!CONSTANT_ADDRESS_P (disp))
3b3c6a3f
MM
2605 {
2606 ADDR_INVALID ("Displacement is not valid.\n", disp);
2607 return FALSE;
2608 }
2609
32b5b1aa 2610 else if (GET_CODE (disp) == CONST_DOUBLE)
3b3c6a3f
MM
2611 {
2612 ADDR_INVALID ("Displacement is a const_double.\n", disp);
2613 return FALSE;
2614 }
2615
91bb873f 2616 if (flag_pic && SYMBOLIC_CONST (disp))
3b3c6a3f 2617 {
91bb873f
RH
2618 if (! legitimate_pic_address_disp_p (disp))
2619 {
2620 ADDR_INVALID ("Displacement is an invalid PIC construct.\n",
2621 disp);
2622 return FALSE;
2623 }
2624
2625 if (base != pic_offset_table_rtx
2626 && (indx != pic_offset_table_rtx || scale != NULL_RTX))
2627 {
2628 ADDR_INVALID ("PIC displacement against invalid base.\n", disp);
2629 return FALSE;
2630 }
3b3c6a3f
MM
2631 }
2632
91bb873f 2633 else if (HALF_PIC_P ())
3b3c6a3f 2634 {
91bb873f
RH
2635 if (! HALF_PIC_ADDRESS_P (disp)
2636 || (base != NULL_RTX || indx != NULL_RTX))
2637 {
2638 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n",
2639 disp);
2640 return FALSE;
2641 }
3b3c6a3f
MM
2642 }
2643 }
2644
2645 if (TARGET_DEBUG_ADDR)
2646 fprintf (stderr, "Address is valid.\n");
2647
2648 /* Everything looks valid, return true */
2649 return TRUE;
2650}
3b3c6a3f
MM
2651\f
2652/* Return a legitimate reference for ORIG (an address) using the
2653 register REG. If REG is 0, a new pseudo is generated.
2654
91bb873f 2655 There are two types of references that must be handled:
3b3c6a3f
MM
2656
2657 1. Global data references must load the address from the GOT, via
2658 the PIC reg. An insn is emitted to do this load, and the reg is
2659 returned.
2660
91bb873f
RH
2661 2. Static data references, constant pool addresses, and code labels
2662 compute the address as an offset from the GOT, whose base is in
2663 the PIC reg. Static data objects have SYMBOL_REF_FLAG set to
2664 differentiate them from global data objects. The returned
2665 address is the PIC reg + an unspec constant.
3b3c6a3f
MM
2666
2667 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
91bb873f 2668 reg also appears in the address. */
3b3c6a3f
MM
2669
2670rtx
2671legitimize_pic_address (orig, reg)
2672 rtx orig;
2673 rtx reg;
2674{
2675 rtx addr = orig;
2676 rtx new = orig;
91bb873f 2677 rtx base;
3b3c6a3f 2678
91bb873f
RH
2679 if (GET_CODE (addr) == LABEL_REF
2680 || (GET_CODE (addr) == SYMBOL_REF
2681 && (CONSTANT_POOL_ADDRESS_P (addr)
2682 || SYMBOL_REF_FLAG (addr))))
3b3c6a3f 2683 {
91bb873f
RH
2684 /* This symbol may be referenced via a displacement from the PIC
2685 base address (@GOTOFF). */
3b3c6a3f 2686
91bb873f
RH
2687 current_function_uses_pic_offset_table = 1;
2688 new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, addr), 7);
2689 new = gen_rtx_CONST (VOIDmode, new);
2690 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
3b3c6a3f 2691
91bb873f
RH
2692 if (reg != 0)
2693 {
3b3c6a3f 2694 emit_move_insn (reg, new);
91bb873f 2695 new = reg;
3b3c6a3f 2696 }
3b3c6a3f 2697 }
91bb873f 2698 else if (GET_CODE (addr) == SYMBOL_REF)
3b3c6a3f 2699 {
91bb873f
RH
2700 /* This symbol must be referenced via a load from the
2701 Global Offset Table (@GOT). */
3b3c6a3f 2702
91bb873f
RH
2703 current_function_uses_pic_offset_table = 1;
2704 new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, addr), 6);
2705 new = gen_rtx_CONST (VOIDmode, new);
2706 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2707 new = gen_rtx_MEM (Pmode, new);
2708 RTX_UNCHANGING_P (new) = 1;
3b3c6a3f
MM
2709
2710 if (reg == 0)
2711 reg = gen_reg_rtx (Pmode);
91bb873f
RH
2712 emit_move_insn (reg, new);
2713 new = reg;
2714 }
2715 else
2716 {
2717 if (GET_CODE (addr) == CONST)
3b3c6a3f 2718 {
91bb873f
RH
2719 addr = XEXP (addr, 0);
2720 if (GET_CODE (addr) == UNSPEC)
2721 {
2722 /* Check that the unspec is one of the ones we generate? */
2723 }
2724 else if (GET_CODE (addr) != PLUS)
2725 abort();
3b3c6a3f 2726 }
91bb873f
RH
2727 if (GET_CODE (addr) == PLUS)
2728 {
2729 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
e9a25f70 2730
91bb873f
RH
2731 /* Check first to see if this is a constant offset from a @GOTOFF
2732 symbol reference. */
2733 if ((GET_CODE (op0) == LABEL_REF
2734 || (GET_CODE (op0) == SYMBOL_REF
2735 && (CONSTANT_POOL_ADDRESS_P (op0)
2736 || SYMBOL_REF_FLAG (op0))))
2737 && GET_CODE (op1) == CONST_INT)
2738 {
2739 current_function_uses_pic_offset_table = 1;
2740 new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, op0), 7);
2741 new = gen_rtx_PLUS (VOIDmode, new, op1);
2742 new = gen_rtx_CONST (VOIDmode, new);
2743 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2744
2745 if (reg != 0)
2746 {
2747 emit_move_insn (reg, new);
2748 new = reg;
2749 }
2750 }
2751 else
2752 {
2753 base = legitimize_pic_address (XEXP (addr, 0), reg);
2754 new = legitimize_pic_address (XEXP (addr, 1),
2755 base == reg ? NULL_RTX : reg);
2756
2757 if (GET_CODE (new) == CONST_INT)
2758 new = plus_constant (base, INTVAL (new));
2759 else
2760 {
2761 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2762 {
2763 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2764 new = XEXP (new, 1);
2765 }
2766 new = gen_rtx_PLUS (Pmode, base, new);
2767 }
2768 }
2769 }
3b3c6a3f
MM
2770 }
2771 return new;
2772}
2773\f
3b3c6a3f
MM
2774/* Emit insns to move operands[1] into operands[0]. */
2775
2776void
2777emit_pic_move (operands, mode)
2778 rtx *operands;
bb5177ac 2779 enum machine_mode mode ATTRIBUTE_UNUSED;
3b3c6a3f
MM
2780{
2781 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
2782
2783 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
91bb873f 2784 operands[1] = force_reg (Pmode, operands[1]);
3b3c6a3f
MM
2785 else
2786 operands[1] = legitimize_pic_address (operands[1], temp);
2787}
3b3c6a3f
MM
2788\f
2789/* Try machine-dependent ways of modifying an illegitimate address
2790 to be legitimate. If we find one, return the new, valid address.
2791 This macro is used in only one place: `memory_address' in explow.c.
2792
2793 OLDX is the address as it was before break_out_memory_refs was called.
2794 In some cases it is useful to look at this to decide what needs to be done.
2795
2796 MODE and WIN are passed so that this macro can use
2797 GO_IF_LEGITIMATE_ADDRESS.
2798
2799 It is always safe for this macro to do nothing. It exists to recognize
2800 opportunities to optimize the output.
2801
2802 For the 80386, we handle X+REG by loading X into a register R and
2803 using R+REG. R will go in a general reg and indexing will be used.
2804 However, if REG is a broken-out memory address or multiplication,
2805 nothing needs to be done because REG can certainly go in a general reg.
2806
2807 When -fpic is used, special handling is needed for symbolic references.
2808 See comments by legitimize_pic_address in i386.c for details. */
2809
2810rtx
2811legitimize_address (x, oldx, mode)
2812 register rtx x;
bb5177ac 2813 register rtx oldx ATTRIBUTE_UNUSED;
3b3c6a3f
MM
2814 enum machine_mode mode;
2815{
2816 int changed = 0;
2817 unsigned log;
2818
2819 if (TARGET_DEBUG_ADDR)
2820 {
e9a25f70
JL
2821 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n",
2822 GET_MODE_NAME (mode));
3b3c6a3f
MM
2823 debug_rtx (x);
2824 }
2825
2826 if (flag_pic && SYMBOLIC_CONST (x))
2827 return legitimize_pic_address (x, 0);
2828
2829 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2830 if (GET_CODE (x) == ASHIFT
2831 && GET_CODE (XEXP (x, 1)) == CONST_INT
2832 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2833 {
2834 changed = 1;
a269a03c
JC
2835 x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
2836 GEN_INT (1 << log));
3b3c6a3f
MM
2837 }
2838
2839 if (GET_CODE (x) == PLUS)
2840 {
e9a25f70
JL
2841 /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
2842
3b3c6a3f
MM
2843 if (GET_CODE (XEXP (x, 0)) == ASHIFT
2844 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2845 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2846 {
2847 changed = 1;
2848 XEXP (x, 0) = gen_rtx (MULT, Pmode,
2849 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2850 GEN_INT (1 << log));
2851 }
2852
2853 if (GET_CODE (XEXP (x, 1)) == ASHIFT
2854 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2855 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2856 {
2857 changed = 1;
2858 XEXP (x, 1) = gen_rtx (MULT, Pmode,
2859 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2860 GEN_INT (1 << log));
2861 }
2862
e9a25f70 2863 /* Put multiply first if it isn't already. */
3b3c6a3f
MM
2864 if (GET_CODE (XEXP (x, 1)) == MULT)
2865 {
2866 rtx tmp = XEXP (x, 0);
2867 XEXP (x, 0) = XEXP (x, 1);
2868 XEXP (x, 1) = tmp;
2869 changed = 1;
2870 }
2871
2872 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2873 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2874 created by virtual register instantiation, register elimination, and
2875 similar optimizations. */
2876 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2877 {
2878 changed = 1;
2879 x = gen_rtx (PLUS, Pmode,
e9a25f70
JL
2880 gen_rtx (PLUS, Pmode, XEXP (x, 0),
2881 XEXP (XEXP (x, 1), 0)),
3b3c6a3f
MM
2882 XEXP (XEXP (x, 1), 1));
2883 }
2884
e9a25f70
JL
2885 /* Canonicalize
2886 (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
3b3c6a3f
MM
2887 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2888 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2889 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2890 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2891 && CONSTANT_P (XEXP (x, 1)))
2892 {
00c79232
ML
2893 rtx constant;
2894 rtx other = NULL_RTX;
3b3c6a3f
MM
2895
2896 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2897 {
2898 constant = XEXP (x, 1);
2899 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2900 }
2901 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2902 {
2903 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2904 other = XEXP (x, 1);
2905 }
2906 else
2907 constant = 0;
2908
2909 if (constant)
2910 {
2911 changed = 1;
2912 x = gen_rtx (PLUS, Pmode,
2913 gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
2914 XEXP (XEXP (XEXP (x, 0), 1), 0)),
2915 plus_constant (other, INTVAL (constant)));
2916 }
2917 }
2918
2919 if (changed && legitimate_address_p (mode, x, FALSE))
2920 return x;
2921
2922 if (GET_CODE (XEXP (x, 0)) == MULT)
2923 {
2924 changed = 1;
2925 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2926 }
2927
2928 if (GET_CODE (XEXP (x, 1)) == MULT)
2929 {
2930 changed = 1;
2931 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2932 }
2933
2934 if (changed
2935 && GET_CODE (XEXP (x, 1)) == REG
2936 && GET_CODE (XEXP (x, 0)) == REG)
2937 return x;
2938
2939 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2940 {
2941 changed = 1;
2942 x = legitimize_pic_address (x, 0);
2943 }
2944
2945 if (changed && legitimate_address_p (mode, x, FALSE))
2946 return x;
2947
2948 if (GET_CODE (XEXP (x, 0)) == REG)
2949 {
2950 register rtx temp = gen_reg_rtx (Pmode);
2951 register rtx val = force_operand (XEXP (x, 1), temp);
2952 if (val != temp)
2953 emit_move_insn (temp, val);
2954
2955 XEXP (x, 1) = temp;
2956 return x;
2957 }
2958
2959 else if (GET_CODE (XEXP (x, 1)) == REG)
2960 {
2961 register rtx temp = gen_reg_rtx (Pmode);
2962 register rtx val = force_operand (XEXP (x, 0), temp);
2963 if (val != temp)
2964 emit_move_insn (temp, val);
2965
2966 XEXP (x, 0) = temp;
2967 return x;
2968 }
2969 }
2970
2971 return x;
2972}
2a2ab3f9
JVA
2973\f
2974/* Print an integer constant expression in assembler syntax. Addition
2975 and subtraction are the only arithmetic that may appear in these
2976 expressions. FILE is the stdio stream to write to, X is the rtx, and
2977 CODE is the operand print code from the output string. */
2978
2979static void
2980output_pic_addr_const (file, x, code)
2981 FILE *file;
2982 rtx x;
2983 int code;
2984{
2985 char buf[256];
2986
2987 switch (GET_CODE (x))
2988 {
2989 case PC:
2990 if (flag_pic)
2991 putc ('.', file);
2992 else
2993 abort ();
2994 break;
2995
2996 case SYMBOL_REF:
91bb873f
RH
2997 assemble_name (file, XSTR (x, 0));
2998 if (code == 'P' && ! SYMBOL_REF_FLAG (x))
2999 fputs ("@PLT", file);
2a2ab3f9
JVA
3000 break;
3001
91bb873f
RH
3002 case LABEL_REF:
3003 x = XEXP (x, 0);
3004 /* FALLTHRU */
2a2ab3f9
JVA
3005 case CODE_LABEL:
3006 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
3007 assemble_name (asm_out_file, buf);
3008 break;
3009
3010 case CONST_INT:
f64cecad 3011 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2a2ab3f9
JVA
3012 break;
3013
3014 case CONST:
3015 /* This used to output parentheses around the expression,
3016 but that does not work on the 386 (either ATT or BSD assembler). */
3017 output_pic_addr_const (file, XEXP (x, 0), code);
3018 break;
3019
3020 case CONST_DOUBLE:
3021 if (GET_MODE (x) == VOIDmode)
3022 {
3023 /* We can use %d if the number is <32 bits and positive. */
3024 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
f64cecad
JC
3025 fprintf (file, "0x%lx%08lx",
3026 (unsigned long) CONST_DOUBLE_HIGH (x),
3027 (unsigned long) CONST_DOUBLE_LOW (x));
2a2ab3f9 3028 else
f64cecad 3029 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
2a2ab3f9
JVA
3030 }
3031 else
3032 /* We can't handle floating point constants;
3033 PRINT_OPERAND must handle them. */
3034 output_operand_lossage ("floating constant misused");
3035 break;
3036
3037 case PLUS:
e9a25f70 3038 /* Some assemblers need integer constants to appear first. */
2a2ab3f9
JVA
3039 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
3040 {
2a2ab3f9 3041 output_pic_addr_const (file, XEXP (x, 0), code);
91bb873f 3042 fprintf (file, "+");
e9a25f70 3043 output_pic_addr_const (file, XEXP (x, 1), code);
2a2ab3f9 3044 }
91bb873f 3045 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2a2ab3f9 3046 {
2a2ab3f9 3047 output_pic_addr_const (file, XEXP (x, 1), code);
91bb873f 3048 fprintf (file, "+");
e9a25f70 3049 output_pic_addr_const (file, XEXP (x, 0), code);
2a2ab3f9 3050 }
91bb873f
RH
3051 else
3052 abort ();
2a2ab3f9
JVA
3053 break;
3054
3055 case MINUS:
3056 output_pic_addr_const (file, XEXP (x, 0), code);
3057 fprintf (file, "-");
3058 output_pic_addr_const (file, XEXP (x, 1), code);
3059 break;
3060
91bb873f
RH
3061 case UNSPEC:
3062 if (XVECLEN (x, 0) != 1)
3063 abort ();
3064 output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
3065 switch (XINT (x, 1))
3066 {
3067 case 6:
3068 fputs ("@GOT", file);
3069 break;
3070 case 7:
3071 fputs ("@GOTOFF", file);
3072 break;
3073 case 8:
3074 fputs ("@PLT", file);
3075 break;
3076 default:
3077 output_operand_lossage ("invalid UNSPEC as operand");
3078 break;
3079 }
3080 break;
3081
2a2ab3f9
JVA
3082 default:
3083 output_operand_lossage ("invalid expression as operand");
3084 }
3085}
3086\f
a269a03c
JC
3087static void
3088put_jump_code (code, reverse, file)
3089 enum rtx_code code;
3090 int reverse;
3091 FILE *file;
3092{
3093 int flags = cc_prev_status.flags;
a9ba8a88 3094 int ieee = (TARGET_IEEE_FP && (flags & CC_IN_80387));
a269a03c
JC
3095 const char *suffix;
3096
3097 if (flags & CC_Z_IN_NOT_C)
3098 switch (code)
3099 {
3100 case EQ:
3101 fputs (reverse ? "c" : "nc", file);
3102 return;
3103
3104 case NE:
3105 fputs (reverse ? "nc" : "c", file);
3106 return;
3107
3108 default:
3109 abort ();
3110 }
3111 if (ieee)
3112 {
3113 switch (code)
3114 {
3115 case LE:
3116 suffix = reverse ? "ae" : "b";
3117 break;
3118 case GT:
3119 case LT:
3120 case GE:
3121 suffix = reverse ? "ne" : "e";
3122 break;
3123 case EQ:
3124 suffix = reverse ? "ne" : "e";
3125 break;
3126 case NE:
3127 suffix = reverse ? "e" : "ne";
3128 break;
3129 default:
3130 abort ();
3131 }
3132 fputs (suffix, file);
3133 return;
3134 }
3135 if (flags & CC_TEST_AX)
3136 abort();
3137 if ((flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
3138 abort ();
3139 if (reverse)
3140 code = reverse_condition (code);
3141 switch (code)
3142 {
3143 case EQ:
3144 suffix = "e";
3145 break;
3146
3147 case NE:
3148 suffix = "ne";
3149 break;
3150
3151 case GT:
3152 suffix = flags & CC_IN_80387 ? "a" : "g";
3153 break;
3154
3155 case GTU:
3156 suffix = "a";
3157 break;
3158
3159 case LT:
3160 if (flags & CC_NO_OVERFLOW)
3161 suffix = "s";
3162 else
3163 suffix = flags & CC_IN_80387 ? "b" : "l";
3164 break;
3165
3166 case LTU:
3167 suffix = "b";
3168 break;
3169
3170 case GE:
3171 if (flags & CC_NO_OVERFLOW)
3172 suffix = "ns";
3173 else
3174 suffix = flags & CC_IN_80387 ? "ae" : "ge";
3175 break;
3176
3177 case GEU:
3178 suffix = "ae";
3179 break;
3180
3181 case LE:
3182 suffix = flags & CC_IN_80387 ? "be" : "le";
3183 break;
3184
3185 case LEU:
3186 suffix = "be";
3187 break;
3188
3189 default:
3190 abort ();
3191 }
3192 fputs (suffix, file);
3193}
3194
e9a25f70 3195/* Append the correct conditional move suffix which corresponds to CODE. */
e5cb57e8
SC
3196
3197static void
c27d9c3b 3198put_condition_code (code, reverse_cc, mode, file)
fe25fea3 3199 enum rtx_code code;
c27d9c3b 3200 int reverse_cc;
fe25fea3
SC
3201 enum mode_class mode;
3202 FILE * file;
e5cb57e8 3203{
e9a25f70
JL
3204 int ieee = (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
3205 && ! (cc_prev_status.flags & CC_FCOMI));
c27d9c3b
SC
3206 if (reverse_cc && ! ieee)
3207 code = reverse_condition (code);
3208
fe25fea3 3209 if (mode == MODE_INT)
e9a25f70
JL
3210 switch (code)
3211 {
79325812 3212 case NE:
e9a25f70
JL
3213 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
3214 fputs ("b", file);
3215 else
3216 fputs ("ne", file);
3217 return;
3218
3219 case EQ:
3220 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
3221 fputs ("ae", file);
3222 else
3223 fputs ("e", file);
3224 return;
3225
3226 case GE:
b657fc39
L
3227 if (cc_prev_status.flags & CC_NO_OVERFLOW)
3228 fputs ("ns", file);
3229 else
3230 fputs ("ge", file);
e9a25f70
JL
3231 return;
3232
3233 case GT:
3234 fputs ("g", file);
3235 return;
3236
3237 case LE:
3238 fputs ("le", file);
3239 return;
3240
3241 case LT:
b657fc39
L
3242 if (cc_prev_status.flags & CC_NO_OVERFLOW)
3243 fputs ("s", file);
3244 else
3245 fputs ("l", file);
e9a25f70
JL
3246 return;
3247
3248 case GEU:
3249 fputs ("ae", file);
3250 return;
3251
3252 case GTU:
3253 fputs ("a", file);
3254 return;
3255
3256 case LEU:
3257 fputs ("be", file);
3258 return;
3259
3260 case LTU:
3261 fputs ("b", file);
3262 return;
3263
3264 default:
3265 output_operand_lossage ("Invalid %%C operand");
3266 }
3267
fe25fea3 3268 else if (mode == MODE_FLOAT)
e9a25f70
JL
3269 switch (code)
3270 {
79325812 3271 case NE:
e9a25f70
JL
3272 fputs (ieee ? (reverse_cc ? "ne" : "e") : "ne", file);
3273 return;
79325812 3274 case EQ:
e9a25f70
JL
3275 fputs (ieee ? (reverse_cc ? "ne" : "e") : "e", file);
3276 return;
79325812 3277 case GE:
e9a25f70
JL
3278 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3279 return;
79325812 3280 case GT:
e9a25f70
JL
3281 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3282 return;
79325812 3283 case LE:
e9a25f70
JL
3284 fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3285 return;
79325812 3286 case LT:
e9a25f70
JL
3287 fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3288 return;
79325812 3289 case GEU:
e9a25f70
JL
3290 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3291 return;
79325812 3292 case GTU:
e9a25f70
JL
3293 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3294 return;
79325812 3295 case LEU:
e9a25f70
JL
3296 fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3297 return;
79325812 3298 case LTU:
e9a25f70
JL
3299 fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3300 return;
3301 default:
3302 output_operand_lossage ("Invalid %%C operand");
fe25fea3 3303 }
e5cb57e8
SC
3304}
3305
2a2ab3f9 3306/* Meaning of CODE:
fe25fea3 3307 L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
e5cb57e8 3308 C -- print opcode suffix for set/cmov insn.
fe25fea3
SC
3309 c -- like C, but print reversed condition
3310 F -- print opcode suffix for fcmov insn.
a269a03c
JC
3311 f -- like F, but print reversed condition
3312 D -- print the opcode suffix for a jump
3313 d -- like D, but print reversed condition
2a2ab3f9
JVA
3314 R -- print the prefix for register names.
3315 z -- print the opcode suffix for the size of the current operand.
3316 * -- print a star (in certain assembler syntax)
3317 w -- print the operand as if it's a "word" (HImode) even if it isn't.
b08de47e 3318 J -- print the appropriate jump operand.
2d49677f
SC
3319 s -- print a shift double count, followed by the assemblers argument
3320 delimiter.
fe25fea3
SC
3321 b -- print the QImode name of the register for the indicated operand.
3322 %b0 would print %al if operands[0] is reg 0.
3323 w -- likewise, print the HImode name of the register.
3324 k -- likewise, print the SImode name of the register.
3325 h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
3326 y -- print "st(0)" instead of "st" as a register.
d119f84c
RH
3327 P -- print as a PIC constant
3328 _ -- output "_" if YES_UNDERSCORES */
2a2ab3f9
JVA
3329
3330void
3331print_operand (file, x, code)
3332 FILE *file;
3333 rtx x;
3334 int code;
3335{
3336 if (code)
3337 {
3338 switch (code)
3339 {
3340 case '*':
3341 if (USE_STAR)
3342 putc ('*', file);
3343 return;
3344
d119f84c
RH
3345 case '_':
3346#ifdef YES_UNDERSCORES
3347 putc ('_', file);
3348#endif
3349 return;
3350
2a2ab3f9
JVA
3351 case 'L':
3352 PUT_OP_SIZE (code, 'l', file);
3353 return;
3354
3355 case 'W':
3356 PUT_OP_SIZE (code, 'w', file);
3357 return;
3358
3359 case 'B':
3360 PUT_OP_SIZE (code, 'b', file);
3361 return;
3362
3363 case 'Q':
3364 PUT_OP_SIZE (code, 'l', file);
3365 return;
3366
3367 case 'S':
3368 PUT_OP_SIZE (code, 's', file);
3369 return;
3370
5f1ec3e6
JVA
3371 case 'T':
3372 PUT_OP_SIZE (code, 't', file);
3373 return;
3374
2a2ab3f9
JVA
3375 case 'z':
3376 /* 387 opcodes don't get size suffixes if the operands are
3377 registers. */
3378
3379 if (STACK_REG_P (x))
3380 return;
3381
3382 /* this is the size of op from size of operand */
3383 switch (GET_MODE_SIZE (GET_MODE (x)))
3384 {
2a2ab3f9 3385 case 2:
53b5ce19
JW
3386#ifdef HAVE_GAS_FILDS_FISTS
3387 PUT_OP_SIZE ('W', 's', file);
3388#endif
2a2ab3f9
JVA
3389 return;
3390
3391 case 4:
3392 if (GET_MODE (x) == SFmode)
3393 {
3394 PUT_OP_SIZE ('S', 's', file);
3395 return;
3396 }
3397 else
3398 PUT_OP_SIZE ('L', 'l', file);
3399 return;
3400
5f1ec3e6
JVA
3401 case 12:
3402 PUT_OP_SIZE ('T', 't', file);
3403 return;
3404
2a2ab3f9
JVA
3405 case 8:
3406 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
56c0e8fa
JVA
3407 {
3408#ifdef GAS_MNEMONICS
3409 PUT_OP_SIZE ('Q', 'q', file);
3410 return;
3411#else
3412 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
3413#endif
3414 }
2a2ab3f9
JVA
3415
3416 PUT_OP_SIZE ('Q', 'l', file);
3417 return;
53b5ce19
JW
3418
3419 default:
3420 abort ();
2a2ab3f9 3421 }
4af3895e
JVA
3422
3423 case 'b':
3424 case 'w':
3425 case 'k':
3426 case 'h':
3427 case 'y':
3428 case 'P':
5cb6195d 3429 case 'X':
4af3895e
JVA
3430 break;
3431
b08de47e
MM
3432 case 'J':
3433 switch (GET_CODE (x))
3434 {
c645b1c9
MM
3435 /* These conditions are appropriate for testing the result
3436 of an arithmetic operation, not for a compare operation.
3437 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
3438 CC_Z_IN_NOT_C false and not floating point. */
b08de47e
MM
3439 case NE: fputs ("jne", file); return;
3440 case EQ: fputs ("je", file); return;
c645b1c9 3441 case GE: fputs ("jns", file); return;
c645b1c9 3442 case LT: fputs ("js", file); return;
d784886d
RK
3443 case GEU: fputs ("jmp", file); return;
3444 case GTU: fputs ("jne", file); return;
3445 case LEU: fputs ("je", file); return;
3446 case LTU: fputs ("#branch never", file); return;
79325812 3447
d784886d 3448 /* no matching branches for GT nor LE */
79325812 3449
00c79232
ML
3450 default:
3451 abort ();
b08de47e 3452 }
b08de47e 3453
2d49677f
SC
3454 case 's':
3455 if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
3456 {
3457 PRINT_OPERAND (file, x, 0);
3458 fputs (AS2C (,) + 1, file);
3459 }
e9a25f70 3460
2d49677f
SC
3461 return;
3462
a269a03c
JC
3463 case 'D':
3464 put_jump_code (GET_CODE (x), 0, file);
3465 return;
3466
3467 case 'd':
3468 put_jump_code (GET_CODE (x), 1, file);
3469 return;
3470
1853aadd
RK
3471 /* This is used by the conditional move instructions. */
3472 case 'C':
c27d9c3b 3473 put_condition_code (GET_CODE (x), 0, MODE_INT, file);
1853aadd 3474 return;
fe25fea3 3475
e9a25f70 3476 /* Like above, but reverse condition */
fe25fea3 3477 case 'c':
c27d9c3b 3478 put_condition_code (GET_CODE (x), 1, MODE_INT, file); return;
fe25fea3
SC
3479
3480 case 'F':
c27d9c3b 3481 put_condition_code (GET_CODE (x), 0, MODE_FLOAT, file);
fe25fea3
SC
3482 return;
3483
e9a25f70 3484 /* Like above, but reverse condition */
fe25fea3 3485 case 'f':
c27d9c3b 3486 put_condition_code (GET_CODE (x), 1, MODE_FLOAT, file);
1853aadd 3487 return;
e5cb57e8 3488
4af3895e 3489 default:
68daafd4
JVA
3490 {
3491 char str[50];
3492
3493 sprintf (str, "invalid operand code `%c'", code);
3494 output_operand_lossage (str);
3495 }
2a2ab3f9
JVA
3496 }
3497 }
e9a25f70 3498
2a2ab3f9
JVA
3499 if (GET_CODE (x) == REG)
3500 {
3501 PRINT_REG (x, code, file);
3502 }
e9a25f70 3503
2a2ab3f9
JVA
3504 else if (GET_CODE (x) == MEM)
3505 {
3506 PRINT_PTR (x, file);
3507 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
3508 {
3509 if (flag_pic)
3510 output_pic_addr_const (file, XEXP (x, 0), code);
3511 else
3512 output_addr_const (file, XEXP (x, 0));
3513 }
3514 else
3515 output_address (XEXP (x, 0));
3516 }
e9a25f70 3517
2a2ab3f9
JVA
3518 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
3519 {
e9a25f70
JL
3520 REAL_VALUE_TYPE r;
3521 long l;
3522
5f1ec3e6
JVA
3523 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3524 REAL_VALUE_TO_TARGET_SINGLE (r, l);
4af3895e 3525 PRINT_IMMED_PREFIX (file);
52267fcb 3526 fprintf (file, "0x%lx", l);
5f1ec3e6 3527 }
e9a25f70 3528
5f1ec3e6
JVA
3529 /* These float cases don't actually occur as immediate operands. */
3530 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
3531 {
e9a25f70
JL
3532 REAL_VALUE_TYPE r;
3533 char dstr[30];
3534
5f1ec3e6
JVA
3535 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3536 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3537 fprintf (file, "%s", dstr);
2a2ab3f9 3538 }
e9a25f70 3539
5f1ec3e6 3540 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2a2ab3f9 3541 {
e9a25f70
JL
3542 REAL_VALUE_TYPE r;
3543 char dstr[30];
3544
5f1ec3e6
JVA
3545 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3546 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3547 fprintf (file, "%s", dstr);
2a2ab3f9 3548 }
79325812 3549 else
2a2ab3f9 3550 {
4af3895e 3551 if (code != 'P')
2a2ab3f9 3552 {
695dac07 3553 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2a2ab3f9
JVA
3554 PRINT_IMMED_PREFIX (file);
3555 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
3556 || GET_CODE (x) == LABEL_REF)
3557 PRINT_OFFSET_PREFIX (file);
3558 }
3559 if (flag_pic)
3560 output_pic_addr_const (file, x, code);
3561 else
3562 output_addr_const (file, x);
3563 }
3564}
3565\f
3566/* Print a memory operand whose address is ADDR. */
3567
3568void
3569print_operand_address (file, addr)
3570 FILE *file;
3571 register rtx addr;
3572{
3573 register rtx reg1, reg2, breg, ireg;
3574 rtx offset;
3575
3576 switch (GET_CODE (addr))
3577 {
3578 case REG:
69a8af43
JH
3579 /* ESI addressing makes instruction vector decoded on the K6. We can
3580 avoid this by ESI+0 addressing. */
3581 if (REGNO_REG_CLASS (REGNO (addr)) == SIREG
3582 && ix86_cpu == PROCESSOR_K6 && !optimize_size)
3583 output_addr_const (file, const0_rtx);
2a2ab3f9
JVA
3584 ADDR_BEG (file);
3585 fprintf (file, "%se", RP);
3586 fputs (hi_reg_name[REGNO (addr)], file);
3587 ADDR_END (file);
3588 break;
3589
3590 case PLUS:
3591 reg1 = 0;
3592 reg2 = 0;
3593 ireg = 0;
3594 breg = 0;
3595 offset = 0;
3596 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3597 {
3598 offset = XEXP (addr, 0);
3599 addr = XEXP (addr, 1);
3600 }
3601 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3602 {
3603 offset = XEXP (addr, 1);
3604 addr = XEXP (addr, 0);
3605 }
e9a25f70
JL
3606
3607 if (GET_CODE (addr) != PLUS)
3608 ;
2a2ab3f9 3609 else if (GET_CODE (XEXP (addr, 0)) == MULT)
e9a25f70 3610 reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
2a2ab3f9 3611 else if (GET_CODE (XEXP (addr, 1)) == MULT)
e9a25f70 3612 reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
2a2ab3f9 3613 else if (GET_CODE (XEXP (addr, 0)) == REG)
e9a25f70 3614 reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
2a2ab3f9 3615 else if (GET_CODE (XEXP (addr, 1)) == REG)
e9a25f70
JL
3616 reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3617
2a2ab3f9
JVA
3618 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
3619 {
e9a25f70
JL
3620 if (reg1 == 0)
3621 reg1 = addr;
3622 else
3623 reg2 = addr;
3624
2a2ab3f9
JVA
3625 addr = 0;
3626 }
e9a25f70 3627
2a2ab3f9
JVA
3628 if (offset != 0)
3629 {
e9a25f70
JL
3630 if (addr != 0)
3631 abort ();
2a2ab3f9
JVA
3632 addr = offset;
3633 }
e9a25f70 3634
2a2ab3f9
JVA
3635 if ((reg1 && GET_CODE (reg1) == MULT)
3636 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3637 {
3638 breg = reg2;
3639 ireg = reg1;
3640 }
3641 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3642 {
3643 breg = reg1;
3644 ireg = reg2;
3645 }
3646
3647 if (ireg != 0 || breg != 0)
3648 {
3649 int scale = 1;
3650
3651 if (addr != 0)
3652 {
c399861d
MM
3653 if (flag_pic)
3654 output_pic_addr_const (file, addr, 0);
c399861d 3655 else if (GET_CODE (addr) == LABEL_REF)
2a2ab3f9
JVA
3656 output_asm_label (addr);
3657 else
c399861d 3658 output_addr_const (file, addr);
2a2ab3f9
JVA
3659 }
3660
3661 if (ireg != 0 && GET_CODE (ireg) == MULT)
3662 {
3663 scale = INTVAL (XEXP (ireg, 1));
3664 ireg = XEXP (ireg, 0);
3665 }
3666
3667 /* The stack pointer can only appear as a base register,
3668 never an index register, so exchange the regs if it is wrong. */
3669
3670 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
3671 {
3672 rtx tmp;
3673
3674 tmp = breg;
3675 breg = ireg;
3676 ireg = tmp;
3677 }
3678
3679 /* output breg+ireg*scale */
3680 PRINT_B_I_S (breg, ireg, scale, file);
3681 break;
3682 }
3683
3684 case MULT:
3685 {
3686 int scale;
e9a25f70 3687
2a2ab3f9
JVA
3688 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
3689 {
3690 scale = INTVAL (XEXP (addr, 0));
3691 ireg = XEXP (addr, 1);
3692 }
3693 else
3694 {
3695 scale = INTVAL (XEXP (addr, 1));
3696 ireg = XEXP (addr, 0);
3697 }
e9a25f70 3698
69a8af43 3699 /* (reg,reg,) is shorter than (,reg,2). */
91e3ded8 3700 if (scale == 2)
69a8af43
JH
3701 {
3702 PRINT_B_I_S (ireg, ireg, 1, file);
3703 }
3704 else
3705 {
3706 output_addr_const (file, const0_rtx);
3707 PRINT_B_I_S (NULL_RTX, ireg, scale, file);
3708 }
2a2ab3f9
JVA
3709 }
3710 break;
3711
3712 default:
3713 if (GET_CODE (addr) == CONST_INT
3714 && INTVAL (addr) < 0x8000
3715 && INTVAL (addr) >= -0x8000)
f64cecad 3716 fprintf (file, "%d", (int) INTVAL (addr));
2a2ab3f9
JVA
3717 else
3718 {
3719 if (flag_pic)
3720 output_pic_addr_const (file, addr, 0);
3721 else
3722 output_addr_const (file, addr);
3723 }
3724 }
3725}
3726\f
3727/* Set the cc_status for the results of an insn whose pattern is EXP.
3728 On the 80386, we assume that only test and compare insns, as well
5cb6195d 3729 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, BSF, ASHIFT,
2a2ab3f9 3730 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
4c0d89b5
RS
3731 Also, we assume that jumps, moves and sCOND don't affect the condition
3732 codes. All else clobbers the condition codes, by assumption.
3733
3734 We assume that ALL integer add, minus, etc. instructions effect the
3735 condition codes. This MUST be consistent with i386.md.
2a2ab3f9 3736
4c0d89b5
RS
3737 We don't record any float test or compare - the redundant test &
3738 compare check in final.c does not handle stack-like regs correctly. */
2a2ab3f9
JVA
3739
3740void
3741notice_update_cc (exp)
3742 rtx exp;
3743{
3744 if (GET_CODE (exp) == SET)
3745 {
3746 /* Jumps do not alter the cc's. */
3747 if (SET_DEST (exp) == pc_rtx)
3748 return;
e9a25f70 3749
2a2ab3f9
JVA
3750 /* Moving register or memory into a register:
3751 it doesn't alter the cc's, but it might invalidate
3752 the RTX's which we remember the cc's came from.
3753 (Note that moving a constant 0 or 1 MAY set the cc's). */
3754 if (REG_P (SET_DEST (exp))
4c0d89b5 3755 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
9c8c5afb 3756 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'
a32126ad 3757 || GET_CODE (SET_SRC (exp)) == IF_THEN_ELSE))
2a2ab3f9
JVA
3758 {
3759 if (cc_status.value1
3760 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3761 cc_status.value1 = 0;
e9a25f70 3762
2a2ab3f9
JVA
3763 if (cc_status.value2
3764 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3765 cc_status.value2 = 0;
e9a25f70 3766
2a2ab3f9
JVA
3767 return;
3768 }
e9a25f70 3769
2a2ab3f9
JVA
3770 /* Moving register into memory doesn't alter the cc's.
3771 It may invalidate the RTX's which we remember the cc's came from. */
4c0d89b5
RS
3772 if (GET_CODE (SET_DEST (exp)) == MEM
3773 && (REG_P (SET_SRC (exp))
3774 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2a2ab3f9 3775 {
e9a25f70
JL
3776 if (cc_status.value1
3777 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2a2ab3f9 3778 cc_status.value1 = 0;
e9a25f70
JL
3779 if (cc_status.value2
3780 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2a2ab3f9 3781 cc_status.value2 = 0;
e9a25f70 3782
2a2ab3f9
JVA
3783 return;
3784 }
e9a25f70 3785
2a2ab3f9
JVA
3786 /* Function calls clobber the cc's. */
3787 else if (GET_CODE (SET_SRC (exp)) == CALL)
3788 {
3789 CC_STATUS_INIT;
3790 return;
3791 }
e9a25f70 3792
2a2ab3f9
JVA
3793 /* Tests and compares set the cc's in predictable ways. */
3794 else if (SET_DEST (exp) == cc0_rtx)
3795 {
3796 CC_STATUS_INIT;
3797 cc_status.value1 = SET_SRC (exp);
3798 return;
3799 }
e9a25f70 3800
2a2ab3f9
JVA
3801 /* Certain instructions effect the condition codes. */
3802 else if (GET_MODE (SET_SRC (exp)) == SImode
3803 || GET_MODE (SET_SRC (exp)) == HImode
3804 || GET_MODE (SET_SRC (exp)) == QImode)
3805 switch (GET_CODE (SET_SRC (exp)))
3806 {
e9a25f70 3807 case ASHIFTRT: case LSHIFTRT: case ASHIFT:
2a2ab3f9
JVA
3808 /* Shifts on the 386 don't set the condition codes if the
3809 shift count is zero. */
3810 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
3811 {
3812 CC_STATUS_INIT;
3813 break;
3814 }
e9a25f70 3815
2a2ab3f9
JVA
3816 /* We assume that the CONST_INT is non-zero (this rtx would
3817 have been deleted if it were zero. */
3818
3819 case PLUS: case MINUS: case NEG:
3820 case AND: case IOR: case XOR:
3821 cc_status.flags = CC_NO_OVERFLOW;
3822 cc_status.value1 = SET_SRC (exp);
3823 cc_status.value2 = SET_DEST (exp);
3824 break;
3825
ce193852
RH
3826 /* This is the bsf pattern used by ffs. */
3827 case UNSPEC:
3828 if (XINT (SET_SRC (exp), 1) == 5)
3829 {
3830 /* Only the Z flag is defined after bsf. */
3831 cc_status.flags
3832 = CC_NOT_POSITIVE | CC_NOT_NEGATIVE | CC_NO_OVERFLOW;
3833 cc_status.value1 = XVECEXP (SET_SRC (exp), 0, 0);
9d932d43 3834 cc_status.value2 = 0;
ce193852
RH
3835 break;
3836 }
3837 /* FALLTHRU */
3838
2a2ab3f9
JVA
3839 default:
3840 CC_STATUS_INIT;
3841 }
3842 else
3843 {
3844 CC_STATUS_INIT;
3845 }
3846 }
3847 else if (GET_CODE (exp) == PARALLEL
3848 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
3849 {
3850 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
3851 return;
3852 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
e9a25f70 3853
2a2ab3f9
JVA
3854 {
3855 CC_STATUS_INIT;
a8620236
SC
3856 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
3857 {
3858 cc_status.flags |= CC_IN_80387;
a9ba8a88 3859 if (0 && TARGET_CMOVE && stack_regs_mentioned_p
a8620236
SC
3860 (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1)))
3861 cc_status.flags |= CC_FCOMI;
3862 }
2247a58c 3863 else
4c0d89b5 3864 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2a2ab3f9
JVA
3865 return;
3866 }
e9a25f70 3867
2a2ab3f9
JVA
3868 CC_STATUS_INIT;
3869 }
3870 else
3871 {
3872 CC_STATUS_INIT;
3873 }
3874}
3875\f
3876/* Split one or more DImode RTL references into pairs of SImode
3877 references. The RTL can be REG, offsettable MEM, integer constant, or
3878 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3879 split and "num" is its length. lo_half and hi_half are output arrays
3880 that parallel "operands". */
3881
3882void
3883split_di (operands, num, lo_half, hi_half)
3884 rtx operands[];
3885 int num;
3886 rtx lo_half[], hi_half[];
3887{
3888 while (num--)
3889 {
57dbca5e 3890 rtx op = operands[num];
a269a03c
JC
3891 if (! reload_completed)
3892 {
3893 lo_half[num] = gen_lowpart (SImode, op);
3894 hi_half[num] = gen_highpart (SImode, op);
3895 }
3896 else if (GET_CODE (op) == REG)
2a2ab3f9 3897 {
57dbca5e
BS
3898 lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
3899 hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
2a2ab3f9 3900 }
57dbca5e
BS
3901 else if (CONSTANT_P (op))
3902 split_double (op, &lo_half[num], &hi_half[num]);
3903 else if (offsettable_memref_p (op))
2a2ab3f9 3904 {
57dbca5e
BS
3905 rtx lo_addr = XEXP (op, 0);
3906 rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
3907 lo_half[num] = change_address (op, SImode, lo_addr);
3908 hi_half[num] = change_address (op, SImode, hi_addr);
2a2ab3f9
JVA
3909 }
3910 else
3911 abort();
3912 }
3913}
3914\f
3915/* Return 1 if this is a valid binary operation on a 387.
3916 OP is the expression matched, and MODE is its mode. */
3917
3918int
3919binary_387_op (op, mode)
3920 register rtx op;
3921 enum machine_mode mode;
3922{
3923 if (mode != VOIDmode && mode != GET_MODE (op))
3924 return 0;
3925
3926 switch (GET_CODE (op))
3927 {
3928 case PLUS:
3929 case MINUS:
3930 case MULT:
3931 case DIV:
3932 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3933
3934 default:
3935 return 0;
3936 }
3937}
3b3c6a3f 3938\f
2a2ab3f9
JVA
3939/* Return 1 if this is a valid shift or rotate operation on a 386.
3940 OP is the expression matched, and MODE is its mode. */
3941
3942int
3943shift_op (op, mode)
3944 register rtx op;
3945 enum machine_mode mode;
3946{
3947 rtx operand = XEXP (op, 0);
3948
3949 if (mode != VOIDmode && mode != GET_MODE (op))
3950 return 0;
3951
3952 if (GET_MODE (operand) != GET_MODE (op)
3953 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3954 return 0;
3955
3956 return (GET_CODE (op) == ASHIFT
3957 || GET_CODE (op) == ASHIFTRT
3958 || GET_CODE (op) == LSHIFTRT
3959 || GET_CODE (op) == ROTATE
3960 || GET_CODE (op) == ROTATERT);
3961}
ac2afb64
JVA
3962
3963/* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3964 MODE is not used. */
3965
3966int
3967VOIDmode_compare_op (op, mode)
3968 register rtx op;
bb5177ac 3969 enum machine_mode mode ATTRIBUTE_UNUSED;
ac2afb64
JVA
3970{
3971 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3972}
2a2ab3f9
JVA
3973\f
3974/* Output code to perform a 387 binary operation in INSN, one of PLUS,
3975 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3976 is the expression of the binary operation. The output may either be
3977 emitted here, or returned to the caller, like all output_* functions.
3978
3979 There is no guarantee that the operands are the same mode, as they
3980 might be within FLOAT or FLOAT_EXTEND expressions. */
3981
3982char *
3983output_387_binary_op (insn, operands)
3984 rtx insn;
3985 rtx *operands;
3986{
3987 rtx temp;
3988 char *base_op;
3989 static char buf[100];
3990
3991 switch (GET_CODE (operands[3]))
3992 {
3993 case PLUS:
87aa5246 3994 base_op = "fadd";
2a2ab3f9
JVA
3995 break;
3996
3997 case MINUS:
87aa5246 3998 base_op = "fsub";
2a2ab3f9
JVA
3999 break;
4000
4001 case MULT:
87aa5246 4002 base_op = "fmul";
2a2ab3f9
JVA
4003 break;
4004
4005 case DIV:
87aa5246 4006 base_op = "fdiv";
2a2ab3f9
JVA
4007 break;
4008
4009 default:
4010 abort ();
4011 }
4012
4013 strcpy (buf, base_op);
4014
4015 switch (GET_CODE (operands[3]))
4016 {
4017 case MULT:
4018 case PLUS:
4019 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
4020 {
4021 temp = operands[2];
4022 operands[2] = operands[1];
4023 operands[1] = temp;
4024 }
4025
4026 if (GET_CODE (operands[2]) == MEM)
4027 return strcat (buf, AS1 (%z2,%2));
4028
87aa5246
JW
4029 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
4030 abort ();
2a2ab3f9
JVA
4031
4032 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
4033 {
4034 if (STACK_TOP_P (operands[0]))
4035 return strcat (buf, AS2 (p,%0,%2));
4036 else
4037 return strcat (buf, AS2 (p,%2,%0));
4038 }
2a2ab3f9
JVA
4039
4040 if (STACK_TOP_P (operands[0]))
3f6d0a8c 4041 return strcat (buf, AS2C (%y2,%0));
2a2ab3f9 4042 else
3f6d0a8c 4043 return strcat (buf, AS2C (%2,%0));
2a2ab3f9
JVA
4044
4045 case MINUS:
4046 case DIV:
4047 if (GET_CODE (operands[1]) == MEM)
4048 return strcat (buf, AS1 (r%z1,%1));
4049
4050 if (GET_CODE (operands[2]) == MEM)
4051 return strcat (buf, AS1 (%z2,%2));
4052
2a2ab3f9
JVA
4053 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
4054 abort ();
4055
4056 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
4057 {
4058 if (STACK_TOP_P (operands[0]))
4059 return strcat (buf, AS2 (p,%0,%2));
4060 else
4061 return strcat (buf, AS2 (rp,%2,%0));
4062 }
2a2ab3f9
JVA
4063
4064 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
6b28fd63
JL
4065 {
4066 if (STACK_TOP_P (operands[0]))
4067 return strcat (buf, AS2 (rp,%0,%1));
4068 else
4069 return strcat (buf, AS2 (p,%1,%0));
4070 }
2a2ab3f9
JVA
4071
4072 if (STACK_TOP_P (operands[0]))
4073 {
4074 if (STACK_TOP_P (operands[1]))
3f6d0a8c 4075 return strcat (buf, AS2C (%y2,%0));
2a2ab3f9
JVA
4076 else
4077 return strcat (buf, AS2 (r,%y1,%0));
4078 }
4079 else if (STACK_TOP_P (operands[1]))
3f6d0a8c 4080 return strcat (buf, AS2C (%1,%0));
2a2ab3f9
JVA
4081 else
4082 return strcat (buf, AS2 (r,%2,%0));
4083
4084 default:
4085 abort ();
4086 }
4087}
4088\f
4089/* Output code for INSN to convert a float to a signed int. OPERANDS
4090 are the insn operands. The output may be SFmode or DFmode and the
4091 input operand may be SImode or DImode. As a special case, make sure
4092 that the 387 stack top dies if the output mode is DImode, because the
4093 hardware requires this. */
4094
4095char *
4096output_fix_trunc (insn, operands)
4097 rtx insn;
4098 rtx *operands;
4099{
4100 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
305f097e 4101 rtx xops[2];
2a2ab3f9 4102
2e14a41b 4103 if (! STACK_TOP_P (operands[1]))
2a2ab3f9
JVA
4104 abort ();
4105
305f097e
JVA
4106 xops[0] = GEN_INT (12);
4107 xops[1] = operands[4];
4108
4109 output_asm_insn (AS1 (fnstc%W2,%2), operands);
4110 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
4111 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
4112 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
4113 output_asm_insn (AS1 (fldc%W3,%3), operands);
2a2ab3f9
JVA
4114
4115 if (NON_STACK_REG_P (operands[0]))
c27d9c3b 4116 output_to_reg (operands[0], stack_top_dies, operands[3]);
e9a25f70 4117
2a2ab3f9
JVA
4118 else if (GET_CODE (operands[0]) == MEM)
4119 {
2a2ab3f9
JVA
4120 if (stack_top_dies)
4121 output_asm_insn (AS1 (fistp%z0,%0), operands);
2e14a41b
JW
4122 else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
4123 {
4124 /* There is no DImode version of this without a stack pop, so
4125 we must emulate it. It doesn't matter much what the second
4126 instruction is, because the value being pushed on the FP stack
4127 is not used except for the following stack popping store.
4128 This case can only happen without optimization, so it doesn't
4129 matter that it is inefficient. */
4130 output_asm_insn (AS1 (fistp%z0,%0), operands);
4131 output_asm_insn (AS1 (fild%z0,%0), operands);
4132 }
2a2ab3f9
JVA
4133 else
4134 output_asm_insn (AS1 (fist%z0,%0), operands);
4135 }
4136 else
4137 abort ();
4138
305f097e 4139 return AS1 (fldc%W2,%2);
2a2ab3f9
JVA
4140}
4141\f
cda749b1
JW
4142/* Output code for INSN to extend a float. OPERANDS are the insn
4143 operands. The output may be DFmode or XFmode and the input operand
4144 may be SFmode or DFmode. Operands 2 and 3 are scratch memory and
4145 are only necessary if operands 0 or 1 are non-stack registers. */
4146
4147void
4148output_float_extend (insn, operands)
4149 rtx insn;
4150 rtx *operands;
4151{
4152 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4153 rtx xops[2];
4154
4155 if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
4156 abort ();
4157
4158 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]) && stack_top_dies)
4159 return;
4160
4161 if (STACK_TOP_P (operands[0]) )
4162 {
4163 if (NON_STACK_REG_P (operands[1]))
4164 {
4165 if (GET_MODE (operands[1]) == SFmode)
4166 output_asm_insn (AS2 (mov%L0,%1,%2), operands);
4167 else
4168 {
4169 xops[0] = operands[2];
4170 xops[1] = operands[1];
4171 output_asm_insn (output_move_double (xops), xops);
4172 }
4173 }
4174
4175 xops[0] = NON_STACK_REG_P (operands[1]) ? operands[2] : operands[1];
4176
4177 output_asm_insn (AS1 (fld%z0,%y0), xops);
4178 }
4179 else
4180 {
4181 xops[0] = NON_STACK_REG_P (operands[0]) ? operands[3] : operands[0];
4182
4183 if (stack_top_dies
4184 || (GET_CODE (xops[0]) == MEM && GET_MODE (xops[0]) == XFmode))
4185 {
4186 output_asm_insn (AS1 (fstp%z0,%y0), xops);
4187 if (! stack_top_dies)
4188 output_asm_insn (AS1 (fld%z0,%y0), xops);
4189 }
4190 else
4191 output_asm_insn (AS1 (fst%z0,%y0), xops);
4192
4193 if (NON_STACK_REG_P (operands[0]))
4194 {
4195 xops[0] = operands[0];
4196 xops[1] = operands[3];
4197 output_asm_insn (output_move_double (xops), xops);
4198 }
4199 }
4200}
4201\f
2a2ab3f9
JVA
4202/* Output code for INSN to compare OPERANDS. The two operands might
4203 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
c572e5ba
JVA
4204 expression. If the compare is in mode CCFPEQmode, use an opcode that
4205 will not fault if a qNaN is present. */
2a2ab3f9
JVA
4206
4207char *
4208output_float_compare (insn, operands)
4209 rtx insn;
4210 rtx *operands;
4211{
4212 int stack_top_dies;
c572e5ba
JVA
4213 rtx body = XVECEXP (PATTERN (insn), 0, 0);
4214 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
32b5b1aa 4215 rtx tmp;
4f74d15b 4216
a9ba8a88 4217 if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
4f74d15b
SC
4218 {
4219 cc_status.flags |= CC_FCOMI;
4220 cc_prev_status.flags &= ~CC_TEST_AX;
4221 }
4222
32b5b1aa
SC
4223 if (! STACK_TOP_P (operands[0]))
4224 {
4225 tmp = operands[0];
4226 operands[0] = operands[1];
4227 operands[1] = tmp;
4228 cc_status.flags |= CC_REVERSED;
4229 }
79325812 4230
2a2ab3f9
JVA
4231 if (! STACK_TOP_P (operands[0]))
4232 abort ();
4233
4234 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4235
4236 if (STACK_REG_P (operands[1])
4237 && stack_top_dies
4238 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4239 && REGNO (operands[1]) != FIRST_STACK_REG)
4240 {
4241 /* If both the top of the 387 stack dies, and the other operand
4242 is also a stack register that dies, then this must be a
4243 `fcompp' float compare */
4244
c572e5ba 4245 if (unordered_compare)
e9a25f70
JL
4246 {
4247 if (cc_status.flags & CC_FCOMI)
4248 {
4249 output_asm_insn (AS2 (fucomip,%y1,%0), operands);
4250 output_asm_insn (AS1 (fstp, %y0), operands);
a9ba8a88 4251 return "";
e9a25f70
JL
4252 }
4253 else
4254 output_asm_insn ("fucompp", operands);
4255 }
c572e5ba 4256 else
858a9ffc 4257 {
e9a25f70
JL
4258 if (cc_status.flags & CC_FCOMI)
4259 {
4260 output_asm_insn (AS2 (fcomip, %y1,%0), operands);
4261 output_asm_insn (AS1 (fstp, %y0), operands);
4262 return "";
4263 }
4264 else
4265 output_asm_insn ("fcompp", operands);
858a9ffc 4266 }
2a2ab3f9
JVA
4267 }
4268 else
4269 {
4270 static char buf[100];
4271
87aa5246 4272 /* Decide if this is a float compare or an unordered float compare. */
2a2ab3f9 4273
c572e5ba 4274 if (unordered_compare)
4f74d15b 4275 strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fucomi" : "fucom");
2a2ab3f9 4276 else
87aa5246 4277 strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom");
2a2ab3f9
JVA
4278
4279 /* Modify the opcode if the 387 stack is to be popped. */
4280
4281 if (stack_top_dies)
4282 strcat (buf, "p");
4283
87aa5246 4284 if (cc_status.flags & CC_FCOMI)
5703bb66 4285 {
858a9ffc 4286 output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
a9ba8a88 4287 return "";
5703bb66 4288 }
2a2ab3f9
JVA
4289 else
4290 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
4291 }
4292
4293 /* Now retrieve the condition code. */
4294
c572e5ba
JVA
4295 return output_fp_cc0_set (insn);
4296}
4297\f
4298/* Output opcodes to transfer the results of FP compare or test INSN
4299 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
4300 result of the compare or test is unordered, no comparison operator
4301 succeeds except NE. Return an output template, if any. */
4302
4303char *
4304output_fp_cc0_set (insn)
4305 rtx insn;
4306{
4307 rtx xops[3];
c572e5ba
JVA
4308 rtx next;
4309 enum rtx_code code;
4310
a9ba8a88
JL
4311 xops[0] = gen_rtx_REG (HImode, 0);
4312 output_asm_insn (AS1 (fnsts%W0,%0), xops);
c572e5ba
JVA
4313
4314 if (! TARGET_IEEE_FP)
32b5b1aa
SC
4315 {
4316 if (!(cc_status.flags & CC_REVERSED))
4317 {
4318 next = next_cc0_user (insn);
a9ba8a88
JL
4319
4320 if (GET_CODE (next) == JUMP_INSN
4321 && GET_CODE (PATTERN (next)) == SET
32b5b1aa
SC
4322 && SET_DEST (PATTERN (next)) == pc_rtx
4323 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
e9a25f70 4324 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
32b5b1aa 4325 else if (GET_CODE (PATTERN (next)) == SET)
e9a25f70 4326 code = GET_CODE (SET_SRC (PATTERN (next)));
32b5b1aa 4327 else
e9a25f70
JL
4328 return "sahf";
4329
4330 if (code == GT || code == LT || code == EQ || code == NE
4331 || code == LE || code == GE)
4332 {
4333 /* We will test eax directly. */
32b5b1aa 4334 cc_status.flags |= CC_TEST_AX;
e9a25f70 4335 return "";
32b5b1aa
SC
4336 }
4337 }
e9a25f70 4338
32b5b1aa
SC
4339 return "sahf";
4340 }
2a2ab3f9 4341
c572e5ba 4342 next = next_cc0_user (insn);
dd9611dc
JVA
4343 if (next == NULL_RTX)
4344 abort ();
c572e5ba 4345
a9ba8a88
JL
4346 if (GET_CODE (next) == JUMP_INSN
4347 && GET_CODE (PATTERN (next)) == SET
c572e5ba
JVA
4348 && SET_DEST (PATTERN (next)) == pc_rtx
4349 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
e9a25f70 4350 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
c572e5ba
JVA
4351 else if (GET_CODE (PATTERN (next)) == SET)
4352 {
fe25fea3
SC
4353 if (GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4354 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
e9a25f70
JL
4355 else
4356 code = GET_CODE (SET_SRC (PATTERN (next)));
c572e5ba 4357 }
e9a25f70 4358
4f74d15b
SC
4359 else if (GET_CODE (PATTERN (next)) == PARALLEL
4360 && GET_CODE (XVECEXP (PATTERN (next), 0, 0)) == SET)
4361 {
4362 if (GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0))) == IF_THEN_ELSE)
e9a25f70
JL
4363 code = GET_CODE (XEXP (SET_SRC (XVECEXP (PATTERN (next), 0, 0)), 0));
4364 else
4365 code = GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0)));
4f74d15b 4366 }
c572e5ba
JVA
4367 else
4368 abort ();
4369
a9ba8a88 4370 xops[0] = gen_rtx_REG (QImode, 0);
a14003ee 4371
a9ba8a88 4372 switch (code)
c572e5ba 4373 {
a9ba8a88
JL
4374 case GT:
4375 xops[1] = GEN_INT (0x45);
4376 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4377 /* je label */
4378 break;
c572e5ba 4379
a9ba8a88
JL
4380 case LT:
4381 xops[1] = GEN_INT (0x45);
4382 xops[2] = GEN_INT (0x01);
4383 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4384 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4385 /* je label */
4386 break;
c572e5ba 4387
a9ba8a88
JL
4388 case GE:
4389 xops[1] = GEN_INT (0x05);
4390 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4391 /* je label */
4392 break;
c572e5ba 4393
a9ba8a88
JL
4394 case LE:
4395 xops[1] = GEN_INT (0x45);
4396 xops[2] = GEN_INT (0x40);
4397 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4398 output_asm_insn (AS1 (dec%B0,%h0), xops);
4399 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4400 /* jb label */
4401 break;
c572e5ba 4402
a9ba8a88
JL
4403 case EQ:
4404 xops[1] = GEN_INT (0x45);
4405 xops[2] = GEN_INT (0x40);
4406 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4407 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4408 /* je label */
4409 break;
c572e5ba 4410
a9ba8a88
JL
4411 case NE:
4412 xops[1] = GEN_INT (0x44);
4413 xops[2] = GEN_INT (0x40);
4414 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4415 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
4416 /* jne label */
4417 break;
a14003ee 4418
a9ba8a88
JL
4419 case GTU:
4420 case LTU:
4421 case GEU:
4422 case LEU:
4423 default:
4424 abort ();
c572e5ba 4425 }
e9a25f70
JL
4426
4427 return "";
2a2ab3f9 4428}
305f097e
JVA
4429\f
4430#define MAX_386_STACK_LOCALS 2
4431
4432static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4433
ecbc4695
RS
4434/* Define the structure for the machine field in struct function. */
4435struct machine_function
4436{
4437 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
b94b5c16
JL
4438 rtx pic_label_rtx;
4439 char pic_label_name[256];
ecbc4695
RS
4440};
4441
4442/* Functions to save and restore i386_stack_locals.
4443 These will be called, via pointer variables,
4444 from push_function_context and pop_function_context. */
4445
4446void
4447save_386_machine_status (p)
4448 struct function *p;
4449{
b94b5c16
JL
4450 p->machine
4451 = (struct machine_function *) xmalloc (sizeof (struct machine_function));
dde866c6 4452 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
ecbc4695 4453 sizeof i386_stack_locals);
b94b5c16
JL
4454 p->machine->pic_label_rtx = pic_label_rtx;
4455 bcopy (pic_label_name, p->machine->pic_label_name, 256);
ecbc4695
RS
4456}
4457
4458void
4459restore_386_machine_status (p)
4460 struct function *p;
4461{
dde866c6 4462 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
ecbc4695 4463 sizeof i386_stack_locals);
b94b5c16
JL
4464 pic_label_rtx = p->machine->pic_label_rtx;
4465 bcopy (p->machine->pic_label_name, pic_label_name, 256);
ecbc4695 4466 free (p->machine);
b94b5c16 4467 p->machine = NULL;
ecbc4695
RS
4468}
4469
305f097e
JVA
4470/* Clear stack slot assignments remembered from previous functions.
4471 This is called from INIT_EXPANDERS once before RTL is emitted for each
ecbc4695 4472 function. */
305f097e
JVA
4473
4474void
4475clear_386_stack_locals ()
4476{
4477 enum machine_mode mode;
4478 int n;
4479
4480 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
4481 mode = (enum machine_mode) ((int) mode + 1))
4482 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
4483 i386_stack_locals[(int) mode][n] = NULL_RTX;
ecbc4695 4484
b94b5c16
JL
4485 pic_label_rtx = NULL_RTX;
4486 bzero (pic_label_name, 256);
ecbc4695
RS
4487 /* Arrange to save and restore i386_stack_locals around nested functions. */
4488 save_machine_status = save_386_machine_status;
4489 restore_machine_status = restore_386_machine_status;
305f097e
JVA
4490}
4491
4492/* Return a MEM corresponding to a stack slot with mode MODE.
4493 Allocate a new slot if necessary.
4494
4495 The RTL for a function can have several slots available: N is
4496 which slot to use. */
4497
4498rtx
4499assign_386_stack_local (mode, n)
4500 enum machine_mode mode;
4501 int n;
4502{
4503 if (n < 0 || n >= MAX_386_STACK_LOCALS)
4504 abort ();
4505
4506 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
4507 i386_stack_locals[(int) mode][n]
4508 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
4509
4510 return i386_stack_locals[(int) mode][n];
4511}
32b5b1aa
SC
4512\f
4513int is_mul(op,mode)
4514 register rtx op;
bb5177ac 4515 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4516{
4517 return (GET_CODE (op) == MULT);
4518}
4519
4520int is_div(op,mode)
4521 register rtx op;
bb5177ac 4522 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4523{
4524 return (GET_CODE (op) == DIV);
4525}
32b5b1aa
SC
4526\f
4527#ifdef NOTYET
4528/* Create a new copy of an rtx.
4529 Recursively copies the operands of the rtx,
4530 except for those few rtx codes that are sharable.
4531 Doesn't share CONST */
4532
4533rtx
4534copy_all_rtx (orig)
4535 register rtx orig;
4536{
4537 register rtx copy;
4538 register int i, j;
4539 register RTX_CODE code;
4540 register char *format_ptr;
4541
4542 code = GET_CODE (orig);
4543
4544 switch (code)
4545 {
4546 case REG:
4547 case QUEUED:
4548 case CONST_INT:
4549 case CONST_DOUBLE:
4550 case SYMBOL_REF:
4551 case CODE_LABEL:
4552 case PC:
4553 case CC0:
4554 case SCRATCH:
4555 /* SCRATCH must be shared because they represent distinct values. */
4556 return orig;
4557
4558#if 0
4559 case CONST:
4560 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
4561 a LABEL_REF, it isn't sharable. */
4562 if (GET_CODE (XEXP (orig, 0)) == PLUS
4563 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
4564 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
4565 return orig;
4566 break;
4567#endif
4568 /* A MEM with a constant address is not sharable. The problem is that
4569 the constant address may need to be reloaded. If the mem is shared,
4570 then reloading one copy of this mem will cause all copies to appear
4571 to have been reloaded. */
4572 }
4573
4574 copy = rtx_alloc (code);
4575 PUT_MODE (copy, GET_MODE (orig));
4576 copy->in_struct = orig->in_struct;
4577 copy->volatil = orig->volatil;
4578 copy->unchanging = orig->unchanging;
4579 copy->integrated = orig->integrated;
4580 /* intel1 */
4581 copy->is_spill_rtx = orig->is_spill_rtx;
79325812 4582
32b5b1aa
SC
4583 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
4584
4585 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
4586 {
4587 switch (*format_ptr++)
4588 {
4589 case 'e':
4590 XEXP (copy, i) = XEXP (orig, i);
4591 if (XEXP (orig, i) != NULL)
4592 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
4593 break;
4594
4595 case '0':
4596 case 'u':
4597 XEXP (copy, i) = XEXP (orig, i);
4598 break;
4599
4600 case 'E':
4601 case 'V':
4602 XVEC (copy, i) = XVEC (orig, i);
4603 if (XVEC (orig, i) != NULL)
4604 {
4605 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
4606 for (j = 0; j < XVECLEN (copy, i); j++)
4607 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
4608 }
4609 break;
4610
4611 case 'w':
4612 XWINT (copy, i) = XWINT (orig, i);
4613 break;
4614
4615 case 'i':
4616 XINT (copy, i) = XINT (orig, i);
4617 break;
4618
4619 case 's':
4620 case 'S':
4621 XSTR (copy, i) = XSTR (orig, i);
4622 break;
4623
4624 default:
4625 abort ();
4626 }
4627 }
4628 return copy;
4629}
4630
4631\f
e9a25f70
JL
4632/* Try to rewrite a memory address to make it valid */
4633
79325812 4634void
32b5b1aa
SC
4635rewrite_address (mem_rtx)
4636 rtx mem_rtx;
4637{
4638 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
4639 int scale = 1;
4640 int offset_adjust = 0;
4641 int was_only_offset = 0;
4642 rtx mem_addr = XEXP (mem_rtx, 0);
e9a25f70 4643 char *storage = oballoc (0);
32b5b1aa
SC
4644 int in_struct = 0;
4645 int is_spill_rtx = 0;
4646
4647 in_struct = MEM_IN_STRUCT_P (mem_rtx);
4648 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
4649
e9a25f70
JL
4650 if (GET_CODE (mem_addr) == PLUS
4651 && GET_CODE (XEXP (mem_addr, 1)) == PLUS
4652 && GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
4653 {
4654 /* This part is utilized by the combiner. */
4655 ret_rtx
4656 = gen_rtx (PLUS, GET_MODE (mem_addr),
4657 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
4658 XEXP (mem_addr, 0), XEXP (XEXP (mem_addr, 1), 0)),
4659 XEXP (XEXP (mem_addr, 1), 1));
4660
32b5b1aa
SC
4661 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
4662 {
4663 XEXP (mem_rtx, 0) = ret_rtx;
4664 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
4665 return;
4666 }
e9a25f70 4667
32b5b1aa
SC
4668 obfree (storage);
4669 }
4670
79325812 4671 /* This part is utilized by loop.c.
e9a25f70
JL
4672 If the address contains PLUS (reg,const) and this pattern is invalid
4673 in this case - try to rewrite the address to make it valid. */
4674 storage = oballoc (0);
32b5b1aa 4675 index_rtx = base_rtx = offset_rtx = NULL;
e9a25f70
JL
4676
4677 /* Find the base index and offset elements of the memory address. */
32b5b1aa
SC
4678 if (GET_CODE (mem_addr) == PLUS)
4679 {
4680 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
4681 {
4682 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
e9a25f70 4683 base_rtx = XEXP (mem_addr, 1), index_rtx = XEXP (mem_addr, 0);
32b5b1aa 4684 else
e9a25f70 4685 base_rtx = XEXP (mem_addr, 0), offset_rtx = XEXP (mem_addr, 1);
32b5b1aa 4686 }
e9a25f70 4687
32b5b1aa
SC
4688 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
4689 {
4690 index_rtx = XEXP (mem_addr, 0);
4691 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
e9a25f70 4692 base_rtx = XEXP (mem_addr, 1);
32b5b1aa 4693 else
e9a25f70 4694 offset_rtx = XEXP (mem_addr, 1);
32b5b1aa 4695 }
e9a25f70 4696
32b5b1aa
SC
4697 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
4698 {
e9a25f70
JL
4699 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS
4700 && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT
4701 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0))
4702 == REG)
4703 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1))
4704 == CONST_INT)
4705 && (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1))
4706 == CONST_INT)
4707 && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG
4708 && GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
32b5b1aa
SC
4709 {
4710 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
4711 offset_rtx = XEXP (mem_addr, 1);
4712 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4713 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
4714 }
4715 else
4716 {
4717 offset_rtx = XEXP (mem_addr, 1);
4718 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
4719 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4720 }
4721 }
e9a25f70 4722
32b5b1aa
SC
4723 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
4724 {
4725 was_only_offset = 1;
4726 index_rtx = NULL;
4727 base_rtx = NULL;
4728 offset_rtx = XEXP (mem_addr, 1);
4729 offset_adjust = INTVAL (XEXP (mem_addr, 0));
4730 if (offset_adjust == 0)
4731 {
4732 XEXP (mem_rtx, 0) = offset_rtx;
4733 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4734 return;
4735 }
4736 }
4737 else
4738 {
4739 obfree (storage);
4740 return;
4741 }
4742 }
4743 else if (GET_CODE (mem_addr) == MULT)
e9a25f70 4744 index_rtx = mem_addr;
32b5b1aa
SC
4745 else
4746 {
4747 obfree (storage);
4748 return;
4749 }
e9a25f70
JL
4750
4751 if (index_rtx != 0 && GET_CODE (index_rtx) == MULT)
32b5b1aa
SC
4752 {
4753 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
4754 {
4755 obfree (storage);
4756 return;
4757 }
e9a25f70 4758
32b5b1aa
SC
4759 scale_rtx = XEXP (index_rtx, 1);
4760 scale = INTVAL (scale_rtx);
4761 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4762 }
e9a25f70
JL
4763
4764 /* Now find which of the elements are invalid and try to fix them. */
32b5b1aa
SC
4765 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
4766 {
4767 offset_adjust = INTVAL (index_rtx) * scale;
e9a25f70
JL
4768
4769 if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4770 offset_rtx = plus_constant (offset_rtx, offset_adjust);
4771 else if (offset_rtx == 0)
4772 offset_rtx = const0_rtx;
4773
32b5b1aa
SC
4774 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4775 XEXP (mem_rtx, 0) = offset_rtx;
4776 return;
4777 }
e9a25f70
JL
4778
4779 if (base_rtx && GET_CODE (base_rtx) == PLUS
4780 && GET_CODE (XEXP (base_rtx, 0)) == REG
4781 && GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
32b5b1aa
SC
4782 {
4783 offset_adjust += INTVAL (XEXP (base_rtx, 1));
4784 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
4785 }
e9a25f70 4786
32b5b1aa
SC
4787 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
4788 {
4789 offset_adjust += INTVAL (base_rtx);
4790 base_rtx = NULL;
4791 }
e9a25f70
JL
4792
4793 if (index_rtx && GET_CODE (index_rtx) == PLUS
4794 && GET_CODE (XEXP (index_rtx, 0)) == REG
4795 && GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
32b5b1aa
SC
4796 {
4797 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
4798 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4799 }
e9a25f70 4800
32b5b1aa
SC
4801 if (index_rtx)
4802 {
e9a25f70
JL
4803 if (! LEGITIMATE_INDEX_P (index_rtx)
4804 && ! (index_rtx == stack_pointer_rtx && scale == 1
4805 && base_rtx == NULL))
32b5b1aa
SC
4806 {
4807 obfree (storage);
4808 return;
4809 }
4810 }
e9a25f70 4811
32b5b1aa
SC
4812 if (base_rtx)
4813 {
e9a25f70 4814 if (! LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
32b5b1aa
SC
4815 {
4816 obfree (storage);
4817 return;
4818 }
4819 }
e9a25f70 4820
32b5b1aa
SC
4821 if (offset_adjust != 0)
4822 {
e9a25f70
JL
4823 if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4824 offset_rtx = plus_constant (offset_rtx, offset_adjust);
32b5b1aa 4825 else
e9a25f70
JL
4826 offset_rtx = const0_rtx;
4827
32b5b1aa
SC
4828 if (index_rtx)
4829 {
4830 if (base_rtx)
4831 {
4832 if (scale != 1)
4833 {
e9a25f70
JL
4834 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
4835 gen_rtx (MULT, GET_MODE (index_rtx),
4836 index_rtx, scale_rtx),
4837 base_rtx);
4838
4839 if (GET_CODE (offset_rtx) != CONST_INT
4840 || INTVAL (offset_rtx) != 0)
4841 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4842 ret_rtx, offset_rtx);
32b5b1aa
SC
4843 }
4844 else
4845 {
e9a25f70
JL
4846 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4847 index_rtx, base_rtx);
4848
4849 if (GET_CODE (offset_rtx) != CONST_INT
4850 || INTVAL (offset_rtx) != 0)
4851 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4852 ret_rtx, offset_rtx);
32b5b1aa
SC
4853 }
4854 }
4855 else
4856 {
4857 if (scale != 1)
4858 {
e9a25f70
JL
4859 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx),
4860 index_rtx, scale_rtx);
4861
4862 if (GET_CODE (offset_rtx) != CONST_INT
4863 || INTVAL (offset_rtx) != 0)
4864 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4865 ret_rtx, offset_rtx);
32b5b1aa
SC
4866 }
4867 else
4868 {
e9a25f70
JL
4869 if (GET_CODE (offset_rtx) == CONST_INT
4870 && INTVAL (offset_rtx) == 0)
4871 ret_rtx = index_rtx;
32b5b1aa 4872 else
e9a25f70
JL
4873 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4874 index_rtx, offset_rtx);
32b5b1aa
SC
4875 }
4876 }
4877 }
4878 else
4879 {
4880 if (base_rtx)
4881 {
e9a25f70
JL
4882 if (GET_CODE (offset_rtx) == CONST_INT
4883 && INTVAL (offset_rtx) == 0)
4884 ret_rtx = base_rtx;
32b5b1aa 4885 else
e9a25f70
JL
4886 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx,
4887 offset_rtx);
32b5b1aa
SC
4888 }
4889 else if (was_only_offset)
e9a25f70 4890 ret_rtx = offset_rtx;
32b5b1aa
SC
4891 else
4892 {
4893 obfree (storage);
4894 return;
4895 }
4896 }
e9a25f70 4897
32b5b1aa
SC
4898 XEXP (mem_rtx, 0) = ret_rtx;
4899 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4900 return;
4901 }
4902 else
4903 {
4904 obfree (storage);
4905 return;
4906 }
4907}
4908#endif /* NOTYET */
32b5b1aa 4909\f
e9a25f70
JL
4910/* Return 1 if the first insn to set cc before INSN also sets the register
4911 REG_RTX; otherwise return 0. */
32b5b1aa
SC
4912int
4913last_to_set_cc (reg_rtx, insn)
4914 rtx reg_rtx, insn;
4915{
4916 rtx prev_insn = PREV_INSN (insn);
4917
4918 while (prev_insn)
4919 {
4920 if (GET_CODE (prev_insn) == NOTE)
4921 ;
4922
4923 else if (GET_CODE (prev_insn) == INSN)
4924 {
4925 if (GET_CODE (PATTERN (prev_insn)) != SET)
4926 return (0);
4927
4928 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4929 {
4930 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4931 return (1);
4932
4933 return (0);
4934 }
4935
e9a25f70 4936 else if (! doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
32b5b1aa
SC
4937 return (0);
4938 }
4939
4940 else
4941 return (0);
4942
4943 prev_insn = PREV_INSN (prev_insn);
4944 }
4945
4946 return (0);
4947}
32b5b1aa
SC
4948\f
4949int
4950doesnt_set_condition_code (pat)
4951 rtx pat;
4952{
4953 switch (GET_CODE (pat))
4954 {
4955 case MEM:
4956 case REG:
e9a25f70 4957 return 1;
32b5b1aa
SC
4958
4959 default:
e9a25f70 4960 return 0;
32b5b1aa
SC
4961
4962 }
4963}
32b5b1aa
SC
4964\f
4965int
4966sets_condition_code (pat)
4967 rtx pat;
4968{
4969 switch (GET_CODE (pat))
4970 {
4971 case PLUS:
4972 case MINUS:
4973 case AND:
4974 case IOR:
4975 case XOR:
4976 case NOT:
4977 case NEG:
4978 case MULT:
4979 case DIV:
4980 case MOD:
4981 case UDIV:
4982 case UMOD:
e9a25f70 4983 return 1;
32b5b1aa
SC
4984
4985 default:
4986 return (0);
32b5b1aa
SC
4987 }
4988}
32b5b1aa
SC
4989\f
4990int
4991str_immediate_operand (op, mode)
4992 register rtx op;
bb5177ac 4993 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4994{
4995 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
e9a25f70 4996 return 1;
32b5b1aa 4997
e9a25f70
JL
4998 return 0;
4999}
32b5b1aa
SC
5000\f
5001int
5002is_fp_insn (insn)
5003 rtx insn;
5004{
5005 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5006 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
5007 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
5008 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
e9a25f70 5009 return 1;
32b5b1aa 5010
e9a25f70 5011 return 0;
32b5b1aa
SC
5012}
5013
e9a25f70
JL
5014/* Return 1 if the mode of the SET_DEST of insn is floating point
5015 and it is not an fld or a move from memory to memory.
5016 Otherwise return 0 */
5017
32b5b1aa
SC
5018int
5019is_fp_dest (insn)
5020 rtx insn;
5021{
5022 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5023 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
5024 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
5025 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
5026 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
5027 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
48d4389d 5028 && GET_CODE (SET_SRC (PATTERN (insn))) != MEM)
e9a25f70 5029 return 1;
32b5b1aa 5030
e9a25f70 5031 return 0;
32b5b1aa
SC
5032}
5033
e9a25f70
JL
5034/* Return 1 if the mode of the SET_DEST of INSN is floating point and is
5035 memory and the source is a register. */
5036
32b5b1aa
SC
5037int
5038is_fp_store (insn)
5039 rtx insn;
5040{
5041 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5042 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
5043 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
5044 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
5045 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
5046 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
e9a25f70 5047 return 1;
32b5b1aa 5048
e9a25f70 5049 return 0;
32b5b1aa 5050}
32b5b1aa 5051\f
e9a25f70
JL
5052/* Return 1 if DEP_INSN sets a register which INSN uses as a base
5053 or index to reference memory.
5054 otherwise return 0 */
32b5b1aa
SC
5055
5056int
5057agi_dependent (insn, dep_insn)
5058 rtx insn, dep_insn;
5059{
b985a30f 5060 int push = 0, push_dep = 0;
32b5b1aa
SC
5061 if (GET_CODE (dep_insn) == INSN
5062 && GET_CODE (PATTERN (dep_insn)) == SET
b985a30f
JH
5063 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG
5064 && reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn))
5065 return 1;
5066
5067 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5068 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
5069 && push_operand (SET_DEST (PATTERN (insn)),
5070 GET_MODE (SET_DEST (PATTERN (insn)))))
5071 push = 1;
32b5b1aa
SC
5072
5073 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
5074 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
5075 && push_operand (SET_DEST (PATTERN (dep_insn)),
5076 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
b985a30f
JH
5077 push_dep = 1;
5078
5079 /* CPUs contain special hardware to allow two pushes. */
5080 if (push && push_dep)
5081 return 0;
5082
5083 /* Push operation implicitly change stack pointer causing AGI stalls. */
5084 if (push_dep && reg_mentioned_in_mem (stack_pointer_rtx, insn))
5085 return 1;
5086
5087 /* Push also implicitly read stack pointer. */
5088 if (push && modified_in_p (stack_pointer_rtx, dep_insn))
5089 return 1;
32b5b1aa 5090
e9a25f70
JL
5091 return 0;
5092}
32b5b1aa 5093\f
e9a25f70
JL
5094/* Return 1 if reg is used in rtl as a base or index for a memory ref
5095 otherwise return 0. */
32b5b1aa
SC
5096
5097int
5098reg_mentioned_in_mem (reg, rtl)
5099 rtx reg, rtl;
5100{
5101 register char *fmt;
e9a25f70 5102 register int i, j;
32b5b1aa
SC
5103 register enum rtx_code code;
5104
5105 if (rtl == NULL)
e9a25f70 5106 return 0;
32b5b1aa
SC
5107
5108 code = GET_CODE (rtl);
5109
5110 switch (code)
5111 {
5112 case HIGH:
5113 case CONST_INT:
5114 case CONST:
5115 case CONST_DOUBLE:
5116 case SYMBOL_REF:
5117 case LABEL_REF:
5118 case PC:
5119 case CC0:
5120 case SUBREG:
e9a25f70 5121 return 0;
00c79232 5122 default:
53949fac 5123 break;
32b5b1aa
SC
5124 }
5125
5126 if (code == MEM && reg_mentioned_p (reg, rtl))
e9a25f70 5127 return 1;
32b5b1aa
SC
5128
5129 fmt = GET_RTX_FORMAT (code);
5130 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
5131 {
5132 if (fmt[i] == 'E')
c7271385
JL
5133 {
5134 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
5135 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
5136 return 1;
5137 }
32b5b1aa
SC
5138
5139 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
5140 return 1;
5141 }
5142
e9a25f70 5143 return 0;
32b5b1aa 5144}
3f803cd9 5145\f
956d6950 5146/* Output the appropriate insns for doing strlen if not just doing repnz; scasb
3f803cd9
SC
5147
5148 operands[0] = result, initialized with the startaddress
5149 operands[1] = alignment of the address.
5150 operands[2] = scratch register, initialized with the startaddress when
5151 not aligned, otherwise undefined
5152
5153 This is just the body. It needs the initialisations mentioned above and
5154 some address computing at the end. These things are done in i386.md. */
5155
5156char *
5157output_strlen_unroll (operands)
5158 rtx operands[];
5159{
5160 rtx xops[18];
5161
5162 xops[0] = operands[0]; /* Result */
5163 /* operands[1]; * Alignment */
5164 xops[1] = operands[2]; /* Scratch */
5165 xops[2] = GEN_INT (0);
5166 xops[3] = GEN_INT (2);
5167 xops[4] = GEN_INT (3);
5168 xops[5] = GEN_INT (4);
5169 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
5170 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
5171 xops[8] = gen_label_rtx (); /* label of main loop */
e9a25f70
JL
5172
5173 if (TARGET_USE_Q_REG && QI_REG_P (xops[1]))
3f803cd9 5174 xops[9] = gen_label_rtx (); /* pentium optimisation */
e9a25f70 5175
3f803cd9
SC
5176 xops[10] = gen_label_rtx (); /* end label 2 */
5177 xops[11] = gen_label_rtx (); /* end label 1 */
5178 xops[12] = gen_label_rtx (); /* end label */
5179 /* xops[13] * Temporary used */
5180 xops[14] = GEN_INT (0xff);
5181 xops[15] = GEN_INT (0xff00);
5182 xops[16] = GEN_INT (0xff0000);
5183 xops[17] = GEN_INT (0xff000000);
5184
e9a25f70 5185 /* Loop to check 1..3 bytes for null to get an aligned pointer. */
3f803cd9 5186
e9a25f70 5187 /* Is there a known alignment and is it less than 4? */
3f803cd9
SC
5188 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
5189 {
e9a25f70 5190 /* Is there a known alignment and is it not 2? */
3f803cd9
SC
5191 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5192 {
e9a25f70
JL
5193 xops[6] = gen_label_rtx (); /* Label when aligned to 3-byte */
5194 xops[7] = gen_label_rtx (); /* Label when aligned to 2-byte */
3f803cd9 5195
e9a25f70
JL
5196 /* Leave just the 3 lower bits.
5197 If this is a q-register, then the high part is used later
5198 therefore use andl rather than andb. */
3f803cd9 5199 output_asm_insn (AS2 (and%L1,%4,%1), xops);
e9a25f70 5200
956d6950 5201 /* Is aligned to 4-byte address when zero */
3f803cd9 5202 output_asm_insn (AS1 (je,%l8), xops);
e9a25f70
JL
5203
5204 /* Side-effect even Parity when %eax == 3 */
3f803cd9
SC
5205 output_asm_insn (AS1 (jp,%6), xops);
5206
e9a25f70 5207 /* Is it aligned to 2 bytes ? */
3f803cd9
SC
5208 if (QI_REG_P (xops[1]))
5209 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5210 else
5211 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
e9a25f70 5212
3f803cd9
SC
5213 output_asm_insn (AS1 (je,%7), xops);
5214 }
5215 else
5216 {
e9a25f70
JL
5217 /* Since the alignment is 2, we have to check 2 or 0 bytes;
5218 check if is aligned to 4 - byte. */
3f803cd9 5219 output_asm_insn (AS2 (and%L1,%3,%1), xops);
e9a25f70 5220
956d6950 5221 /* Is aligned to 4-byte address when zero */
3f803cd9
SC
5222 output_asm_insn (AS1 (je,%l8), xops);
5223 }
5224
f64cecad 5225 xops[13] = gen_rtx_MEM (QImode, xops[0]);
e9a25f70
JL
5226
5227 /* Now compare the bytes; compare with the high part of a q-reg
5228 gives shorter code. */
3f803cd9
SC
5229 if (QI_REG_P (xops[1]))
5230 {
e9a25f70 5231 /* Compare the first n unaligned byte on a byte per byte basis. */
3f803cd9 5232 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
e9a25f70
JL
5233
5234 /* When zero we reached the end. */
3f803cd9 5235 output_asm_insn (AS1 (je,%l12), xops);
e9a25f70
JL
5236
5237 /* Increment the address. */
3f803cd9
SC
5238 output_asm_insn (AS1 (inc%L0,%0), xops);
5239
e9a25f70 5240 /* Not needed with an alignment of 2 */
3f803cd9
SC
5241 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5242 {
e9a25f70
JL
5243 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5244 CODE_LABEL_NUMBER (xops[7]));
3f803cd9
SC
5245 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5246 output_asm_insn (AS1 (je,%l12), xops);
5247 output_asm_insn (AS1 (inc%L0,%0), xops);
5248
e9a25f70
JL
5249 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5250 CODE_LABEL_NUMBER (xops[6]));
3f803cd9 5251 }
e9a25f70 5252
3f803cd9
SC
5253 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5254 }
5255 else
5256 {
5257 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5258 output_asm_insn (AS1 (je,%l12), xops);
5259 output_asm_insn (AS1 (inc%L0,%0), xops);
5260
e9a25f70
JL
5261 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5262 CODE_LABEL_NUMBER (xops[7]));
3f803cd9
SC
5263 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5264 output_asm_insn (AS1 (je,%l12), xops);
5265 output_asm_insn (AS1 (inc%L0,%0), xops);
5266
e9a25f70
JL
5267 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5268 CODE_LABEL_NUMBER (xops[6]));
3f803cd9
SC
5269 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5270 }
e9a25f70 5271
3f803cd9
SC
5272 output_asm_insn (AS1 (je,%l12), xops);
5273 output_asm_insn (AS1 (inc%L0,%0), xops);
5274 }
5275
e9a25f70
JL
5276 /* Generate loop to check 4 bytes at a time. It is not a good idea to
5277 align this loop. It gives only huge programs, but does not help to
5278 speed up. */
3f803cd9
SC
5279 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
5280
f64cecad 5281 xops[13] = gen_rtx_MEM (SImode, xops[0]);
3f803cd9
SC
5282 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
5283
5284 if (QI_REG_P (xops[1]))
5285 {
1853aadd
RK
5286 /* On i586 it is faster to combine the hi- and lo- part as
5287 a kind of lookahead. If anding both yields zero, then one
5288 of both *could* be zero, otherwise none of both is zero;
5289 this saves one instruction, on i486 this is slower
5290 tested with P-90, i486DX2-66, AMD486DX2-66 */
e9a25f70 5291 if (TARGET_PENTIUM)
3f803cd9
SC
5292 {
5293 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
5294 output_asm_insn (AS1 (jne,%l9), xops);
5295 }
5296
e9a25f70 5297 /* Check first byte. */
3f803cd9
SC
5298 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
5299 output_asm_insn (AS1 (je,%l12), xops);
5300
e9a25f70 5301 /* Check second byte. */
3f803cd9
SC
5302 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
5303 output_asm_insn (AS1 (je,%l11), xops);
5304
e9a25f70
JL
5305 if (TARGET_PENTIUM)
5306 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5307 CODE_LABEL_NUMBER (xops[9]));
3f803cd9 5308 }
e9a25f70 5309
3f803cd9
SC
5310 else
5311 {
e9a25f70 5312 /* Check first byte. */
3f803cd9
SC
5313 output_asm_insn (AS2 (test%L1,%14,%1), xops);
5314 output_asm_insn (AS1 (je,%l12), xops);
5315
e9a25f70 5316 /* Check second byte. */
3f803cd9
SC
5317 output_asm_insn (AS2 (test%L1,%15,%1), xops);
5318 output_asm_insn (AS1 (je,%l11), xops);
5319 }
5320
e9a25f70 5321 /* Check third byte. */
3f803cd9
SC
5322 output_asm_insn (AS2 (test%L1,%16,%1), xops);
5323 output_asm_insn (AS1 (je,%l10), xops);
79325812 5324
e9a25f70 5325 /* Check fourth byte and increment address. */
3f803cd9
SC
5326 output_asm_insn (AS2 (add%L0,%5,%0), xops);
5327 output_asm_insn (AS2 (test%L1,%17,%1), xops);
5328 output_asm_insn (AS1 (jne,%l8), xops);
5329
e9a25f70 5330 /* Now generate fixups when the compare stops within a 4-byte word. */
3f803cd9
SC
5331 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
5332
5333 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
5334 output_asm_insn (AS1 (inc%L0,%0), xops);
5335
5336 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
5337 output_asm_insn (AS1 (inc%L0,%0), xops);
5338
5339 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));
5340
e9a25f70 5341 return "";
3f803cd9 5342}
b657fc39
L
5343
5344char *
5345output_fp_conditional_move (which_alternative, operands)
5346 int which_alternative;
5347 rtx operands[];
5348{
80309a9c
L
5349 enum rtx_code code = GET_CODE (operands[1]);
5350
5351 /* This should never happen. */
5352 if (!(cc_prev_status.flags & CC_IN_80387)
5353 && (code == GT || code == LE || code == GE || code == LT))
5354 abort ();
5355
b657fc39
L
5356 switch (which_alternative)
5357 {
5358 case 0:
5359 /* r <- cond ? arg : r */
5360 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5361 break;
79325812 5362
b657fc39
L
5363 case 1:
5364 /* r <- cond ? r : arg */
5365 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5366 break;
5367
b657fc39
L
5368 default:
5369 abort ();
5370 }
5371
5372 return "";
5373}
5374
5375char *
5376output_int_conditional_move (which_alternative, operands)
5377 int which_alternative;
5378 rtx operands[];
5379{
9a6ac4b0 5380 enum rtx_code code = GET_CODE (operands[1]);
b657fc39
L
5381
5382 /* This is very tricky. We have to do it right. For a code segement
5383 like:
5384
5385 int foo, bar;
5386 ....
5387 foo = foo - x;
5388 if (foo >= 0)
5389 bar = y;
5390
5391 final_scan_insn () may delete the insn which sets CC. We have to
5392 tell final_scan_insn () if it should be reinserted. When CODE is
5393 GT or LE, we have to check the CC_NO_OVERFLOW bit and return
5394 NULL_PTR to tell final to reinsert the test insn because the
5395 conditional move cannot be handled properly without it. */
5396 if ((code == GT || code == LE)
5397 && (cc_prev_status.flags & CC_NO_OVERFLOW))
5398 return NULL_PTR;
5399
b657fc39
L
5400 switch (which_alternative)
5401 {
5402 case 0:
5403 /* r <- cond ? arg : r */
5404 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
b657fc39
L
5405 break;
5406
5407 case 1:
5408 /* r <- cond ? r : arg */
5409 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
b657fc39
L
5410 break;
5411
b657fc39
L
5412 default:
5413 abort ();
5414 }
5415
5416 return "";
5417}
a269a03c
JC
5418
5419int
5420x86_adjust_cost (insn, link, dep_insn, cost)
5421 rtx insn, link, dep_insn;
5422 int cost;
5423{
5424 rtx next_inst;
5425
5426 if (GET_CODE (dep_insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
5427 return 0;
5428
5429 if (GET_CODE (dep_insn) == INSN
5430 && GET_CODE (PATTERN (dep_insn)) == SET
5431 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG
5432 && GET_CODE (insn) == INSN
5433 && GET_CODE (PATTERN (insn)) == SET
5434 && !reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)),
5435 SET_SRC (PATTERN (insn))))
5436 return 0; /* ??? */
5437
5438
5439 switch (ix86_cpu)
5440 {
5441 case PROCESSOR_PENTIUM:
5442 if (cost != 0 && is_fp_insn (insn) && is_fp_insn (dep_insn)
5443 && !is_fp_dest (dep_insn))
5444 return 0;
5445
5446 if (agi_dependent (insn, dep_insn))
42ebbb0a 5447 return cost ? cost + 1 : 2;
a269a03c
JC
5448
5449 if (GET_CODE (insn) == INSN
5450 && GET_CODE (PATTERN (insn)) == SET
5451 && SET_DEST (PATTERN (insn)) == cc0_rtx
5452 && (next_inst = next_nonnote_insn (insn))
5453 && GET_CODE (next_inst) == JUMP_INSN)
5454 /* compare probably paired with jump */
5455 return 0;
a269a03c 5456
42ebbb0a
JH
5457 /* Stores stalls one cycle longer than other insns. */
5458 if (is_fp_insn (insn) && cost && is_fp_store (dep_insn))
6ec6d558 5459 cost++;
a14003ee 5460 break;
a269a03c
JC
5461 case PROCESSOR_K6:
5462 default:
5463 if (!is_fp_dest (dep_insn))
5464 {
5465 if(!agi_dependent (insn, dep_insn))
5466 return 0;
5467 if (TARGET_486)
5468 return 2;
5469 }
5470 else
5471 if (is_fp_store (insn) && is_fp_insn (dep_insn)
5472 && NEXT_INSN (insn) && NEXT_INSN (NEXT_INSN (insn))
5473 && NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))
5474 && (GET_CODE (NEXT_INSN (insn)) == INSN)
5475 && (GET_CODE (NEXT_INSN (NEXT_INSN (insn))) == JUMP_INSN)
5476 && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) == NOTE)
5477 && (NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn))))
5478 == NOTE_INSN_LOOP_END))
5479 return 3;
5480 break;
5481 }
5482
5483 return cost;
5484}
0a726ef1
JL
5485
5486/* Output assembly code for a left shift.
5487
5488 Always use "sal" when shifting a memory operand or for a non constant
5489 shift count.
5490
5491 When optimizing for size, we know that src == dest, and we should always
5492 use "sal". If src != dest, then copy src to dest and use "sal".
5493
5494 Pentium and PPro (speed):
5495
5496 When src == dest, use "add" for a shift counts of one, else use
5497 "sal". If we modeled Pentium AGI stalls and U/V pipelining better we
5498 would want to generate lea for some shifts on the Pentium.
5499
5500 When src != dest, use "lea" for small shift counts. Otherwise,
5501 copy src to dest and use the normal shifting code. Exception for
5502 TARGET_DOUBLE_WITH_ADD. */
5503
5504char *
6ec6d558
JH
5505output_ashl (insn, operands)
5506 rtx insn, *operands;
0a726ef1
JL
5507{
5508 /* Handle case where srcreg != dstreg. */
5509 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
5510 {
5511 if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1)
6ec6d558
JH
5512 switch (GET_MODE (operands[0]))
5513 {
5514 case SImode:
5515 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
5516 return AS2 (add%L0,%1,%0);
5517 case HImode:
5518 output_asm_insn (AS2 (mov%L0,%k1,%k0), operands);
5519 if (i386_cc_probably_useless_p (insn))
5520 {
5521 CC_STATUS_INIT;
5522 return AS2 (add%L0,%k1,%k0);
5523 }
5524 return AS2 (add%W0,%k1,%k0);
5525 case QImode:
5526 output_asm_insn (AS2 (mov%B0,%1,%0), operands);
5527 return AS2 (add%B0,%1,%0);
5528 default:
5529 abort ();
5530 }
0a726ef1 5531 else
6ec6d558
JH
5532 {
5533 CC_STATUS_INIT;
0a726ef1
JL
5534
5535 /* This should be extremely rare (impossible?). We can not encode a
5536 shift of the stack pointer using an lea instruction. So copy the
5537 stack pointer into the destination register and use an lea. */
5538 if (operands[1] == stack_pointer_rtx)
5539 {
6ec6d558 5540 output_asm_insn (AS2 (mov%L0,%k1,%k0), operands);
0a726ef1
JL
5541 operands[1] = operands[0];
5542 }
5543
5544 /* For shifts up to and including 3 bits, use lea. */
6ec6d558
JH
5545 operands[1] = gen_rtx_MULT (SImode,
5546 gen_rtx_REG (SImode, REGNO (operands[1])),
0a726ef1 5547 GEN_INT (1 << INTVAL (operands[2])));
6ec6d558 5548 return AS2 (lea%L0,%a1,%k0);
0a726ef1
JL
5549 }
5550 }
5551
5552 /* Source and destination match. */
5553
5554 /* Handle variable shift. */
5555 if (REG_P (operands[2]))
6ec6d558
JH
5556 switch (GET_MODE (operands[0]))
5557 {
5558 case SImode:
5559 return AS2 (sal%L0,%b2,%0);
5560 case HImode:
5561 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
5562 {
5563 CC_STATUS_INIT;
5564 return AS2 (sal%L0,%b2,%k0);
5565 }
5566 else
5567 return AS2 (sal%W0,%b2,%0);
5568 case QImode:
5569 return AS2 (sal%B0,%b2,%0);
5570 default:
5571 abort ();
5572 }
0a726ef1
JL
5573
5574 /* Always perform shift by 1 using an add instruction. */
5575 if (REG_P (operands[0]) && operands[2] == const1_rtx)
6ec6d558
JH
5576 switch (GET_MODE (operands[0]))
5577 {
5578 case SImode:
5579 return AS2 (add%L0,%0,%0);
5580 case HImode:
5581 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
5582 {
5583 CC_STATUS_INIT;
5584 return AS2 (add%L0,%k0,%k0);
5585 }
5586 else
5587 return AS2 (add%W0,%0,%0);
5588 case QImode:
5589 return AS2 (add%B0,%0,%0);
5590 default:
5591 abort ();
5592 }
0a726ef1
JL
5593
5594#if 0
6ec6d558
JH
5595 /* ??? Currently disabled. Because our model of Pentium is far from being
5596 exact, this change will need some benchmarking. */
0a726ef1
JL
5597 /* Shift reg by 2 or 3 use an lea instruction for Pentium if this is
5598 insn is expected to issue into the V pipe (the insn's mode will be
5599 TImode for a U pipe, and !TImode for a V pipe instruction). */
5600 if (! optimize_size
5601 && REG_P (operands[0])
5602 && GET_CODE (operands[2]) == CONST_INT
5603 && INTVAL (operands[2]) <= 3
5604 && (int)ix86_cpu == (int)PROCESSOR_PENTIUM
5605 && GET_MODE (insn) != TImode)
5606 {
5607 CC_STATUS_INIT;
6ec6d558 5608 operands[1] = gen_rtx_MULT (SImode, gen_rtx_REG (SImode, REGNO (operands[1])),
0a726ef1
JL
5609 GEN_INT (1 << INTVAL (operands[2])));
5610 return AS2 (lea%L0,%a1,%0);
5611 }
5612#endif
5613
5614 /* Otherwise use a shift instruction. */
6ec6d558
JH
5615 switch (GET_MODE (operands[0]))
5616 {
5617 case SImode:
5618 return AS2 (sal%L0,%2,%0);
5619 case HImode:
5620 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
5621 {
5622 CC_STATUS_INIT;
5623 return AS2 (sal%L0,%2,%k0);
5624 }
5625 else
5626 return AS2 (sal%W0,%2,%0);
5627 case QImode:
5628 return AS2 (sal%B0,%2,%0);
5629 default:
5630 abort ();
5631 }
0a726ef1 5632}
fb693d44 5633
b222082e
JH
5634/* Given the memory address ADDR, calculate the length of the address or
5635 the length of just the displacement (controlled by DISP_LENGTH).
5636
5637 The length returned does not include the one-byte modrm, opcode,
5638 or prefix. */
fb693d44
RH
5639
5640int
b222082e 5641memory_address_info (addr, disp_length)
fb693d44 5642 rtx addr;
b222082e 5643 int disp_length;
fb693d44
RH
5644{
5645 rtx base, index, disp, scale;
5646 rtx op0, op1;
5647 int len;
5648
5649 if (GET_CODE (addr) == PRE_DEC
5650 || GET_CODE (addr) == POST_INC)
5651 return 0;
5652
5653 /* Register Indirect. */
5654 if (register_operand (addr, Pmode))
5655 {
5656 /* Special cases: ebp and esp need the two-byte modrm form.
5657
5658 We change [ESI] to [ESI+0] on the K6 when not optimizing
5659 for size. */
5660 if (addr == stack_pointer_rtx
5661 || addr == arg_pointer_rtx
5662 || addr == frame_pointer_rtx
5663 || (REGNO_REG_CLASS (REGNO (addr)) == SIREG
d2328603 5664 && ix86_cpu == PROCESSOR_K6 && !optimize_size))
fb693d44
RH
5665 return 1;
5666 else
5667 return 0;
5668 }
5669
5670 /* Direct Addressing. */
5671 if (CONSTANT_P (addr))
5672 return 4;
5673
5674 index = base = disp = scale = NULL_RTX;
5675 op0 = XEXP (addr, 0);
5676 op1 = XEXP (addr, 1);
5677
5678 if (GET_CODE (addr) == PLUS)
5679 {
5680 if (register_operand (op0, Pmode))
5681 {
5682 if (register_operand (op1, Pmode))
5683 index = op0, base = op1;
5684 else
5685 base = op0, disp = op1;
5686 }
5687 else if (GET_CODE (op0) == MULT)
5688 {
5689 index = XEXP (op0, 0);
5690 scale = XEXP (op0, 1);
5691 if (register_operand (op1, Pmode))
5692 base = op1;
5693 else
5694 disp = op1;
5695 }
5696 else if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
5697 {
5698 index = XEXP (XEXP (op0, 0), 0);
5699 scale = XEXP (XEXP (op0, 0), 1);
5700 base = XEXP (op0, 1);
5701 disp = op1;
5702 }
5703 else if (GET_CODE (op0) == PLUS)
5704 {
5705 index = XEXP (op0, 0);
5706 base = XEXP (op0, 1);
5707 disp = op1;
5708 }
5709 else
5710 abort ();
5711 }
5712 else if (GET_CODE (addr) == MULT
5713 /* We're called for lea too, which implements ashift on occasion. */
5714 || GET_CODE (addr) == ASHIFT)
5715 {
5716 index = XEXP (addr, 0);
5717 scale = XEXP (addr, 1);
5718 }
5719 else
5720 abort ();
5721
5722 /* Allow arg pointer and stack pointer as index if there is not scaling */
5723 if (base && index && !scale
5724 && (index == stack_pointer_rtx
5725 || index == arg_pointer_rtx
5726 || index == frame_pointer_rtx))
5727 {
5728 rtx tmp = base;
5729 base = index;
5730 index = tmp;
5731 }
5732
5733 /* Special case: ebp cannot be encoded as a base without a displacement. */
5734 if (base == frame_pointer_rtx && !disp)
5735 disp = const0_rtx;
5736
b222082e
JH
5737 /* Scaling can not be encoded without base or displacement.
5738 Except for scale == 1 where we can encode reg + reg instead of reg * 2. */
5739 if (!base && index && scale != 1)
5740 disp = const0_rtx;
5741
fb693d44
RH
5742 /* Find the length of the displacement constant. */
5743 len = 0;
5744 if (disp)
5745 {
5746 if (GET_CODE (disp) == CONST_INT
5747 && CONST_OK_FOR_LETTER_P (INTVAL (disp), 'K'))
5748 len = 1;
5749 else
5750 len = 4;
5751 }
5752
b222082e
JH
5753 /* An index requires the two-byte modrm form. Not important
5754 if we are computing just length of the displacement. */
5755 if (index && ! disp_length)
fb693d44
RH
5756 len += 1;
5757
5758 return len;
5759}
This page took 1.438638 seconds and 5 git commands to generate.