]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.c
machmode.h (mode_name): Constify a char*.
[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;
870a0c2c
L
2998 int ieee = (TARGET_IEEE_FP && (flags & CC_IN_80387)
2999 && !(cc_prev_status.flags & CC_FCOMI));
a269a03c
JC
3000 const char *suffix;
3001
3002 if (flags & CC_Z_IN_NOT_C)
3003 switch (code)
3004 {
3005 case EQ:
3006 fputs (reverse ? "c" : "nc", file);
3007 return;
3008
3009 case NE:
3010 fputs (reverse ? "nc" : "c", file);
3011 return;
3012
3013 default:
3014 abort ();
3015 }
3016 if (ieee)
3017 {
3018 switch (code)
3019 {
3020 case LE:
3021 suffix = reverse ? "ae" : "b";
3022 break;
3023 case GT:
3024 case LT:
3025 case GE:
3026 suffix = reverse ? "ne" : "e";
3027 break;
3028 case EQ:
3029 suffix = reverse ? "ne" : "e";
3030 break;
3031 case NE:
3032 suffix = reverse ? "e" : "ne";
3033 break;
3034 default:
3035 abort ();
3036 }
3037 fputs (suffix, file);
3038 return;
3039 }
3040 if (flags & CC_TEST_AX)
3041 abort();
3042 if ((flags & CC_NO_OVERFLOW) && (code == LE || code == GT))
3043 abort ();
3044 if (reverse)
3045 code = reverse_condition (code);
3046 switch (code)
3047 {
3048 case EQ:
3049 suffix = "e";
3050 break;
3051
3052 case NE:
3053 suffix = "ne";
3054 break;
3055
3056 case GT:
3057 suffix = flags & CC_IN_80387 ? "a" : "g";
3058 break;
3059
3060 case GTU:
3061 suffix = "a";
3062 break;
3063
3064 case LT:
3065 if (flags & CC_NO_OVERFLOW)
3066 suffix = "s";
3067 else
3068 suffix = flags & CC_IN_80387 ? "b" : "l";
3069 break;
3070
3071 case LTU:
3072 suffix = "b";
3073 break;
3074
3075 case GE:
3076 if (flags & CC_NO_OVERFLOW)
3077 suffix = "ns";
3078 else
3079 suffix = flags & CC_IN_80387 ? "ae" : "ge";
3080 break;
3081
3082 case GEU:
3083 suffix = "ae";
3084 break;
3085
3086 case LE:
3087 suffix = flags & CC_IN_80387 ? "be" : "le";
3088 break;
3089
3090 case LEU:
3091 suffix = "be";
3092 break;
3093
3094 default:
3095 abort ();
3096 }
3097 fputs (suffix, file);
3098}
3099
e9a25f70 3100/* Append the correct conditional move suffix which corresponds to CODE. */
e5cb57e8
SC
3101
3102static void
c27d9c3b 3103put_condition_code (code, reverse_cc, mode, file)
fe25fea3 3104 enum rtx_code code;
c27d9c3b 3105 int reverse_cc;
fe25fea3
SC
3106 enum mode_class mode;
3107 FILE * file;
e5cb57e8 3108{
e9a25f70
JL
3109 int ieee = (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
3110 && ! (cc_prev_status.flags & CC_FCOMI));
c27d9c3b
SC
3111 if (reverse_cc && ! ieee)
3112 code = reverse_condition (code);
3113
fe25fea3 3114 if (mode == MODE_INT)
e9a25f70
JL
3115 switch (code)
3116 {
79325812 3117 case NE:
e9a25f70
JL
3118 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
3119 fputs ("b", file);
3120 else
3121 fputs ("ne", file);
3122 return;
3123
3124 case EQ:
3125 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
3126 fputs ("ae", file);
3127 else
3128 fputs ("e", file);
3129 return;
3130
3131 case GE:
b657fc39
L
3132 if (cc_prev_status.flags & CC_NO_OVERFLOW)
3133 fputs ("ns", file);
3134 else
3135 fputs ("ge", file);
e9a25f70
JL
3136 return;
3137
3138 case GT:
3139 fputs ("g", file);
3140 return;
3141
3142 case LE:
3143 fputs ("le", file);
3144 return;
3145
3146 case LT:
b657fc39
L
3147 if (cc_prev_status.flags & CC_NO_OVERFLOW)
3148 fputs ("s", file);
3149 else
3150 fputs ("l", file);
e9a25f70
JL
3151 return;
3152
3153 case GEU:
3154 fputs ("ae", file);
3155 return;
3156
3157 case GTU:
3158 fputs ("a", file);
3159 return;
3160
3161 case LEU:
3162 fputs ("be", file);
3163 return;
3164
3165 case LTU:
3166 fputs ("b", file);
3167 return;
3168
3169 default:
3170 output_operand_lossage ("Invalid %%C operand");
3171 }
3172
fe25fea3 3173 else if (mode == MODE_FLOAT)
e9a25f70
JL
3174 switch (code)
3175 {
79325812 3176 case NE:
e9a25f70
JL
3177 fputs (ieee ? (reverse_cc ? "ne" : "e") : "ne", file);
3178 return;
79325812 3179 case EQ:
e9a25f70
JL
3180 fputs (ieee ? (reverse_cc ? "ne" : "e") : "e", file);
3181 return;
79325812 3182 case GE:
e9a25f70
JL
3183 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3184 return;
79325812 3185 case GT:
e9a25f70
JL
3186 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3187 return;
79325812 3188 case LE:
e9a25f70
JL
3189 fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3190 return;
79325812 3191 case LT:
e9a25f70
JL
3192 fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3193 return;
79325812 3194 case GEU:
e9a25f70
JL
3195 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3196 return;
79325812 3197 case GTU:
e9a25f70
JL
3198 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3199 return;
79325812 3200 case LEU:
e9a25f70
JL
3201 fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3202 return;
79325812 3203 case LTU:
e9a25f70
JL
3204 fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3205 return;
3206 default:
3207 output_operand_lossage ("Invalid %%C operand");
fe25fea3 3208 }
e5cb57e8
SC
3209}
3210
2a2ab3f9 3211/* Meaning of CODE:
fe25fea3 3212 L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
e5cb57e8 3213 C -- print opcode suffix for set/cmov insn.
fe25fea3
SC
3214 c -- like C, but print reversed condition
3215 F -- print opcode suffix for fcmov insn.
a269a03c
JC
3216 f -- like F, but print reversed condition
3217 D -- print the opcode suffix for a jump
3218 d -- like D, but print reversed condition
2a2ab3f9
JVA
3219 R -- print the prefix for register names.
3220 z -- print the opcode suffix for the size of the current operand.
3221 * -- print a star (in certain assembler syntax)
3222 w -- print the operand as if it's a "word" (HImode) even if it isn't.
b08de47e 3223 J -- print the appropriate jump operand.
2d49677f
SC
3224 s -- print a shift double count, followed by the assemblers argument
3225 delimiter.
fe25fea3
SC
3226 b -- print the QImode name of the register for the indicated operand.
3227 %b0 would print %al if operands[0] is reg 0.
3228 w -- likewise, print the HImode name of the register.
3229 k -- likewise, print the SImode name of the register.
3230 h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
3231 y -- print "st(0)" instead of "st" as a register.
d119f84c
RH
3232 P -- print as a PIC constant
3233 _ -- output "_" if YES_UNDERSCORES */
2a2ab3f9
JVA
3234
3235void
3236print_operand (file, x, code)
3237 FILE *file;
3238 rtx x;
3239 int code;
3240{
3241 if (code)
3242 {
3243 switch (code)
3244 {
3245 case '*':
3246 if (USE_STAR)
3247 putc ('*', file);
3248 return;
3249
d119f84c
RH
3250 case '_':
3251#ifdef YES_UNDERSCORES
3252 putc ('_', file);
3253#endif
3254 return;
3255
2a2ab3f9
JVA
3256 case 'L':
3257 PUT_OP_SIZE (code, 'l', file);
3258 return;
3259
3260 case 'W':
3261 PUT_OP_SIZE (code, 'w', file);
3262 return;
3263
3264 case 'B':
3265 PUT_OP_SIZE (code, 'b', file);
3266 return;
3267
3268 case 'Q':
3269 PUT_OP_SIZE (code, 'l', file);
3270 return;
3271
3272 case 'S':
3273 PUT_OP_SIZE (code, 's', file);
3274 return;
3275
5f1ec3e6
JVA
3276 case 'T':
3277 PUT_OP_SIZE (code, 't', file);
3278 return;
3279
2a2ab3f9
JVA
3280 case 'z':
3281 /* 387 opcodes don't get size suffixes if the operands are
3282 registers. */
3283
3284 if (STACK_REG_P (x))
3285 return;
3286
3287 /* this is the size of op from size of operand */
3288 switch (GET_MODE_SIZE (GET_MODE (x)))
3289 {
2a2ab3f9 3290 case 2:
53b5ce19
JW
3291#ifdef HAVE_GAS_FILDS_FISTS
3292 PUT_OP_SIZE ('W', 's', file);
3293#endif
2a2ab3f9
JVA
3294 return;
3295
3296 case 4:
3297 if (GET_MODE (x) == SFmode)
3298 {
3299 PUT_OP_SIZE ('S', 's', file);
3300 return;
3301 }
3302 else
3303 PUT_OP_SIZE ('L', 'l', file);
3304 return;
3305
5f1ec3e6
JVA
3306 case 12:
3307 PUT_OP_SIZE ('T', 't', file);
3308 return;
3309
2a2ab3f9
JVA
3310 case 8:
3311 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
56c0e8fa
JVA
3312 {
3313#ifdef GAS_MNEMONICS
3314 PUT_OP_SIZE ('Q', 'q', file);
3315 return;
3316#else
3317 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
3318#endif
3319 }
2a2ab3f9
JVA
3320
3321 PUT_OP_SIZE ('Q', 'l', file);
3322 return;
53b5ce19
JW
3323
3324 default:
3325 abort ();
2a2ab3f9 3326 }
4af3895e
JVA
3327
3328 case 'b':
3329 case 'w':
3330 case 'k':
3331 case 'h':
3332 case 'y':
3333 case 'P':
5cb6195d 3334 case 'X':
4af3895e
JVA
3335 break;
3336
b08de47e
MM
3337 case 'J':
3338 switch (GET_CODE (x))
3339 {
c645b1c9
MM
3340 /* These conditions are appropriate for testing the result
3341 of an arithmetic operation, not for a compare operation.
3342 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
3343 CC_Z_IN_NOT_C false and not floating point. */
b08de47e
MM
3344 case NE: fputs ("jne", file); return;
3345 case EQ: fputs ("je", file); return;
c645b1c9 3346 case GE: fputs ("jns", file); return;
c645b1c9 3347 case LT: fputs ("js", file); return;
d784886d
RK
3348 case GEU: fputs ("jmp", file); return;
3349 case GTU: fputs ("jne", file); return;
3350 case LEU: fputs ("je", file); return;
3351 case LTU: fputs ("#branch never", file); return;
79325812 3352
d784886d 3353 /* no matching branches for GT nor LE */
79325812 3354
00c79232
ML
3355 default:
3356 abort ();
b08de47e 3357 }
b08de47e 3358
2d49677f
SC
3359 case 's':
3360 if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
3361 {
3362 PRINT_OPERAND (file, x, 0);
3363 fputs (AS2C (,) + 1, file);
3364 }
e9a25f70 3365
2d49677f
SC
3366 return;
3367
a269a03c
JC
3368 case 'D':
3369 put_jump_code (GET_CODE (x), 0, file);
3370 return;
3371
3372 case 'd':
3373 put_jump_code (GET_CODE (x), 1, file);
3374 return;
3375
1853aadd
RK
3376 /* This is used by the conditional move instructions. */
3377 case 'C':
c27d9c3b 3378 put_condition_code (GET_CODE (x), 0, MODE_INT, file);
1853aadd 3379 return;
fe25fea3 3380
e9a25f70 3381 /* Like above, but reverse condition */
fe25fea3 3382 case 'c':
c27d9c3b 3383 put_condition_code (GET_CODE (x), 1, MODE_INT, file); return;
fe25fea3
SC
3384
3385 case 'F':
c27d9c3b 3386 put_condition_code (GET_CODE (x), 0, MODE_FLOAT, file);
fe25fea3
SC
3387 return;
3388
e9a25f70 3389 /* Like above, but reverse condition */
fe25fea3 3390 case 'f':
c27d9c3b 3391 put_condition_code (GET_CODE (x), 1, MODE_FLOAT, file);
1853aadd 3392 return;
e5cb57e8 3393
4af3895e 3394 default:
68daafd4
JVA
3395 {
3396 char str[50];
3397
3398 sprintf (str, "invalid operand code `%c'", code);
3399 output_operand_lossage (str);
3400 }
2a2ab3f9
JVA
3401 }
3402 }
e9a25f70 3403
2a2ab3f9
JVA
3404 if (GET_CODE (x) == REG)
3405 {
3406 PRINT_REG (x, code, file);
3407 }
e9a25f70 3408
2a2ab3f9
JVA
3409 else if (GET_CODE (x) == MEM)
3410 {
3411 PRINT_PTR (x, file);
3412 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
3413 {
3414 if (flag_pic)
3415 output_pic_addr_const (file, XEXP (x, 0), code);
3416 else
3417 output_addr_const (file, XEXP (x, 0));
3418 }
3419 else
3420 output_address (XEXP (x, 0));
3421 }
e9a25f70 3422
2a2ab3f9
JVA
3423 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
3424 {
e9a25f70
JL
3425 REAL_VALUE_TYPE r;
3426 long l;
3427
5f1ec3e6
JVA
3428 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3429 REAL_VALUE_TO_TARGET_SINGLE (r, l);
4af3895e 3430 PRINT_IMMED_PREFIX (file);
52267fcb 3431 fprintf (file, "0x%lx", l);
5f1ec3e6 3432 }
e9a25f70 3433
5f1ec3e6
JVA
3434 /* These float cases don't actually occur as immediate operands. */
3435 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
3436 {
e9a25f70
JL
3437 REAL_VALUE_TYPE r;
3438 char dstr[30];
3439
5f1ec3e6
JVA
3440 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3441 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3442 fprintf (file, "%s", dstr);
2a2ab3f9 3443 }
e9a25f70 3444
5f1ec3e6 3445 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2a2ab3f9 3446 {
e9a25f70
JL
3447 REAL_VALUE_TYPE r;
3448 char dstr[30];
3449
5f1ec3e6
JVA
3450 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3451 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3452 fprintf (file, "%s", dstr);
2a2ab3f9 3453 }
79325812 3454 else
2a2ab3f9 3455 {
4af3895e 3456 if (code != 'P')
2a2ab3f9 3457 {
695dac07 3458 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2a2ab3f9
JVA
3459 PRINT_IMMED_PREFIX (file);
3460 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
3461 || GET_CODE (x) == LABEL_REF)
3462 PRINT_OFFSET_PREFIX (file);
3463 }
3464 if (flag_pic)
3465 output_pic_addr_const (file, x, code);
3466 else
3467 output_addr_const (file, x);
3468 }
3469}
3470\f
3471/* Print a memory operand whose address is ADDR. */
3472
3473void
3474print_operand_address (file, addr)
3475 FILE *file;
3476 register rtx addr;
3477{
3478 register rtx reg1, reg2, breg, ireg;
3479 rtx offset;
3480
3481 switch (GET_CODE (addr))
3482 {
3483 case REG:
69a8af43
JH
3484 /* ESI addressing makes instruction vector decoded on the K6. We can
3485 avoid this by ESI+0 addressing. */
3486 if (REGNO_REG_CLASS (REGNO (addr)) == SIREG
3487 && ix86_cpu == PROCESSOR_K6 && !optimize_size)
3488 output_addr_const (file, const0_rtx);
2a2ab3f9
JVA
3489 ADDR_BEG (file);
3490 fprintf (file, "%se", RP);
3491 fputs (hi_reg_name[REGNO (addr)], file);
3492 ADDR_END (file);
3493 break;
3494
3495 case PLUS:
3496 reg1 = 0;
3497 reg2 = 0;
3498 ireg = 0;
3499 breg = 0;
3500 offset = 0;
3501 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3502 {
3503 offset = XEXP (addr, 0);
3504 addr = XEXP (addr, 1);
3505 }
3506 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3507 {
3508 offset = XEXP (addr, 1);
3509 addr = XEXP (addr, 0);
3510 }
e9a25f70
JL
3511
3512 if (GET_CODE (addr) != PLUS)
3513 ;
2a2ab3f9 3514 else if (GET_CODE (XEXP (addr, 0)) == MULT)
e9a25f70 3515 reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
2a2ab3f9 3516 else if (GET_CODE (XEXP (addr, 1)) == MULT)
e9a25f70 3517 reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
2a2ab3f9 3518 else if (GET_CODE (XEXP (addr, 0)) == REG)
e9a25f70 3519 reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
2a2ab3f9 3520 else if (GET_CODE (XEXP (addr, 1)) == REG)
e9a25f70
JL
3521 reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3522
2a2ab3f9
JVA
3523 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
3524 {
e9a25f70
JL
3525 if (reg1 == 0)
3526 reg1 = addr;
3527 else
3528 reg2 = addr;
3529
2a2ab3f9
JVA
3530 addr = 0;
3531 }
e9a25f70 3532
2a2ab3f9
JVA
3533 if (offset != 0)
3534 {
e9a25f70
JL
3535 if (addr != 0)
3536 abort ();
2a2ab3f9
JVA
3537 addr = offset;
3538 }
e9a25f70 3539
2a2ab3f9
JVA
3540 if ((reg1 && GET_CODE (reg1) == MULT)
3541 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3542 {
3543 breg = reg2;
3544 ireg = reg1;
3545 }
3546 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3547 {
3548 breg = reg1;
3549 ireg = reg2;
3550 }
3551
3552 if (ireg != 0 || breg != 0)
3553 {
3554 int scale = 1;
3555
3556 if (addr != 0)
3557 {
c399861d
MM
3558 if (flag_pic)
3559 output_pic_addr_const (file, addr, 0);
c399861d 3560 else if (GET_CODE (addr) == LABEL_REF)
2a2ab3f9
JVA
3561 output_asm_label (addr);
3562 else
c399861d 3563 output_addr_const (file, addr);
2a2ab3f9
JVA
3564 }
3565
3566 if (ireg != 0 && GET_CODE (ireg) == MULT)
3567 {
3568 scale = INTVAL (XEXP (ireg, 1));
3569 ireg = XEXP (ireg, 0);
3570 }
3571
3572 /* The stack pointer can only appear as a base register,
3573 never an index register, so exchange the regs if it is wrong. */
3574
3575 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
3576 {
3577 rtx tmp;
3578
3579 tmp = breg;
3580 breg = ireg;
3581 ireg = tmp;
3582 }
3583
3584 /* output breg+ireg*scale */
3585 PRINT_B_I_S (breg, ireg, scale, file);
3586 break;
3587 }
3588
3589 case MULT:
3590 {
3591 int scale;
e9a25f70 3592
2a2ab3f9
JVA
3593 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
3594 {
3595 scale = INTVAL (XEXP (addr, 0));
3596 ireg = XEXP (addr, 1);
3597 }
3598 else
3599 {
3600 scale = INTVAL (XEXP (addr, 1));
3601 ireg = XEXP (addr, 0);
3602 }
e9a25f70 3603
69a8af43 3604 /* (reg,reg,) is shorter than (,reg,2). */
91e3ded8 3605 if (scale == 2)
69a8af43
JH
3606 {
3607 PRINT_B_I_S (ireg, ireg, 1, file);
3608 }
3609 else
3610 {
3611 output_addr_const (file, const0_rtx);
3612 PRINT_B_I_S (NULL_RTX, ireg, scale, file);
3613 }
2a2ab3f9
JVA
3614 }
3615 break;
3616
3617 default:
3618 if (GET_CODE (addr) == CONST_INT
3619 && INTVAL (addr) < 0x8000
3620 && INTVAL (addr) >= -0x8000)
f64cecad 3621 fprintf (file, "%d", (int) INTVAL (addr));
2a2ab3f9
JVA
3622 else
3623 {
3624 if (flag_pic)
3625 output_pic_addr_const (file, addr, 0);
3626 else
3627 output_addr_const (file, addr);
3628 }
3629 }
3630}
3631\f
3632/* Set the cc_status for the results of an insn whose pattern is EXP.
3633 On the 80386, we assume that only test and compare insns, as well
5cb6195d 3634 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, BSF, ASHIFT,
2a2ab3f9 3635 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
4c0d89b5
RS
3636 Also, we assume that jumps, moves and sCOND don't affect the condition
3637 codes. All else clobbers the condition codes, by assumption.
3638
3639 We assume that ALL integer add, minus, etc. instructions effect the
3640 condition codes. This MUST be consistent with i386.md.
2a2ab3f9 3641
4c0d89b5
RS
3642 We don't record any float test or compare - the redundant test &
3643 compare check in final.c does not handle stack-like regs correctly. */
2a2ab3f9
JVA
3644
3645void
3646notice_update_cc (exp)
3647 rtx exp;
3648{
3649 if (GET_CODE (exp) == SET)
3650 {
3651 /* Jumps do not alter the cc's. */
3652 if (SET_DEST (exp) == pc_rtx)
3653 return;
e9a25f70 3654
2a2ab3f9
JVA
3655 /* Moving register or memory into a register:
3656 it doesn't alter the cc's, but it might invalidate
3657 the RTX's which we remember the cc's came from.
3658 (Note that moving a constant 0 or 1 MAY set the cc's). */
3659 if (REG_P (SET_DEST (exp))
4c0d89b5 3660 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
9c8c5afb 3661 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'
a32126ad 3662 || GET_CODE (SET_SRC (exp)) == IF_THEN_ELSE))
2a2ab3f9
JVA
3663 {
3664 if (cc_status.value1
3665 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3666 cc_status.value1 = 0;
e9a25f70 3667
2a2ab3f9
JVA
3668 if (cc_status.value2
3669 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3670 cc_status.value2 = 0;
e9a25f70 3671
2a2ab3f9
JVA
3672 return;
3673 }
e9a25f70 3674
2a2ab3f9
JVA
3675 /* Moving register into memory doesn't alter the cc's.
3676 It may invalidate the RTX's which we remember the cc's came from. */
4c0d89b5
RS
3677 if (GET_CODE (SET_DEST (exp)) == MEM
3678 && (REG_P (SET_SRC (exp))
3679 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2a2ab3f9 3680 {
e9a25f70
JL
3681 if (cc_status.value1
3682 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2a2ab3f9 3683 cc_status.value1 = 0;
e9a25f70
JL
3684 if (cc_status.value2
3685 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2a2ab3f9 3686 cc_status.value2 = 0;
e9a25f70 3687
2a2ab3f9
JVA
3688 return;
3689 }
e9a25f70 3690
2a2ab3f9
JVA
3691 /* Function calls clobber the cc's. */
3692 else if (GET_CODE (SET_SRC (exp)) == CALL)
3693 {
3694 CC_STATUS_INIT;
3695 return;
3696 }
e9a25f70 3697
2a2ab3f9
JVA
3698 /* Tests and compares set the cc's in predictable ways. */
3699 else if (SET_DEST (exp) == cc0_rtx)
3700 {
3701 CC_STATUS_INIT;
3702 cc_status.value1 = SET_SRC (exp);
3703 return;
3704 }
e9a25f70 3705
2a2ab3f9
JVA
3706 /* Certain instructions effect the condition codes. */
3707 else if (GET_MODE (SET_SRC (exp)) == SImode
3708 || GET_MODE (SET_SRC (exp)) == HImode
3709 || GET_MODE (SET_SRC (exp)) == QImode)
3710 switch (GET_CODE (SET_SRC (exp)))
3711 {
e9a25f70 3712 case ASHIFTRT: case LSHIFTRT: case ASHIFT:
2a2ab3f9
JVA
3713 /* Shifts on the 386 don't set the condition codes if the
3714 shift count is zero. */
3715 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
3716 {
3717 CC_STATUS_INIT;
3718 break;
3719 }
e9a25f70 3720
2a2ab3f9
JVA
3721 /* We assume that the CONST_INT is non-zero (this rtx would
3722 have been deleted if it were zero. */
3723
3724 case PLUS: case MINUS: case NEG:
3725 case AND: case IOR: case XOR:
3726 cc_status.flags = CC_NO_OVERFLOW;
3727 cc_status.value1 = SET_SRC (exp);
3728 cc_status.value2 = SET_DEST (exp);
3729 break;
3730
ce193852
RH
3731 /* This is the bsf pattern used by ffs. */
3732 case UNSPEC:
3733 if (XINT (SET_SRC (exp), 1) == 5)
3734 {
3735 /* Only the Z flag is defined after bsf. */
3736 cc_status.flags
3737 = CC_NOT_POSITIVE | CC_NOT_NEGATIVE | CC_NO_OVERFLOW;
3738 cc_status.value1 = XVECEXP (SET_SRC (exp), 0, 0);
9d932d43 3739 cc_status.value2 = 0;
ce193852
RH
3740 break;
3741 }
3742 /* FALLTHRU */
3743
2a2ab3f9
JVA
3744 default:
3745 CC_STATUS_INIT;
3746 }
3747 else
3748 {
3749 CC_STATUS_INIT;
3750 }
3751 }
3752 else if (GET_CODE (exp) == PARALLEL
3753 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
3754 {
3755 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
3756 return;
3757 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
e9a25f70 3758
2a2ab3f9
JVA
3759 {
3760 CC_STATUS_INIT;
a8620236
SC
3761 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
3762 {
3763 cc_status.flags |= CC_IN_80387;
870a0c2c 3764 if (TARGET_CMOVE && stack_regs_mentioned_p
a8620236
SC
3765 (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1)))
3766 cc_status.flags |= CC_FCOMI;
3767 }
2247a58c 3768 else
4c0d89b5 3769 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2a2ab3f9
JVA
3770 return;
3771 }
e9a25f70 3772
2a2ab3f9
JVA
3773 CC_STATUS_INIT;
3774 }
3775 else
3776 {
3777 CC_STATUS_INIT;
3778 }
3779}
3780\f
3781/* Split one or more DImode RTL references into pairs of SImode
3782 references. The RTL can be REG, offsettable MEM, integer constant, or
3783 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3784 split and "num" is its length. lo_half and hi_half are output arrays
3785 that parallel "operands". */
3786
3787void
3788split_di (operands, num, lo_half, hi_half)
3789 rtx operands[];
3790 int num;
3791 rtx lo_half[], hi_half[];
3792{
3793 while (num--)
3794 {
57dbca5e 3795 rtx op = operands[num];
a269a03c
JC
3796 if (! reload_completed)
3797 {
3798 lo_half[num] = gen_lowpart (SImode, op);
3799 hi_half[num] = gen_highpart (SImode, op);
3800 }
3801 else if (GET_CODE (op) == REG)
2a2ab3f9 3802 {
57dbca5e
BS
3803 lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
3804 hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
2a2ab3f9 3805 }
57dbca5e
BS
3806 else if (CONSTANT_P (op))
3807 split_double (op, &lo_half[num], &hi_half[num]);
3808 else if (offsettable_memref_p (op))
2a2ab3f9 3809 {
57dbca5e
BS
3810 rtx lo_addr = XEXP (op, 0);
3811 rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
3812 lo_half[num] = change_address (op, SImode, lo_addr);
3813 hi_half[num] = change_address (op, SImode, hi_addr);
2a2ab3f9
JVA
3814 }
3815 else
3816 abort();
3817 }
3818}
3819\f
3820/* Return 1 if this is a valid binary operation on a 387.
3821 OP is the expression matched, and MODE is its mode. */
3822
3823int
3824binary_387_op (op, mode)
3825 register rtx op;
3826 enum machine_mode mode;
3827{
3828 if (mode != VOIDmode && mode != GET_MODE (op))
3829 return 0;
3830
3831 switch (GET_CODE (op))
3832 {
3833 case PLUS:
3834 case MINUS:
3835 case MULT:
3836 case DIV:
3837 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3838
3839 default:
3840 return 0;
3841 }
3842}
3b3c6a3f 3843\f
2a2ab3f9
JVA
3844/* Return 1 if this is a valid shift or rotate operation on a 386.
3845 OP is the expression matched, and MODE is its mode. */
3846
3847int
3848shift_op (op, mode)
3849 register rtx op;
3850 enum machine_mode mode;
3851{
3852 rtx operand = XEXP (op, 0);
3853
3854 if (mode != VOIDmode && mode != GET_MODE (op))
3855 return 0;
3856
3857 if (GET_MODE (operand) != GET_MODE (op)
3858 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3859 return 0;
3860
3861 return (GET_CODE (op) == ASHIFT
3862 || GET_CODE (op) == ASHIFTRT
3863 || GET_CODE (op) == LSHIFTRT
3864 || GET_CODE (op) == ROTATE
3865 || GET_CODE (op) == ROTATERT);
3866}
ac2afb64
JVA
3867
3868/* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3869 MODE is not used. */
3870
3871int
3872VOIDmode_compare_op (op, mode)
3873 register rtx op;
bb5177ac 3874 enum machine_mode mode ATTRIBUTE_UNUSED;
ac2afb64
JVA
3875{
3876 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3877}
2a2ab3f9
JVA
3878\f
3879/* Output code to perform a 387 binary operation in INSN, one of PLUS,
3880 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3881 is the expression of the binary operation. The output may either be
3882 emitted here, or returned to the caller, like all output_* functions.
3883
3884 There is no guarantee that the operands are the same mode, as they
3885 might be within FLOAT or FLOAT_EXTEND expressions. */
3886
3887char *
3888output_387_binary_op (insn, operands)
3889 rtx insn;
3890 rtx *operands;
3891{
3892 rtx temp;
3893 char *base_op;
3894 static char buf[100];
3895
3896 switch (GET_CODE (operands[3]))
3897 {
3898 case PLUS:
87aa5246 3899 base_op = "fadd";
2a2ab3f9
JVA
3900 break;
3901
3902 case MINUS:
87aa5246 3903 base_op = "fsub";
2a2ab3f9
JVA
3904 break;
3905
3906 case MULT:
87aa5246 3907 base_op = "fmul";
2a2ab3f9
JVA
3908 break;
3909
3910 case DIV:
87aa5246 3911 base_op = "fdiv";
2a2ab3f9
JVA
3912 break;
3913
3914 default:
3915 abort ();
3916 }
3917
3918 strcpy (buf, base_op);
3919
3920 switch (GET_CODE (operands[3]))
3921 {
3922 case MULT:
3923 case PLUS:
3924 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3925 {
3926 temp = operands[2];
3927 operands[2] = operands[1];
3928 operands[1] = temp;
3929 }
3930
3931 if (GET_CODE (operands[2]) == MEM)
3932 return strcat (buf, AS1 (%z2,%2));
3933
87aa5246
JW
3934 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3935 abort ();
2a2ab3f9
JVA
3936
3937 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
3938 {
3939 if (STACK_TOP_P (operands[0]))
3940 return strcat (buf, AS2 (p,%0,%2));
3941 else
3942 return strcat (buf, AS2 (p,%2,%0));
3943 }
2a2ab3f9
JVA
3944
3945 if (STACK_TOP_P (operands[0]))
3f6d0a8c 3946 return strcat (buf, AS2C (%y2,%0));
2a2ab3f9 3947 else
3f6d0a8c 3948 return strcat (buf, AS2C (%2,%0));
2a2ab3f9
JVA
3949
3950 case MINUS:
3951 case DIV:
3952 if (GET_CODE (operands[1]) == MEM)
3953 return strcat (buf, AS1 (r%z1,%1));
3954
3955 if (GET_CODE (operands[2]) == MEM)
3956 return strcat (buf, AS1 (%z2,%2));
3957
2a2ab3f9
JVA
3958 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3959 abort ();
3960
3961 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
3962 {
3963 if (STACK_TOP_P (operands[0]))
3964 return strcat (buf, AS2 (p,%0,%2));
3965 else
3966 return strcat (buf, AS2 (rp,%2,%0));
3967 }
2a2ab3f9
JVA
3968
3969 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
6b28fd63
JL
3970 {
3971 if (STACK_TOP_P (operands[0]))
3972 return strcat (buf, AS2 (rp,%0,%1));
3973 else
3974 return strcat (buf, AS2 (p,%1,%0));
3975 }
2a2ab3f9
JVA
3976
3977 if (STACK_TOP_P (operands[0]))
3978 {
3979 if (STACK_TOP_P (operands[1]))
3f6d0a8c 3980 return strcat (buf, AS2C (%y2,%0));
2a2ab3f9
JVA
3981 else
3982 return strcat (buf, AS2 (r,%y1,%0));
3983 }
3984 else if (STACK_TOP_P (operands[1]))
3f6d0a8c 3985 return strcat (buf, AS2C (%1,%0));
2a2ab3f9
JVA
3986 else
3987 return strcat (buf, AS2 (r,%2,%0));
3988
3989 default:
3990 abort ();
3991 }
3992}
3993\f
3994/* Output code for INSN to convert a float to a signed int. OPERANDS
10195bd8
JW
3995 are the insn operands. The input may be SFmode, DFmode, or XFmode
3996 and the output operand may be SImode or DImode. As a special case,
3997 make sure that the 387 stack top dies if the output mode is DImode,
3998 because the hardware requires this. */
2a2ab3f9
JVA
3999
4000char *
4001output_fix_trunc (insn, operands)
4002 rtx insn;
4003 rtx *operands;
4004{
4005 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
305f097e 4006 rtx xops[2];
2a2ab3f9 4007
2e14a41b 4008 if (! STACK_TOP_P (operands[1]))
2a2ab3f9
JVA
4009 abort ();
4010
10195bd8
JW
4011 if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
4012 abort ();
4013
4014 xops[0] = GEN_INT (0x0c00);
4015 xops[1] = operands[5];
305f097e
JVA
4016
4017 output_asm_insn (AS1 (fnstc%W2,%2), operands);
10195bd8
JW
4018 output_asm_insn (AS2 (mov%W5,%2,%w5), operands);
4019 output_asm_insn (AS2 (or%W1,%0,%w1), xops);
4020 output_asm_insn (AS2 (mov%W3,%w5,%3), operands);
305f097e 4021 output_asm_insn (AS1 (fldc%W3,%3), operands);
2a2ab3f9 4022
10195bd8 4023 xops[0] = NON_STACK_REG_P (operands[0]) ? operands[4] : operands[0];
e9a25f70 4024
10195bd8
JW
4025 if (stack_top_dies)
4026 output_asm_insn (AS1 (fistp%z0,%y0), xops);
4027 else
4028 output_asm_insn (AS1 (fist%z0,%y0), xops);
4029
4030 if (NON_STACK_REG_P (operands[0]))
2a2ab3f9 4031 {
10195bd8
JW
4032 if (GET_MODE (operands[0]) == SImode)
4033 output_asm_insn (AS2 (mov%L0,%4,%0), operands);
4034 else
2e14a41b 4035 {
10195bd8
JW
4036 xops[0] = operands[0];
4037 xops[1] = operands[4];
4038 output_asm_insn (output_move_double (xops), xops);
2e14a41b 4039 }
2a2ab3f9 4040 }
2a2ab3f9 4041
305f097e 4042 return AS1 (fldc%W2,%2);
2a2ab3f9
JVA
4043}
4044\f
cda749b1
JW
4045/* Output code for INSN to extend a float. OPERANDS are the insn
4046 operands. The output may be DFmode or XFmode and the input operand
4047 may be SFmode or DFmode. Operands 2 and 3 are scratch memory and
4048 are only necessary if operands 0 or 1 are non-stack registers. */
4049
4050void
4051output_float_extend (insn, operands)
4052 rtx insn;
4053 rtx *operands;
4054{
4055 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4056 rtx xops[2];
4057
4058 if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1]))
4059 abort ();
4060
4061 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]) && stack_top_dies)
4062 return;
4063
4064 if (STACK_TOP_P (operands[0]) )
4065 {
4066 if (NON_STACK_REG_P (operands[1]))
4067 {
4068 if (GET_MODE (operands[1]) == SFmode)
4069 output_asm_insn (AS2 (mov%L0,%1,%2), operands);
4070 else
4071 {
4072 xops[0] = operands[2];
4073 xops[1] = operands[1];
4074 output_asm_insn (output_move_double (xops), xops);
4075 }
4076 }
4077
4078 xops[0] = NON_STACK_REG_P (operands[1]) ? operands[2] : operands[1];
4079
4080 output_asm_insn (AS1 (fld%z0,%y0), xops);
4081 }
4082 else
4083 {
4084 xops[0] = NON_STACK_REG_P (operands[0]) ? operands[3] : operands[0];
4085
4086 if (stack_top_dies
4087 || (GET_CODE (xops[0]) == MEM && GET_MODE (xops[0]) == XFmode))
4088 {
4089 output_asm_insn (AS1 (fstp%z0,%y0), xops);
4090 if (! stack_top_dies)
4091 output_asm_insn (AS1 (fld%z0,%y0), xops);
4092 }
4093 else
4094 output_asm_insn (AS1 (fst%z0,%y0), xops);
4095
4096 if (NON_STACK_REG_P (operands[0]))
4097 {
4098 xops[0] = operands[0];
4099 xops[1] = operands[3];
4100 output_asm_insn (output_move_double (xops), xops);
4101 }
4102 }
4103}
4104\f
2a2ab3f9
JVA
4105/* Output code for INSN to compare OPERANDS. The two operands might
4106 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
c572e5ba
JVA
4107 expression. If the compare is in mode CCFPEQmode, use an opcode that
4108 will not fault if a qNaN is present. */
2a2ab3f9
JVA
4109
4110char *
4111output_float_compare (insn, operands)
4112 rtx insn;
4113 rtx *operands;
4114{
4115 int stack_top_dies;
c572e5ba
JVA
4116 rtx body = XVECEXP (PATTERN (insn), 0, 0);
4117 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
32b5b1aa 4118 rtx tmp;
e74389ff
JH
4119 int cc0_set = 1;
4120 int i;
4f74d15b 4121
870a0c2c
L
4122 if (TARGET_CMOVE && STACK_REG_P (operands[1])
4123 && STACK_REG_P (operands[0]))
4f74d15b
SC
4124 {
4125 cc_status.flags |= CC_FCOMI;
4126 cc_prev_status.flags &= ~CC_TEST_AX;
4127 }
4128
32b5b1aa
SC
4129 if (! STACK_TOP_P (operands[0]))
4130 {
4131 tmp = operands[0];
4132 operands[0] = operands[1];
4133 operands[1] = tmp;
4134 cc_status.flags |= CC_REVERSED;
4135 }
79325812 4136
2a2ab3f9
JVA
4137 if (! STACK_TOP_P (operands[0]))
4138 abort ();
4139
4140 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4141
4142 if (STACK_REG_P (operands[1])
4143 && stack_top_dies
4144 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
e74389ff 4145 && REGNO (operands[1]) == FIRST_STACK_REG + 1)
2a2ab3f9
JVA
4146 {
4147 /* If both the top of the 387 stack dies, and the other operand
4148 is also a stack register that dies, then this must be a
4149 `fcompp' float compare */
4150
c572e5ba 4151 if (unordered_compare)
e9a25f70
JL
4152 {
4153 if (cc_status.flags & CC_FCOMI)
4154 {
4155 output_asm_insn (AS2 (fucomip,%y1,%0), operands);
4156 output_asm_insn (AS1 (fstp, %y0), operands);
870a0c2c
L
4157 if (!TARGET_IEEE_FP)
4158 cc0_set = 0;
e9a25f70
JL
4159 }
4160 else
4161 output_asm_insn ("fucompp", operands);
4162 }
c572e5ba 4163 else
858a9ffc 4164 {
e9a25f70
JL
4165 if (cc_status.flags & CC_FCOMI)
4166 {
4167 output_asm_insn (AS2 (fcomip, %y1,%0), operands);
4168 output_asm_insn (AS1 (fstp, %y0), operands);
870a0c2c
L
4169 if (!TARGET_IEEE_FP)
4170 cc0_set = 0;
e9a25f70
JL
4171 }
4172 else
4173 output_asm_insn ("fcompp", operands);
858a9ffc 4174 }
2a2ab3f9
JVA
4175 }
4176 else
4177 {
4178 static char buf[100];
4179
87aa5246 4180 /* Decide if this is a float compare or an unordered float compare. */
2a2ab3f9 4181
c572e5ba 4182 if (unordered_compare)
4f74d15b 4183 strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fucomi" : "fucom");
2a2ab3f9 4184 else
87aa5246 4185 strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom");
2a2ab3f9
JVA
4186
4187 /* Modify the opcode if the 387 stack is to be popped. */
4188
4189 if (stack_top_dies)
4190 strcat (buf, "p");
4191
87aa5246 4192 if (cc_status.flags & CC_FCOMI)
5703bb66 4193 {
858a9ffc 4194 output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
870a0c2c
L
4195 if (!TARGET_IEEE_FP)
4196 cc0_set = 0;
5703bb66 4197 }
2a2ab3f9
JVA
4198 else
4199 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
4200 }
4201
4202 /* Now retrieve the condition code. */
e74389ff
JH
4203 if (cc0_set)
4204 {
4205 char *r = output_fp_cc0_set (insn);
4206 if (r[0]) output_asm_insn (r, operands);
4207 }
4208
4209
4210 /* We emit fstp instruction after integer comparsions to improve
4211 scheduling. */
4212 for (i = 0; i < 2 ; i++)
4213 {
4214 if (STACK_REG_P (operands[i])
4215 && find_regno_note (insn, REG_DEAD, REGNO (operands[i]))
4216 && REGNO (operands[i]) != FIRST_STACK_REG
4217 && (!stack_top_dies || REGNO (operands[i]) != FIRST_STACK_REG + 1))
4218 {
446ba526 4219 rtx xexp[2];
e74389ff
JH
4220 xexp[0] = gen_rtx_REG (DFmode,
4221 REGNO (operands[i]) - (stack_top_dies != 0));
4222 output_asm_insn (AS1 (fstp, %y0), xexp);
4223 }
4224 }
4225
4226 return "";
4227
2a2ab3f9 4228
c572e5ba
JVA
4229}
4230\f
4231/* Output opcodes to transfer the results of FP compare or test INSN
4232 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
4233 result of the compare or test is unordered, no comparison operator
4234 succeeds except NE. Return an output template, if any. */
4235
4236char *
4237output_fp_cc0_set (insn)
4238 rtx insn;
4239{
4240 rtx xops[3];
c572e5ba
JVA
4241 rtx next;
4242 enum rtx_code code;
4243
870a0c2c
L
4244 if (!(cc_status.flags & CC_FCOMI))
4245 {
4246 xops[0] = gen_rtx_REG (HImode, 0);
4247 output_asm_insn (AS1 (fnsts%W0,%0), xops);
4248 }
c572e5ba
JVA
4249
4250 if (! TARGET_IEEE_FP)
32b5b1aa
SC
4251 {
4252 if (!(cc_status.flags & CC_REVERSED))
4253 {
4254 next = next_cc0_user (insn);
870a0c2c
L
4255
4256 if (GET_CODE (PATTERN (next)) == SET
32b5b1aa
SC
4257 && SET_DEST (PATTERN (next)) == pc_rtx
4258 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
e9a25f70 4259 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
32b5b1aa 4260 else if (GET_CODE (PATTERN (next)) == SET)
e9a25f70 4261 code = GET_CODE (SET_SRC (PATTERN (next)));
32b5b1aa 4262 else
e9a25f70
JL
4263 return "sahf";
4264
4265 if (code == GT || code == LT || code == EQ || code == NE
4266 || code == LE || code == GE)
4267 {
4268 /* We will test eax directly. */
32b5b1aa 4269 cc_status.flags |= CC_TEST_AX;
e9a25f70 4270 return "";
32b5b1aa
SC
4271 }
4272 }
e9a25f70 4273
32b5b1aa
SC
4274 return "sahf";
4275 }
2a2ab3f9 4276
c572e5ba 4277 next = next_cc0_user (insn);
dd9611dc
JVA
4278 if (next == NULL_RTX)
4279 abort ();
c572e5ba 4280
870a0c2c 4281 if (GET_CODE (PATTERN (next)) == SET
c572e5ba
JVA
4282 && SET_DEST (PATTERN (next)) == pc_rtx
4283 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
e9a25f70 4284 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
c572e5ba
JVA
4285 else if (GET_CODE (PATTERN (next)) == SET)
4286 {
fe25fea3
SC
4287 if (GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4288 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
e9a25f70
JL
4289 else
4290 code = GET_CODE (SET_SRC (PATTERN (next)));
c572e5ba 4291 }
e9a25f70 4292
4f74d15b
SC
4293 else if (GET_CODE (PATTERN (next)) == PARALLEL
4294 && GET_CODE (XVECEXP (PATTERN (next), 0, 0)) == SET)
4295 {
4296 if (GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0))) == IF_THEN_ELSE)
e9a25f70
JL
4297 code = GET_CODE (XEXP (SET_SRC (XVECEXP (PATTERN (next), 0, 0)), 0));
4298 else
4299 code = GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0)));
4f74d15b 4300 }
c572e5ba
JVA
4301 else
4302 abort ();
4303
870a0c2c
L
4304 if (cc_status.flags & CC_FCOMI)
4305 {
4306 /* It is very tricky. We have to do it right. */
4307
4308 xops [0] = gen_rtx_REG (QImode, 0);
446ba526 4309
870a0c2c
L
4310 switch (code)
4311 {
4312 case GT:
4313 case GE:
4314 break;
4315
4316 case LT:
4317 output_asm_insn (AS1 (setb,%b0), xops);
4318 output_asm_insn (AS1 (setp,%h0), xops);
4319 output_asm_insn (AS2 (cmp%B0,%b0,%h0), xops);
4320 break;
4321
4322 case LE:
4323 output_asm_insn (AS1 (setbe,%b0), xops);
4324 output_asm_insn (AS1 (setnp,%h0), xops);
4325 output_asm_insn (AS2 (xor%B0,%b0,%h0), xops);
4326 break;
4327
4328 case EQ:
4329 case NE:
4330 output_asm_insn (AS1 (setne,%b0), xops);
4331 output_asm_insn (AS1 (setp,%h0), xops);
4332 output_asm_insn (AS2 (or%B0,%b0,%h0), xops);
4333 break;
4334
4335 case GTU:
4336 case LTU:
4337 case GEU:
4338 case LEU:
4339 default:
4340 abort ();
4341 }
4342 }
4343 else
c572e5ba 4344 {
870a0c2c 4345 xops[0] = gen_rtx_REG (QImode, 0);
c572e5ba 4346
870a0c2c
L
4347 switch (code)
4348 {
4349 case GT:
4350 xops[1] = GEN_INT (0x45);
4351 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4352 /* je label */
4353 break;
c572e5ba 4354
870a0c2c
L
4355 case LT:
4356 xops[1] = GEN_INT (0x45);
4357 xops[2] = GEN_INT (0x01);
4358 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4359 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4360 /* je label */
4361 break;
c572e5ba 4362
870a0c2c
L
4363 case GE:
4364 xops[1] = GEN_INT (0x05);
4365 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4366 /* je label */
4367 break;
c572e5ba 4368
870a0c2c
L
4369 case LE:
4370 xops[1] = GEN_INT (0x45);
4371 xops[2] = GEN_INT (0x40);
4372 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4373 output_asm_insn (AS1 (dec%B0,%h0), xops);
4374 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4375 /* jb label */
4376 break;
a14003ee 4377
870a0c2c
L
4378 case EQ:
4379 xops[1] = GEN_INT (0x45);
4380 xops[2] = GEN_INT (0x40);
4381 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4382 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4383 /* je label */
4384 break;
446ba526 4385
870a0c2c
L
4386 case NE:
4387 xops[1] = GEN_INT (0x44);
4388 xops[2] = GEN_INT (0x40);
4389 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4390 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
4391 /* jne label */
4392 break;
4393
4394 case GTU:
4395 case LTU:
4396 case GEU:
4397 case LEU:
4398 default:
4399 abort ();
4400 }
c572e5ba 4401 }
e9a25f70
JL
4402
4403 return "";
2a2ab3f9 4404}
305f097e
JVA
4405\f
4406#define MAX_386_STACK_LOCALS 2
4407
4408static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4409
ecbc4695
RS
4410/* Define the structure for the machine field in struct function. */
4411struct machine_function
4412{
4413 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
b94b5c16
JL
4414 rtx pic_label_rtx;
4415 char pic_label_name[256];
ecbc4695
RS
4416};
4417
4418/* Functions to save and restore i386_stack_locals.
4419 These will be called, via pointer variables,
4420 from push_function_context and pop_function_context. */
4421
4422void
4423save_386_machine_status (p)
4424 struct function *p;
4425{
b94b5c16
JL
4426 p->machine
4427 = (struct machine_function *) xmalloc (sizeof (struct machine_function));
dde866c6 4428 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
ecbc4695 4429 sizeof i386_stack_locals);
b94b5c16
JL
4430 p->machine->pic_label_rtx = pic_label_rtx;
4431 bcopy (pic_label_name, p->machine->pic_label_name, 256);
ecbc4695
RS
4432}
4433
4434void
4435restore_386_machine_status (p)
4436 struct function *p;
4437{
dde866c6 4438 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
ecbc4695 4439 sizeof i386_stack_locals);
b94b5c16
JL
4440 pic_label_rtx = p->machine->pic_label_rtx;
4441 bcopy (p->machine->pic_label_name, pic_label_name, 256);
ecbc4695 4442 free (p->machine);
b94b5c16 4443 p->machine = NULL;
ecbc4695
RS
4444}
4445
305f097e
JVA
4446/* Clear stack slot assignments remembered from previous functions.
4447 This is called from INIT_EXPANDERS once before RTL is emitted for each
ecbc4695 4448 function. */
305f097e
JVA
4449
4450void
4451clear_386_stack_locals ()
4452{
4453 enum machine_mode mode;
4454 int n;
4455
4456 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
4457 mode = (enum machine_mode) ((int) mode + 1))
4458 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
4459 i386_stack_locals[(int) mode][n] = NULL_RTX;
ecbc4695 4460
b94b5c16
JL
4461 pic_label_rtx = NULL_RTX;
4462 bzero (pic_label_name, 256);
ecbc4695
RS
4463 /* Arrange to save and restore i386_stack_locals around nested functions. */
4464 save_machine_status = save_386_machine_status;
4465 restore_machine_status = restore_386_machine_status;
305f097e
JVA
4466}
4467
4468/* Return a MEM corresponding to a stack slot with mode MODE.
4469 Allocate a new slot if necessary.
4470
4471 The RTL for a function can have several slots available: N is
4472 which slot to use. */
4473
4474rtx
4475assign_386_stack_local (mode, n)
4476 enum machine_mode mode;
4477 int n;
4478{
4479 if (n < 0 || n >= MAX_386_STACK_LOCALS)
4480 abort ();
4481
4482 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
4483 i386_stack_locals[(int) mode][n]
4484 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
4485
4486 return i386_stack_locals[(int) mode][n];
4487}
32b5b1aa
SC
4488\f
4489int is_mul(op,mode)
4490 register rtx op;
bb5177ac 4491 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4492{
4493 return (GET_CODE (op) == MULT);
4494}
4495
4496int is_div(op,mode)
4497 register rtx op;
bb5177ac 4498 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4499{
4500 return (GET_CODE (op) == DIV);
4501}
32b5b1aa
SC
4502\f
4503#ifdef NOTYET
4504/* Create a new copy of an rtx.
4505 Recursively copies the operands of the rtx,
4506 except for those few rtx codes that are sharable.
4507 Doesn't share CONST */
4508
4509rtx
4510copy_all_rtx (orig)
4511 register rtx orig;
4512{
4513 register rtx copy;
4514 register int i, j;
4515 register RTX_CODE code;
4516 register char *format_ptr;
4517
4518 code = GET_CODE (orig);
4519
4520 switch (code)
4521 {
4522 case REG:
4523 case QUEUED:
4524 case CONST_INT:
4525 case CONST_DOUBLE:
4526 case SYMBOL_REF:
4527 case CODE_LABEL:
4528 case PC:
4529 case CC0:
4530 case SCRATCH:
4531 /* SCRATCH must be shared because they represent distinct values. */
4532 return orig;
4533
4534#if 0
4535 case CONST:
4536 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
4537 a LABEL_REF, it isn't sharable. */
4538 if (GET_CODE (XEXP (orig, 0)) == PLUS
4539 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
4540 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
4541 return orig;
4542 break;
4543#endif
4544 /* A MEM with a constant address is not sharable. The problem is that
4545 the constant address may need to be reloaded. If the mem is shared,
4546 then reloading one copy of this mem will cause all copies to appear
4547 to have been reloaded. */
4548 }
4549
4550 copy = rtx_alloc (code);
4551 PUT_MODE (copy, GET_MODE (orig));
4552 copy->in_struct = orig->in_struct;
4553 copy->volatil = orig->volatil;
4554 copy->unchanging = orig->unchanging;
4555 copy->integrated = orig->integrated;
4556 /* intel1 */
4557 copy->is_spill_rtx = orig->is_spill_rtx;
79325812 4558
32b5b1aa
SC
4559 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
4560
4561 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
4562 {
4563 switch (*format_ptr++)
4564 {
4565 case 'e':
4566 XEXP (copy, i) = XEXP (orig, i);
4567 if (XEXP (orig, i) != NULL)
4568 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
4569 break;
4570
4571 case '0':
4572 case 'u':
4573 XEXP (copy, i) = XEXP (orig, i);
4574 break;
4575
4576 case 'E':
4577 case 'V':
4578 XVEC (copy, i) = XVEC (orig, i);
4579 if (XVEC (orig, i) != NULL)
4580 {
4581 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
4582 for (j = 0; j < XVECLEN (copy, i); j++)
4583 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
4584 }
4585 break;
4586
4587 case 'w':
4588 XWINT (copy, i) = XWINT (orig, i);
4589 break;
4590
4591 case 'i':
4592 XINT (copy, i) = XINT (orig, i);
4593 break;
4594
4595 case 's':
4596 case 'S':
4597 XSTR (copy, i) = XSTR (orig, i);
4598 break;
4599
4600 default:
4601 abort ();
4602 }
4603 }
4604 return copy;
4605}
4606
4607\f
e9a25f70
JL
4608/* Try to rewrite a memory address to make it valid */
4609
79325812 4610void
32b5b1aa
SC
4611rewrite_address (mem_rtx)
4612 rtx mem_rtx;
4613{
4614 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
4615 int scale = 1;
4616 int offset_adjust = 0;
4617 int was_only_offset = 0;
4618 rtx mem_addr = XEXP (mem_rtx, 0);
e9a25f70 4619 char *storage = oballoc (0);
32b5b1aa
SC
4620 int in_struct = 0;
4621 int is_spill_rtx = 0;
4622
4623 in_struct = MEM_IN_STRUCT_P (mem_rtx);
4624 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
4625
e9a25f70
JL
4626 if (GET_CODE (mem_addr) == PLUS
4627 && GET_CODE (XEXP (mem_addr, 1)) == PLUS
4628 && GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
4629 {
4630 /* This part is utilized by the combiner. */
4631 ret_rtx
4632 = gen_rtx (PLUS, GET_MODE (mem_addr),
4633 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
4634 XEXP (mem_addr, 0), XEXP (XEXP (mem_addr, 1), 0)),
4635 XEXP (XEXP (mem_addr, 1), 1));
4636
32b5b1aa
SC
4637 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
4638 {
4639 XEXP (mem_rtx, 0) = ret_rtx;
4640 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
4641 return;
4642 }
e9a25f70 4643
32b5b1aa
SC
4644 obfree (storage);
4645 }
4646
79325812 4647 /* This part is utilized by loop.c.
e9a25f70
JL
4648 If the address contains PLUS (reg,const) and this pattern is invalid
4649 in this case - try to rewrite the address to make it valid. */
4650 storage = oballoc (0);
32b5b1aa 4651 index_rtx = base_rtx = offset_rtx = NULL;
e9a25f70
JL
4652
4653 /* Find the base index and offset elements of the memory address. */
32b5b1aa
SC
4654 if (GET_CODE (mem_addr) == PLUS)
4655 {
4656 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
4657 {
4658 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
e9a25f70 4659 base_rtx = XEXP (mem_addr, 1), index_rtx = XEXP (mem_addr, 0);
32b5b1aa 4660 else
e9a25f70 4661 base_rtx = XEXP (mem_addr, 0), offset_rtx = XEXP (mem_addr, 1);
32b5b1aa 4662 }
e9a25f70 4663
32b5b1aa
SC
4664 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
4665 {
4666 index_rtx = XEXP (mem_addr, 0);
4667 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
e9a25f70 4668 base_rtx = XEXP (mem_addr, 1);
32b5b1aa 4669 else
e9a25f70 4670 offset_rtx = XEXP (mem_addr, 1);
32b5b1aa 4671 }
e9a25f70 4672
32b5b1aa
SC
4673 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
4674 {
e9a25f70
JL
4675 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS
4676 && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT
4677 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0))
4678 == REG)
4679 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1))
4680 == CONST_INT)
4681 && (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1))
4682 == CONST_INT)
4683 && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG
4684 && GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
32b5b1aa
SC
4685 {
4686 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
4687 offset_rtx = XEXP (mem_addr, 1);
4688 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4689 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
4690 }
4691 else
4692 {
4693 offset_rtx = XEXP (mem_addr, 1);
4694 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
4695 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4696 }
4697 }
e9a25f70 4698
32b5b1aa
SC
4699 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
4700 {
4701 was_only_offset = 1;
4702 index_rtx = NULL;
4703 base_rtx = NULL;
4704 offset_rtx = XEXP (mem_addr, 1);
4705 offset_adjust = INTVAL (XEXP (mem_addr, 0));
4706 if (offset_adjust == 0)
4707 {
4708 XEXP (mem_rtx, 0) = offset_rtx;
4709 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4710 return;
4711 }
4712 }
4713 else
4714 {
4715 obfree (storage);
4716 return;
4717 }
4718 }
4719 else if (GET_CODE (mem_addr) == MULT)
e9a25f70 4720 index_rtx = mem_addr;
32b5b1aa
SC
4721 else
4722 {
4723 obfree (storage);
4724 return;
4725 }
e9a25f70
JL
4726
4727 if (index_rtx != 0 && GET_CODE (index_rtx) == MULT)
32b5b1aa
SC
4728 {
4729 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
4730 {
4731 obfree (storage);
4732 return;
4733 }
e9a25f70 4734
32b5b1aa
SC
4735 scale_rtx = XEXP (index_rtx, 1);
4736 scale = INTVAL (scale_rtx);
4737 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4738 }
e9a25f70
JL
4739
4740 /* Now find which of the elements are invalid and try to fix them. */
32b5b1aa
SC
4741 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
4742 {
4743 offset_adjust = INTVAL (index_rtx) * scale;
e9a25f70
JL
4744
4745 if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4746 offset_rtx = plus_constant (offset_rtx, offset_adjust);
4747 else if (offset_rtx == 0)
4748 offset_rtx = const0_rtx;
4749
32b5b1aa
SC
4750 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4751 XEXP (mem_rtx, 0) = offset_rtx;
4752 return;
4753 }
e9a25f70
JL
4754
4755 if (base_rtx && GET_CODE (base_rtx) == PLUS
4756 && GET_CODE (XEXP (base_rtx, 0)) == REG
4757 && GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
32b5b1aa
SC
4758 {
4759 offset_adjust += INTVAL (XEXP (base_rtx, 1));
4760 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
4761 }
e9a25f70 4762
32b5b1aa
SC
4763 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
4764 {
4765 offset_adjust += INTVAL (base_rtx);
4766 base_rtx = NULL;
4767 }
e9a25f70
JL
4768
4769 if (index_rtx && GET_CODE (index_rtx) == PLUS
4770 && GET_CODE (XEXP (index_rtx, 0)) == REG
4771 && GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
32b5b1aa
SC
4772 {
4773 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
4774 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4775 }
e9a25f70 4776
32b5b1aa
SC
4777 if (index_rtx)
4778 {
e9a25f70
JL
4779 if (! LEGITIMATE_INDEX_P (index_rtx)
4780 && ! (index_rtx == stack_pointer_rtx && scale == 1
4781 && base_rtx == NULL))
32b5b1aa
SC
4782 {
4783 obfree (storage);
4784 return;
4785 }
4786 }
e9a25f70 4787
32b5b1aa
SC
4788 if (base_rtx)
4789 {
e9a25f70 4790 if (! LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
32b5b1aa
SC
4791 {
4792 obfree (storage);
4793 return;
4794 }
4795 }
e9a25f70 4796
32b5b1aa
SC
4797 if (offset_adjust != 0)
4798 {
e9a25f70
JL
4799 if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4800 offset_rtx = plus_constant (offset_rtx, offset_adjust);
32b5b1aa 4801 else
e9a25f70
JL
4802 offset_rtx = const0_rtx;
4803
32b5b1aa
SC
4804 if (index_rtx)
4805 {
4806 if (base_rtx)
4807 {
4808 if (scale != 1)
4809 {
e9a25f70
JL
4810 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
4811 gen_rtx (MULT, GET_MODE (index_rtx),
4812 index_rtx, scale_rtx),
4813 base_rtx);
4814
4815 if (GET_CODE (offset_rtx) != CONST_INT
4816 || INTVAL (offset_rtx) != 0)
4817 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4818 ret_rtx, offset_rtx);
32b5b1aa
SC
4819 }
4820 else
4821 {
e9a25f70
JL
4822 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4823 index_rtx, base_rtx);
4824
4825 if (GET_CODE (offset_rtx) != CONST_INT
4826 || INTVAL (offset_rtx) != 0)
4827 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4828 ret_rtx, offset_rtx);
32b5b1aa
SC
4829 }
4830 }
4831 else
4832 {
4833 if (scale != 1)
4834 {
e9a25f70
JL
4835 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx),
4836 index_rtx, scale_rtx);
4837
4838 if (GET_CODE (offset_rtx) != CONST_INT
4839 || INTVAL (offset_rtx) != 0)
4840 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4841 ret_rtx, offset_rtx);
32b5b1aa
SC
4842 }
4843 else
4844 {
e9a25f70
JL
4845 if (GET_CODE (offset_rtx) == CONST_INT
4846 && INTVAL (offset_rtx) == 0)
4847 ret_rtx = index_rtx;
32b5b1aa 4848 else
e9a25f70
JL
4849 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4850 index_rtx, offset_rtx);
32b5b1aa
SC
4851 }
4852 }
4853 }
4854 else
4855 {
4856 if (base_rtx)
4857 {
e9a25f70
JL
4858 if (GET_CODE (offset_rtx) == CONST_INT
4859 && INTVAL (offset_rtx) == 0)
4860 ret_rtx = base_rtx;
32b5b1aa 4861 else
e9a25f70
JL
4862 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx,
4863 offset_rtx);
32b5b1aa
SC
4864 }
4865 else if (was_only_offset)
e9a25f70 4866 ret_rtx = offset_rtx;
32b5b1aa
SC
4867 else
4868 {
4869 obfree (storage);
4870 return;
4871 }
4872 }
e9a25f70 4873
32b5b1aa
SC
4874 XEXP (mem_rtx, 0) = ret_rtx;
4875 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4876 return;
4877 }
4878 else
4879 {
4880 obfree (storage);
4881 return;
4882 }
4883}
4884#endif /* NOTYET */
32b5b1aa 4885\f
e9a25f70
JL
4886/* Return 1 if the first insn to set cc before INSN also sets the register
4887 REG_RTX; otherwise return 0. */
32b5b1aa
SC
4888int
4889last_to_set_cc (reg_rtx, insn)
4890 rtx reg_rtx, insn;
4891{
4892 rtx prev_insn = PREV_INSN (insn);
4893
4894 while (prev_insn)
4895 {
4896 if (GET_CODE (prev_insn) == NOTE)
4897 ;
4898
4899 else if (GET_CODE (prev_insn) == INSN)
4900 {
4901 if (GET_CODE (PATTERN (prev_insn)) != SET)
4902 return (0);
4903
4904 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4905 {
4906 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4907 return (1);
4908
4909 return (0);
4910 }
4911
e9a25f70 4912 else if (! doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
32b5b1aa
SC
4913 return (0);
4914 }
4915
4916 else
4917 return (0);
4918
4919 prev_insn = PREV_INSN (prev_insn);
4920 }
4921
4922 return (0);
4923}
32b5b1aa
SC
4924\f
4925int
4926doesnt_set_condition_code (pat)
4927 rtx pat;
4928{
4929 switch (GET_CODE (pat))
4930 {
4931 case MEM:
4932 case REG:
e9a25f70 4933 return 1;
32b5b1aa
SC
4934
4935 default:
e9a25f70 4936 return 0;
32b5b1aa
SC
4937
4938 }
4939}
32b5b1aa
SC
4940\f
4941int
4942sets_condition_code (pat)
4943 rtx pat;
4944{
4945 switch (GET_CODE (pat))
4946 {
4947 case PLUS:
4948 case MINUS:
4949 case AND:
4950 case IOR:
4951 case XOR:
4952 case NOT:
4953 case NEG:
4954 case MULT:
4955 case DIV:
4956 case MOD:
4957 case UDIV:
4958 case UMOD:
e9a25f70 4959 return 1;
32b5b1aa
SC
4960
4961 default:
4962 return (0);
32b5b1aa
SC
4963 }
4964}
32b5b1aa
SC
4965\f
4966int
4967str_immediate_operand (op, mode)
4968 register rtx op;
bb5177ac 4969 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4970{
4971 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
e9a25f70 4972 return 1;
32b5b1aa 4973
e9a25f70
JL
4974 return 0;
4975}
32b5b1aa
SC
4976\f
4977int
4978is_fp_insn (insn)
4979 rtx insn;
4980{
4981 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4982 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4983 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4984 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
e9a25f70 4985 return 1;
32b5b1aa 4986
e9a25f70 4987 return 0;
32b5b1aa
SC
4988}
4989
e9a25f70
JL
4990/* Return 1 if the mode of the SET_DEST of insn is floating point
4991 and it is not an fld or a move from memory to memory.
4992 Otherwise return 0 */
4993
32b5b1aa
SC
4994int
4995is_fp_dest (insn)
4996 rtx insn;
4997{
4998 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4999 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
5000 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
5001 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
5002 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
5003 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
48d4389d 5004 && GET_CODE (SET_SRC (PATTERN (insn))) != MEM)
e9a25f70 5005 return 1;
32b5b1aa 5006
e9a25f70 5007 return 0;
32b5b1aa
SC
5008}
5009
e9a25f70
JL
5010/* Return 1 if the mode of the SET_DEST of INSN is floating point and is
5011 memory and the source is a register. */
5012
32b5b1aa
SC
5013int
5014is_fp_store (insn)
5015 rtx insn;
5016{
5017 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5018 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
5019 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
5020 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
5021 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
5022 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
e9a25f70 5023 return 1;
32b5b1aa 5024
e9a25f70 5025 return 0;
32b5b1aa 5026}
32b5b1aa 5027\f
e9a25f70
JL
5028/* Return 1 if DEP_INSN sets a register which INSN uses as a base
5029 or index to reference memory.
5030 otherwise return 0 */
32b5b1aa
SC
5031
5032int
5033agi_dependent (insn, dep_insn)
5034 rtx insn, dep_insn;
5035{
b985a30f 5036 int push = 0, push_dep = 0;
32b5b1aa
SC
5037 if (GET_CODE (dep_insn) == INSN
5038 && GET_CODE (PATTERN (dep_insn)) == SET
b985a30f
JH
5039 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG
5040 && reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn))
5041 return 1;
5042
5043 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
5044 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
5045 && push_operand (SET_DEST (PATTERN (insn)),
5046 GET_MODE (SET_DEST (PATTERN (insn)))))
5047 push = 1;
32b5b1aa
SC
5048
5049 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
5050 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
5051 && push_operand (SET_DEST (PATTERN (dep_insn)),
5052 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
b985a30f
JH
5053 push_dep = 1;
5054
5055 /* CPUs contain special hardware to allow two pushes. */
5056 if (push && push_dep)
5057 return 0;
5058
5059 /* Push operation implicitly change stack pointer causing AGI stalls. */
5060 if (push_dep && reg_mentioned_in_mem (stack_pointer_rtx, insn))
5061 return 1;
5062
5063 /* Push also implicitly read stack pointer. */
5064 if (push && modified_in_p (stack_pointer_rtx, dep_insn))
5065 return 1;
32b5b1aa 5066
e9a25f70
JL
5067 return 0;
5068}
32b5b1aa 5069\f
e9a25f70
JL
5070/* Return 1 if reg is used in rtl as a base or index for a memory ref
5071 otherwise return 0. */
32b5b1aa
SC
5072
5073int
5074reg_mentioned_in_mem (reg, rtl)
5075 rtx reg, rtl;
5076{
5077 register char *fmt;
e9a25f70 5078 register int i, j;
32b5b1aa
SC
5079 register enum rtx_code code;
5080
5081 if (rtl == NULL)
e9a25f70 5082 return 0;
32b5b1aa
SC
5083
5084 code = GET_CODE (rtl);
5085
5086 switch (code)
5087 {
5088 case HIGH:
5089 case CONST_INT:
5090 case CONST:
5091 case CONST_DOUBLE:
5092 case SYMBOL_REF:
5093 case LABEL_REF:
5094 case PC:
5095 case CC0:
5096 case SUBREG:
e9a25f70 5097 return 0;
00c79232 5098 default:
53949fac 5099 break;
32b5b1aa
SC
5100 }
5101
5102 if (code == MEM && reg_mentioned_p (reg, rtl))
e9a25f70 5103 return 1;
32b5b1aa
SC
5104
5105 fmt = GET_RTX_FORMAT (code);
5106 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
5107 {
5108 if (fmt[i] == 'E')
c7271385
JL
5109 {
5110 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
5111 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
5112 return 1;
5113 }
32b5b1aa
SC
5114
5115 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
5116 return 1;
5117 }
5118
e9a25f70 5119 return 0;
32b5b1aa 5120}
3f803cd9 5121\f
956d6950 5122/* Output the appropriate insns for doing strlen if not just doing repnz; scasb
3f803cd9
SC
5123
5124 operands[0] = result, initialized with the startaddress
5125 operands[1] = alignment of the address.
5126 operands[2] = scratch register, initialized with the startaddress when
5127 not aligned, otherwise undefined
5128
5129 This is just the body. It needs the initialisations mentioned above and
5130 some address computing at the end. These things are done in i386.md. */
5131
5132char *
5133output_strlen_unroll (operands)
5134 rtx operands[];
5135{
5136 rtx xops[18];
5137
5138 xops[0] = operands[0]; /* Result */
5139 /* operands[1]; * Alignment */
5140 xops[1] = operands[2]; /* Scratch */
5141 xops[2] = GEN_INT (0);
5142 xops[3] = GEN_INT (2);
5143 xops[4] = GEN_INT (3);
5144 xops[5] = GEN_INT (4);
5145 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
5146 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
5147 xops[8] = gen_label_rtx (); /* label of main loop */
e9a25f70
JL
5148
5149 if (TARGET_USE_Q_REG && QI_REG_P (xops[1]))
3f803cd9 5150 xops[9] = gen_label_rtx (); /* pentium optimisation */
e9a25f70 5151
3f803cd9
SC
5152 xops[10] = gen_label_rtx (); /* end label 2 */
5153 xops[11] = gen_label_rtx (); /* end label 1 */
5154 xops[12] = gen_label_rtx (); /* end label */
5155 /* xops[13] * Temporary used */
5156 xops[14] = GEN_INT (0xff);
5157 xops[15] = GEN_INT (0xff00);
5158 xops[16] = GEN_INT (0xff0000);
5159 xops[17] = GEN_INT (0xff000000);
5160
e9a25f70 5161 /* Loop to check 1..3 bytes for null to get an aligned pointer. */
3f803cd9 5162
e9a25f70 5163 /* Is there a known alignment and is it less than 4? */
3f803cd9
SC
5164 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
5165 {
e9a25f70 5166 /* Is there a known alignment and is it not 2? */
3f803cd9
SC
5167 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5168 {
e9a25f70
JL
5169 xops[6] = gen_label_rtx (); /* Label when aligned to 3-byte */
5170 xops[7] = gen_label_rtx (); /* Label when aligned to 2-byte */
3f803cd9 5171
e9a25f70
JL
5172 /* Leave just the 3 lower bits.
5173 If this is a q-register, then the high part is used later
5174 therefore use andl rather than andb. */
3f803cd9 5175 output_asm_insn (AS2 (and%L1,%4,%1), xops);
e9a25f70 5176
956d6950 5177 /* Is aligned to 4-byte address when zero */
3f803cd9 5178 output_asm_insn (AS1 (je,%l8), xops);
e9a25f70
JL
5179
5180 /* Side-effect even Parity when %eax == 3 */
3f803cd9
SC
5181 output_asm_insn (AS1 (jp,%6), xops);
5182
e9a25f70 5183 /* Is it aligned to 2 bytes ? */
3f803cd9
SC
5184 if (QI_REG_P (xops[1]))
5185 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5186 else
5187 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
e9a25f70 5188
3f803cd9
SC
5189 output_asm_insn (AS1 (je,%7), xops);
5190 }
5191 else
5192 {
e9a25f70
JL
5193 /* Since the alignment is 2, we have to check 2 or 0 bytes;
5194 check if is aligned to 4 - byte. */
3f803cd9 5195 output_asm_insn (AS2 (and%L1,%3,%1), xops);
e9a25f70 5196
956d6950 5197 /* Is aligned to 4-byte address when zero */
3f803cd9
SC
5198 output_asm_insn (AS1 (je,%l8), xops);
5199 }
5200
f64cecad 5201 xops[13] = gen_rtx_MEM (QImode, xops[0]);
e9a25f70
JL
5202
5203 /* Now compare the bytes; compare with the high part of a q-reg
5204 gives shorter code. */
3f803cd9
SC
5205 if (QI_REG_P (xops[1]))
5206 {
e9a25f70 5207 /* Compare the first n unaligned byte on a byte per byte basis. */
3f803cd9 5208 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
e9a25f70
JL
5209
5210 /* When zero we reached the end. */
3f803cd9 5211 output_asm_insn (AS1 (je,%l12), xops);
e9a25f70
JL
5212
5213 /* Increment the address. */
3f803cd9
SC
5214 output_asm_insn (AS1 (inc%L0,%0), xops);
5215
e9a25f70 5216 /* Not needed with an alignment of 2 */
3f803cd9
SC
5217 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5218 {
e9a25f70
JL
5219 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5220 CODE_LABEL_NUMBER (xops[7]));
3f803cd9
SC
5221 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5222 output_asm_insn (AS1 (je,%l12), xops);
5223 output_asm_insn (AS1 (inc%L0,%0), xops);
5224
e9a25f70
JL
5225 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5226 CODE_LABEL_NUMBER (xops[6]));
3f803cd9 5227 }
e9a25f70 5228
3f803cd9
SC
5229 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5230 }
5231 else
5232 {
5233 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5234 output_asm_insn (AS1 (je,%l12), xops);
5235 output_asm_insn (AS1 (inc%L0,%0), xops);
5236
e9a25f70
JL
5237 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5238 CODE_LABEL_NUMBER (xops[7]));
3f803cd9
SC
5239 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5240 output_asm_insn (AS1 (je,%l12), xops);
5241 output_asm_insn (AS1 (inc%L0,%0), xops);
5242
e9a25f70
JL
5243 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5244 CODE_LABEL_NUMBER (xops[6]));
3f803cd9
SC
5245 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5246 }
e9a25f70 5247
3f803cd9
SC
5248 output_asm_insn (AS1 (je,%l12), xops);
5249 output_asm_insn (AS1 (inc%L0,%0), xops);
5250 }
5251
e9a25f70
JL
5252 /* Generate loop to check 4 bytes at a time. It is not a good idea to
5253 align this loop. It gives only huge programs, but does not help to
5254 speed up. */
3f803cd9
SC
5255 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
5256
f64cecad 5257 xops[13] = gen_rtx_MEM (SImode, xops[0]);
3f803cd9
SC
5258 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
5259
5260 if (QI_REG_P (xops[1]))
5261 {
1853aadd
RK
5262 /* On i586 it is faster to combine the hi- and lo- part as
5263 a kind of lookahead. If anding both yields zero, then one
5264 of both *could* be zero, otherwise none of both is zero;
5265 this saves one instruction, on i486 this is slower
5266 tested with P-90, i486DX2-66, AMD486DX2-66 */
e9a25f70 5267 if (TARGET_PENTIUM)
3f803cd9
SC
5268 {
5269 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
5270 output_asm_insn (AS1 (jne,%l9), xops);
5271 }
5272
e9a25f70 5273 /* Check first byte. */
3f803cd9
SC
5274 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
5275 output_asm_insn (AS1 (je,%l12), xops);
5276
e9a25f70 5277 /* Check second byte. */
3f803cd9
SC
5278 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
5279 output_asm_insn (AS1 (je,%l11), xops);
5280
e9a25f70
JL
5281 if (TARGET_PENTIUM)
5282 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5283 CODE_LABEL_NUMBER (xops[9]));
3f803cd9 5284 }
e9a25f70 5285
3f803cd9
SC
5286 else
5287 {
e9a25f70 5288 /* Check first byte. */
3f803cd9
SC
5289 output_asm_insn (AS2 (test%L1,%14,%1), xops);
5290 output_asm_insn (AS1 (je,%l12), xops);
5291
e9a25f70 5292 /* Check second byte. */
3f803cd9
SC
5293 output_asm_insn (AS2 (test%L1,%15,%1), xops);
5294 output_asm_insn (AS1 (je,%l11), xops);
5295 }
5296
e9a25f70 5297 /* Check third byte. */
3f803cd9
SC
5298 output_asm_insn (AS2 (test%L1,%16,%1), xops);
5299 output_asm_insn (AS1 (je,%l10), xops);
79325812 5300
e9a25f70 5301 /* Check fourth byte and increment address. */
3f803cd9
SC
5302 output_asm_insn (AS2 (add%L0,%5,%0), xops);
5303 output_asm_insn (AS2 (test%L1,%17,%1), xops);
5304 output_asm_insn (AS1 (jne,%l8), xops);
5305
e9a25f70 5306 /* Now generate fixups when the compare stops within a 4-byte word. */
3f803cd9
SC
5307 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
5308
5309 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
5310 output_asm_insn (AS1 (inc%L0,%0), xops);
5311
5312 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
5313 output_asm_insn (AS1 (inc%L0,%0), xops);
5314
5315 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));
5316
e9a25f70 5317 return "";
3f803cd9 5318}
b657fc39
L
5319
5320char *
5321output_fp_conditional_move (which_alternative, operands)
5322 int which_alternative;
5323 rtx operands[];
5324{
80309a9c
L
5325 enum rtx_code code = GET_CODE (operands[1]);
5326
5327 /* This should never happen. */
5328 if (!(cc_prev_status.flags & CC_IN_80387)
5329 && (code == GT || code == LE || code == GE || code == LT))
5330 abort ();
5331
b657fc39
L
5332 switch (which_alternative)
5333 {
5334 case 0:
5335 /* r <- cond ? arg : r */
5336 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5337 break;
79325812 5338
b657fc39
L
5339 case 1:
5340 /* r <- cond ? r : arg */
5341 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5342 break;
5343
b657fc39
L
5344 default:
5345 abort ();
5346 }
5347
5348 return "";
5349}
5350
5351char *
5352output_int_conditional_move (which_alternative, operands)
5353 int which_alternative;
5354 rtx operands[];
5355{
9a6ac4b0 5356 enum rtx_code code = GET_CODE (operands[1]);
b657fc39
L
5357
5358 /* This is very tricky. We have to do it right. For a code segement
5359 like:
5360
5361 int foo, bar;
5362 ....
5363 foo = foo - x;
5364 if (foo >= 0)
5365 bar = y;
5366
5367 final_scan_insn () may delete the insn which sets CC. We have to
5368 tell final_scan_insn () if it should be reinserted. When CODE is
5369 GT or LE, we have to check the CC_NO_OVERFLOW bit and return
5370 NULL_PTR to tell final to reinsert the test insn because the
5371 conditional move cannot be handled properly without it. */
5372 if ((code == GT || code == LE)
5373 && (cc_prev_status.flags & CC_NO_OVERFLOW))
5374 return NULL_PTR;
5375
b657fc39
L
5376 switch (which_alternative)
5377 {
5378 case 0:
5379 /* r <- cond ? arg : r */
5380 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
b657fc39
L
5381 break;
5382
5383 case 1:
5384 /* r <- cond ? r : arg */
5385 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
b657fc39
L
5386 break;
5387
b657fc39
L
5388 default:
5389 abort ();
5390 }
5391
5392 return "";
5393}
a269a03c
JC
5394
5395int
5396x86_adjust_cost (insn, link, dep_insn, cost)
5397 rtx insn, link, dep_insn;
5398 int cost;
5399{
5400 rtx next_inst;
5401
5402 if (GET_CODE (dep_insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN)
5403 return 0;
5404
5405 if (GET_CODE (dep_insn) == INSN
5406 && GET_CODE (PATTERN (dep_insn)) == SET
5407 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG
5408 && GET_CODE (insn) == INSN
5409 && GET_CODE (PATTERN (insn)) == SET
5410 && !reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)),
5411 SET_SRC (PATTERN (insn))))
5412 return 0; /* ??? */
5413
5414
5415 switch (ix86_cpu)
5416 {
5417 case PROCESSOR_PENTIUM:
5418 if (cost != 0 && is_fp_insn (insn) && is_fp_insn (dep_insn)
5419 && !is_fp_dest (dep_insn))
5420 return 0;
5421
5422 if (agi_dependent (insn, dep_insn))
42ebbb0a 5423 return cost ? cost + 1 : 2;
a269a03c
JC
5424
5425 if (GET_CODE (insn) == INSN
5426 && GET_CODE (PATTERN (insn)) == SET
5427 && SET_DEST (PATTERN (insn)) == cc0_rtx
5428 && (next_inst = next_nonnote_insn (insn))
5429 && GET_CODE (next_inst) == JUMP_INSN)
5430 /* compare probably paired with jump */
5431 return 0;
a269a03c 5432
42ebbb0a
JH
5433 /* Stores stalls one cycle longer than other insns. */
5434 if (is_fp_insn (insn) && cost && is_fp_store (dep_insn))
6ec6d558 5435 cost++;
a14003ee 5436 break;
a269a03c
JC
5437 case PROCESSOR_K6:
5438 default:
5439 if (!is_fp_dest (dep_insn))
5440 {
5441 if(!agi_dependent (insn, dep_insn))
5442 return 0;
5443 if (TARGET_486)
5444 return 2;
5445 }
5446 else
5447 if (is_fp_store (insn) && is_fp_insn (dep_insn)
5448 && NEXT_INSN (insn) && NEXT_INSN (NEXT_INSN (insn))
5449 && NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))
5450 && (GET_CODE (NEXT_INSN (insn)) == INSN)
5451 && (GET_CODE (NEXT_INSN (NEXT_INSN (insn))) == JUMP_INSN)
5452 && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) == NOTE)
5453 && (NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn))))
5454 == NOTE_INSN_LOOP_END))
5455 return 3;
5456 break;
5457 }
5458
5459 return cost;
5460}
0a726ef1
JL
5461
5462/* Output assembly code for a left shift.
5463
5464 Always use "sal" when shifting a memory operand or for a non constant
5465 shift count.
5466
5467 When optimizing for size, we know that src == dest, and we should always
5468 use "sal". If src != dest, then copy src to dest and use "sal".
5469
5470 Pentium and PPro (speed):
5471
5472 When src == dest, use "add" for a shift counts of one, else use
5473 "sal". If we modeled Pentium AGI stalls and U/V pipelining better we
5474 would want to generate lea for some shifts on the Pentium.
5475
5476 When src != dest, use "lea" for small shift counts. Otherwise,
5477 copy src to dest and use the normal shifting code. Exception for
5478 TARGET_DOUBLE_WITH_ADD. */
5479
5480char *
6ec6d558
JH
5481output_ashl (insn, operands)
5482 rtx insn, *operands;
0a726ef1
JL
5483{
5484 /* Handle case where srcreg != dstreg. */
5485 if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
5486 {
5487 if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1)
6ec6d558
JH
5488 switch (GET_MODE (operands[0]))
5489 {
5490 case SImode:
5491 output_asm_insn (AS2 (mov%L0,%1,%0), operands);
5492 return AS2 (add%L0,%1,%0);
5493 case HImode:
5494 output_asm_insn (AS2 (mov%L0,%k1,%k0), operands);
5495 if (i386_cc_probably_useless_p (insn))
5496 {
5497 CC_STATUS_INIT;
5498 return AS2 (add%L0,%k1,%k0);
5499 }
5500 return AS2 (add%W0,%k1,%k0);
5501 case QImode:
5502 output_asm_insn (AS2 (mov%B0,%1,%0), operands);
5503 return AS2 (add%B0,%1,%0);
5504 default:
5505 abort ();
5506 }
0a726ef1 5507 else
6ec6d558
JH
5508 {
5509 CC_STATUS_INIT;
0a726ef1
JL
5510
5511 /* This should be extremely rare (impossible?). We can not encode a
5512 shift of the stack pointer using an lea instruction. So copy the
5513 stack pointer into the destination register and use an lea. */
5514 if (operands[1] == stack_pointer_rtx)
5515 {
6ec6d558 5516 output_asm_insn (AS2 (mov%L0,%k1,%k0), operands);
0a726ef1
JL
5517 operands[1] = operands[0];
5518 }
5519
5520 /* For shifts up to and including 3 bits, use lea. */
6ec6d558
JH
5521 operands[1] = gen_rtx_MULT (SImode,
5522 gen_rtx_REG (SImode, REGNO (operands[1])),
0a726ef1 5523 GEN_INT (1 << INTVAL (operands[2])));
6ec6d558 5524 return AS2 (lea%L0,%a1,%k0);
0a726ef1
JL
5525 }
5526 }
5527
5528 /* Source and destination match. */
5529
5530 /* Handle variable shift. */
5531 if (REG_P (operands[2]))
6ec6d558
JH
5532 switch (GET_MODE (operands[0]))
5533 {
5534 case SImode:
5535 return AS2 (sal%L0,%b2,%0);
5536 case HImode:
5537 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
5538 {
5539 CC_STATUS_INIT;
5540 return AS2 (sal%L0,%b2,%k0);
5541 }
5542 else
5543 return AS2 (sal%W0,%b2,%0);
5544 case QImode:
5545 return AS2 (sal%B0,%b2,%0);
5546 default:
5547 abort ();
5548 }
0a726ef1
JL
5549
5550 /* Always perform shift by 1 using an add instruction. */
5551 if (REG_P (operands[0]) && operands[2] == const1_rtx)
6ec6d558
JH
5552 switch (GET_MODE (operands[0]))
5553 {
5554 case SImode:
5555 return AS2 (add%L0,%0,%0);
5556 case HImode:
5557 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
5558 {
5559 CC_STATUS_INIT;
5560 return AS2 (add%L0,%k0,%k0);
5561 }
5562 else
5563 return AS2 (add%W0,%0,%0);
5564 case QImode:
5565 return AS2 (add%B0,%0,%0);
5566 default:
5567 abort ();
5568 }
0a726ef1
JL
5569
5570#if 0
6ec6d558
JH
5571 /* ??? Currently disabled. Because our model of Pentium is far from being
5572 exact, this change will need some benchmarking. */
0a726ef1
JL
5573 /* Shift reg by 2 or 3 use an lea instruction for Pentium if this is
5574 insn is expected to issue into the V pipe (the insn's mode will be
5575 TImode for a U pipe, and !TImode for a V pipe instruction). */
5576 if (! optimize_size
5577 && REG_P (operands[0])
5578 && GET_CODE (operands[2]) == CONST_INT
5579 && INTVAL (operands[2]) <= 3
5580 && (int)ix86_cpu == (int)PROCESSOR_PENTIUM
5581 && GET_MODE (insn) != TImode)
5582 {
5583 CC_STATUS_INIT;
6ec6d558 5584 operands[1] = gen_rtx_MULT (SImode, gen_rtx_REG (SImode, REGNO (operands[1])),
0a726ef1
JL
5585 GEN_INT (1 << INTVAL (operands[2])));
5586 return AS2 (lea%L0,%a1,%0);
5587 }
5588#endif
5589
5590 /* Otherwise use a shift instruction. */
6ec6d558
JH
5591 switch (GET_MODE (operands[0]))
5592 {
5593 case SImode:
5594 return AS2 (sal%L0,%2,%0);
5595 case HImode:
5596 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn))
5597 {
5598 CC_STATUS_INIT;
5599 return AS2 (sal%L0,%2,%k0);
5600 }
5601 else
5602 return AS2 (sal%W0,%2,%0);
5603 case QImode:
5604 return AS2 (sal%B0,%2,%0);
5605 default:
5606 abort ();
5607 }
0a726ef1 5608}
fb693d44 5609
b222082e
JH
5610/* Given the memory address ADDR, calculate the length of the address or
5611 the length of just the displacement (controlled by DISP_LENGTH).
5612
5613 The length returned does not include the one-byte modrm, opcode,
5614 or prefix. */
fb693d44
RH
5615
5616int
b222082e 5617memory_address_info (addr, disp_length)
fb693d44 5618 rtx addr;
b222082e 5619 int disp_length;
fb693d44
RH
5620{
5621 rtx base, index, disp, scale;
5622 rtx op0, op1;
5623 int len;
5624
5625 if (GET_CODE (addr) == PRE_DEC
5626 || GET_CODE (addr) == POST_INC)
5627 return 0;
5628
5629 /* Register Indirect. */
5630 if (register_operand (addr, Pmode))
5631 {
5632 /* Special cases: ebp and esp need the two-byte modrm form.
5633
5634 We change [ESI] to [ESI+0] on the K6 when not optimizing
5635 for size. */
5636 if (addr == stack_pointer_rtx
5637 || addr == arg_pointer_rtx
5638 || addr == frame_pointer_rtx
5639 || (REGNO_REG_CLASS (REGNO (addr)) == SIREG
d2328603 5640 && ix86_cpu == PROCESSOR_K6 && !optimize_size))
fb693d44
RH
5641 return 1;
5642 else
5643 return 0;
5644 }
5645
5646 /* Direct Addressing. */
5647 if (CONSTANT_P (addr))
5648 return 4;
5649
5650 index = base = disp = scale = NULL_RTX;
5651 op0 = XEXP (addr, 0);
5652 op1 = XEXP (addr, 1);
5653
5654 if (GET_CODE (addr) == PLUS)
5655 {
5656 if (register_operand (op0, Pmode))
5657 {
5658 if (register_operand (op1, Pmode))
5659 index = op0, base = op1;
5660 else
5661 base = op0, disp = op1;
5662 }
5663 else if (GET_CODE (op0) == MULT)
5664 {
5665 index = XEXP (op0, 0);
5666 scale = XEXP (op0, 1);
5667 if (register_operand (op1, Pmode))
5668 base = op1;
5669 else
5670 disp = op1;
5671 }
5672 else if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
5673 {
5674 index = XEXP (XEXP (op0, 0), 0);
5675 scale = XEXP (XEXP (op0, 0), 1);
5676 base = XEXP (op0, 1);
5677 disp = op1;
5678 }
5679 else if (GET_CODE (op0) == PLUS)
5680 {
5681 index = XEXP (op0, 0);
5682 base = XEXP (op0, 1);
5683 disp = op1;
5684 }
5685 else
5686 abort ();
5687 }
5688 else if (GET_CODE (addr) == MULT
5689 /* We're called for lea too, which implements ashift on occasion. */
5690 || GET_CODE (addr) == ASHIFT)
5691 {
5692 index = XEXP (addr, 0);
5693 scale = XEXP (addr, 1);
5694 }
5695 else
5696 abort ();
5697
5698 /* Allow arg pointer and stack pointer as index if there is not scaling */
5699 if (base && index && !scale
5700 && (index == stack_pointer_rtx
5701 || index == arg_pointer_rtx
5702 || index == frame_pointer_rtx))
5703 {
5704 rtx tmp = base;
5705 base = index;
5706 index = tmp;
5707 }
5708
5709 /* Special case: ebp cannot be encoded as a base without a displacement. */
5710 if (base == frame_pointer_rtx && !disp)
5711 disp = const0_rtx;
5712
b222082e
JH
5713 /* Scaling can not be encoded without base or displacement.
5714 Except for scale == 1 where we can encode reg + reg instead of reg * 2. */
35f43fd1
GS
5715 if (!base && index
5716 && (!scale || GET_CODE (scale) != CONST_INT || (INTVAL (scale) != 1)))
b222082e
JH
5717 disp = const0_rtx;
5718
fb693d44
RH
5719 /* Find the length of the displacement constant. */
5720 len = 0;
5721 if (disp)
5722 {
5723 if (GET_CODE (disp) == CONST_INT
5724 && CONST_OK_FOR_LETTER_P (INTVAL (disp), 'K'))
5725 len = 1;
5726 else
5727 len = 4;
5728 }
5729
b222082e
JH
5730 /* An index requires the two-byte modrm form. Not important
5731 if we are computing just length of the displacement. */
5732 if (index && ! disp_length)
fb693d44
RH
5733 len += 1;
5734
5735 return len;
5736}
This page took 1.272448 seconds and 5 git commands to generate.