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