]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.c
ppc-asm.h (FUNC_START): Use USER_LABEL_PREFIX.
[gcc.git] / gcc / config / i386 / i386.c
CommitLineData
e075ae69 1/* Subroutines used for code generation on IA-32.
0ef2e39a 2 Copyright (C) 1988, 92, 94-99, 2000 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 24#include "rtl.h"
6baf1cc8
BS
25#include "tree.h"
26#include "tm_p.h"
2a2ab3f9
JVA
27#include "regs.h"
28#include "hard-reg-set.h"
29#include "real.h"
30#include "insn-config.h"
31#include "conditions.h"
32#include "insn-flags.h"
33#include "output.h"
34#include "insn-attr.h"
2a2ab3f9 35#include "flags.h"
a8ffcc81 36#include "except.h"
ecbc4695 37#include "function.h"
00c79232 38#include "recog.h"
ced8dd8c 39#include "expr.h"
f103890b 40#include "toplev.h"
e075ae69 41#include "basic-block.h"
1526a060 42#include "ggc.h"
2a2ab3f9 43
997de79c
JVA
44#ifdef EXTRA_CONSTRAINT
45/* If EXTRA_CONSTRAINT is defined, then the 'S'
46 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
47 asm statements that need 'S' for class SIREG will break. */
ad5a6adc
RS
48 error EXTRA_CONSTRAINT conflicts with S constraint letter
49/* The previous line used to be #error, but some compilers barf
50 even if the conditional was untrue. */
997de79c
JVA
51#endif
52
8dfe5673
RK
53#ifndef CHECK_STACK_LIMIT
54#define CHECK_STACK_LIMIT -1
55#endif
56
32b5b1aa
SC
57/* Processor costs (relative to an add) */
58struct processor_costs i386_cost = { /* 386 specific costs */
e9a25f70 59 1, /* cost of an add instruction */
32b5b1aa
SC
60 1, /* cost of a lea instruction */
61 3, /* variable shift costs */
62 2, /* constant shift costs */
63 6, /* cost of starting a multiply */
64 1, /* cost of multiply per each bit set */
e075ae69 65 23, /* cost of a divide/mod */
96e7ae40 66 15, /* "large" insn */
e2e52e1b 67 3, /* MOVE_RATIO */
7c6b971d 68 4, /* cost for loading QImode using movzbl */
96e7ae40
JH
69 {2, 4, 2}, /* cost of loading integer registers
70 in QImode, HImode and SImode.
71 Relative to reg-reg move (2). */
72 {2, 4, 2}, /* cost of storing integer registers */
73 2, /* cost of reg,reg fld/fst */
74 {8, 8, 8}, /* cost of loading fp registers
75 in SFmode, DFmode and XFmode */
76 {8, 8, 8} /* cost of loading integer registers */
32b5b1aa
SC
77};
78
79struct processor_costs i486_cost = { /* 486 specific costs */
80 1, /* cost of an add instruction */
81 1, /* cost of a lea instruction */
82 3, /* variable shift costs */
83 2, /* constant shift costs */
84 12, /* cost of starting a multiply */
85 1, /* cost of multiply per each bit set */
e075ae69 86 40, /* cost of a divide/mod */
96e7ae40 87 15, /* "large" insn */
e2e52e1b 88 3, /* MOVE_RATIO */
7c6b971d 89 4, /* cost for loading QImode using movzbl */
96e7ae40
JH
90 {2, 4, 2}, /* cost of loading integer registers
91 in QImode, HImode and SImode.
92 Relative to reg-reg move (2). */
93 {2, 4, 2}, /* cost of storing integer registers */
94 2, /* cost of reg,reg fld/fst */
95 {8, 8, 8}, /* cost of loading fp registers
96 in SFmode, DFmode and XFmode */
97 {8, 8, 8} /* cost of loading integer registers */
32b5b1aa
SC
98};
99
e5cb57e8 100struct processor_costs pentium_cost = {
32b5b1aa
SC
101 1, /* cost of an add instruction */
102 1, /* cost of a lea instruction */
856b07a1 103 4, /* variable shift costs */
e5cb57e8 104 1, /* constant shift costs */
856b07a1
SC
105 11, /* cost of starting a multiply */
106 0, /* cost of multiply per each bit set */
e075ae69 107 25, /* cost of a divide/mod */
96e7ae40 108 8, /* "large" insn */
e2e52e1b 109 6, /* MOVE_RATIO */
7c6b971d 110 6, /* cost for loading QImode using movzbl */
96e7ae40
JH
111 {2, 4, 2}, /* cost of loading integer registers
112 in QImode, HImode and SImode.
113 Relative to reg-reg move (2). */
114 {2, 4, 2}, /* cost of storing integer registers */
115 2, /* cost of reg,reg fld/fst */
116 {2, 2, 6}, /* cost of loading fp registers
117 in SFmode, DFmode and XFmode */
118 {4, 4, 6} /* cost of loading integer registers */
32b5b1aa
SC
119};
120
856b07a1
SC
121struct processor_costs pentiumpro_cost = {
122 1, /* cost of an add instruction */
123 1, /* cost of a lea instruction */
e075ae69 124 1, /* variable shift costs */
856b07a1 125 1, /* constant shift costs */
e075ae69 126 1, /* cost of starting a multiply */
856b07a1 127 0, /* cost of multiply per each bit set */
e075ae69 128 17, /* cost of a divide/mod */
96e7ae40 129 8, /* "large" insn */
e2e52e1b 130 6, /* MOVE_RATIO */
7c6b971d 131 2, /* cost for loading QImode using movzbl */
96e7ae40
JH
132 {4, 4, 4}, /* cost of loading integer registers
133 in QImode, HImode and SImode.
134 Relative to reg-reg move (2). */
135 {2, 2, 2}, /* cost of storing integer registers */
136 2, /* cost of reg,reg fld/fst */
137 {2, 2, 6}, /* cost of loading fp registers
138 in SFmode, DFmode and XFmode */
139 {4, 4, 6} /* cost of loading integer registers */
856b07a1
SC
140};
141
a269a03c
JC
142struct processor_costs k6_cost = {
143 1, /* cost of an add instruction */
e075ae69 144 2, /* cost of a lea instruction */
a269a03c
JC
145 1, /* variable shift costs */
146 1, /* constant shift costs */
73fe76e4 147 3, /* cost of starting a multiply */
a269a03c 148 0, /* cost of multiply per each bit set */
e075ae69 149 18, /* cost of a divide/mod */
96e7ae40 150 8, /* "large" insn */
e2e52e1b 151 4, /* MOVE_RATIO */
7c6b971d 152 3, /* cost for loading QImode using movzbl */
96e7ae40
JH
153 {4, 5, 4}, /* cost of loading integer registers
154 in QImode, HImode and SImode.
155 Relative to reg-reg move (2). */
156 {2, 3, 2}, /* cost of storing integer registers */
157 4, /* cost of reg,reg fld/fst */
158 {6, 6, 6}, /* cost of loading fp registers
159 in SFmode, DFmode and XFmode */
160 {4, 4, 4} /* cost of loading integer registers */
a269a03c
JC
161};
162
309ada50
JH
163struct processor_costs athlon_cost = {
164 1, /* cost of an add instruction */
165 1, /* cost of a lea instruction */
166 1, /* variable shift costs */
167 1, /* constant shift costs */
168 5, /* cost of starting a multiply */
169 0, /* cost of multiply per each bit set */
170 19, /* cost of a divide/mod */
171 8, /* "large" insn */
e2e52e1b 172 9, /* MOVE_RATIO */
309ada50
JH
173 4, /* cost for loading QImode using movzbl */
174 {4, 5, 4}, /* cost of loading integer registers
175 in QImode, HImode and SImode.
176 Relative to reg-reg move (2). */
177 {2, 3, 2}, /* cost of storing integer registers */
178 4, /* cost of reg,reg fld/fst */
179 {6, 6, 6}, /* cost of loading fp registers
180 in SFmode, DFmode and XFmode */
181 {4, 4, 4} /* cost of loading integer registers */
182};
183
32b5b1aa
SC
184struct processor_costs *ix86_cost = &pentium_cost;
185
a269a03c
JC
186/* Processor feature/optimization bitmasks. */
187#define m_386 (1<<PROCESSOR_I386)
188#define m_486 (1<<PROCESSOR_I486)
189#define m_PENT (1<<PROCESSOR_PENTIUM)
190#define m_PPRO (1<<PROCESSOR_PENTIUMPRO)
191#define m_K6 (1<<PROCESSOR_K6)
309ada50 192#define m_ATHLON (1<<PROCESSOR_ATHLON)
a269a03c 193
309ada50
JH
194const int x86_use_leave = m_386 | m_K6 | m_ATHLON;
195const int x86_push_memory = m_386 | m_K6 | m_ATHLON;
a269a03c 196const int x86_zero_extend_with_and = m_486 | m_PENT;
309ada50 197const int x86_movx = m_ATHLON /* m_386 | m_PPRO | m_K6 */;
e075ae69 198const int x86_double_with_add = ~m_386;
a269a03c 199const int x86_use_bit_test = m_386;
e2e52e1b 200const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON | m_K6;
a269a03c
JC
201const int x86_use_q_reg = m_PENT | m_PPRO | m_K6;
202const int x86_use_any_reg = m_486;
309ada50
JH
203const int x86_cmove = m_PPRO | m_ATHLON;
204const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON;
205const int x86_use_sahf = m_PPRO | m_K6 | m_ATHLON;
e075ae69
RH
206const int x86_partial_reg_stall = m_PPRO;
207const int x86_use_loop = m_K6;
309ada50 208const int x86_use_fiop = ~(m_PPRO | m_ATHLON | m_PENT);
e075ae69
RH
209const int x86_use_mov0 = m_K6;
210const int x86_use_cltd = ~(m_PENT | m_K6);
211const int x86_read_modify_write = ~m_PENT;
212const int x86_read_modify = ~(m_PENT | m_PPRO);
213const int x86_split_long_moves = m_PPRO;
e9e80858 214const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486;
f90800f8 215const int x86_single_stringop = m_386;
a269a03c 216
564d80f4 217#define AT_BP(mode) (gen_rtx_MEM ((mode), hard_frame_pointer_rtx))
2a2ab3f9 218
e075ae69
RH
219const char * const hi_reg_name[] = HI_REGISTER_NAMES;
220const char * const qi_reg_name[] = QI_REGISTER_NAMES;
221const char * const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
4c0d89b5
RS
222
223/* Array of the smallest class containing reg number REGNO, indexed by
224 REGNO. Used by REGNO_REG_CLASS in i386.h. */
225
e075ae69 226enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
4c0d89b5
RS
227{
228 /* ax, dx, cx, bx */
ab408a86 229 AREG, DREG, CREG, BREG,
4c0d89b5 230 /* si, di, bp, sp */
e075ae69 231 SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
4c0d89b5
RS
232 /* FP registers */
233 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
79325812 234 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
4c0d89b5 235 /* arg pointer */
83774849 236 NON_Q_REGS,
564d80f4
JH
237 /* flags, fpsr, dirflag, frame */
238 NO_REGS, NO_REGS, NO_REGS, NON_Q_REGS
4c0d89b5 239};
c572e5ba 240
83774849
RH
241/* The "default" register map. */
242
243int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
244{
245 0, 2, 1, 3, 6, 7, 4, 5, /* general regs */
246 12, 13, 14, 15, 16, 17, 18, 19, /* fp regs */
247 -1, -1, -1, -1, /* arg, flags, fpsr, dir */
248};
249
250/* Define the register numbers to be used in Dwarf debugging information.
251 The SVR4 reference port C compiler uses the following register numbers
252 in its Dwarf output code:
253 0 for %eax (gcc regno = 0)
254 1 for %ecx (gcc regno = 2)
255 2 for %edx (gcc regno = 1)
256 3 for %ebx (gcc regno = 3)
257 4 for %esp (gcc regno = 7)
258 5 for %ebp (gcc regno = 6)
259 6 for %esi (gcc regno = 4)
260 7 for %edi (gcc regno = 5)
261 The following three DWARF register numbers are never generated by
262 the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
263 believes these numbers have these meanings.
264 8 for %eip (no gcc equivalent)
265 9 for %eflags (gcc regno = 17)
266 10 for %trapno (no gcc equivalent)
267 It is not at all clear how we should number the FP stack registers
268 for the x86 architecture. If the version of SDB on x86/svr4 were
269 a bit less brain dead with respect to floating-point then we would
270 have a precedent to follow with respect to DWARF register numbers
271 for x86 FP registers, but the SDB on x86/svr4 is so completely
272 broken with respect to FP registers that it is hardly worth thinking
273 of it as something to strive for compatibility with.
274 The version of x86/svr4 SDB I have at the moment does (partially)
275 seem to believe that DWARF register number 11 is associated with
276 the x86 register %st(0), but that's about all. Higher DWARF
277 register numbers don't seem to be associated with anything in
278 particular, and even for DWARF regno 11, SDB only seems to under-
279 stand that it should say that a variable lives in %st(0) (when
280 asked via an `=' command) if we said it was in DWARF regno 11,
281 but SDB still prints garbage when asked for the value of the
282 variable in question (via a `/' command).
283 (Also note that the labels SDB prints for various FP stack regs
284 when doing an `x' command are all wrong.)
285 Note that these problems generally don't affect the native SVR4
286 C compiler because it doesn't allow the use of -O with -g and
287 because when it is *not* optimizing, it allocates a memory
288 location for each floating-point variable, and the memory
289 location is what gets described in the DWARF AT_location
290 attribute for the variable in question.
291 Regardless of the severe mental illness of the x86/svr4 SDB, we
292 do something sensible here and we use the following DWARF
293 register numbers. Note that these are all stack-top-relative
294 numbers.
295 11 for %st(0) (gcc regno = 8)
296 12 for %st(1) (gcc regno = 9)
297 13 for %st(2) (gcc regno = 10)
298 14 for %st(3) (gcc regno = 11)
299 15 for %st(4) (gcc regno = 12)
300 16 for %st(5) (gcc regno = 13)
301 17 for %st(6) (gcc regno = 14)
302 18 for %st(7) (gcc regno = 15)
303*/
304int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
305{
306 0, 2, 1, 3, 6, 7, 5, 4, /* general regs */
307 11, 12, 13, 14, 15, 16, 17, 18, /* fp regs */
308 -1, 9, -1, -1, /* arg, flags, fpsr, dir */
309};
310
311
312
c572e5ba
JVA
313/* Test and compare insns in i386.md store the information needed to
314 generate branch and scc insns here. */
315
e075ae69
RH
316struct rtx_def *ix86_compare_op0 = NULL_RTX;
317struct rtx_def *ix86_compare_op1 = NULL_RTX;
f5316dfe 318
36edd3cc
BS
319#define MAX_386_STACK_LOCALS 2
320
321/* Define the structure for the machine field in struct function. */
322struct machine_function
323{
324 rtx stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
325};
326
01d939e8 327#define ix86_stack_locals (cfun->machine->stack_locals)
36edd3cc 328
c8c5cb99 329/* which cpu are we scheduling for */
e42ea7f9 330enum processor_type ix86_cpu;
c8c5cb99
SC
331
332/* which instruction set architecture to use. */
c942177e 333int ix86_arch;
c8c5cb99
SC
334
335/* Strings to hold which cpu and instruction set architecture to use. */
9c23aa47
ZW
336const char *ix86_cpu_string; /* for -mcpu=<xxx> */
337const char *ix86_arch_string; /* for -march=<xxx> */
c8c5cb99 338
f5316dfe 339/* Register allocation order */
e075ae69 340const char *ix86_reg_alloc_order;
f5316dfe
MM
341static char regs_allocated[FIRST_PSEUDO_REGISTER];
342
b08de47e 343/* # of registers to use to pass arguments. */
e075ae69 344const char *ix86_regparm_string;
e9a25f70 345
e075ae69
RH
346/* ix86_regparm_string as a number */
347int ix86_regparm;
e9a25f70
JL
348
349/* Alignment to use for loops and jumps: */
350
351/* Power of two alignment for loops. */
e075ae69 352const char *ix86_align_loops_string;
e9a25f70
JL
353
354/* Power of two alignment for non-loop jumps. */
e075ae69 355const char *ix86_align_jumps_string;
e9a25f70 356
3af4bd89 357/* Power of two alignment for stack boundary in bytes. */
e075ae69 358const char *ix86_preferred_stack_boundary_string;
3af4bd89
JH
359
360/* Preferred alignment for stack boundary in bits. */
e075ae69 361int ix86_preferred_stack_boundary;
3af4bd89 362
e9a25f70 363/* Values 1-5: see jump.c */
e075ae69
RH
364int ix86_branch_cost;
365const char *ix86_branch_cost_string;
e9a25f70
JL
366
367/* Power of two alignment for functions. */
e075ae69
RH
368int ix86_align_funcs;
369const char *ix86_align_funcs_string;
b08de47e 370
e9a25f70 371/* Power of two alignment for loops. */
e075ae69 372int ix86_align_loops;
b08de47e 373
e9a25f70 374/* Power of two alignment for non-loop jumps. */
e075ae69
RH
375int ix86_align_jumps;
376\f
f6da8bc3
KG
377static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
378static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
e075ae69 379 int, int, FILE *));
f6da8bc3
KG
380static enum rtx_code unsigned_comparison PARAMS ((enum rtx_code code));
381static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
382static rtx ix86_expand_fp_compare PARAMS ((enum rtx_code, rtx, rtx, int));
383static rtx ix86_expand_compare PARAMS ((enum rtx_code, int));
384static rtx gen_push PARAMS ((rtx));
385static int memory_address_length PARAMS ((rtx addr));
386static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type));
387static int ix86_agi_dependant PARAMS ((rtx, rtx, enum attr_type));
388static int ix86_safe_length PARAMS ((rtx));
389static enum attr_memory ix86_safe_memory PARAMS ((rtx));
390static enum attr_pent_pair ix86_safe_pent_pair PARAMS ((rtx));
391static enum attr_ppro_uops ix86_safe_ppro_uops PARAMS ((rtx));
392static void ix86_dump_ppro_packet PARAMS ((FILE *));
393static void ix86_reorder_insn PARAMS ((rtx *, rtx *));
394static rtx * ix86_pent_find_pair PARAMS ((rtx *, rtx *, enum attr_pent_pair,
e075ae69 395 rtx));
f6da8bc3
KG
396static void ix86_init_machine_status PARAMS ((struct function *));
397static void ix86_mark_machine_status PARAMS ((struct function *));
398static void ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode));
399static int ix86_safe_length_prefix PARAMS ((rtx));
564d80f4
JH
400static HOST_WIDE_INT ix86_compute_frame_size PARAMS((HOST_WIDE_INT,
401 int *, int *, int *));
0903fcab
JH
402static int ix86_nsaved_regs PARAMS((void));
403static void ix86_emit_save_regs PARAMS((void));
0903fcab 404static void ix86_emit_epilogue_esp_adjustment PARAMS((int));
e075ae69
RH
405
406struct ix86_address
407{
408 rtx base, index, disp;
409 HOST_WIDE_INT scale;
410};
b08de47e 411
e075ae69
RH
412static int ix86_decompose_address PARAMS ((rtx, struct ix86_address *));
413\f
f5316dfe
MM
414/* Sometimes certain combinations of command options do not make
415 sense on a particular target machine. You can define a macro
416 `OVERRIDE_OPTIONS' to take account of this. This macro, if
417 defined, is executed once just after all the command options have
418 been parsed.
419
420 Don't use this macro to turn on various extra optimizations for
421 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
422
423void
424override_options ()
425{
e075ae69
RH
426 /* Comes from final.c -- no real reason to change it. */
427#define MAX_CODE_ALIGN 16
f5316dfe 428
c8c5cb99
SC
429 static struct ptt
430 {
e075ae69
RH
431 struct processor_costs *cost; /* Processor costs */
432 int target_enable; /* Target flags to enable. */
433 int target_disable; /* Target flags to disable. */
434 int align_loop; /* Default alignments. */
435 int align_jump;
436 int align_func;
437 int branch_cost;
438 }
439 const processor_target_table[PROCESSOR_max] =
440 {
441 {&i386_cost, 0, 0, 2, 2, 2, 1},
442 {&i486_cost, 0, 0, 4, 4, 4, 1},
443 {&pentium_cost, 0, 0, -4, -4, -4, 1},
444 {&pentiumpro_cost, 0, 0, 4, -4, 4, 1},
309ada50
JH
445 {&k6_cost, 0, 0, -5, -5, 4, 1},
446 {&athlon_cost, 0, 0, 4, -4, 4, 1}
e075ae69
RH
447 };
448
449 static struct pta
450 {
69ddee61 451 const char *name; /* processor name or nickname. */
e075ae69
RH
452 enum processor_type processor;
453 }
454 const processor_alias_table[] =
455 {
456 {"i386", PROCESSOR_I386},
457 {"i486", PROCESSOR_I486},
458 {"i586", PROCESSOR_PENTIUM},
459 {"pentium", PROCESSOR_PENTIUM},
460 {"i686", PROCESSOR_PENTIUMPRO},
461 {"pentiumpro", PROCESSOR_PENTIUMPRO},
e075ae69 462 {"k6", PROCESSOR_K6},
309ada50 463 {"athlon", PROCESSOR_ATHLON},
3af4bd89 464 };
c8c5cb99 465
e075ae69 466 int const pta_size = sizeof(processor_alias_table)/sizeof(struct pta);
c8c5cb99 467
f5316dfe
MM
468#ifdef SUBTARGET_OVERRIDE_OPTIONS
469 SUBTARGET_OVERRIDE_OPTIONS;
470#endif
471
5a6ee819 472 ix86_arch = PROCESSOR_I386;
e075ae69
RH
473 ix86_cpu = (enum processor_type) TARGET_CPU_DEFAULT;
474
475 if (ix86_arch_string != 0)
476 {
477 int i;
478 for (i = 0; i < pta_size; i++)
479 if (! strcmp (ix86_arch_string, processor_alias_table[i].name))
480 {
481 ix86_arch = processor_alias_table[i].processor;
482 /* Default cpu tuning to the architecture. */
483 ix86_cpu = ix86_arch;
484 break;
485 }
486 if (i == pta_size)
487 error ("bad value (%s) for -march= switch", ix86_arch_string);
488 }
489
490 if (ix86_cpu_string != 0)
491 {
492 int i;
493 for (i = 0; i < pta_size; i++)
494 if (! strcmp (ix86_cpu_string, processor_alias_table[i].name))
495 {
496 ix86_cpu = processor_alias_table[i].processor;
497 break;
498 }
499 if (i == pta_size)
500 error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
501 }
502
503 ix86_cost = processor_target_table[ix86_cpu].cost;
504 target_flags |= processor_target_table[ix86_cpu].target_enable;
505 target_flags &= ~processor_target_table[ix86_cpu].target_disable;
506
36edd3cc
BS
507 /* Arrange to set up i386_stack_locals for all functions. */
508 init_machine_status = ix86_init_machine_status;
1526a060 509 mark_machine_status = ix86_mark_machine_status;
36edd3cc 510
e9a25f70 511 /* Validate registers in register allocation order. */
e075ae69 512 if (ix86_reg_alloc_order)
f5316dfe 513 {
e075ae69
RH
514 int i, ch;
515 for (i = 0; (ch = ix86_reg_alloc_order[i]) != '\0'; i++)
f5316dfe 516 {
00c79232 517 int regno = 0;
79325812 518
f5316dfe
MM
519 switch (ch)
520 {
521 case 'a': regno = 0; break;
522 case 'd': regno = 1; break;
523 case 'c': regno = 2; break;
524 case 'b': regno = 3; break;
525 case 'S': regno = 4; break;
526 case 'D': regno = 5; break;
527 case 'B': regno = 6; break;
528
529 default: fatal ("Register '%c' is unknown", ch);
530 }
531
532 if (regs_allocated[regno])
e9a25f70 533 fatal ("Register '%c' already specified in allocation order", ch);
f5316dfe
MM
534
535 regs_allocated[regno] = 1;
536 }
537 }
b08de47e 538
e9a25f70 539 /* Validate -mregparm= value. */
e075ae69 540 if (ix86_regparm_string)
b08de47e 541 {
e075ae69
RH
542 ix86_regparm = atoi (ix86_regparm_string);
543 if (ix86_regparm < 0 || ix86_regparm > REGPARM_MAX)
e9a25f70 544 fatal ("-mregparm=%d is not between 0 and %d",
e075ae69 545 ix86_regparm, REGPARM_MAX);
b08de47e
MM
546 }
547
e9a25f70 548 /* Validate -malign-loops= value, or provide default. */
e075ae69
RH
549 ix86_align_loops = processor_target_table[ix86_cpu].align_loop;
550 if (ix86_align_loops_string)
b08de47e 551 {
e075ae69
RH
552 ix86_align_loops = atoi (ix86_align_loops_string);
553 if (ix86_align_loops < 0 || ix86_align_loops > MAX_CODE_ALIGN)
b08de47e 554 fatal ("-malign-loops=%d is not between 0 and %d",
e075ae69 555 ix86_align_loops, MAX_CODE_ALIGN);
b08de47e 556 }
3af4bd89
JH
557
558 /* Validate -malign-jumps= value, or provide default. */
e075ae69
RH
559 ix86_align_jumps = processor_target_table[ix86_cpu].align_jump;
560 if (ix86_align_jumps_string)
b08de47e 561 {
e075ae69
RH
562 ix86_align_jumps = atoi (ix86_align_jumps_string);
563 if (ix86_align_jumps < 0 || ix86_align_jumps > MAX_CODE_ALIGN)
b08de47e 564 fatal ("-malign-jumps=%d is not between 0 and %d",
e075ae69 565 ix86_align_jumps, MAX_CODE_ALIGN);
b08de47e 566 }
b08de47e 567
e9a25f70 568 /* Validate -malign-functions= value, or provide default. */
e075ae69
RH
569 ix86_align_funcs = processor_target_table[ix86_cpu].align_func;
570 if (ix86_align_funcs_string)
b08de47e 571 {
e075ae69
RH
572 ix86_align_funcs = atoi (ix86_align_funcs_string);
573 if (ix86_align_funcs < 0 || ix86_align_funcs > MAX_CODE_ALIGN)
b08de47e 574 fatal ("-malign-functions=%d is not between 0 and %d",
e075ae69 575 ix86_align_funcs, MAX_CODE_ALIGN);
b08de47e 576 }
3af4bd89 577
e4c0478d 578 /* Validate -mpreferred-stack-boundary= value, or provide default.
3af4bd89 579 The default of 128 bits is for Pentium III's SSE __m128. */
e075ae69
RH
580 ix86_preferred_stack_boundary = 128;
581 if (ix86_preferred_stack_boundary_string)
3af4bd89 582 {
e075ae69 583 int i = atoi (ix86_preferred_stack_boundary_string);
3af4bd89 584 if (i < 2 || i > 31)
e4c0478d 585 fatal ("-mpreferred-stack-boundary=%d is not between 2 and 31", i);
e075ae69 586 ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
3af4bd89 587 }
77a989d1 588
e9a25f70 589 /* Validate -mbranch-cost= value, or provide default. */
e075ae69
RH
590 ix86_branch_cost = processor_target_table[ix86_cpu].branch_cost;
591 if (ix86_branch_cost_string)
804a8ee0 592 {
e075ae69
RH
593 ix86_branch_cost = atoi (ix86_branch_cost_string);
594 if (ix86_branch_cost < 0 || ix86_branch_cost > 5)
595 fatal ("-mbranch-cost=%d is not between 0 and 5",
596 ix86_branch_cost);
804a8ee0 597 }
804a8ee0 598
e9a25f70
JL
599 /* Keep nonleaf frame pointers. */
600 if (TARGET_OMIT_LEAF_FRAME_POINTER)
77a989d1 601 flag_omit_frame_pointer = 1;
e075ae69
RH
602
603 /* If we're doing fast math, we don't care about comparison order
604 wrt NaNs. This lets us use a shorter comparison sequence. */
605 if (flag_fast_math)
606 target_flags &= ~MASK_IEEE_FP;
607
608 /* If we're planning on using `loop', use it. */
609 if (TARGET_USE_LOOP && optimize)
610 flag_branch_on_count_reg = 1;
f5316dfe
MM
611}
612\f
613/* A C statement (sans semicolon) to choose the order in which to
614 allocate hard registers for pseudo-registers local to a basic
615 block.
616
617 Store the desired register order in the array `reg_alloc_order'.
618 Element 0 should be the register to allocate first; element 1, the
619 next register; and so on.
620
621 The macro body should not assume anything about the contents of
622 `reg_alloc_order' before execution of the macro.
623
624 On most machines, it is not necessary to define this macro. */
625
626void
627order_regs_for_local_alloc ()
628{
00c79232 629 int i, ch, order;
f5316dfe 630
e9a25f70
JL
631 /* User specified the register allocation order. */
632
e075ae69 633 if (ix86_reg_alloc_order)
f5316dfe 634 {
e075ae69 635 for (i = order = 0; (ch = ix86_reg_alloc_order[i]) != '\0'; i++)
f5316dfe 636 {
00c79232 637 int regno = 0;
79325812 638
f5316dfe
MM
639 switch (ch)
640 {
641 case 'a': regno = 0; break;
642 case 'd': regno = 1; break;
643 case 'c': regno = 2; break;
644 case 'b': regno = 3; break;
645 case 'S': regno = 4; break;
646 case 'D': regno = 5; break;
647 case 'B': regno = 6; break;
648 }
649
650 reg_alloc_order[order++] = regno;
651 }
652
653 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
654 {
e9a25f70 655 if (! regs_allocated[i])
f5316dfe
MM
656 reg_alloc_order[order++] = i;
657 }
658 }
659
e9a25f70 660 /* If user did not specify a register allocation order, use natural order. */
f5316dfe
MM
661 else
662 {
663 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
664 reg_alloc_order[i] = i;
f5316dfe
MM
665 }
666}
32b5b1aa
SC
667\f
668void
c6aded7c 669optimization_options (level, size)
32b5b1aa 670 int level;
bb5177ac 671 int size ATTRIBUTE_UNUSED;
32b5b1aa 672{
e9a25f70
JL
673 /* For -O2 and beyond, turn off -fschedule-insns by default. It tends to
674 make the problem with not enough registers even worse. */
32b5b1aa
SC
675#ifdef INSN_SCHEDULING
676 if (level > 1)
677 flag_schedule_insns = 0;
678#endif
679}
b08de47e
MM
680\f
681/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
682 attribute for DECL. The attributes in ATTRIBUTES have previously been
683 assigned to DECL. */
684
685int
e075ae69 686ix86_valid_decl_attribute_p (decl, attributes, identifier, args)
bb5177ac
RL
687 tree decl ATTRIBUTE_UNUSED;
688 tree attributes ATTRIBUTE_UNUSED;
689 tree identifier ATTRIBUTE_UNUSED;
690 tree args ATTRIBUTE_UNUSED;
b08de47e
MM
691{
692 return 0;
693}
694
695/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
696 attribute for TYPE. The attributes in ATTRIBUTES have previously been
697 assigned to TYPE. */
698
699int
e075ae69 700ix86_valid_type_attribute_p (type, attributes, identifier, args)
b08de47e 701 tree type;
bb5177ac 702 tree attributes ATTRIBUTE_UNUSED;
b08de47e
MM
703 tree identifier;
704 tree args;
705{
706 if (TREE_CODE (type) != FUNCTION_TYPE
ac478ac0 707 && TREE_CODE (type) != METHOD_TYPE
b08de47e
MM
708 && TREE_CODE (type) != FIELD_DECL
709 && TREE_CODE (type) != TYPE_DECL)
710 return 0;
711
712 /* Stdcall attribute says callee is responsible for popping arguments
713 if they are not variable. */
714 if (is_attribute_p ("stdcall", identifier))
715 return (args == NULL_TREE);
716
e9a25f70 717 /* Cdecl attribute says the callee is a normal C declaration. */
b08de47e
MM
718 if (is_attribute_p ("cdecl", identifier))
719 return (args == NULL_TREE);
720
721 /* Regparm attribute specifies how many integer arguments are to be
e9a25f70 722 passed in registers. */
b08de47e
MM
723 if (is_attribute_p ("regparm", identifier))
724 {
725 tree cst;
726
e9a25f70 727 if (! args || TREE_CODE (args) != TREE_LIST
b08de47e
MM
728 || TREE_CHAIN (args) != NULL_TREE
729 || TREE_VALUE (args) == NULL_TREE)
730 return 0;
731
732 cst = TREE_VALUE (args);
733 if (TREE_CODE (cst) != INTEGER_CST)
734 return 0;
735
736 if (TREE_INT_CST_HIGH (cst) != 0
737 || TREE_INT_CST_LOW (cst) < 0
738 || TREE_INT_CST_LOW (cst) > REGPARM_MAX)
739 return 0;
740
741 return 1;
742 }
743
744 return 0;
745}
746
747/* Return 0 if the attributes for two types are incompatible, 1 if they
748 are compatible, and 2 if they are nearly compatible (which causes a
749 warning to be generated). */
750
751int
e075ae69 752ix86_comp_type_attributes (type1, type2)
afcfe58c
MM
753 tree type1;
754 tree type2;
b08de47e 755{
afcfe58c 756 /* Check for mismatch of non-default calling convention. */
69ddee61 757 const char *rtdstr = TARGET_RTD ? "cdecl" : "stdcall";
afcfe58c
MM
758
759 if (TREE_CODE (type1) != FUNCTION_TYPE)
760 return 1;
761
762 /* Check for mismatched return types (cdecl vs stdcall). */
6093f019
RH
763 if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
764 != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
afcfe58c 765 return 0;
b08de47e
MM
766 return 1;
767}
b08de47e
MM
768\f
769/* Value is the number of bytes of arguments automatically
770 popped when returning from a subroutine call.
771 FUNDECL is the declaration node of the function (as a tree),
772 FUNTYPE is the data type of the function (as a tree),
773 or for a library call it is an identifier node for the subroutine name.
774 SIZE is the number of bytes of arguments passed on the stack.
775
776 On the 80386, the RTD insn may be used to pop them if the number
777 of args is fixed, but if the number is variable then the caller
778 must pop them all. RTD can't be used for library calls now
779 because the library is compiled with the Unix compiler.
780 Use of RTD is a selectable option, since it is incompatible with
781 standard Unix calling sequences. If the option is not selected,
782 the caller must always pop the args.
783
784 The attribute stdcall is equivalent to RTD on a per module basis. */
785
786int
e075ae69 787ix86_return_pops_args (fundecl, funtype, size)
b08de47e
MM
788 tree fundecl;
789 tree funtype;
790 int size;
79325812 791{
3345ee7d 792 int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
b08de47e 793
e9a25f70
JL
794 /* Cdecl functions override -mrtd, and never pop the stack. */
795 if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
79325812 796
e9a25f70 797 /* Stdcall functions will pop the stack if not variable args. */
698cdd84
SC
798 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
799 rtd = 1;
79325812 800
698cdd84
SC
801 if (rtd
802 && (TYPE_ARG_TYPES (funtype) == NULL_TREE
e9a25f70
JL
803 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype)))
804 == void_type_node)))
698cdd84
SC
805 return size;
806 }
79325812 807
e9a25f70 808 /* Lose any fake structure return argument. */
698cdd84
SC
809 if (aggregate_value_p (TREE_TYPE (funtype)))
810 return GET_MODE_SIZE (Pmode);
79325812 811
2614aac6 812 return 0;
b08de47e 813}
b08de47e
MM
814\f
815/* Argument support functions. */
816
817/* Initialize a variable CUM of type CUMULATIVE_ARGS
818 for a call to a function whose data type is FNTYPE.
819 For a library call, FNTYPE is 0. */
820
821void
822init_cumulative_args (cum, fntype, libname)
e9a25f70 823 CUMULATIVE_ARGS *cum; /* Argument info to initialize */
b08de47e
MM
824 tree fntype; /* tree ptr for function decl */
825 rtx libname; /* SYMBOL_REF of library name or 0 */
826{
827 static CUMULATIVE_ARGS zero_cum;
828 tree param, next_param;
829
830 if (TARGET_DEBUG_ARG)
831 {
832 fprintf (stderr, "\ninit_cumulative_args (");
833 if (fntype)
e9a25f70
JL
834 fprintf (stderr, "fntype code = %s, ret code = %s",
835 tree_code_name[(int) TREE_CODE (fntype)],
836 tree_code_name[(int) TREE_CODE (TREE_TYPE (fntype))]);
b08de47e
MM
837 else
838 fprintf (stderr, "no fntype");
839
840 if (libname)
841 fprintf (stderr, ", libname = %s", XSTR (libname, 0));
842 }
843
844 *cum = zero_cum;
845
846 /* Set up the number of registers to use for passing arguments. */
e075ae69 847 cum->nregs = ix86_regparm;
b08de47e
MM
848 if (fntype)
849 {
850 tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
e9a25f70 851
b08de47e
MM
852 if (attr)
853 cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
854 }
855
856 /* Determine if this function has variable arguments. This is
857 indicated by the last argument being 'void_type_mode' if there
858 are no variable arguments. If there are variable arguments, then
859 we won't pass anything in registers */
860
861 if (cum->nregs)
862 {
863 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
e9a25f70 864 param != 0; param = next_param)
b08de47e
MM
865 {
866 next_param = TREE_CHAIN (param);
e9a25f70 867 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
b08de47e
MM
868 cum->nregs = 0;
869 }
870 }
871
872 if (TARGET_DEBUG_ARG)
873 fprintf (stderr, ", nregs=%d )\n", cum->nregs);
874
875 return;
876}
877
878/* Update the data in CUM to advance over an argument
879 of mode MODE and data type TYPE.
880 (TYPE is null for libcalls where that information may not be available.) */
881
882void
883function_arg_advance (cum, mode, type, named)
884 CUMULATIVE_ARGS *cum; /* current arg information */
885 enum machine_mode mode; /* current arg mode */
886 tree type; /* type of the argument or 0 if lib support */
887 int named; /* whether or not the argument was named */
888{
e9a25f70
JL
889 int bytes
890 = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
b08de47e
MM
891 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
892
893 if (TARGET_DEBUG_ARG)
894 fprintf (stderr,
e9a25f70 895 "function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
b08de47e
MM
896 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
897
898 cum->words += words;
899 cum->nregs -= words;
900 cum->regno += words;
901
902 if (cum->nregs <= 0)
903 {
904 cum->nregs = 0;
905 cum->regno = 0;
906 }
907
908 return;
909}
910
911/* Define where to put the arguments to a function.
912 Value is zero to push the argument on the stack,
913 or a hard register in which to store the argument.
914
915 MODE is the argument's machine mode.
916 TYPE is the data type of the argument (as a tree).
917 This is null for libcalls where that information may
918 not be available.
919 CUM is a variable of type CUMULATIVE_ARGS which gives info about
920 the preceding args and about the function being called.
921 NAMED is nonzero if this argument is a named parameter
922 (otherwise it is an extra parameter matching an ellipsis). */
923
924struct rtx_def *
925function_arg (cum, mode, type, named)
926 CUMULATIVE_ARGS *cum; /* current arg information */
927 enum machine_mode mode; /* current arg mode */
928 tree type; /* type of the argument or 0 if lib support */
929 int named; /* != 0 for normal args, == 0 for ... args */
930{
931 rtx ret = NULL_RTX;
e9a25f70
JL
932 int bytes
933 = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
b08de47e
MM
934 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
935
936 switch (mode)
937 {
e9a25f70
JL
938 /* For now, pass fp/complex values on the stack. */
939 default:
b08de47e
MM
940 break;
941
942 case BLKmode:
943 case DImode:
944 case SImode:
945 case HImode:
946 case QImode:
947 if (words <= cum->nregs)
f64cecad 948 ret = gen_rtx_REG (mode, cum->regno);
b08de47e
MM
949 break;
950 }
951
952 if (TARGET_DEBUG_ARG)
953 {
954 fprintf (stderr,
e9a25f70 955 "function_arg (size=%d, wds=%2d, nregs=%d, mode=%4s, named=%d",
b08de47e
MM
956 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
957
958 if (ret)
959 fprintf (stderr, ", reg=%%e%s", reg_names[ REGNO(ret) ]);
960 else
961 fprintf (stderr, ", stack");
962
963 fprintf (stderr, " )\n");
964 }
965
966 return ret;
967}
e075ae69
RH
968\f
969/* Returns 1 if OP is either a symbol reference or a sum of a symbol
970 reference and a constant. */
b08de47e
MM
971
972int
e075ae69
RH
973symbolic_operand (op, mode)
974 register rtx op;
975 enum machine_mode mode ATTRIBUTE_UNUSED;
2a2ab3f9 976{
e075ae69 977 switch (GET_CODE (op))
2a2ab3f9 978 {
e075ae69
RH
979 case SYMBOL_REF:
980 case LABEL_REF:
981 return 1;
982
983 case CONST:
984 op = XEXP (op, 0);
985 if (GET_CODE (op) == SYMBOL_REF
986 || GET_CODE (op) == LABEL_REF
987 || (GET_CODE (op) == UNSPEC
988 && XINT (op, 1) >= 6
989 && XINT (op, 1) <= 7))
990 return 1;
991 if (GET_CODE (op) != PLUS
992 || GET_CODE (XEXP (op, 1)) != CONST_INT)
993 return 0;
994
995 op = XEXP (op, 0);
996 if (GET_CODE (op) == SYMBOL_REF
997 || GET_CODE (op) == LABEL_REF)
998 return 1;
999 /* Only @GOTOFF gets offsets. */
1000 if (GET_CODE (op) != UNSPEC
1001 || XINT (op, 1) != 7)
1002 return 0;
1003
1004 op = XVECEXP (op, 0, 0);
1005 if (GET_CODE (op) == SYMBOL_REF
1006 || GET_CODE (op) == LABEL_REF)
1007 return 1;
1008 return 0;
1009
1010 default:
1011 return 0;
2a2ab3f9
JVA
1012 }
1013}
2a2ab3f9 1014
e075ae69 1015/* Return true if the operand contains a @GOT or @GOTOFF reference. */
3b3c6a3f 1016
e075ae69
RH
1017int
1018pic_symbolic_operand (op, mode)
1019 register rtx op;
1020 enum machine_mode mode ATTRIBUTE_UNUSED;
1021{
1022 if (GET_CODE (op) == CONST)
2a2ab3f9 1023 {
e075ae69
RH
1024 op = XEXP (op, 0);
1025 if (GET_CODE (op) == UNSPEC)
1026 return 1;
1027 if (GET_CODE (op) != PLUS
1028 || GET_CODE (XEXP (op, 1)) != CONST_INT)
1029 return 0;
1030 op = XEXP (op, 0);
1031 if (GET_CODE (op) == UNSPEC)
1032 return 1;
2a2ab3f9 1033 }
e075ae69 1034 return 0;
2a2ab3f9 1035}
2a2ab3f9 1036
28d52ffb
RH
1037/* Test for a valid operand for a call instruction. Don't allow the
1038 arg pointer register or virtual regs since they may decay into
1039 reg + const, which the patterns can't handle. */
2a2ab3f9 1040
e075ae69
RH
1041int
1042call_insn_operand (op, mode)
1043 rtx op;
1044 enum machine_mode mode ATTRIBUTE_UNUSED;
1045{
1046 if (GET_CODE (op) != MEM)
1047 return 0;
1048 op = XEXP (op, 0);
2a2ab3f9 1049
e075ae69
RH
1050 /* Disallow indirect through a virtual register. This leads to
1051 compiler aborts when trying to eliminate them. */
1052 if (GET_CODE (op) == REG
1053 && (op == arg_pointer_rtx
564d80f4 1054 || op == frame_pointer_rtx
e075ae69
RH
1055 || (REGNO (op) >= FIRST_PSEUDO_REGISTER
1056 && REGNO (op) <= LAST_VIRTUAL_REGISTER)))
1057 return 0;
2a2ab3f9 1058
28d52ffb
RH
1059 /* Disallow `call 1234'. Due to varying assembler lameness this
1060 gets either rejected or translated to `call .+1234'. */
1061 if (GET_CODE (op) == CONST_INT)
1062 return 0;
1063
e075ae69
RH
1064 /* Otherwise we can allow any general_operand in the address. */
1065 return general_operand (op, Pmode);
1066}
2a2ab3f9 1067
28d52ffb 1068/* Like call_insn_operand but allow (mem (symbol_ref ...)) even if pic. */
5f1ec3e6 1069
e075ae69
RH
1070int
1071expander_call_insn_operand (op, mode)
1072 rtx op;
28d52ffb 1073 enum machine_mode mode;
e075ae69 1074{
28d52ffb
RH
1075 if (GET_CODE (op) == MEM
1076 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF)
e075ae69 1077 return 1;
2a2ab3f9 1078
28d52ffb 1079 return call_insn_operand (op, mode);
e075ae69 1080}
79325812 1081
e075ae69
RH
1082int
1083constant_call_address_operand (op, mode)
1084 rtx op;
1085 enum machine_mode mode ATTRIBUTE_UNUSED;
1086{
1087 return GET_CODE (op) == MEM && CONSTANT_ADDRESS_P (XEXP (op, 0));
1088}
2a2ab3f9 1089
e075ae69 1090/* Match exactly zero and one. */
e9a25f70 1091
e075ae69
RH
1092int
1093const0_operand (op, mode)
1094 register rtx op;
1095 enum machine_mode mode;
1096{
1097 return op == CONST0_RTX (mode);
1098}
e9a25f70 1099
e075ae69
RH
1100int
1101const1_operand (op, mode)
1102 register rtx op;
1103 enum machine_mode mode ATTRIBUTE_UNUSED;
1104{
1105 return op == const1_rtx;
1106}
2a2ab3f9 1107
e075ae69 1108/* Match 2, 4, or 8. Used for leal multiplicands. */
e9a25f70 1109
e075ae69
RH
1110int
1111const248_operand (op, mode)
1112 register rtx op;
1113 enum machine_mode mode ATTRIBUTE_UNUSED;
1114{
1115 return (GET_CODE (op) == CONST_INT
1116 && (INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8));
1117}
e9a25f70 1118
e075ae69 1119/* True if this is a constant appropriate for an increment or decremenmt. */
81fd0956 1120
e075ae69
RH
1121int
1122incdec_operand (op, mode)
1123 register rtx op;
1124 enum machine_mode mode;
1125{
1126 if (op == const1_rtx || op == constm1_rtx)
1127 return 1;
1128 if (GET_CODE (op) != CONST_INT)
1129 return 0;
1130 if (mode == SImode && INTVAL (op) == (HOST_WIDE_INT) 0xffffffff)
1131 return 1;
1132 if (mode == HImode && INTVAL (op) == (HOST_WIDE_INT) 0xffff)
1133 return 1;
1134 if (mode == QImode && INTVAL (op) == (HOST_WIDE_INT) 0xff)
1135 return 1;
1136 return 0;
1137}
2a2ab3f9 1138
e075ae69
RH
1139/* Return false if this is the stack pointer, or any other fake
1140 register eliminable to the stack pointer. Otherwise, this is
1141 a register operand.
2a2ab3f9 1142
e075ae69
RH
1143 This is used to prevent esp from being used as an index reg.
1144 Which would only happen in pathological cases. */
5f1ec3e6 1145
e075ae69
RH
1146int
1147reg_no_sp_operand (op, mode)
1148 register rtx op;
1149 enum machine_mode mode;
1150{
1151 rtx t = op;
1152 if (GET_CODE (t) == SUBREG)
1153 t = SUBREG_REG (t);
564d80f4 1154 if (t == stack_pointer_rtx || t == arg_pointer_rtx || t == frame_pointer_rtx)
e075ae69 1155 return 0;
2a2ab3f9 1156
e075ae69 1157 return register_operand (op, mode);
2a2ab3f9 1158}
b840bfb0 1159
2c5a510c
RH
1160/* Return false if this is any eliminable register. Otherwise
1161 general_operand. */
1162
1163int
1164general_no_elim_operand (op, mode)
1165 register rtx op;
1166 enum machine_mode mode;
1167{
1168 rtx t = op;
1169 if (GET_CODE (t) == SUBREG)
1170 t = SUBREG_REG (t);
1171 if (t == arg_pointer_rtx || t == frame_pointer_rtx
1172 || t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
1173 || t == virtual_stack_dynamic_rtx)
1174 return 0;
1175
1176 return general_operand (op, mode);
1177}
1178
1179/* Return false if this is any eliminable register. Otherwise
1180 register_operand or const_int. */
1181
1182int
1183nonmemory_no_elim_operand (op, mode)
1184 register rtx op;
1185 enum machine_mode mode;
1186{
1187 rtx t = op;
1188 if (GET_CODE (t) == SUBREG)
1189 t = SUBREG_REG (t);
1190 if (t == arg_pointer_rtx || t == frame_pointer_rtx
1191 || t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
1192 || t == virtual_stack_dynamic_rtx)
1193 return 0;
1194
1195 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
1196}
1197
e075ae69 1198/* Return true if op is a Q_REGS class register. */
b840bfb0 1199
e075ae69
RH
1200int
1201q_regs_operand (op, mode)
1202 register rtx op;
1203 enum machine_mode mode;
b840bfb0 1204{
e075ae69
RH
1205 if (mode != VOIDmode && GET_MODE (op) != mode)
1206 return 0;
1207 if (GET_CODE (op) == SUBREG)
1208 op = SUBREG_REG (op);
1209 return QI_REG_P (op);
1210}
b840bfb0 1211
e075ae69 1212/* Return true if op is a NON_Q_REGS class register. */
b840bfb0 1213
e075ae69
RH
1214int
1215non_q_regs_operand (op, mode)
1216 register rtx op;
1217 enum machine_mode mode;
1218{
1219 if (mode != VOIDmode && GET_MODE (op) != mode)
1220 return 0;
1221 if (GET_CODE (op) == SUBREG)
1222 op = SUBREG_REG (op);
1223 return NON_QI_REG_P (op);
1224}
b840bfb0 1225
e075ae69
RH
1226/* Return 1 if OP is a comparison operator that can use the condition code
1227 generated by a logical operation, which characteristicly does not set
1228 overflow or carry. To be used with CCNOmode. */
b840bfb0 1229
e075ae69
RH
1230int
1231no_comparison_operator (op, mode)
1232 register rtx op;
1233 enum machine_mode mode;
1234{
1235 return ((mode == VOIDmode || GET_MODE (op) == mode)
1236 && GET_RTX_CLASS (GET_CODE (op)) == '<'
1237 && GET_CODE (op) != LE
1238 && GET_CODE (op) != GT);
1239}
b840bfb0 1240
e075ae69 1241/* Return 1 if OP is a comparison operator that can be issued by fcmov. */
b840bfb0 1242
e075ae69
RH
1243int
1244fcmov_comparison_operator (op, mode)
1245 register rtx op;
1246 enum machine_mode mode;
1247{
1248 return ((mode == VOIDmode || GET_MODE (op) == mode)
1249 && GET_RTX_CLASS (GET_CODE (op)) == '<'
1250 && GET_CODE (op) == unsigned_condition (GET_CODE (op)));
1251}
b840bfb0 1252
e9e80858
JH
1253/* Return 1 if OP is a binary operator that can be promoted to wider mode. */
1254
1255int
1256promotable_binary_operator (op, mode)
1257 register rtx op;
1258 enum machine_mode mode ATTRIBUTE_UNUSED;
1259{
1260 switch (GET_CODE (op))
1261 {
1262 case MULT:
1263 /* Modern CPUs have same latency for HImode and SImode multiply,
1264 but 386 and 486 do HImode multiply faster. */
1265 return ix86_cpu > PROCESSOR_I486;
1266 case PLUS:
1267 case AND:
1268 case IOR:
1269 case XOR:
1270 case ASHIFT:
1271 return 1;
1272 default:
1273 return 0;
1274 }
1275}
1276
e075ae69
RH
1277/* Nearly general operand, but accept any const_double, since we wish
1278 to be able to drop them into memory rather than have them get pulled
1279 into registers. */
b840bfb0 1280
2a2ab3f9 1281int
e075ae69
RH
1282cmp_fp_expander_operand (op, mode)
1283 register rtx op;
1284 enum machine_mode mode;
2a2ab3f9 1285{
e075ae69 1286 if (mode != VOIDmode && mode != GET_MODE (op))
0b6b2900 1287 return 0;
e075ae69 1288 if (GET_CODE (op) == CONST_DOUBLE)
2a2ab3f9 1289 return 1;
e075ae69 1290 return general_operand (op, mode);
2a2ab3f9
JVA
1291}
1292
e075ae69 1293/* Match an SI or HImode register for a zero_extract. */
2a2ab3f9
JVA
1294
1295int
e075ae69 1296ext_register_operand (op, mode)
2a2ab3f9 1297 register rtx op;
bb5177ac 1298 enum machine_mode mode ATTRIBUTE_UNUSED;
2a2ab3f9 1299{
e075ae69
RH
1300 if (GET_MODE (op) != SImode && GET_MODE (op) != HImode)
1301 return 0;
1302 return register_operand (op, VOIDmode);
1303}
1304
1305/* Return 1 if this is a valid binary floating-point operation.
1306 OP is the expression matched, and MODE is its mode. */
1307
1308int
1309binary_fp_operator (op, mode)
1310 register rtx op;
1311 enum machine_mode mode;
1312{
1313 if (mode != VOIDmode && mode != GET_MODE (op))
1314 return 0;
1315
2a2ab3f9
JVA
1316 switch (GET_CODE (op))
1317 {
e075ae69
RH
1318 case PLUS:
1319 case MINUS:
1320 case MULT:
1321 case DIV:
1322 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
e9a25f70 1323
2a2ab3f9
JVA
1324 default:
1325 return 0;
1326 }
1327}
fee2770d 1328
e075ae69
RH
1329int
1330mult_operator(op, mode)
1331 register rtx op;
1332 enum machine_mode mode ATTRIBUTE_UNUSED;
1333{
1334 return GET_CODE (op) == MULT;
1335}
1336
1337int
1338div_operator(op, mode)
1339 register rtx op;
1340 enum machine_mode mode ATTRIBUTE_UNUSED;
1341{
1342 return GET_CODE (op) == DIV;
1343}
0a726ef1
JL
1344
1345int
e075ae69
RH
1346arith_or_logical_operator (op, mode)
1347 rtx op;
1348 enum machine_mode mode;
0a726ef1 1349{
e075ae69
RH
1350 return ((mode == VOIDmode || GET_MODE (op) == mode)
1351 && (GET_RTX_CLASS (GET_CODE (op)) == 'c'
1352 || GET_RTX_CLASS (GET_CODE (op)) == '2'));
0a726ef1
JL
1353}
1354
e075ae69 1355/* Returns 1 if OP is memory operand with a displacement. */
fee2770d
RS
1356
1357int
e075ae69
RH
1358memory_displacement_operand (op, mode)
1359 register rtx op;
1360 enum machine_mode mode;
4f2c8ebb 1361{
e075ae69 1362 struct ix86_address parts;
e9a25f70 1363
e075ae69
RH
1364 if (! memory_operand (op, mode))
1365 return 0;
1366
1367 if (! ix86_decompose_address (XEXP (op, 0), &parts))
1368 abort ();
1369
1370 return parts.disp != NULL_RTX;
4f2c8ebb
RS
1371}
1372
e075ae69
RH
1373/* To avoid problems when jump re-emits comparisons like testqi_ext_0,
1374 re-recognize the operand to avoid a copy_to_mode_reg that will fail.
1375
1376 ??? It seems likely that this will only work because cmpsi is an
1377 expander, and no actual insns use this. */
4f2c8ebb
RS
1378
1379int
e075ae69
RH
1380cmpsi_operand (op, mode)
1381 rtx op;
1382 enum machine_mode mode;
fee2770d 1383{
e075ae69
RH
1384 if (general_operand (op, mode))
1385 return 1;
1386
1387 if (GET_CODE (op) == AND
1388 && GET_MODE (op) == SImode
1389 && GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT
1390 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
1391 && GET_CODE (XEXP (XEXP (op, 0), 2)) == CONST_INT
1392 && INTVAL (XEXP (XEXP (op, 0), 1)) == 8
1393 && INTVAL (XEXP (XEXP (op, 0), 2)) == 8
1394 && GET_CODE (XEXP (op, 1)) == CONST_INT)
fee2770d 1395 return 1;
e9a25f70 1396
fee2770d
RS
1397 return 0;
1398}
d784886d 1399
e075ae69
RH
1400/* Returns 1 if OP is memory operand that can not be represented by the
1401 modRM array. */
d784886d
RK
1402
1403int
e075ae69 1404long_memory_operand (op, mode)
d784886d
RK
1405 register rtx op;
1406 enum machine_mode mode;
1407{
e075ae69 1408 if (! memory_operand (op, mode))
d784886d
RK
1409 return 0;
1410
e075ae69 1411 return memory_address_length (op) != 0;
d784886d 1412}
2247f6ed
JH
1413
1414/* Return nonzero if the rtx is known aligned. */
1415
1416int
1417aligned_operand (op, mode)
1418 rtx op;
1419 enum machine_mode mode;
1420{
1421 struct ix86_address parts;
1422
1423 if (!general_operand (op, mode))
1424 return 0;
1425
1426 /* Registers and immediate operands are always "aligned". */
1427 if (GET_CODE (op) != MEM)
1428 return 1;
1429
1430 /* Don't even try to do any aligned optimizations with volatiles. */
1431 if (MEM_VOLATILE_P (op))
1432 return 0;
1433
1434 op = XEXP (op, 0);
1435
1436 /* Pushes and pops are only valid on the stack pointer. */
1437 if (GET_CODE (op) == PRE_DEC
1438 || GET_CODE (op) == POST_INC)
1439 return 1;
1440
1441 /* Decode the address. */
1442 if (! ix86_decompose_address (op, &parts))
1443 abort ();
1444
1445 /* Look for some component that isn't known to be aligned. */
1446 if (parts.index)
1447 {
1448 if (parts.scale < 4
1449 && REGNO_POINTER_ALIGN (REGNO (parts.index)) < 4)
1450 return 0;
1451 }
1452 if (parts.base)
1453 {
1454 if (REGNO_POINTER_ALIGN (REGNO (parts.base)) < 4)
1455 return 0;
1456 }
1457 if (parts.disp)
1458 {
1459 if (GET_CODE (parts.disp) != CONST_INT
1460 || (INTVAL (parts.disp) & 3) != 0)
1461 return 0;
1462 }
1463
1464 /* Didn't find one -- this must be an aligned address. */
1465 return 1;
1466}
e075ae69
RH
1467\f
1468/* Return true if the constant is something that can be loaded with
1469 a special instruction. Only handle 0.0 and 1.0; others are less
1470 worthwhile. */
57dbca5e
BS
1471
1472int
e075ae69
RH
1473standard_80387_constant_p (x)
1474 rtx x;
57dbca5e 1475{
e075ae69
RH
1476 if (GET_CODE (x) != CONST_DOUBLE)
1477 return -1;
1478
1479#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1480 {
1481 REAL_VALUE_TYPE d;
1482 jmp_buf handler;
1483 int is0, is1;
1484
1485 if (setjmp (handler))
1486 return 0;
1487
1488 set_float_handler (handler);
1489 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1490 is0 = REAL_VALUES_EQUAL (d, dconst0) && !REAL_VALUE_MINUS_ZERO (d);
1491 is1 = REAL_VALUES_EQUAL (d, dconst1);
1492 set_float_handler (NULL_PTR);
1493
1494 if (is0)
1495 return 1;
1496
1497 if (is1)
1498 return 2;
1499
1500 /* Note that on the 80387, other constants, such as pi,
1501 are much slower to load as standard constants
1502 than to load from doubles in memory! */
1503 /* ??? Not true on K6: all constants are equal cost. */
1504 }
1505#endif
1506
1507 return 0;
57dbca5e
BS
1508}
1509
2a2ab3f9
JVA
1510/* Returns 1 if OP contains a symbol reference */
1511
1512int
1513symbolic_reference_mentioned_p (op)
1514 rtx op;
1515{
6f7d635c 1516 register const char *fmt;
2a2ab3f9
JVA
1517 register int i;
1518
1519 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1520 return 1;
1521
1522 fmt = GET_RTX_FORMAT (GET_CODE (op));
1523 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1524 {
1525 if (fmt[i] == 'E')
1526 {
1527 register int j;
1528
1529 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1530 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1531 return 1;
1532 }
e9a25f70 1533
2a2ab3f9
JVA
1534 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1535 return 1;
1536 }
1537
1538 return 0;
1539}
e075ae69
RH
1540
1541/* Return 1 if it is appropriate to emit `ret' instructions in the
1542 body of a function. Do this only if the epilogue is simple, needing a
1543 couple of insns. Prior to reloading, we can't tell how many registers
1544 must be saved, so return 0 then. Return 0 if there is no frame
1545 marker to de-allocate.
1546
1547 If NON_SAVING_SETJMP is defined and true, then it is not possible
1548 for the epilogue to be simple, so return 0. This is a special case
1549 since NON_SAVING_SETJMP will not cause regs_ever_live to change
1550 until final, but jump_optimize may need to know sooner if a
1551 `return' is OK. */
32b5b1aa
SC
1552
1553int
e075ae69 1554ix86_can_use_return_insn_p ()
32b5b1aa 1555{
e075ae69
RH
1556#ifdef NON_SAVING_SETJMP
1557 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
1558 return 0;
1559#endif
32b5b1aa 1560
e075ae69
RH
1561 if (! reload_completed)
1562 return 0;
32b5b1aa 1563
0903fcab 1564 return ix86_nsaved_regs () == 0 || ! frame_pointer_needed;
e075ae69
RH
1565}
1566\f
21a427cc 1567static char *pic_label_name;
e075ae69 1568static int pic_label_output;
21a427cc 1569static char *global_offset_table_name;
e9a25f70 1570
e075ae69
RH
1571/* This function generates code for -fpic that loads %ebx with
1572 the return address of the caller and then returns. */
1573
1574void
1575asm_output_function_prefix (file, name)
1576 FILE *file;
1577 char *name ATTRIBUTE_UNUSED;
1578{
1579 rtx xops[2];
1580 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1581 || current_function_uses_const_pool);
1582 xops[0] = pic_offset_table_rtx;
1583 xops[1] = stack_pointer_rtx;
32b5b1aa 1584
e075ae69
RH
1585 /* Deep branch prediction favors having a return for every call. */
1586 if (pic_reg_used && TARGET_DEEP_BRANCH_PREDICTION)
32b5b1aa 1587 {
e075ae69
RH
1588 if (!pic_label_output)
1589 {
1590 /* This used to call ASM_DECLARE_FUNCTION_NAME() but since it's an
1591 internal (non-global) label that's being emitted, it didn't make
1592 sense to have .type information for local labels. This caused
1593 the SCO OpenServer 5.0.4 ELF assembler grief (why are you giving
1594 me debug info for a label that you're declaring non-global?) this
1595 was changed to call ASM_OUTPUT_LABEL() instead. */
32b5b1aa 1596
e075ae69 1597 ASM_OUTPUT_LABEL (file, pic_label_name);
e9a25f70 1598
e075ae69
RH
1599 xops[1] = gen_rtx_MEM (SImode, xops[1]);
1600 output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
1601 output_asm_insn ("ret", xops);
0afeb08a 1602
e075ae69 1603 pic_label_output = 1;
32b5b1aa 1604 }
32b5b1aa 1605 }
32b5b1aa 1606}
32b5b1aa 1607
e075ae69
RH
1608void
1609load_pic_register ()
32b5b1aa 1610{
e075ae69 1611 rtx gotsym, pclab;
32b5b1aa 1612
21a427cc
AS
1613 if (global_offset_table_name == NULL)
1614 {
1615 global_offset_table_name =
1616 ggc_alloc_string ("_GLOBAL_OFFSET_TABLE_", 21);
1617 ggc_add_string_root (&global_offset_table_name, 1);
1618 }
1619 gotsym = gen_rtx_SYMBOL_REF (Pmode, global_offset_table_name);
32b5b1aa 1620
e075ae69 1621 if (TARGET_DEEP_BRANCH_PREDICTION)
32b5b1aa 1622 {
21a427cc
AS
1623 if (pic_label_name == NULL)
1624 {
1625 pic_label_name = ggc_alloc_string (NULL, 32);
1626 ggc_add_string_root (&pic_label_name, 1);
1627 ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
1628 }
e075ae69 1629 pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name));
32b5b1aa 1630 }
e075ae69 1631 else
e5cb57e8 1632 {
e075ae69 1633 pclab = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
e5cb57e8 1634 }
e5cb57e8 1635
e075ae69 1636 emit_insn (gen_prologue_get_pc (pic_offset_table_rtx, pclab));
2a2ab3f9 1637
e075ae69
RH
1638 if (! TARGET_DEEP_BRANCH_PREDICTION)
1639 emit_insn (gen_popsi1 (pic_offset_table_rtx));
79325812 1640
e075ae69 1641 emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab));
e9a25f70 1642}
8dfe5673 1643
e075ae69 1644/* Generate an SImode "push" pattern for input ARG. */
e9a25f70 1645
e075ae69
RH
1646static rtx
1647gen_push (arg)
1648 rtx arg;
e9a25f70 1649{
c5c76735
JL
1650 return gen_rtx_SET (VOIDmode,
1651 gen_rtx_MEM (SImode,
1652 gen_rtx_PRE_DEC (SImode,
1653 stack_pointer_rtx)),
1654 arg);
e9a25f70
JL
1655}
1656
0903fcab
JH
1657/* Return number of registers to be saved on the stack. */
1658
1659static int
1660ix86_nsaved_regs ()
1661{
1662 int nregs = 0;
1663 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1664 || current_function_uses_const_pool);
1665 int limit = (frame_pointer_needed
1666 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1667 int regno;
1668
1669 for (regno = limit - 1; regno >= 0; regno--)
1670 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1671 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1672 {
1673 nregs ++;
1674 }
1675 return nregs;
1676}
1677
1678/* Return the offset between two registers, one to be eliminated, and the other
1679 its replacement, at the start of a routine. */
1680
1681HOST_WIDE_INT
1682ix86_initial_elimination_offset (from, to)
1683 int from;
1684 int to;
1685{
564d80f4
JH
1686 int padding1;
1687 int nregs;
1688
1689 /* Stack grows downward:
1690
1691 [arguments]
1692 <- ARG_POINTER
1693 saved pc
1694
1695 saved frame pointer if frame_pointer_needed
1696 <- HARD_FRAME_POINTER
1c71e60e 1697 [saved regs]
564d80f4
JH
1698
1699 [padding1] \
1700 | <- FRAME_POINTER
1701 [frame] > tsize
1702 |
1703 [padding2] /
564d80f4
JH
1704 */
1705
1706 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
1707 /* Skip saved PC and previous frame pointer.
1708 Executed only when frame_pointer_needed. */
1709 return 8;
1710 else if (from == FRAME_POINTER_REGNUM
1711 && to == HARD_FRAME_POINTER_REGNUM)
1712 {
1713 ix86_compute_frame_size (get_frame_size (), &nregs, &padding1, (int *)0);
1c71e60e 1714 padding1 += nregs * UNITS_PER_WORD;
564d80f4
JH
1715 return -padding1;
1716 }
0903fcab
JH
1717 else
1718 {
564d80f4
JH
1719 /* ARG_POINTER or FRAME_POINTER to STACK_POINTER elimination. */
1720 int frame_size = frame_pointer_needed ? 8 : 4;
0903fcab 1721 HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (),
564d80f4 1722 &nregs, &padding1, (int *)0);
0903fcab 1723
0903fcab 1724
564d80f4
JH
1725 if (to != STACK_POINTER_REGNUM)
1726 abort ();
1727 else if (from == ARG_POINTER_REGNUM)
1728 return tsize + nregs * UNITS_PER_WORD + frame_size;
1729 else if (from != FRAME_POINTER_REGNUM)
1730 abort ();
0903fcab 1731 else
1c71e60e 1732 return tsize - padding1;
0903fcab
JH
1733 }
1734}
1735
65954bd8
JL
1736/* Compute the size of local storage taking into consideration the
1737 desired stack alignment which is to be maintained. Also determine
564d80f4
JH
1738 the number of registers saved below the local storage.
1739
1740 PADDING1 returns padding before stack frame and PADDING2 returns
1741 padding after stack frame;
1742 */
1743
1744static HOST_WIDE_INT
1745ix86_compute_frame_size (size, nregs_on_stack, rpadding1, rpadding2)
65954bd8
JL
1746 HOST_WIDE_INT size;
1747 int *nregs_on_stack;
564d80f4
JH
1748 int *rpadding1;
1749 int *rpadding2;
65954bd8 1750{
65954bd8 1751 int nregs;
564d80f4
JH
1752 int padding1 = 0;
1753 int padding2 = 0;
65954bd8 1754 HOST_WIDE_INT total_size;
564d80f4 1755 int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT;
65954bd8 1756
564d80f4 1757 nregs = ix86_nsaved_regs ();
564d80f4 1758 total_size = size;
65954bd8
JL
1759
1760#ifdef PREFERRED_STACK_BOUNDARY
1761 {
1762 int offset;
1763 int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
1764
564d80f4
JH
1765 offset = frame_pointer_needed ? 8 : 4;
1766
1767 /* When frame is not empty we ought to have recorded the alignment. */
1768 if (size && !stack_alignment_needed)
1769 abort ();
1770
1771 if (stack_alignment_needed < 4)
1772 stack_alignment_needed = 4;
1773
1c71e60e 1774 if (stack_alignment_needed > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
564d80f4
JH
1775 abort ();
1776
1c71e60e 1777 offset += nregs * UNITS_PER_WORD;
65954bd8
JL
1778
1779 total_size += offset;
65954bd8 1780
564d80f4 1781 /* Align start of frame for local function. */
eebe34b4
RH
1782 if (size > 0)
1783 {
1784 padding1 = ((offset + stack_alignment_needed - 1)
1785 & -stack_alignment_needed) - offset;
1786 total_size += padding1;
1787 }
54ff41b7 1788
564d80f4 1789 /* Align stack boundary. */
1c71e60e
JH
1790 padding2 = ((total_size + preferred_alignment - 1)
1791 & -preferred_alignment) - total_size;
65954bd8
JL
1792 }
1793#endif
1794
1795 if (nregs_on_stack)
1796 *nregs_on_stack = nregs;
564d80f4
JH
1797 if (rpadding1)
1798 *rpadding1 = padding1;
564d80f4
JH
1799 if (rpadding2)
1800 *rpadding2 = padding2;
1801
1802 return size + padding1 + padding2;
65954bd8
JL
1803}
1804
0903fcab
JH
1805/* Emit code to save registers in the prologue. */
1806
1807static void
1808ix86_emit_save_regs ()
1809{
1810 register int regno;
1811 int limit;
1812 rtx insn;
1813 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1814 || current_function_uses_const_pool);
1815 limit = (frame_pointer_needed
564d80f4 1816 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
0903fcab
JH
1817
1818 for (regno = limit - 1; regno >= 0; regno--)
1819 if ((regs_ever_live[regno] && !call_used_regs[regno])
1820 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1821 {
1822 insn = emit_insn (gen_push (gen_rtx_REG (SImode, regno)));
1823 RTX_FRAME_RELATED_P (insn) = 1;
1824 }
1825}
1826
e075ae69
RH
1827/* Expand the prologue into a bunch of separate insns. */
1828
1829void
1830ix86_expand_prologue ()
2a2ab3f9 1831{
564d80f4
JH
1832 HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), (int *)0, (int *)0,
1833 (int *)0);
1834 rtx insn;
aae75261
JVA
1835 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1836 || current_function_uses_const_pool);
79325812 1837
e075ae69
RH
1838 /* Note: AT&T enter does NOT have reversed args. Enter is probably
1839 slower on all targets. Also sdb doesn't like it. */
e9a25f70 1840
2a2ab3f9
JVA
1841 if (frame_pointer_needed)
1842 {
564d80f4 1843 insn = emit_insn (gen_push (hard_frame_pointer_rtx));
e075ae69 1844 RTX_FRAME_RELATED_P (insn) = 1;
e9a25f70 1845
564d80f4 1846 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
e075ae69 1847 RTX_FRAME_RELATED_P (insn) = 1;
2a2ab3f9
JVA
1848 }
1849
1c71e60e 1850 ix86_emit_save_regs ();
564d80f4 1851
8dfe5673
RK
1852 if (tsize == 0)
1853 ;
1854 else if (! TARGET_STACK_PROBE || tsize < CHECK_STACK_LIMIT)
469ac993 1855 {
e075ae69 1856 if (frame_pointer_needed)
1c71e60e
JH
1857 insn = emit_insn (gen_pro_epilogue_adjust_stack
1858 (stack_pointer_rtx, stack_pointer_rtx,
1859 GEN_INT (-tsize), hard_frame_pointer_rtx));
79325812 1860 else
e075ae69
RH
1861 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1862 GEN_INT (-tsize)));
1863 RTX_FRAME_RELATED_P (insn) = 1;
469ac993 1864 }
79325812 1865 else
8dfe5673 1866 {
e075ae69 1867 /* ??? Is this only valid for Win32? */
e9a25f70 1868
e075ae69 1869 rtx arg0, sym;
e9a25f70 1870
e075ae69
RH
1871 arg0 = gen_rtx_REG (SImode, 0);
1872 emit_move_insn (arg0, GEN_INT (tsize));
77a989d1 1873
e075ae69
RH
1874 sym = gen_rtx_MEM (FUNCTION_MODE,
1875 gen_rtx_SYMBOL_REF (Pmode, "_alloca"));
1876 insn = emit_call_insn (gen_call (sym, const0_rtx));
1877
1878 CALL_INSN_FUNCTION_USAGE (insn)
276ab4a4
RH
1879 = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0),
1880 CALL_INSN_FUNCTION_USAGE (insn));
e075ae69 1881 }
e9a25f70 1882
84530511
SC
1883#ifdef SUBTARGET_PROLOGUE
1884 SUBTARGET_PROLOGUE;
1885#endif
1886
e9a25f70 1887 if (pic_reg_used)
e075ae69 1888 load_pic_register ();
77a989d1 1889
e9a25f70
JL
1890 /* If we are profiling, make sure no instructions are scheduled before
1891 the call to mcount. However, if -fpic, the above call will have
1892 done that. */
e075ae69 1893 if ((profile_flag || profile_block_flag) && ! pic_reg_used)
e9a25f70 1894 emit_insn (gen_blockage ());
77a989d1
SC
1895}
1896
0903fcab
JH
1897/* Emit code to add TSIZE to esp value. Use POP instruction when
1898 profitable. */
1899
1900static void
1901ix86_emit_epilogue_esp_adjustment (tsize)
1902 int tsize;
1903{
1904 /* Intel's docs say that for 4 or 8 bytes of stack frame one should
1905 use `pop' and not `add'. */
1906 int use_pop = tsize == 4;
1907 rtx edx = 0, ecx;
1908
1909 /* Use two pops only for the Pentium processors. */
1910 if (tsize == 8 && !TARGET_386 && !TARGET_486)
1911 {
1912 rtx retval = current_function_return_rtx;
1913
1914 edx = gen_rtx_REG (SImode, 1);
1915
1916 /* This case is a bit more complex. Since we cannot pop into
1917 %ecx twice we need a second register. But this is only
1918 available if the return value is not of DImode in which
1919 case the %edx register is not available. */
1920 use_pop = (retval == NULL
1921 || !reg_overlap_mentioned_p (edx, retval));
1922 }
1923
1924 if (use_pop)
1925 {
1926 ecx = gen_rtx_REG (SImode, 2);
1927
1928 /* We have to prevent the two pops here from being scheduled.
1929 GCC otherwise would try in some situation to put other
1930 instructions in between them which has a bad effect. */
1931 emit_insn (gen_blockage ());
1932 emit_insn (gen_popsi1 (ecx));
1933 if (tsize == 8)
1934 emit_insn (gen_popsi1 (edx));
1935 }
1936 else
1937 {
1c71e60e
JH
1938 /* If a frame pointer is present, we must be sure to tie the sp
1939 to the fp so that we don't mis-schedule. */
1940 if (frame_pointer_needed)
1941 emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
1942 stack_pointer_rtx,
1943 GEN_INT (tsize),
1944 hard_frame_pointer_rtx));
1945 else
1946 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1947 GEN_INT (tsize)));
0903fcab
JH
1948 }
1949}
1950
79325812 1951/* Restore function stack, frame, and registers. */
e9a25f70 1952
2a2ab3f9 1953void
77a989d1 1954ix86_expand_epilogue ()
2a2ab3f9 1955{
65954bd8 1956 int nregs;
1c71e60e
JH
1957 int regno;
1958
aae75261
JVA
1959 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1960 || current_function_uses_const_pool);
fdb8a883 1961 int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
65954bd8 1962 HOST_WIDE_INT offset;
1c71e60e
JH
1963 HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), &nregs,
1964 (int *)0, (int *)0);
2a2ab3f9 1965
2a2ab3f9 1966
1c71e60e
JH
1967 /* Calculate start of saved registers relative to ebp. */
1968 offset = -nregs * UNITS_PER_WORD;
2a2ab3f9 1969
1c71e60e
JH
1970#ifdef FUNCTION_BLOCK_PROFILER_EXIT
1971 if (profile_block_flag == 2)
564d80f4 1972 {
1c71e60e 1973 FUNCTION_BLOCK_PROFILER_EXIT;
564d80f4 1974 }
1c71e60e 1975#endif
564d80f4 1976
fdb8a883
JW
1977 /* If we're only restoring one register and sp is not valid then
1978 using a move instruction to restore the register since it's
1c71e60e
JH
1979 less work than reloading sp and popping the register. */
1980 if (!sp_valid && nregs <= 1)
2a2ab3f9 1981 {
1c71e60e
JH
1982 if (!frame_pointer_needed)
1983 abort();
2a2ab3f9 1984
1c71e60e 1985 for (regno = 0; regno < HARD_FRAME_POINTER_REGNUM; regno++)
e075ae69
RH
1986 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1987 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1988 {
1989 emit_move_insn (gen_rtx_REG (SImode, regno),
1990 adj_offsettable_operand (AT_BP (Pmode), offset));
1991 offset += 4;
1992 }
2a2ab3f9 1993
c8c5cb99 1994 /* If not an i386, mov & pop is faster than "leave". */
564d80f4
JH
1995 if (TARGET_USE_LEAVE || optimize_size)
1996 emit_insn (gen_leave ());
c8c5cb99 1997 else
2a2ab3f9 1998 {
1c71e60e
JH
1999 emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
2000 hard_frame_pointer_rtx,
2001 const0_rtx,
2002 hard_frame_pointer_rtx));
564d80f4 2003 emit_insn (gen_popsi1 (hard_frame_pointer_rtx));
e9a25f70
JL
2004 }
2005 }
1c71e60e 2006 else
68f654ec 2007 {
1c71e60e
JH
2008 /* First step is to deallocate the stack frame so that we can
2009 pop the registers. */
2010 if (!sp_valid)
2011 {
2012 if (!frame_pointer_needed)
2013 abort ();
2014 emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
2015 hard_frame_pointer_rtx,
2016 GEN_INT (offset),
2017 hard_frame_pointer_rtx));
2018 }
2019 else if (tsize)
2020 ix86_emit_epilogue_esp_adjustment (tsize);
2021
2022 for (regno = 0; regno < STACK_POINTER_REGNUM; regno++)
2023 if ((regs_ever_live[regno] && !call_used_regs[regno])
2024 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2025 emit_insn (gen_popsi1 (gen_rtx_REG (SImode, regno)));
68f654ec 2026 }
68f654ec 2027
2a2ab3f9
JVA
2028 if (current_function_pops_args && current_function_args_size)
2029 {
e075ae69 2030 rtx popc = GEN_INT (current_function_pops_args);
2a2ab3f9
JVA
2031
2032 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
2033 asked to pop more, pop return address, do explicit add, and jump
2034 indirectly to the caller. */
2035
2036 if (current_function_pops_args >= 32768)
2037 {
e075ae69 2038 rtx ecx = gen_rtx_REG (SImode, 2);
e9a25f70 2039
e075ae69
RH
2040 emit_insn (gen_popsi1 (ecx));
2041 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, popc));
2042 emit_indirect_jump (ecx);
e9a25f70 2043 }
79325812 2044 else
e075ae69
RH
2045 emit_jump_insn (gen_return_pop_internal (popc));
2046 }
2047 else
2048 emit_jump_insn (gen_return_internal ());
2049}
2050\f
2051/* Extract the parts of an RTL expression that is a valid memory address
2052 for an instruction. Return false if the structure of the address is
2053 grossly off. */
2054
2055static int
2056ix86_decompose_address (addr, out)
2057 register rtx addr;
2058 struct ix86_address *out;
2059{
2060 rtx base = NULL_RTX;
2061 rtx index = NULL_RTX;
2062 rtx disp = NULL_RTX;
2063 HOST_WIDE_INT scale = 1;
2064 rtx scale_rtx = NULL_RTX;
2065
2066 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
2067 base = addr;
2068 else if (GET_CODE (addr) == PLUS)
2069 {
2070 rtx op0 = XEXP (addr, 0);
2071 rtx op1 = XEXP (addr, 1);
2072 enum rtx_code code0 = GET_CODE (op0);
2073 enum rtx_code code1 = GET_CODE (op1);
2074
2075 if (code0 == REG || code0 == SUBREG)
2076 {
2077 if (code1 == REG || code1 == SUBREG)
2078 index = op0, base = op1; /* index + base */
2079 else
2080 base = op0, disp = op1; /* base + displacement */
2081 }
2082 else if (code0 == MULT)
e9a25f70 2083 {
e075ae69
RH
2084 index = XEXP (op0, 0);
2085 scale_rtx = XEXP (op0, 1);
2086 if (code1 == REG || code1 == SUBREG)
2087 base = op1; /* index*scale + base */
e9a25f70 2088 else
e075ae69
RH
2089 disp = op1; /* index*scale + disp */
2090 }
2091 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
2092 {
2093 index = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
2094 scale_rtx = XEXP (XEXP (op0, 0), 1);
2095 base = XEXP (op0, 1);
2096 disp = op1;
2a2ab3f9 2097 }
e075ae69
RH
2098 else if (code0 == PLUS)
2099 {
2100 index = XEXP (op0, 0); /* index + base + disp */
2101 base = XEXP (op0, 1);
2102 disp = op1;
2103 }
2104 else
2105 return FALSE;
2106 }
2107 else if (GET_CODE (addr) == MULT)
2108 {
2109 index = XEXP (addr, 0); /* index*scale */
2110 scale_rtx = XEXP (addr, 1);
2111 }
2112 else if (GET_CODE (addr) == ASHIFT)
2113 {
2114 rtx tmp;
2115
2116 /* We're called for lea too, which implements ashift on occasion. */
2117 index = XEXP (addr, 0);
2118 tmp = XEXP (addr, 1);
2119 if (GET_CODE (tmp) != CONST_INT)
2120 return FALSE;
2121 scale = INTVAL (tmp);
2122 if ((unsigned HOST_WIDE_INT) scale > 3)
2123 return FALSE;
2124 scale = 1 << scale;
2a2ab3f9 2125 }
2a2ab3f9 2126 else
e075ae69
RH
2127 disp = addr; /* displacement */
2128
2129 /* Extract the integral value of scale. */
2130 if (scale_rtx)
e9a25f70 2131 {
e075ae69
RH
2132 if (GET_CODE (scale_rtx) != CONST_INT)
2133 return FALSE;
2134 scale = INTVAL (scale_rtx);
e9a25f70 2135 }
3b3c6a3f 2136
e075ae69
RH
2137 /* Allow arg pointer and stack pointer as index if there is not scaling */
2138 if (base && index && scale == 1
564d80f4
JH
2139 && (index == arg_pointer_rtx || index == frame_pointer_rtx
2140 || index == stack_pointer_rtx))
e075ae69
RH
2141 {
2142 rtx tmp = base;
2143 base = index;
2144 index = tmp;
2145 }
2146
2147 /* Special case: %ebp cannot be encoded as a base without a displacement. */
564d80f4
JH
2148 if ((base == hard_frame_pointer_rtx
2149 || base == frame_pointer_rtx
2150 || base == arg_pointer_rtx) && !disp)
e075ae69
RH
2151 disp = const0_rtx;
2152
2153 /* Special case: on K6, [%esi] makes the instruction vector decoded.
2154 Avoid this by transforming to [%esi+0]. */
2155 if (ix86_cpu == PROCESSOR_K6 && !optimize_size
2156 && base && !index && !disp
329e1d01 2157 && REG_P (base)
e075ae69
RH
2158 && REGNO_REG_CLASS (REGNO (base)) == SIREG)
2159 disp = const0_rtx;
2160
2161 /* Special case: encode reg+reg instead of reg*2. */
2162 if (!base && index && scale && scale == 2)
2163 base = index, scale = 1;
2164
2165 /* Special case: scaling cannot be encoded without base or displacement. */
2166 if (!base && !disp && index && scale != 1)
2167 disp = const0_rtx;
2168
2169 out->base = base;
2170 out->index = index;
2171 out->disp = disp;
2172 out->scale = scale;
3b3c6a3f 2173
e075ae69
RH
2174 return TRUE;
2175}
3b3c6a3f 2176
e075ae69
RH
2177/* Determine if a given CONST RTX is a valid memory displacement
2178 in PIC mode. */
2179
59be65f6 2180int
91bb873f
RH
2181legitimate_pic_address_disp_p (disp)
2182 register rtx disp;
2183{
2184 if (GET_CODE (disp) != CONST)
2185 return 0;
2186 disp = XEXP (disp, 0);
2187
2188 if (GET_CODE (disp) == PLUS)
2189 {
2190 if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
2191 return 0;
2192 disp = XEXP (disp, 0);
2193 }
2194
2195 if (GET_CODE (disp) != UNSPEC
2196 || XVECLEN (disp, 0) != 1)
2197 return 0;
2198
2199 /* Must be @GOT or @GOTOFF. */
2200 if (XINT (disp, 1) != 6
2201 && XINT (disp, 1) != 7)
2202 return 0;
2203
2204 if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
2205 && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
2206 return 0;
2207
2208 return 1;
2209}
2210
e075ae69
RH
2211/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a valid
2212 memory address for an instruction. The MODE argument is the machine mode
2213 for the MEM expression that wants to use this address.
2214
2215 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
2216 convert common non-canonical forms to canonical form so that they will
2217 be recognized. */
2218
3b3c6a3f
MM
2219int
2220legitimate_address_p (mode, addr, strict)
2221 enum machine_mode mode;
2222 register rtx addr;
2223 int strict;
2224{
e075ae69
RH
2225 struct ix86_address parts;
2226 rtx base, index, disp;
2227 HOST_WIDE_INT scale;
2228 const char *reason = NULL;
2229 rtx reason_rtx = NULL_RTX;
3b3c6a3f
MM
2230
2231 if (TARGET_DEBUG_ADDR)
2232 {
2233 fprintf (stderr,
e9a25f70 2234 "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
3b3c6a3f 2235 GET_MODE_NAME (mode), strict);
3b3c6a3f
MM
2236 debug_rtx (addr);
2237 }
2238
e075ae69 2239 if (! ix86_decompose_address (addr, &parts))
3b3c6a3f 2240 {
e075ae69
RH
2241 reason = "decomposition failed";
2242 goto error;
3b3c6a3f
MM
2243 }
2244
e075ae69
RH
2245 base = parts.base;
2246 index = parts.index;
2247 disp = parts.disp;
2248 scale = parts.scale;
91f0226f 2249
e075ae69 2250 /* Validate base register.
e9a25f70
JL
2251
2252 Don't allow SUBREG's here, it can lead to spill failures when the base
3d771dfd
MM
2253 is one word out of a two word structure, which is represented internally
2254 as a DImode int. */
e9a25f70 2255
3b3c6a3f
MM
2256 if (base)
2257 {
e075ae69
RH
2258 reason_rtx = base;
2259
3d771dfd 2260 if (GET_CODE (base) != REG)
3b3c6a3f 2261 {
e075ae69
RH
2262 reason = "base is not a register";
2263 goto error;
3b3c6a3f
MM
2264 }
2265
c954bd01
RH
2266 if (GET_MODE (base) != Pmode)
2267 {
e075ae69
RH
2268 reason = "base is not in Pmode";
2269 goto error;
c954bd01
RH
2270 }
2271
e9a25f70
JL
2272 if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
2273 || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
3b3c6a3f 2274 {
e075ae69
RH
2275 reason = "base is not valid";
2276 goto error;
3b3c6a3f
MM
2277 }
2278 }
2279
e075ae69 2280 /* Validate index register.
e9a25f70
JL
2281
2282 Don't allow SUBREG's here, it can lead to spill failures when the index
3d771dfd
MM
2283 is one word out of a two word structure, which is represented internally
2284 as a DImode int. */
e075ae69
RH
2285
2286 if (index)
3b3c6a3f 2287 {
e075ae69
RH
2288 reason_rtx = index;
2289
2290 if (GET_CODE (index) != REG)
3b3c6a3f 2291 {
e075ae69
RH
2292 reason = "index is not a register";
2293 goto error;
3b3c6a3f
MM
2294 }
2295
e075ae69 2296 if (GET_MODE (index) != Pmode)
c954bd01 2297 {
e075ae69
RH
2298 reason = "index is not in Pmode";
2299 goto error;
c954bd01
RH
2300 }
2301
e075ae69
RH
2302 if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (index))
2303 || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (index)))
3b3c6a3f 2304 {
e075ae69
RH
2305 reason = "index is not valid";
2306 goto error;
3b3c6a3f
MM
2307 }
2308 }
3b3c6a3f 2309
e075ae69
RH
2310 /* Validate scale factor. */
2311 if (scale != 1)
3b3c6a3f 2312 {
e075ae69
RH
2313 reason_rtx = GEN_INT (scale);
2314 if (!index)
3b3c6a3f 2315 {
e075ae69
RH
2316 reason = "scale without index";
2317 goto error;
3b3c6a3f
MM
2318 }
2319
e075ae69 2320 if (scale != 2 && scale != 4 && scale != 8)
3b3c6a3f 2321 {
e075ae69
RH
2322 reason = "scale is not a valid multiplier";
2323 goto error;
3b3c6a3f
MM
2324 }
2325 }
2326
91bb873f 2327 /* Validate displacement. */
3b3c6a3f
MM
2328 if (disp)
2329 {
e075ae69
RH
2330 reason_rtx = disp;
2331
91bb873f 2332 if (!CONSTANT_ADDRESS_P (disp))
3b3c6a3f 2333 {
e075ae69
RH
2334 reason = "displacement is not constant";
2335 goto error;
3b3c6a3f
MM
2336 }
2337
e075ae69 2338 if (GET_CODE (disp) == CONST_DOUBLE)
3b3c6a3f 2339 {
e075ae69
RH
2340 reason = "displacement is a const_double";
2341 goto error;
3b3c6a3f
MM
2342 }
2343
91bb873f 2344 if (flag_pic && SYMBOLIC_CONST (disp))
3b3c6a3f 2345 {
91bb873f
RH
2346 if (! legitimate_pic_address_disp_p (disp))
2347 {
e075ae69
RH
2348 reason = "displacement is an invalid pic construct";
2349 goto error;
91bb873f
RH
2350 }
2351
e075ae69
RH
2352 /* Verify that a symbolic pic displacement includes
2353 the pic_offset_table_rtx register. */
91bb873f 2354 if (base != pic_offset_table_rtx
e075ae69 2355 && (index != pic_offset_table_rtx || scale != 1))
91bb873f 2356 {
e075ae69
RH
2357 reason = "pic displacement against invalid base";
2358 goto error;
91bb873f 2359 }
3b3c6a3f 2360 }
91bb873f 2361 else if (HALF_PIC_P ())
3b3c6a3f 2362 {
91bb873f 2363 if (! HALF_PIC_ADDRESS_P (disp)
e075ae69 2364 || (base != NULL_RTX || index != NULL_RTX))
91bb873f 2365 {
e075ae69
RH
2366 reason = "displacement is an invalid half-pic reference";
2367 goto error;
91bb873f 2368 }
3b3c6a3f
MM
2369 }
2370 }
2371
e075ae69 2372 /* Everything looks valid. */
3b3c6a3f 2373 if (TARGET_DEBUG_ADDR)
e075ae69 2374 fprintf (stderr, "Success.\n");
3b3c6a3f 2375 return TRUE;
e075ae69
RH
2376
2377error:
2378 if (TARGET_DEBUG_ADDR)
2379 {
2380 fprintf (stderr, "Error: %s\n", reason);
2381 debug_rtx (reason_rtx);
2382 }
2383 return FALSE;
3b3c6a3f 2384}
3b3c6a3f
MM
2385\f
2386/* Return a legitimate reference for ORIG (an address) using the
2387 register REG. If REG is 0, a new pseudo is generated.
2388
91bb873f 2389 There are two types of references that must be handled:
3b3c6a3f
MM
2390
2391 1. Global data references must load the address from the GOT, via
2392 the PIC reg. An insn is emitted to do this load, and the reg is
2393 returned.
2394
91bb873f
RH
2395 2. Static data references, constant pool addresses, and code labels
2396 compute the address as an offset from the GOT, whose base is in
2397 the PIC reg. Static data objects have SYMBOL_REF_FLAG set to
2398 differentiate them from global data objects. The returned
2399 address is the PIC reg + an unspec constant.
3b3c6a3f
MM
2400
2401 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
91bb873f 2402 reg also appears in the address. */
3b3c6a3f
MM
2403
2404rtx
2405legitimize_pic_address (orig, reg)
2406 rtx orig;
2407 rtx reg;
2408{
2409 rtx addr = orig;
2410 rtx new = orig;
91bb873f 2411 rtx base;
3b3c6a3f 2412
91bb873f
RH
2413 if (GET_CODE (addr) == LABEL_REF
2414 || (GET_CODE (addr) == SYMBOL_REF
2415 && (CONSTANT_POOL_ADDRESS_P (addr)
2416 || SYMBOL_REF_FLAG (addr))))
3b3c6a3f 2417 {
91bb873f
RH
2418 /* This symbol may be referenced via a displacement from the PIC
2419 base address (@GOTOFF). */
3b3c6a3f 2420
91bb873f
RH
2421 current_function_uses_pic_offset_table = 1;
2422 new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, addr), 7);
2423 new = gen_rtx_CONST (VOIDmode, new);
2424 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
3b3c6a3f 2425
91bb873f
RH
2426 if (reg != 0)
2427 {
3b3c6a3f 2428 emit_move_insn (reg, new);
91bb873f 2429 new = reg;
3b3c6a3f 2430 }
3b3c6a3f 2431 }
91bb873f 2432 else if (GET_CODE (addr) == SYMBOL_REF)
3b3c6a3f 2433 {
91bb873f
RH
2434 /* This symbol must be referenced via a load from the
2435 Global Offset Table (@GOT). */
3b3c6a3f 2436
91bb873f
RH
2437 current_function_uses_pic_offset_table = 1;
2438 new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, addr), 6);
2439 new = gen_rtx_CONST (VOIDmode, new);
2440 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2441 new = gen_rtx_MEM (Pmode, new);
2442 RTX_UNCHANGING_P (new) = 1;
3b3c6a3f
MM
2443
2444 if (reg == 0)
2445 reg = gen_reg_rtx (Pmode);
91bb873f
RH
2446 emit_move_insn (reg, new);
2447 new = reg;
2448 }
2449 else
2450 {
2451 if (GET_CODE (addr) == CONST)
3b3c6a3f 2452 {
91bb873f
RH
2453 addr = XEXP (addr, 0);
2454 if (GET_CODE (addr) == UNSPEC)
2455 {
2456 /* Check that the unspec is one of the ones we generate? */
2457 }
2458 else if (GET_CODE (addr) != PLUS)
564d80f4 2459 abort ();
3b3c6a3f 2460 }
91bb873f
RH
2461 if (GET_CODE (addr) == PLUS)
2462 {
2463 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
e9a25f70 2464
91bb873f
RH
2465 /* Check first to see if this is a constant offset from a @GOTOFF
2466 symbol reference. */
2467 if ((GET_CODE (op0) == LABEL_REF
2468 || (GET_CODE (op0) == SYMBOL_REF
2469 && (CONSTANT_POOL_ADDRESS_P (op0)
2470 || SYMBOL_REF_FLAG (op0))))
2471 && GET_CODE (op1) == CONST_INT)
2472 {
2473 current_function_uses_pic_offset_table = 1;
2474 new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, op0), 7);
2475 new = gen_rtx_PLUS (VOIDmode, new, op1);
2476 new = gen_rtx_CONST (VOIDmode, new);
2477 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
2478
2479 if (reg != 0)
2480 {
2481 emit_move_insn (reg, new);
2482 new = reg;
2483 }
2484 }
2485 else
2486 {
2487 base = legitimize_pic_address (XEXP (addr, 0), reg);
2488 new = legitimize_pic_address (XEXP (addr, 1),
2489 base == reg ? NULL_RTX : reg);
2490
2491 if (GET_CODE (new) == CONST_INT)
2492 new = plus_constant (base, INTVAL (new));
2493 else
2494 {
2495 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
2496 {
2497 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
2498 new = XEXP (new, 1);
2499 }
2500 new = gen_rtx_PLUS (Pmode, base, new);
2501 }
2502 }
2503 }
3b3c6a3f
MM
2504 }
2505 return new;
2506}
2507\f
3b3c6a3f
MM
2508/* Try machine-dependent ways of modifying an illegitimate address
2509 to be legitimate. If we find one, return the new, valid address.
2510 This macro is used in only one place: `memory_address' in explow.c.
2511
2512 OLDX is the address as it was before break_out_memory_refs was called.
2513 In some cases it is useful to look at this to decide what needs to be done.
2514
2515 MODE and WIN are passed so that this macro can use
2516 GO_IF_LEGITIMATE_ADDRESS.
2517
2518 It is always safe for this macro to do nothing. It exists to recognize
2519 opportunities to optimize the output.
2520
2521 For the 80386, we handle X+REG by loading X into a register R and
2522 using R+REG. R will go in a general reg and indexing will be used.
2523 However, if REG is a broken-out memory address or multiplication,
2524 nothing needs to be done because REG can certainly go in a general reg.
2525
2526 When -fpic is used, special handling is needed for symbolic references.
2527 See comments by legitimize_pic_address in i386.c for details. */
2528
2529rtx
2530legitimize_address (x, oldx, mode)
2531 register rtx x;
bb5177ac 2532 register rtx oldx ATTRIBUTE_UNUSED;
3b3c6a3f
MM
2533 enum machine_mode mode;
2534{
2535 int changed = 0;
2536 unsigned log;
2537
2538 if (TARGET_DEBUG_ADDR)
2539 {
e9a25f70
JL
2540 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n",
2541 GET_MODE_NAME (mode));
3b3c6a3f
MM
2542 debug_rtx (x);
2543 }
2544
2545 if (flag_pic && SYMBOLIC_CONST (x))
2546 return legitimize_pic_address (x, 0);
2547
2548 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2549 if (GET_CODE (x) == ASHIFT
2550 && GET_CODE (XEXP (x, 1)) == CONST_INT
2551 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2552 {
2553 changed = 1;
a269a03c
JC
2554 x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
2555 GEN_INT (1 << log));
3b3c6a3f
MM
2556 }
2557
2558 if (GET_CODE (x) == PLUS)
2559 {
e9a25f70
JL
2560 /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
2561
3b3c6a3f
MM
2562 if (GET_CODE (XEXP (x, 0)) == ASHIFT
2563 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2564 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2565 {
2566 changed = 1;
c5c76735
JL
2567 XEXP (x, 0) = gen_rtx_MULT (Pmode,
2568 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2569 GEN_INT (1 << log));
3b3c6a3f
MM
2570 }
2571
2572 if (GET_CODE (XEXP (x, 1)) == ASHIFT
2573 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2574 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2575 {
2576 changed = 1;
c5c76735
JL
2577 XEXP (x, 1) = gen_rtx_MULT (Pmode,
2578 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2579 GEN_INT (1 << log));
3b3c6a3f
MM
2580 }
2581
e9a25f70 2582 /* Put multiply first if it isn't already. */
3b3c6a3f
MM
2583 if (GET_CODE (XEXP (x, 1)) == MULT)
2584 {
2585 rtx tmp = XEXP (x, 0);
2586 XEXP (x, 0) = XEXP (x, 1);
2587 XEXP (x, 1) = tmp;
2588 changed = 1;
2589 }
2590
2591 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2592 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2593 created by virtual register instantiation, register elimination, and
2594 similar optimizations. */
2595 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2596 {
2597 changed = 1;
c5c76735
JL
2598 x = gen_rtx_PLUS (Pmode,
2599 gen_rtx_PLUS (Pmode, XEXP (x, 0),
2600 XEXP (XEXP (x, 1), 0)),
2601 XEXP (XEXP (x, 1), 1));
3b3c6a3f
MM
2602 }
2603
e9a25f70
JL
2604 /* Canonicalize
2605 (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
3b3c6a3f
MM
2606 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2607 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2608 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2609 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2610 && CONSTANT_P (XEXP (x, 1)))
2611 {
00c79232
ML
2612 rtx constant;
2613 rtx other = NULL_RTX;
3b3c6a3f
MM
2614
2615 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2616 {
2617 constant = XEXP (x, 1);
2618 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2619 }
2620 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2621 {
2622 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2623 other = XEXP (x, 1);
2624 }
2625 else
2626 constant = 0;
2627
2628 if (constant)
2629 {
2630 changed = 1;
c5c76735
JL
2631 x = gen_rtx_PLUS (Pmode,
2632 gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
2633 XEXP (XEXP (XEXP (x, 0), 1), 0)),
2634 plus_constant (other, INTVAL (constant)));
3b3c6a3f
MM
2635 }
2636 }
2637
2638 if (changed && legitimate_address_p (mode, x, FALSE))
2639 return x;
2640
2641 if (GET_CODE (XEXP (x, 0)) == MULT)
2642 {
2643 changed = 1;
2644 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2645 }
2646
2647 if (GET_CODE (XEXP (x, 1)) == MULT)
2648 {
2649 changed = 1;
2650 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2651 }
2652
2653 if (changed
2654 && GET_CODE (XEXP (x, 1)) == REG
2655 && GET_CODE (XEXP (x, 0)) == REG)
2656 return x;
2657
2658 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2659 {
2660 changed = 1;
2661 x = legitimize_pic_address (x, 0);
2662 }
2663
2664 if (changed && legitimate_address_p (mode, x, FALSE))
2665 return x;
2666
2667 if (GET_CODE (XEXP (x, 0)) == REG)
2668 {
2669 register rtx temp = gen_reg_rtx (Pmode);
2670 register rtx val = force_operand (XEXP (x, 1), temp);
2671 if (val != temp)
2672 emit_move_insn (temp, val);
2673
2674 XEXP (x, 1) = temp;
2675 return x;
2676 }
2677
2678 else if (GET_CODE (XEXP (x, 1)) == REG)
2679 {
2680 register rtx temp = gen_reg_rtx (Pmode);
2681 register rtx val = force_operand (XEXP (x, 0), temp);
2682 if (val != temp)
2683 emit_move_insn (temp, val);
2684
2685 XEXP (x, 0) = temp;
2686 return x;
2687 }
2688 }
2689
2690 return x;
2691}
2a2ab3f9
JVA
2692\f
2693/* Print an integer constant expression in assembler syntax. Addition
2694 and subtraction are the only arithmetic that may appear in these
2695 expressions. FILE is the stdio stream to write to, X is the rtx, and
2696 CODE is the operand print code from the output string. */
2697
2698static void
2699output_pic_addr_const (file, x, code)
2700 FILE *file;
2701 rtx x;
2702 int code;
2703{
2704 char buf[256];
2705
2706 switch (GET_CODE (x))
2707 {
2708 case PC:
2709 if (flag_pic)
2710 putc ('.', file);
2711 else
2712 abort ();
2713 break;
2714
2715 case SYMBOL_REF:
91bb873f
RH
2716 assemble_name (file, XSTR (x, 0));
2717 if (code == 'P' && ! SYMBOL_REF_FLAG (x))
2718 fputs ("@PLT", file);
2a2ab3f9
JVA
2719 break;
2720
91bb873f
RH
2721 case LABEL_REF:
2722 x = XEXP (x, 0);
2723 /* FALLTHRU */
2a2ab3f9
JVA
2724 case CODE_LABEL:
2725 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2726 assemble_name (asm_out_file, buf);
2727 break;
2728
2729 case CONST_INT:
f64cecad 2730 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2a2ab3f9
JVA
2731 break;
2732
2733 case CONST:
2734 /* This used to output parentheses around the expression,
2735 but that does not work on the 386 (either ATT or BSD assembler). */
2736 output_pic_addr_const (file, XEXP (x, 0), code);
2737 break;
2738
2739 case CONST_DOUBLE:
2740 if (GET_MODE (x) == VOIDmode)
2741 {
2742 /* We can use %d if the number is <32 bits and positive. */
2743 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
f64cecad
JC
2744 fprintf (file, "0x%lx%08lx",
2745 (unsigned long) CONST_DOUBLE_HIGH (x),
2746 (unsigned long) CONST_DOUBLE_LOW (x));
2a2ab3f9 2747 else
f64cecad 2748 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
2a2ab3f9
JVA
2749 }
2750 else
2751 /* We can't handle floating point constants;
2752 PRINT_OPERAND must handle them. */
2753 output_operand_lossage ("floating constant misused");
2754 break;
2755
2756 case PLUS:
e9a25f70 2757 /* Some assemblers need integer constants to appear first. */
2a2ab3f9
JVA
2758 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2759 {
2a2ab3f9 2760 output_pic_addr_const (file, XEXP (x, 0), code);
e075ae69 2761 putc ('+', file);
e9a25f70 2762 output_pic_addr_const (file, XEXP (x, 1), code);
2a2ab3f9 2763 }
91bb873f 2764 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2a2ab3f9 2765 {
2a2ab3f9 2766 output_pic_addr_const (file, XEXP (x, 1), code);
e075ae69 2767 putc ('+', file);
e9a25f70 2768 output_pic_addr_const (file, XEXP (x, 0), code);
2a2ab3f9 2769 }
91bb873f
RH
2770 else
2771 abort ();
2a2ab3f9
JVA
2772 break;
2773
2774 case MINUS:
e075ae69 2775 putc (ASSEMBLER_DIALECT ? '(' : '[', file);
2a2ab3f9 2776 output_pic_addr_const (file, XEXP (x, 0), code);
e075ae69 2777 putc ('-', file);
2a2ab3f9 2778 output_pic_addr_const (file, XEXP (x, 1), code);
e075ae69 2779 putc (ASSEMBLER_DIALECT ? ')' : ']', file);
2a2ab3f9
JVA
2780 break;
2781
91bb873f
RH
2782 case UNSPEC:
2783 if (XVECLEN (x, 0) != 1)
2784 abort ();
2785 output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
2786 switch (XINT (x, 1))
2787 {
2788 case 6:
2789 fputs ("@GOT", file);
2790 break;
2791 case 7:
2792 fputs ("@GOTOFF", file);
2793 break;
2794 case 8:
2795 fputs ("@PLT", file);
2796 break;
2797 default:
2798 output_operand_lossage ("invalid UNSPEC as operand");
2799 break;
2800 }
2801 break;
2802
2a2ab3f9
JVA
2803 default:
2804 output_operand_lossage ("invalid expression as operand");
2805 }
2806}
1865dbb5
JM
2807
2808/* This is called from dwarfout.c via ASM_OUTPUT_DWARF_ADDR_CONST.
2809 We need to handle our special PIC relocations. */
2810
2811void
2812i386_dwarf_output_addr_const (file, x)
2813 FILE *file;
2814 rtx x;
2815{
2816 fprintf (file, "\t%s\t", INT_ASM_OP);
2817 if (flag_pic)
2818 output_pic_addr_const (file, x, '\0');
2819 else
2820 output_addr_const (file, x);
2821 fputc ('\n', file);
2822}
2823
2824/* In the name of slightly smaller debug output, and to cater to
2825 general assembler losage, recognize PIC+GOTOFF and turn it back
2826 into a direct symbol reference. */
2827
2828rtx
2829i386_simplify_dwarf_addr (orig_x)
2830 rtx orig_x;
2831{
2832 rtx x = orig_x;
2833
2834 if (GET_CODE (x) != PLUS
2835 || GET_CODE (XEXP (x, 0)) != REG
2836 || GET_CODE (XEXP (x, 1)) != CONST)
2837 return orig_x;
2838
2839 x = XEXP (XEXP (x, 1), 0);
2840 if (GET_CODE (x) == UNSPEC
2841 && XINT (x, 1) == 7)
2842 return XVECEXP (x, 0, 0);
2843
2844 if (GET_CODE (x) == PLUS
2845 && GET_CODE (XEXP (x, 0)) == UNSPEC
2846 && GET_CODE (XEXP (x, 1)) == CONST_INT
2847 && XINT (XEXP (x, 0), 1) == 7)
2848 return gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
2849
2850 return orig_x;
2851}
2a2ab3f9 2852\f
a269a03c 2853static void
e075ae69 2854put_condition_code (code, mode, reverse, fp, file)
a269a03c 2855 enum rtx_code code;
e075ae69
RH
2856 enum machine_mode mode;
2857 int reverse, fp;
a269a03c
JC
2858 FILE *file;
2859{
a269a03c
JC
2860 const char *suffix;
2861
a269a03c
JC
2862 if (reverse)
2863 code = reverse_condition (code);
e075ae69 2864
a269a03c
JC
2865 switch (code)
2866 {
2867 case EQ:
2868 suffix = "e";
2869 break;
a269a03c
JC
2870 case NE:
2871 suffix = "ne";
2872 break;
a269a03c 2873 case GT:
e075ae69
RH
2874 if (mode == CCNOmode)
2875 abort ();
2876 suffix = "g";
a269a03c 2877 break;
a269a03c 2878 case GTU:
e075ae69
RH
2879 /* ??? Use "nbe" instead of "a" for fcmov losage on some assemblers.
2880 Those same assemblers have the same but opposite losage on cmov. */
2881 suffix = fp ? "nbe" : "a";
a269a03c 2882 break;
a269a03c 2883 case LT:
e075ae69 2884 if (mode == CCNOmode)
a269a03c
JC
2885 suffix = "s";
2886 else
e075ae69 2887 suffix = "l";
a269a03c 2888 break;
a269a03c
JC
2889 case LTU:
2890 suffix = "b";
2891 break;
a269a03c 2892 case GE:
e075ae69 2893 if (mode == CCNOmode)
a269a03c
JC
2894 suffix = "ns";
2895 else
e075ae69 2896 suffix = "ge";
a269a03c 2897 break;
a269a03c 2898 case GEU:
e075ae69
RH
2899 /* ??? As above. */
2900 suffix = fp ? "nb" : "ae";
a269a03c 2901 break;
a269a03c 2902 case LE:
e075ae69
RH
2903 if (mode == CCNOmode)
2904 abort ();
2905 suffix = "le";
a269a03c 2906 break;
a269a03c
JC
2907 case LEU:
2908 suffix = "be";
2909 break;
a269a03c
JC
2910 default:
2911 abort ();
2912 }
2913 fputs (suffix, file);
2914}
2915
e075ae69
RH
2916void
2917print_reg (x, code, file)
2918 rtx x;
2919 int code;
2920 FILE *file;
e5cb57e8 2921{
e075ae69 2922 if (REGNO (x) == ARG_POINTER_REGNUM
564d80f4 2923 || REGNO (x) == FRAME_POINTER_REGNUM
e075ae69
RH
2924 || REGNO (x) == FLAGS_REG
2925 || REGNO (x) == FPSR_REG)
2926 abort ();
e9a25f70 2927
e075ae69
RH
2928 if (ASSEMBLER_DIALECT == 0 || USER_LABEL_PREFIX[0] == 0)
2929 putc ('%', file);
2930
2931 if (code == 'w')
2932 code = 2;
2933 else if (code == 'b')
2934 code = 1;
2935 else if (code == 'k')
2936 code = 4;
2937 else if (code == 'y')
2938 code = 3;
2939 else if (code == 'h')
2940 code = 0;
2941 else
2942 code = GET_MODE_SIZE (GET_MODE (x));
e9a25f70 2943
e075ae69
RH
2944 switch (code)
2945 {
2946 case 3:
2947 if (STACK_TOP_P (x))
2948 {
2949 fputs ("st(0)", file);
2950 break;
2951 }
2952 /* FALLTHRU */
2953 case 4:
2954 case 8:
2955 case 12:
2956 if (! FP_REG_P (x))
2957 putc ('e', file);
2958 /* FALLTHRU */
2959 case 2:
2960 fputs (hi_reg_name[REGNO (x)], file);
2961 break;
2962 case 1:
2963 fputs (qi_reg_name[REGNO (x)], file);
2964 break;
2965 case 0:
2966 fputs (qi_high_reg_name[REGNO (x)], file);
2967 break;
2968 default:
2969 abort ();
fe25fea3 2970 }
e5cb57e8
SC
2971}
2972
2a2ab3f9 2973/* Meaning of CODE:
fe25fea3 2974 L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
e5cb57e8 2975 C -- print opcode suffix for set/cmov insn.
fe25fea3 2976 c -- like C, but print reversed condition
2a2ab3f9
JVA
2977 R -- print the prefix for register names.
2978 z -- print the opcode suffix for the size of the current operand.
2979 * -- print a star (in certain assembler syntax)
2980 w -- print the operand as if it's a "word" (HImode) even if it isn't.
2d49677f
SC
2981 s -- print a shift double count, followed by the assemblers argument
2982 delimiter.
fe25fea3
SC
2983 b -- print the QImode name of the register for the indicated operand.
2984 %b0 would print %al if operands[0] is reg 0.
2985 w -- likewise, print the HImode name of the register.
2986 k -- likewise, print the SImode name of the register.
2987 h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
e075ae69 2988 y -- print "st(0)" instead of "st" as a register. */
2a2ab3f9
JVA
2989
2990void
2991print_operand (file, x, code)
2992 FILE *file;
2993 rtx x;
2994 int code;
2995{
2996 if (code)
2997 {
2998 switch (code)
2999 {
3000 case '*':
e075ae69 3001 if (ASSEMBLER_DIALECT == 0)
2a2ab3f9
JVA
3002 putc ('*', file);
3003 return;
3004
2a2ab3f9 3005 case 'L':
e075ae69
RH
3006 if (ASSEMBLER_DIALECT == 0)
3007 putc ('l', file);
2a2ab3f9
JVA
3008 return;
3009
3010 case 'W':
e075ae69
RH
3011 if (ASSEMBLER_DIALECT == 0)
3012 putc ('w', file);
2a2ab3f9
JVA
3013 return;
3014
3015 case 'B':
e075ae69
RH
3016 if (ASSEMBLER_DIALECT == 0)
3017 putc ('b', file);
2a2ab3f9
JVA
3018 return;
3019
3020 case 'Q':
e075ae69
RH
3021 if (ASSEMBLER_DIALECT == 0)
3022 putc ('l', file);
2a2ab3f9
JVA
3023 return;
3024
3025 case 'S':
e075ae69
RH
3026 if (ASSEMBLER_DIALECT == 0)
3027 putc ('s', file);
2a2ab3f9
JVA
3028 return;
3029
5f1ec3e6 3030 case 'T':
e075ae69
RH
3031 if (ASSEMBLER_DIALECT == 0)
3032 putc ('t', file);
5f1ec3e6
JVA
3033 return;
3034
2a2ab3f9
JVA
3035 case 'z':
3036 /* 387 opcodes don't get size suffixes if the operands are
3037 registers. */
3038
3039 if (STACK_REG_P (x))
3040 return;
3041
e075ae69
RH
3042 /* Intel syntax has no truck with instruction suffixes. */
3043 if (ASSEMBLER_DIALECT != 0)
3044 return;
3045
2a2ab3f9
JVA
3046 /* this is the size of op from size of operand */
3047 switch (GET_MODE_SIZE (GET_MODE (x)))
3048 {
e075ae69
RH
3049 case 1:
3050 putc ('b', file);
3051 return;
3052
2a2ab3f9 3053 case 2:
e075ae69 3054 putc ('w', file);
2a2ab3f9
JVA
3055 return;
3056
3057 case 4:
3058 if (GET_MODE (x) == SFmode)
3059 {
e075ae69 3060 putc ('s', file);
2a2ab3f9
JVA
3061 return;
3062 }
3063 else
e075ae69 3064 putc ('l', file);
2a2ab3f9
JVA
3065 return;
3066
5f1ec3e6 3067 case 12:
e075ae69
RH
3068 putc ('t', file);
3069 return;
5f1ec3e6 3070
2a2ab3f9
JVA
3071 case 8:
3072 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
56c0e8fa
JVA
3073 {
3074#ifdef GAS_MNEMONICS
e075ae69 3075 putc ('q', file);
56c0e8fa 3076#else
e075ae69
RH
3077 putc ('l', file);
3078 putc ('l', file);
56c0e8fa
JVA
3079#endif
3080 }
e075ae69
RH
3081 else
3082 putc ('l', file);
2a2ab3f9
JVA
3083 return;
3084 }
4af3895e
JVA
3085
3086 case 'b':
3087 case 'w':
3088 case 'k':
3089 case 'h':
3090 case 'y':
5cb6195d 3091 case 'X':
e075ae69 3092 case 'P':
4af3895e
JVA
3093 break;
3094
2d49677f
SC
3095 case 's':
3096 if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
3097 {
3098 PRINT_OPERAND (file, x, 0);
e075ae69 3099 putc (',', file);
2d49677f 3100 }
a269a03c
JC
3101 return;
3102
1853aadd 3103 case 'C':
e075ae69 3104 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file);
1853aadd 3105 return;
fe25fea3 3106 case 'F':
e075ae69 3107 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 1, file);
fe25fea3
SC
3108 return;
3109
e9a25f70 3110 /* Like above, but reverse condition */
e075ae69
RH
3111 case 'c':
3112 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 0, file);
3113 return;
fe25fea3 3114 case 'f':
e075ae69 3115 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 1, file);
1853aadd 3116 return;
e5cb57e8 3117
4af3895e 3118 default:
68daafd4
JVA
3119 {
3120 char str[50];
68daafd4
JVA
3121 sprintf (str, "invalid operand code `%c'", code);
3122 output_operand_lossage (str);
3123 }
2a2ab3f9
JVA
3124 }
3125 }
e9a25f70 3126
2a2ab3f9
JVA
3127 if (GET_CODE (x) == REG)
3128 {
3129 PRINT_REG (x, code, file);
3130 }
e9a25f70 3131
2a2ab3f9
JVA
3132 else if (GET_CODE (x) == MEM)
3133 {
e075ae69
RH
3134 /* No `byte ptr' prefix for call instructions. */
3135 if (ASSEMBLER_DIALECT != 0 && code != 'X' && code != 'P')
2a2ab3f9 3136 {
69ddee61 3137 const char * size;
e075ae69
RH
3138 switch (GET_MODE_SIZE (GET_MODE (x)))
3139 {
3140 case 1: size = "BYTE"; break;
3141 case 2: size = "WORD"; break;
3142 case 4: size = "DWORD"; break;
3143 case 8: size = "QWORD"; break;
3144 case 12: size = "XWORD"; break;
3145 default:
564d80f4 3146 abort ();
e075ae69
RH
3147 }
3148 fputs (size, file);
3149 fputs (" PTR ", file);
2a2ab3f9 3150 }
e075ae69
RH
3151
3152 x = XEXP (x, 0);
3153 if (flag_pic && CONSTANT_ADDRESS_P (x))
3154 output_pic_addr_const (file, x, code);
2a2ab3f9 3155 else
e075ae69 3156 output_address (x);
2a2ab3f9 3157 }
e9a25f70 3158
2a2ab3f9
JVA
3159 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
3160 {
e9a25f70
JL
3161 REAL_VALUE_TYPE r;
3162 long l;
3163
5f1ec3e6
JVA
3164 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3165 REAL_VALUE_TO_TARGET_SINGLE (r, l);
e075ae69
RH
3166
3167 if (ASSEMBLER_DIALECT == 0)
3168 putc ('$', file);
52267fcb 3169 fprintf (file, "0x%lx", l);
5f1ec3e6 3170 }
e9a25f70 3171
5f1ec3e6
JVA
3172 /* These float cases don't actually occur as immediate operands. */
3173 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
3174 {
e9a25f70
JL
3175 REAL_VALUE_TYPE r;
3176 char dstr[30];
3177
5f1ec3e6
JVA
3178 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3179 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3180 fprintf (file, "%s", dstr);
2a2ab3f9 3181 }
e9a25f70 3182
5f1ec3e6 3183 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2a2ab3f9 3184 {
e9a25f70
JL
3185 REAL_VALUE_TYPE r;
3186 char dstr[30];
3187
5f1ec3e6
JVA
3188 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3189 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3190 fprintf (file, "%s", dstr);
2a2ab3f9 3191 }
79325812 3192 else
2a2ab3f9 3193 {
4af3895e 3194 if (code != 'P')
2a2ab3f9 3195 {
695dac07 3196 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
e075ae69
RH
3197 {
3198 if (ASSEMBLER_DIALECT == 0)
3199 putc ('$', file);
3200 }
2a2ab3f9
JVA
3201 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
3202 || GET_CODE (x) == LABEL_REF)
e075ae69
RH
3203 {
3204 if (ASSEMBLER_DIALECT == 0)
3205 putc ('$', file);
3206 else
3207 fputs ("OFFSET FLAT:", file);
3208 }
2a2ab3f9 3209 }
e075ae69
RH
3210 if (GET_CODE (x) == CONST_INT)
3211 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
3212 else if (flag_pic)
2a2ab3f9
JVA
3213 output_pic_addr_const (file, x, code);
3214 else
3215 output_addr_const (file, x);
3216 }
3217}
3218\f
3219/* Print a memory operand whose address is ADDR. */
3220
3221void
3222print_operand_address (file, addr)
3223 FILE *file;
3224 register rtx addr;
3225{
e075ae69
RH
3226 struct ix86_address parts;
3227 rtx base, index, disp;
3228 int scale;
e9a25f70 3229
e075ae69
RH
3230 if (! ix86_decompose_address (addr, &parts))
3231 abort ();
e9a25f70 3232
e075ae69
RH
3233 base = parts.base;
3234 index = parts.index;
3235 disp = parts.disp;
3236 scale = parts.scale;
e9a25f70 3237
e075ae69
RH
3238 if (!base && !index)
3239 {
3240 /* Displacement only requires special attention. */
e9a25f70 3241
e075ae69 3242 if (GET_CODE (disp) == CONST_INT)
2a2ab3f9 3243 {
e075ae69
RH
3244 if (ASSEMBLER_DIALECT != 0)
3245 fputs ("ds:", file);
3246 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
2a2ab3f9 3247 }
e075ae69
RH
3248 else if (flag_pic)
3249 output_pic_addr_const (file, addr, 0);
3250 else
3251 output_addr_const (file, addr);
3252 }
3253 else
3254 {
3255 if (ASSEMBLER_DIALECT == 0)
2a2ab3f9 3256 {
e075ae69 3257 if (disp)
2a2ab3f9 3258 {
c399861d 3259 if (flag_pic)
e075ae69
RH
3260 output_pic_addr_const (file, disp, 0);
3261 else if (GET_CODE (disp) == LABEL_REF)
3262 output_asm_label (disp);
2a2ab3f9 3263 else
e075ae69 3264 output_addr_const (file, disp);
2a2ab3f9
JVA
3265 }
3266
e075ae69
RH
3267 putc ('(', file);
3268 if (base)
3269 PRINT_REG (base, 0, file);
3270 if (index)
2a2ab3f9 3271 {
e075ae69
RH
3272 putc (',', file);
3273 PRINT_REG (index, 0, file);
3274 if (scale != 1)
3275 fprintf (file, ",%d", scale);
2a2ab3f9 3276 }
e075ae69 3277 putc (')', file);
2a2ab3f9 3278 }
2a2ab3f9
JVA
3279 else
3280 {
e075ae69 3281 rtx offset = NULL_RTX;
e9a25f70 3282
e075ae69
RH
3283 if (disp)
3284 {
3285 /* Pull out the offset of a symbol; print any symbol itself. */
3286 if (GET_CODE (disp) == CONST
3287 && GET_CODE (XEXP (disp, 0)) == PLUS
3288 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
3289 {
3290 offset = XEXP (XEXP (disp, 0), 1);
3291 disp = gen_rtx_CONST (VOIDmode,
3292 XEXP (XEXP (disp, 0), 0));
3293 }
ce193852 3294
e075ae69
RH
3295 if (flag_pic)
3296 output_pic_addr_const (file, disp, 0);
3297 else if (GET_CODE (disp) == LABEL_REF)
3298 output_asm_label (disp);
3299 else if (GET_CODE (disp) == CONST_INT)
3300 offset = disp;
3301 else
3302 output_addr_const (file, disp);
3303 }
e9a25f70 3304
e075ae69
RH
3305 putc ('[', file);
3306 if (base)
a8620236 3307 {
e075ae69
RH
3308 PRINT_REG (base, 0, file);
3309 if (offset)
3310 {
3311 if (INTVAL (offset) >= 0)
3312 putc ('+', file);
3313 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
3314 }
a8620236 3315 }
e075ae69
RH
3316 else if (offset)
3317 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
2247a58c 3318 else
e075ae69 3319 putc ('0', file);
e9a25f70 3320
e075ae69
RH
3321 if (index)
3322 {
3323 putc ('+', file);
3324 PRINT_REG (index, 0, file);
3325 if (scale != 1)
3326 fprintf (file, "*%d", scale);
3327 }
3328 putc (']', file);
3329 }
2a2ab3f9
JVA
3330 }
3331}
3332\f
3333/* Split one or more DImode RTL references into pairs of SImode
3334 references. The RTL can be REG, offsettable MEM, integer constant, or
3335 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3336 split and "num" is its length. lo_half and hi_half are output arrays
3337 that parallel "operands". */
3338
3339void
3340split_di (operands, num, lo_half, hi_half)
3341 rtx operands[];
3342 int num;
3343 rtx lo_half[], hi_half[];
3344{
3345 while (num--)
3346 {
57dbca5e 3347 rtx op = operands[num];
e075ae69
RH
3348 if (CONSTANT_P (op))
3349 split_double (op, &lo_half[num], &hi_half[num]);
3350 else if (! reload_completed)
a269a03c
JC
3351 {
3352 lo_half[num] = gen_lowpart (SImode, op);
3353 hi_half[num] = gen_highpart (SImode, op);
3354 }
3355 else if (GET_CODE (op) == REG)
2a2ab3f9 3356 {
57dbca5e
BS
3357 lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
3358 hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
2a2ab3f9 3359 }
57dbca5e 3360 else if (offsettable_memref_p (op))
2a2ab3f9 3361 {
57dbca5e
BS
3362 rtx lo_addr = XEXP (op, 0);
3363 rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
3364 lo_half[num] = change_address (op, SImode, lo_addr);
3365 hi_half[num] = change_address (op, SImode, hi_addr);
2a2ab3f9
JVA
3366 }
3367 else
564d80f4 3368 abort ();
2a2ab3f9
JVA
3369 }
3370}
3371\f
2a2ab3f9
JVA
3372/* Output code to perform a 387 binary operation in INSN, one of PLUS,
3373 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3374 is the expression of the binary operation. The output may either be
3375 emitted here, or returned to the caller, like all output_* functions.
3376
3377 There is no guarantee that the operands are the same mode, as they
3378 might be within FLOAT or FLOAT_EXTEND expressions. */
3379
69ddee61 3380const char *
2a2ab3f9
JVA
3381output_387_binary_op (insn, operands)
3382 rtx insn;
3383 rtx *operands;
3384{
2a2ab3f9 3385 static char buf[100];
e075ae69 3386 rtx temp;
69ddee61 3387 const char *p;
2a2ab3f9
JVA
3388
3389 switch (GET_CODE (operands[3]))
3390 {
3391 case PLUS:
e075ae69
RH
3392 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3393 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3394 p = "fiadd";
3395 else
3396 p = "fadd";
2a2ab3f9
JVA
3397 break;
3398
3399 case MINUS:
e075ae69
RH
3400 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3401 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3402 p = "fisub";
3403 else
3404 p = "fsub";
2a2ab3f9
JVA
3405 break;
3406
3407 case MULT:
e075ae69
RH
3408 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3409 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3410 p = "fimul";
3411 else
3412 p = "fmul";
2a2ab3f9
JVA
3413 break;
3414
3415 case DIV:
e075ae69
RH
3416 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3417 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3418 p = "fidiv";
3419 else
3420 p = "fdiv";
2a2ab3f9
JVA
3421 break;
3422
3423 default:
3424 abort ();
3425 }
3426
e075ae69 3427 strcpy (buf, p);
2a2ab3f9
JVA
3428
3429 switch (GET_CODE (operands[3]))
3430 {
3431 case MULT:
3432 case PLUS:
3433 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3434 {
3435 temp = operands[2];
3436 operands[2] = operands[1];
3437 operands[1] = temp;
3438 }
3439
3440 if (GET_CODE (operands[2]) == MEM)
e075ae69
RH
3441 {
3442 p = "%z2\t%2";
3443 break;
3444 }
2a2ab3f9
JVA
3445
3446 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
3447 {
3448 if (STACK_TOP_P (operands[0]))
e075ae69 3449 p = "p\t{%0,%2|%2, %0}";
6b28fd63 3450 else
e075ae69
RH
3451 p = "p\t{%2,%0|%0, %2}";
3452 break;
6b28fd63 3453 }
2a2ab3f9
JVA
3454
3455 if (STACK_TOP_P (operands[0]))
e075ae69 3456 p = "\t{%y2,%0|%0, %y2}";
2a2ab3f9 3457 else
e075ae69
RH
3458 p = "\t{%2,%0|%0, %2}";
3459 break;
2a2ab3f9
JVA
3460
3461 case MINUS:
3462 case DIV:
3463 if (GET_CODE (operands[1]) == MEM)
e075ae69
RH
3464 {
3465 p = "r%z1\t%1";
3466 break;
3467 }
2a2ab3f9
JVA
3468
3469 if (GET_CODE (operands[2]) == MEM)
e075ae69
RH
3470 {
3471 p = "%z2\t%2";
3472 break;
3473 }
2a2ab3f9 3474
2a2ab3f9
JVA
3475 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3476 abort ();
3477
e075ae69
RH
3478 /* Note that the Unixware assembler, and the AT&T assembler before
3479 that, are confusingly not reversed from Intel syntax in this
3480 area. */
2a2ab3f9 3481 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
3482 {
3483 if (STACK_TOP_P (operands[0]))
e075ae69 3484 p = "p\t%0,%2";
6b28fd63 3485 else
e075ae69
RH
3486 p = "rp\t%2,%0";
3487 break;
6b28fd63 3488 }
2a2ab3f9
JVA
3489
3490 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
6b28fd63
JL
3491 {
3492 if (STACK_TOP_P (operands[0]))
e075ae69 3493 p = "rp\t%0,%1";
6b28fd63 3494 else
e075ae69
RH
3495 p = "p\t%1,%0";
3496 break;
6b28fd63 3497 }
2a2ab3f9
JVA
3498
3499 if (STACK_TOP_P (operands[0]))
3500 {
3501 if (STACK_TOP_P (operands[1]))
e075ae69 3502 p = "\t%y2,%0";
2a2ab3f9 3503 else
e075ae69
RH
3504 p = "r\t%y1,%0";
3505 break;
2a2ab3f9
JVA
3506 }
3507 else if (STACK_TOP_P (operands[1]))
e075ae69 3508 p = "\t%1,%0";
2a2ab3f9 3509 else
e075ae69
RH
3510 p = "r\t%2,%0";
3511 break;
2a2ab3f9
JVA
3512
3513 default:
3514 abort ();
3515 }
e075ae69
RH
3516
3517 strcat (buf, p);
3518 return buf;
2a2ab3f9 3519}
e075ae69 3520
2a2ab3f9 3521/* Output code for INSN to convert a float to a signed int. OPERANDS
e075ae69
RH
3522 are the insn operands. The output may be [SD]Imode and the input
3523 operand may be [SDX]Fmode. */
2a2ab3f9 3524
69ddee61 3525const char *
2a2ab3f9
JVA
3526output_fix_trunc (insn, operands)
3527 rtx insn;
3528 rtx *operands;
3529{
3530 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
e075ae69
RH
3531 int dimode_p = GET_MODE (operands[0]) == DImode;
3532 rtx xops[4];
2a2ab3f9 3533
e075ae69
RH
3534 /* Jump through a hoop or two for DImode, since the hardware has no
3535 non-popping instruction. We used to do this a different way, but
3536 that was somewhat fragile and broke with post-reload splitters. */
a05924f9
JH
3537 if (dimode_p && !stack_top_dies)
3538 output_asm_insn ("fld\t%y1", operands);
e075ae69
RH
3539
3540 if (! STACK_TOP_P (operands[1]))
10195bd8
JW
3541 abort ();
3542
e075ae69
RH
3543 xops[0] = GEN_INT (12);
3544 xops[1] = adj_offsettable_operand (operands[2], 1);
3545 xops[1] = change_address (xops[1], QImode, NULL_RTX);
305f097e 3546
e075ae69
RH
3547 xops[2] = operands[0];
3548 if (GET_CODE (operands[0]) != MEM)
3549 xops[2] = operands[3];
2a2ab3f9 3550
e075ae69
RH
3551 output_asm_insn ("fnstcw\t%2", operands);
3552 output_asm_insn ("mov{l}\t{%2, %4|%4, %2}", operands);
3553 output_asm_insn ("mov{b}\t{%0, %1|%1, %0}", xops);
3554 output_asm_insn ("fldcw\t%2", operands);
3555 output_asm_insn ("mov{l}\t{%4, %2|%2, %4}", operands);
e9a25f70 3556
e075ae69
RH
3557 if (stack_top_dies || dimode_p)
3558 output_asm_insn ("fistp%z2\t%2", xops);
10195bd8 3559 else
e075ae69
RH
3560 output_asm_insn ("fist%z2\t%2", xops);
3561
3562 output_asm_insn ("fldcw\t%2", operands);
10195bd8 3563
e075ae69 3564 if (GET_CODE (operands[0]) != MEM)
2a2ab3f9 3565 {
e075ae69 3566 if (dimode_p)
2e14a41b 3567 {
e075ae69
RH
3568 split_di (operands+0, 1, xops+0, xops+1);
3569 split_di (operands+3, 1, xops+2, xops+3);
3570 output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
3571 output_asm_insn ("mov{l}\t{%3, %1|%1, %3}", xops);
2e14a41b 3572 }
e075ae69
RH
3573 else
3574 output_asm_insn ("mov{l}\t{%3,%0|%0, %3}", operands);
2a2ab3f9 3575 }
2a2ab3f9 3576
e075ae69 3577 return "";
2a2ab3f9 3578}
cda749b1 3579
e075ae69
RH
3580/* Output code for INSN to compare OPERANDS. EFLAGS_P is 1 when fcomi
3581 should be used and 2 when fnstsw should be used. UNORDERED_P is true
3582 when fucom should be used. */
3583
69ddee61 3584const char *
e075ae69 3585output_fp_compare (insn, operands, eflags_p, unordered_p)
cda749b1
JW
3586 rtx insn;
3587 rtx *operands;
e075ae69 3588 int eflags_p, unordered_p;
cda749b1 3589{
e075ae69
RH
3590 int stack_top_dies;
3591 rtx cmp_op0 = operands[0];
3592 rtx cmp_op1 = operands[1];
3593
3594 if (eflags_p == 2)
3595 {
3596 cmp_op0 = cmp_op1;
3597 cmp_op1 = operands[2];
3598 }
cda749b1 3599
e075ae69 3600 if (! STACK_TOP_P (cmp_op0))
cda749b1
JW
3601 abort ();
3602
e075ae69 3603 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
cda749b1 3604
e075ae69
RH
3605 if (STACK_REG_P (cmp_op1)
3606 && stack_top_dies
3607 && find_regno_note (insn, REG_DEAD, REGNO (cmp_op1))
3608 && REGNO (cmp_op1) != FIRST_STACK_REG)
cda749b1 3609 {
e075ae69
RH
3610 /* If both the top of the 387 stack dies, and the other operand
3611 is also a stack register that dies, then this must be a
3612 `fcompp' float compare */
3613
3614 if (eflags_p == 1)
3615 {
3616 /* There is no double popping fcomi variant. Fortunately,
3617 eflags is immune from the fstp's cc clobbering. */
3618 if (unordered_p)
3619 output_asm_insn ("fucomip\t{%y1, %0|%0, %y1}", operands);
3620 else
3621 output_asm_insn ("fcomip\t{%y1, %0|%0, %y1}", operands);
3622 return "fstp\t%y0";
3623 }
3624 else
cda749b1 3625 {
e075ae69
RH
3626 if (eflags_p == 2)
3627 {
3628 if (unordered_p)
3629 return "fucompp\n\tfnstsw\t%0";
3630 else
3631 return "fcompp\n\tfnstsw\t%0";
3632 }
cda749b1
JW
3633 else
3634 {
e075ae69
RH
3635 if (unordered_p)
3636 return "fucompp";
3637 else
3638 return "fcompp";
cda749b1
JW
3639 }
3640 }
cda749b1
JW
3641 }
3642 else
3643 {
e075ae69 3644 /* Encoded here as eflags_p | intmode | unordered_p | stack_top_dies. */
cda749b1 3645
69ddee61 3646 static const char * const alt[24] =
e075ae69
RH
3647 {
3648 "fcom%z1\t%y1",
3649 "fcomp%z1\t%y1",
3650 "fucom%z1\t%y1",
3651 "fucomp%z1\t%y1",
3652
3653 "ficom%z1\t%y1",
3654 "ficomp%z1\t%y1",
3655 NULL,
3656 NULL,
3657
3658 "fcomi\t{%y1, %0|%0, %y1}",
3659 "fcomip\t{%y1, %0|%0, %y1}",
3660 "fucomi\t{%y1, %0|%0, %y1}",
3661 "fucomip\t{%y1, %0|%0, %y1}",
3662
3663 NULL,
3664 NULL,
3665 NULL,
3666 NULL,
3667
3668 "fcom%z2\t%y2\n\tfnstsw\t%0",
3669 "fcomp%z2\t%y2\n\tfnstsw\t%0",
3670 "fucom%z2\t%y2\n\tfnstsw\t%0",
3671 "fucomp%z2\t%y2\n\tfnstsw\t%0",
3672
3673 "ficom%z2\t%y2\n\tfnstsw\t%0",
3674 "ficomp%z2\t%y2\n\tfnstsw\t%0",
3675 NULL,
3676 NULL
3677 };
3678
3679 int mask;
69ddee61 3680 const char *ret;
e075ae69
RH
3681
3682 mask = eflags_p << 3;
3683 mask |= (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT) << 2;
3684 mask |= unordered_p << 1;
3685 mask |= stack_top_dies;
3686
3687 if (mask >= 24)
3688 abort ();
3689 ret = alt[mask];
3690 if (ret == NULL)
3691 abort ();
cda749b1 3692
e075ae69 3693 return ret;
cda749b1
JW
3694 }
3695}
2a2ab3f9 3696
e075ae69 3697/* Output assembler code to FILE to initialize basic-block profiling.
2a2ab3f9 3698
e075ae69 3699 If profile_block_flag == 2
2a2ab3f9 3700
e075ae69
RH
3701 Output code to call the subroutine `__bb_init_trace_func'
3702 and pass two parameters to it. The first parameter is
3703 the address of a block allocated in the object module.
3704 The second parameter is the number of the first basic block
3705 of the function.
2a2ab3f9 3706
e075ae69
RH
3707 The name of the block is a local symbol made with this statement:
3708
3709 ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
2a2ab3f9 3710
e075ae69
RH
3711 Of course, since you are writing the definition of
3712 `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
3713 can take a short cut in the definition of this macro and use the
3714 name that you know will result.
2a2ab3f9 3715
e075ae69
RH
3716 The number of the first basic block of the function is
3717 passed to the macro in BLOCK_OR_LABEL.
2a2ab3f9 3718
e075ae69
RH
3719 If described in a virtual assembler language the code to be
3720 output looks like:
2a2ab3f9 3721
e075ae69
RH
3722 parameter1 <- LPBX0
3723 parameter2 <- BLOCK_OR_LABEL
3724 call __bb_init_trace_func
2a2ab3f9 3725
e075ae69 3726 else if profile_block_flag != 0
e74389ff 3727
e075ae69
RH
3728 Output code to call the subroutine `__bb_init_func'
3729 and pass one single parameter to it, which is the same
3730 as the first parameter to `__bb_init_trace_func'.
e74389ff 3731
e075ae69
RH
3732 The first word of this parameter is a flag which will be nonzero if
3733 the object module has already been initialized. So test this word
3734 first, and do not call `__bb_init_func' if the flag is nonzero.
3735 Note: When profile_block_flag == 2 the test need not be done
3736 but `__bb_init_trace_func' *must* be called.
e74389ff 3737
e075ae69
RH
3738 BLOCK_OR_LABEL may be used to generate a label number as a
3739 branch destination in case `__bb_init_func' will not be called.
e74389ff 3740
e075ae69
RH
3741 If described in a virtual assembler language the code to be
3742 output looks like:
2a2ab3f9 3743
e075ae69
RH
3744 cmp (LPBX0),0
3745 jne local_label
3746 parameter1 <- LPBX0
3747 call __bb_init_func
3748 local_label:
3749*/
c572e5ba 3750
e075ae69
RH
3751void
3752ix86_output_function_block_profiler (file, block_or_label)
3753 FILE *file;
3754 int block_or_label;
c572e5ba 3755{
e075ae69
RH
3756 static int num_func = 0;
3757 rtx xops[8];
3758 char block_table[80], false_label[80];
c572e5ba 3759
e075ae69 3760 ASM_GENERATE_INTERNAL_LABEL (block_table, "LPBX", 0);
e9a25f70 3761
e075ae69
RH
3762 xops[1] = gen_rtx_SYMBOL_REF (VOIDmode, block_table);
3763 xops[5] = stack_pointer_rtx;
3764 xops[7] = gen_rtx_REG (Pmode, 0); /* eax */
2a2ab3f9 3765
e075ae69 3766 CONSTANT_POOL_ADDRESS_P (xops[1]) = TRUE;
c572e5ba 3767
e075ae69 3768 switch (profile_block_flag)
c572e5ba 3769 {
e075ae69
RH
3770 case 2:
3771 xops[2] = GEN_INT (block_or_label);
3772 xops[3] = gen_rtx_MEM (Pmode,
3773 gen_rtx_SYMBOL_REF (VOIDmode, "__bb_init_trace_func"));
3774 xops[6] = GEN_INT (8);
e9a25f70 3775
e075ae69
RH
3776 output_asm_insn ("push{l}\t%2", xops);
3777 if (!flag_pic)
3778 output_asm_insn ("push{l}\t%1", xops);
e9a25f70 3779 else
870a0c2c 3780 {
e075ae69
RH
3781 output_asm_insn ("lea{l}\t{%a1, %7|%7, %a1}", xops);
3782 output_asm_insn ("push{l}\t%7", xops);
870a0c2c 3783 }
e075ae69
RH
3784 output_asm_insn ("call\t%P3", xops);
3785 output_asm_insn ("add{l}\t{%6, %5|%5, %6}", xops);
3786 break;
c572e5ba 3787
e075ae69
RH
3788 default:
3789 ASM_GENERATE_INTERNAL_LABEL (false_label, "LPBZ", num_func);
c572e5ba 3790
e075ae69
RH
3791 xops[0] = const0_rtx;
3792 xops[2] = gen_rtx_MEM (Pmode,
3793 gen_rtx_SYMBOL_REF (VOIDmode, false_label));
3794 xops[3] = gen_rtx_MEM (Pmode,
3795 gen_rtx_SYMBOL_REF (VOIDmode, "__bb_init_func"));
3796 xops[4] = gen_rtx_MEM (Pmode, xops[1]);
3797 xops[6] = GEN_INT (4);
a14003ee 3798
e075ae69 3799 CONSTANT_POOL_ADDRESS_P (xops[2]) = TRUE;
446ba526 3800
e075ae69
RH
3801 output_asm_insn ("cmp{l}\t{%0, %4|%4, %0}", xops);
3802 output_asm_insn ("jne\t%2", xops);
870a0c2c 3803
e075ae69
RH
3804 if (!flag_pic)
3805 output_asm_insn ("push{l}\t%1", xops);
3806 else
3807 {
3808 output_asm_insn ("lea{l}\t{%a1, %7|%7, %a2}", xops);
3809 output_asm_insn ("push{l}\t%7", xops);
870a0c2c 3810 }
e075ae69
RH
3811 output_asm_insn ("call\t%P3", xops);
3812 output_asm_insn ("add{l}\t{%6, %5|%5, %6}", xops);
3813 ASM_OUTPUT_INTERNAL_LABEL (file, "LPBZ", num_func);
3814 num_func++;
3815 break;
c572e5ba 3816 }
2a2ab3f9 3817}
305f097e 3818
e075ae69
RH
3819/* Output assembler code to FILE to increment a counter associated
3820 with basic block number BLOCKNO.
305f097e 3821
e075ae69 3822 If profile_block_flag == 2
ecbc4695 3823
e075ae69
RH
3824 Output code to initialize the global structure `__bb' and
3825 call the function `__bb_trace_func' which will increment the
3826 counter.
ecbc4695 3827
e075ae69
RH
3828 `__bb' consists of two words. In the first word the number
3829 of the basic block has to be stored. In the second word
3830 the address of a block allocated in the object module
3831 has to be stored.
ecbc4695 3832
e075ae69 3833 The basic block number is given by BLOCKNO.
ecbc4695 3834
e075ae69 3835 The address of the block is given by the label created with
305f097e 3836
e075ae69 3837 ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
305f097e 3838
e075ae69 3839 by FUNCTION_BLOCK_PROFILER.
ecbc4695 3840
e075ae69
RH
3841 Of course, since you are writing the definition of
3842 `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
3843 can take a short cut in the definition of this macro and use the
3844 name that you know will result.
305f097e 3845
e075ae69
RH
3846 If described in a virtual assembler language the code to be
3847 output looks like:
305f097e 3848
e075ae69
RH
3849 move BLOCKNO -> (__bb)
3850 move LPBX0 -> (__bb+4)
3851 call __bb_trace_func
305f097e 3852
e075ae69
RH
3853 Note that function `__bb_trace_func' must not change the
3854 machine state, especially the flag register. To grant
3855 this, you must output code to save and restore registers
3856 either in this macro or in the macros MACHINE_STATE_SAVE
3857 and MACHINE_STATE_RESTORE. The last two macros will be
3858 used in the function `__bb_trace_func', so you must make
3859 sure that the function prologue does not change any
3860 register prior to saving it with MACHINE_STATE_SAVE.
305f097e 3861
e075ae69 3862 else if profile_block_flag != 0
305f097e 3863
e075ae69
RH
3864 Output code to increment the counter directly.
3865 Basic blocks are numbered separately from zero within each
3866 compiled object module. The count associated with block number
3867 BLOCKNO is at index BLOCKNO in an array of words; the name of
3868 this array is a local symbol made with this statement:
32b5b1aa 3869
e075ae69 3870 ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2);
32b5b1aa 3871
e075ae69
RH
3872 Of course, since you are writing the definition of
3873 `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
3874 can take a short cut in the definition of this macro and use the
3875 name that you know will result.
32b5b1aa 3876
e075ae69
RH
3877 If described in a virtual assembler language the code to be
3878 output looks like:
32b5b1aa 3879
e075ae69
RH
3880 inc (LPBX2+4*BLOCKNO)
3881*/
32b5b1aa 3882
e075ae69
RH
3883void
3884ix86_output_block_profiler (file, blockno)
3885 FILE *file ATTRIBUTE_UNUSED;
3886 int blockno;
3887{
3888 rtx xops[8], cnt_rtx;
3889 char counts[80];
3890 char *block_table = counts;
3891
3892 switch (profile_block_flag)
3893 {
3894 case 2:
3895 ASM_GENERATE_INTERNAL_LABEL (block_table, "LPBX", 0);
32b5b1aa 3896
e075ae69
RH
3897 xops[1] = gen_rtx_SYMBOL_REF (VOIDmode, block_table);
3898 xops[2] = GEN_INT (blockno);
3899 xops[3] = gen_rtx_MEM (Pmode,
3900 gen_rtx_SYMBOL_REF (VOIDmode, "__bb_trace_func"));
3901 xops[4] = gen_rtx_SYMBOL_REF (VOIDmode, "__bb");
3902 xops[5] = plus_constant (xops[4], 4);
3903 xops[0] = gen_rtx_MEM (SImode, xops[4]);
3904 xops[6] = gen_rtx_MEM (SImode, xops[5]);
79325812 3905
e075ae69 3906 CONSTANT_POOL_ADDRESS_P (xops[1]) = TRUE;
32b5b1aa 3907
e075ae69
RH
3908 output_asm_insn ("pushf", xops);
3909 output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
3910 if (flag_pic)
32b5b1aa 3911 {
e075ae69
RH
3912 xops[7] = gen_rtx_REG (Pmode, 0); /* eax */
3913 output_asm_insn ("push{l}\t%7", xops);
3914 output_asm_insn ("lea{l}\t{%a1, %7|%7, %a1}", xops);
3915 output_asm_insn ("mov{l}\t{%7, %6|%6, %7}", xops);
3916 output_asm_insn ("pop{l}\t%7", xops);
3917 }
3918 else
3919 output_asm_insn ("mov{l}\t{%1, %6|%6, %1}", xops);
3920 output_asm_insn ("call\t%P3", xops);
3921 output_asm_insn ("popf", xops);
32b5b1aa 3922
e075ae69 3923 break;
32b5b1aa 3924
e075ae69
RH
3925 default:
3926 ASM_GENERATE_INTERNAL_LABEL (counts, "LPBX", 2);
3927 cnt_rtx = gen_rtx_SYMBOL_REF (VOIDmode, counts);
3928 SYMBOL_REF_FLAG (cnt_rtx) = TRUE;
32b5b1aa 3929
e075ae69
RH
3930 if (blockno)
3931 cnt_rtx = plus_constant (cnt_rtx, blockno*4);
32b5b1aa 3932
e075ae69
RH
3933 if (flag_pic)
3934 cnt_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, cnt_rtx);
32b5b1aa 3935
e075ae69
RH
3936 xops[0] = gen_rtx_MEM (SImode, cnt_rtx);
3937 output_asm_insn ("inc{l}\t%0", xops);
32b5b1aa 3938
e075ae69 3939 break;
32b5b1aa 3940 }
32b5b1aa 3941}
32b5b1aa 3942\f
79325812 3943void
e075ae69
RH
3944ix86_expand_move (mode, operands)
3945 enum machine_mode mode;
3946 rtx operands[];
32b5b1aa 3947{
e075ae69 3948 int strict = (reload_in_progress || reload_completed);
e075ae69 3949 rtx insn;
e9a25f70 3950
e075ae69 3951 if (flag_pic && mode == Pmode && symbolic_operand (operands[1], Pmode))
32b5b1aa 3952 {
e075ae69 3953 /* Emit insns to move operands[1] into operands[0]. */
e9a25f70 3954
e075ae69
RH
3955 if (GET_CODE (operands[0]) == MEM)
3956 operands[1] = force_reg (Pmode, operands[1]);
3957 else
32b5b1aa 3958 {
e075ae69
RH
3959 rtx temp = operands[0];
3960 if (GET_CODE (temp) != REG)
3961 temp = gen_reg_rtx (Pmode);
3962 temp = legitimize_pic_address (operands[1], temp);
3963 if (temp == operands[0])
3964 return;
3965 operands[1] = temp;
32b5b1aa 3966 }
e075ae69
RH
3967 }
3968 else
3969 {
d7a29404
JH
3970 if (GET_CODE (operands[0]) == MEM
3971 && (GET_MODE (operands[0]) == QImode
3972 || !push_operand (operands[0], mode))
3973 && GET_CODE (operands[1]) == MEM)
e075ae69 3974 operands[1] = force_reg (mode, operands[1]);
e9a25f70 3975
2c5a510c
RH
3976 if (push_operand (operands[0], mode)
3977 && ! general_no_elim_operand (operands[1], mode))
3978 operands[1] = copy_to_mode_reg (mode, operands[1]);
3979
e075ae69 3980 if (FLOAT_MODE_P (mode))
32b5b1aa 3981 {
d7a29404
JH
3982 /* If we are loading a floating point constant to a register,
3983 force the value to memory now, since we'll get better code
3984 out the back end. */
e075ae69
RH
3985
3986 if (strict)
3987 ;
e075ae69 3988 else if (GET_CODE (operands[1]) == CONST_DOUBLE
d7a29404 3989 && register_operand (operands[0], mode))
e075ae69 3990 operands[1] = validize_mem (force_const_mem (mode, operands[1]));
32b5b1aa 3991 }
32b5b1aa 3992 }
e9a25f70 3993
e075ae69 3994 insn = gen_rtx_SET (VOIDmode, operands[0], operands[1]);
e9a25f70 3995
e075ae69
RH
3996 emit_insn (insn);
3997}
e9a25f70 3998
e075ae69
RH
3999/* Attempt to expand a binary operator. Make the expansion closer to the
4000 actual machine, then just general_operand, which will allow 3 separate
9d81fc27 4001 memory references (one output, two input) in a single insn. */
e9a25f70 4002
e075ae69
RH
4003void
4004ix86_expand_binary_operator (code, mode, operands)
4005 enum rtx_code code;
4006 enum machine_mode mode;
4007 rtx operands[];
4008{
4009 int matching_memory;
4010 rtx src1, src2, dst, op, clob;
4011
4012 dst = operands[0];
4013 src1 = operands[1];
4014 src2 = operands[2];
4015
4016 /* Recognize <var1> = <value> <op> <var1> for commutative operators */
4017 if (GET_RTX_CLASS (code) == 'c'
4018 && (rtx_equal_p (dst, src2)
4019 || immediate_operand (src1, mode)))
4020 {
4021 rtx temp = src1;
4022 src1 = src2;
4023 src2 = temp;
32b5b1aa 4024 }
e9a25f70 4025
e075ae69
RH
4026 /* If the destination is memory, and we do not have matching source
4027 operands, do things in registers. */
4028 matching_memory = 0;
4029 if (GET_CODE (dst) == MEM)
32b5b1aa 4030 {
e075ae69
RH
4031 if (rtx_equal_p (dst, src1))
4032 matching_memory = 1;
4033 else if (GET_RTX_CLASS (code) == 'c'
4034 && rtx_equal_p (dst, src2))
4035 matching_memory = 2;
4036 else
4037 dst = gen_reg_rtx (mode);
4038 }
4039
4040 /* Both source operands cannot be in memory. */
4041 if (GET_CODE (src1) == MEM && GET_CODE (src2) == MEM)
4042 {
4043 if (matching_memory != 2)
4044 src2 = force_reg (mode, src2);
4045 else
4046 src1 = force_reg (mode, src1);
32b5b1aa 4047 }
e9a25f70 4048
06a964de
JH
4049 /* If the operation is not commutable, source 1 cannot be a constant
4050 or non-matching memory. */
4051 if ((CONSTANT_P (src1)
4052 || (!matching_memory && GET_CODE (src1) == MEM))
4053 && GET_RTX_CLASS (code) != 'c')
e075ae69
RH
4054 src1 = force_reg (mode, src1);
4055
4056 /* If optimizing, copy to regs to improve CSE */
4057 if (optimize && !reload_in_progress && !reload_completed)
32b5b1aa 4058 {
e075ae69
RH
4059 if (GET_CODE (dst) == MEM)
4060 dst = gen_reg_rtx (mode);
4061 if (GET_CODE (src1) == MEM)
4062 src1 = force_reg (mode, src1);
4063 if (GET_CODE (src2) == MEM)
4064 src2 = force_reg (mode, src2);
32b5b1aa 4065 }
e9a25f70 4066
e075ae69
RH
4067 /* Emit the instruction. */
4068
4069 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, mode, src1, src2));
4070 if (reload_in_progress)
4071 {
4072 /* Reload doesn't know about the flags register, and doesn't know that
4073 it doesn't want to clobber it. We can only do this with PLUS. */
4074 if (code != PLUS)
4075 abort ();
4076 emit_insn (op);
4077 }
4078 else
32b5b1aa 4079 {
e075ae69
RH
4080 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
4081 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
32b5b1aa 4082 }
e9a25f70 4083
e075ae69
RH
4084 /* Fix up the destination if needed. */
4085 if (dst != operands[0])
4086 emit_move_insn (operands[0], dst);
4087}
4088
4089/* Return TRUE or FALSE depending on whether the binary operator meets the
4090 appropriate constraints. */
4091
4092int
4093ix86_binary_operator_ok (code, mode, operands)
4094 enum rtx_code code;
4095 enum machine_mode mode ATTRIBUTE_UNUSED;
4096 rtx operands[3];
4097{
4098 /* Both source operands cannot be in memory. */
4099 if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[2]) == MEM)
4100 return 0;
4101 /* If the operation is not commutable, source 1 cannot be a constant. */
4102 if (CONSTANT_P (operands[1]) && GET_RTX_CLASS (code) != 'c')
4103 return 0;
4104 /* If the destination is memory, we must have a matching source operand. */
4105 if (GET_CODE (operands[0]) == MEM
4106 && ! (rtx_equal_p (operands[0], operands[1])
4107 || (GET_RTX_CLASS (code) == 'c'
4108 && rtx_equal_p (operands[0], operands[2]))))
4109 return 0;
06a964de
JH
4110 /* If the operation is not commutable and the source 1 is memory, we must
4111 have a matching destionation. */
4112 if (GET_CODE (operands[1]) == MEM
4113 && GET_RTX_CLASS (code) != 'c'
4114 && ! rtx_equal_p (operands[0], operands[1]))
4115 return 0;
e075ae69
RH
4116 return 1;
4117}
4118
4119/* Attempt to expand a unary operator. Make the expansion closer to the
4120 actual machine, then just general_operand, which will allow 2 separate
9d81fc27 4121 memory references (one output, one input) in a single insn. */
e075ae69 4122
9d81fc27 4123void
e075ae69
RH
4124ix86_expand_unary_operator (code, mode, operands)
4125 enum rtx_code code;
4126 enum machine_mode mode;
4127 rtx operands[];
4128{
06a964de
JH
4129 int matching_memory;
4130 rtx src, dst, op, clob;
4131
4132 dst = operands[0];
4133 src = operands[1];
e075ae69 4134
06a964de
JH
4135 /* If the destination is memory, and we do not have matching source
4136 operands, do things in registers. */
4137 matching_memory = 0;
4138 if (GET_CODE (dst) == MEM)
32b5b1aa 4139 {
06a964de
JH
4140 if (rtx_equal_p (dst, src))
4141 matching_memory = 1;
e075ae69 4142 else
06a964de 4143 dst = gen_reg_rtx (mode);
32b5b1aa 4144 }
e9a25f70 4145
06a964de
JH
4146 /* When source operand is memory, destination must match. */
4147 if (!matching_memory && GET_CODE (src) == MEM)
4148 src = force_reg (mode, src);
4149
4150 /* If optimizing, copy to regs to improve CSE */
4151 if (optimize && !reload_in_progress && !reload_completed)
4152 {
4153 if (GET_CODE (dst) == MEM)
4154 dst = gen_reg_rtx (mode);
4155 if (GET_CODE (src) == MEM)
4156 src = force_reg (mode, src);
4157 }
4158
4159 /* Emit the instruction. */
4160
4161 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_e (code, mode, src));
4162 if (reload_in_progress || code == NOT)
4163 {
4164 /* Reload doesn't know about the flags register, and doesn't know that
4165 it doesn't want to clobber it. */
4166 if (code != NOT)
4167 abort ();
4168 emit_insn (op);
4169 }
4170 else
4171 {
4172 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
4173 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
4174 }
4175
4176 /* Fix up the destination if needed. */
4177 if (dst != operands[0])
4178 emit_move_insn (operands[0], dst);
e075ae69
RH
4179}
4180
4181/* Return TRUE or FALSE depending on whether the unary operator meets the
4182 appropriate constraints. */
4183
4184int
4185ix86_unary_operator_ok (code, mode, operands)
4186 enum rtx_code code ATTRIBUTE_UNUSED;
4187 enum machine_mode mode ATTRIBUTE_UNUSED;
4188 rtx operands[2] ATTRIBUTE_UNUSED;
4189{
06a964de
JH
4190 /* If one of operands is memory, source and destination must match. */
4191 if ((GET_CODE (operands[0]) == MEM
4192 || GET_CODE (operands[1]) == MEM)
4193 && ! rtx_equal_p (operands[0], operands[1]))
4194 return FALSE;
e075ae69
RH
4195 return TRUE;
4196}
4197
4198/* Produce an unsigned comparison for a given signed comparison. */
4199
4200static enum rtx_code
4201unsigned_comparison (code)
4202 enum rtx_code code;
4203{
4204 switch (code)
32b5b1aa 4205 {
e075ae69
RH
4206 case GT:
4207 code = GTU;
4208 break;
4209 case LT:
4210 code = LTU;
4211 break;
4212 case GE:
4213 code = GEU;
4214 break;
4215 case LE:
4216 code = LEU;
4217 break;
4218 case EQ:
4219 case NE:
4220 case LEU:
4221 case LTU:
4222 case GEU:
4223 case GTU:
4224 break;
4225 default:
4226 abort ();
4227 }
4228 return code;
4229}
4230
4231/* Generate insn patterns to do an integer compare of OPERANDS. */
4232
4233static rtx
4234ix86_expand_int_compare (code, op0, op1)
4235 enum rtx_code code;
4236 rtx op0, op1;
4237{
4238 enum machine_mode cmpmode;
4239 rtx tmp, flags;
4240
4241 cmpmode = SELECT_CC_MODE (code, op0, op1);
4242 flags = gen_rtx_REG (cmpmode, FLAGS_REG);
4243
4244 /* This is very simple, but making the interface the same as in the
4245 FP case makes the rest of the code easier. */
4246 tmp = gen_rtx_COMPARE (cmpmode, op0, op1);
4247 emit_insn (gen_rtx_SET (VOIDmode, flags, tmp));
4248
4249 /* Return the test that should be put into the flags user, i.e.
4250 the bcc, scc, or cmov instruction. */
4251 return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
4252}
4253
4254/* Generate insn patterns to do a floating point compare of OPERANDS.
4255 If UNORDERED, allow for unordered compares. */
4256
4257static rtx
4258ix86_expand_fp_compare (code, op0, op1, unordered)
4259 enum rtx_code code;
4260 rtx op0, op1;
4261 int unordered;
4262{
4263 enum machine_mode fpcmp_mode;
4264 enum machine_mode intcmp_mode;
4265 rtx tmp;
4266
4267 /* When not doing IEEE compliant compares, disable unordered. */
4268 if (! TARGET_IEEE_FP)
4269 unordered = 0;
4270 fpcmp_mode = unordered ? CCFPUmode : CCFPmode;
4271
4272 /* ??? If we knew whether invalid-operand exceptions were masked,
4273 we could rely on fcom to raise an exception and take care of
4274 NaNs. But we don't. We could know this from c9x math bits. */
4275 if (TARGET_IEEE_FP)
4276 unordered = 1;
4277
4278 /* All of the unordered compare instructions only work on registers.
4279 The same is true of the XFmode compare instructions. */
4280 if (unordered || GET_MODE (op0) == XFmode)
4281 {
4282 op0 = force_reg (GET_MODE (op0), op0);
4283 op1 = force_reg (GET_MODE (op1), op1);
4284 }
4285 else
4286 {
4287 /* %%% We only allow op1 in memory; op0 must be st(0). So swap
4288 things around if they appear profitable, otherwise force op0
4289 into a register. */
4290
4291 if (standard_80387_constant_p (op0) == 0
4292 || (GET_CODE (op0) == MEM
4293 && ! (standard_80387_constant_p (op1) == 0
4294 || GET_CODE (op1) == MEM)))
32b5b1aa 4295 {
e075ae69
RH
4296 rtx tmp;
4297 tmp = op0, op0 = op1, op1 = tmp;
4298 code = swap_condition (code);
4299 }
4300
4301 if (GET_CODE (op0) != REG)
4302 op0 = force_reg (GET_MODE (op0), op0);
4303
4304 if (CONSTANT_P (op1))
4305 {
4306 if (standard_80387_constant_p (op1))
4307 op1 = force_reg (GET_MODE (op1), op1);
4308 else
4309 op1 = validize_mem (force_const_mem (GET_MODE (op1), op1));
32b5b1aa
SC
4310 }
4311 }
e9a25f70 4312
e075ae69
RH
4313 /* %%% fcomi is probably always faster, even when dealing with memory,
4314 since compare-and-branch would be three insns instead of four. */
4315 if (TARGET_CMOVE && !unordered)
32b5b1aa 4316 {
e075ae69
RH
4317 if (GET_CODE (op0) != REG)
4318 op0 = force_reg (GET_MODE (op0), op0);
4319 if (GET_CODE (op1) != REG)
4320 op1 = force_reg (GET_MODE (op1), op1);
4321
4322 tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
4323 tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG), tmp);
4324 emit_insn (tmp);
4325
4326 /* The FP codes work out to act like unsigned. */
4327 code = unsigned_comparison (code);
4328 intcmp_mode = fpcmp_mode;
4329 }
4330 else
4331 {
4332 /* Sadness wrt reg-stack pops killing fpsr -- gotta get fnstsw first. */
e9a25f70 4333
e075ae69
RH
4334 rtx tmp2;
4335 tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
4336 tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), 9);
4337 tmp = gen_reg_rtx (HImode);
4338 emit_insn (gen_rtx_SET (VOIDmode, tmp, tmp2));
4339
4340 if (! unordered)
32b5b1aa 4341 {
e075ae69
RH
4342 /* We have two options here -- use sahf, or testing bits of ah
4343 directly. On PPRO, they are equivalent, sahf being one byte
4344 smaller. On Pentium, sahf is non-pairable while test is UV
4345 pairable. */
4346
4347 if (TARGET_USE_SAHF || optimize_size)
32b5b1aa 4348 {
e075ae69 4349 do_sahf:
e9a25f70 4350
e075ae69
RH
4351 /* The FP codes work out to act like unsigned. */
4352 code = unsigned_comparison (code);
4353 emit_insn (gen_x86_sahf_1 (tmp));
4354 intcmp_mode = CCmode;
32b5b1aa
SC
4355 }
4356 else
4357 {
e075ae69
RH
4358 /*
4359 * The numbers below correspond to the bits of the FPSW in AH.
d22ce03d 4360 * C3, C2, and C0 are in bits 0x40, 0x4, and 0x01 respectively.
e075ae69
RH
4361 *
4362 * cmp C3 C2 C0
4363 * > 0 0 0
4364 * < 0 0 1
4365 * = 1 0 0
4366 * un 1 1 1
4367 */
4368
4369 int mask;
4370
4371 switch (code)
32b5b1aa 4372 {
e075ae69 4373 case GT:
d22ce03d 4374 mask = 0x41;
e075ae69
RH
4375 code = EQ;
4376 break;
4377 case LT:
4378 mask = 0x01;
4379 code = NE;
4380 break;
4381 case GE:
4382 /* We'd have to use `xorb 1,ah; andb 0x41,ah', so it's
4383 faster in all cases to just fall back on sahf. */
4384 goto do_sahf;
4385 case LE:
4386 mask = 0x41;
4387 code = NE;
4388 break;
4389 case EQ:
4390 mask = 0x40;
4391 code = NE;
4392 break;
4393 case NE:
4394 mask = 0x40;
4395 code = EQ;
4396 break;
4397 default:
4398 abort ();
32b5b1aa 4399 }
e075ae69
RH
4400
4401 emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (mask)));
4402 intcmp_mode = CCNOmode;
32b5b1aa
SC
4403 }
4404 }
4405 else
4406 {
e075ae69
RH
4407 /* In the unordered case, we have to check C2 for NaN's, which
4408 doesn't happen to work out to anything nice combination-wise.
4409 So do some bit twiddling on the value we've got in AH to come
4410 up with an appropriate set of condition codes. */
4411
4412 intcmp_mode = CCNOmode;
4413 switch (code)
32b5b1aa 4414 {
e075ae69
RH
4415 case GT:
4416 emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (0x45)));
4417 code = EQ;
4418 break;
4419 case LT:
4420 emit_insn (gen_andqi_ext_0 (tmp, tmp, GEN_INT (0x45)));
4421 emit_insn (gen_cmpqi_ext_3 (tmp, GEN_INT (0x01)));
4422 intcmp_mode = CCmode;
4423 code = EQ;
4424 break;
4425 case GE:
4426 emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (0x05)));
4427 code = EQ;
4428 break;
4429 case LE:
4430 emit_insn (gen_andqi_ext_0 (tmp, tmp, GEN_INT (0x45)));
4431 emit_insn (gen_addqi_ext_1 (tmp, tmp, constm1_rtx));
4432 emit_insn (gen_cmpqi_ext_3 (tmp, GEN_INT (0x40)));
4433 intcmp_mode = CCmode;
4434 code = LTU;
4435 break;
4436 case EQ:
4437 emit_insn (gen_andqi_ext_0 (tmp, tmp, GEN_INT (0x45)));
4438 emit_insn (gen_cmpqi_ext_3 (tmp, GEN_INT (0x40)));
4439 intcmp_mode = CCmode;
4440 code = EQ;
4441 break;
4442 case NE:
4443 emit_insn (gen_andqi_ext_0 (tmp, tmp, GEN_INT (0x45)));
7abd4e00 4444 emit_insn (gen_xorqi_cc_ext_1 (tmp, tmp, GEN_INT (0x40)));
e075ae69
RH
4445 code = NE;
4446 break;
4447 default:
4448 abort ();
32b5b1aa
SC
4449 }
4450 }
32b5b1aa 4451 }
e075ae69
RH
4452
4453 /* Return the test that should be put into the flags user, i.e.
4454 the bcc, scc, or cmov instruction. */
4455 return gen_rtx_fmt_ee (code, VOIDmode,
4456 gen_rtx_REG (intcmp_mode, FLAGS_REG),
4457 const0_rtx);
4458}
4459
4460static rtx
4461ix86_expand_compare (code, unordered)
4462 enum rtx_code code;
4463 int unordered;
4464{
4465 rtx op0, op1, ret;
4466 op0 = ix86_compare_op0;
4467 op1 = ix86_compare_op1;
4468
4469 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
4470 ret = ix86_expand_fp_compare (code, op0, op1, unordered);
32b5b1aa 4471 else
e075ae69
RH
4472 ret = ix86_expand_int_compare (code, op0, op1);
4473
4474 return ret;
4475}
4476
4477void
4478ix86_expand_branch (code, unordered, label)
4479 enum rtx_code code;
4480 int unordered;
4481 rtx label;
4482{
4483 rtx tmp, lo[2], hi[2], label2;
4484 enum rtx_code code1, code2, code3;
4485
4486 if (GET_MODE (ix86_compare_op0) != DImode)
32b5b1aa 4487 {
e075ae69
RH
4488 tmp = ix86_expand_compare (code, unordered);
4489 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
4490 gen_rtx_LABEL_REF (VOIDmode, label),
4491 pc_rtx);
4492 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
32b5b1aa
SC
4493 return;
4494 }
32b5b1aa 4495
e075ae69
RH
4496 /* Expand DImode branch into multiple compare+branch. */
4497
4498 if (CONSTANT_P (ix86_compare_op0) && ! CONSTANT_P (ix86_compare_op1))
32b5b1aa 4499 {
e075ae69
RH
4500 tmp = ix86_compare_op0;
4501 ix86_compare_op0 = ix86_compare_op1;
4502 ix86_compare_op1 = tmp;
4503 code = swap_condition (code);
4504 }
4505 split_di (&ix86_compare_op0, 1, lo+0, hi+0);
4506 split_di (&ix86_compare_op1, 1, lo+1, hi+1);
32b5b1aa 4507
e075ae69
RH
4508 /* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to avoid
4509 two branches. This costs one extra insn, so disable when optimizing
4510 for size. */
32b5b1aa 4511
e075ae69
RH
4512 if ((code == EQ || code == NE)
4513 && (!optimize_size
4514 || hi[1] == const0_rtx || lo[1] == const0_rtx))
4515 {
4516 rtx xor0, xor1;
32b5b1aa 4517
e075ae69
RH
4518 xor1 = hi[0];
4519 if (hi[1] != const0_rtx)
4520 {
4521 xor1 = expand_binop (SImode, xor_optab, xor1, hi[1],
4522 NULL_RTX, 0, OPTAB_WIDEN);
4523 }
32b5b1aa 4524
e075ae69
RH
4525 xor0 = lo[0];
4526 if (lo[1] != const0_rtx)
4527 {
4528 xor0 = expand_binop (SImode, xor_optab, xor0, lo[1],
4529 NULL_RTX, 0, OPTAB_WIDEN);
32b5b1aa
SC
4530 }
4531
e075ae69
RH
4532 tmp = expand_binop (SImode, ior_optab, xor1, xor0,
4533 NULL_RTX, 0, OPTAB_WIDEN);
32b5b1aa 4534
e075ae69
RH
4535 ix86_compare_op0 = tmp;
4536 ix86_compare_op1 = const0_rtx;
4537 ix86_expand_branch (code, unordered, label);
4538 return;
32b5b1aa
SC
4539 }
4540
e075ae69
RH
4541 /* Otherwise, if we are doing less-than, op1 is a constant and the
4542 low word is zero, then we can just examine the high word. */
4543
4544 if (GET_CODE (hi[1]) == CONST_INT && lo[1] == const0_rtx
4545 && (code == LT || code == LTU))
32b5b1aa 4546 {
e075ae69
RH
4547 ix86_compare_op0 = hi[0];
4548 ix86_compare_op1 = hi[1];
4549 ix86_expand_branch (code, unordered, label);
4550 return;
4551 }
32b5b1aa 4552
e075ae69
RH
4553 /* Otherwise, we need two or three jumps. */
4554
4555 label2 = gen_label_rtx ();
32b5b1aa 4556
e075ae69
RH
4557 code1 = code;
4558 code2 = swap_condition (code);
4559 code3 = unsigned_condition (code);
4560
4561 switch (code)
4562 {
4563 case LT: case GT: case LTU: case GTU:
4564 break;
4565
4566 case LE: code1 = LT; code2 = GT; break;
4567 case GE: code1 = GT; code2 = LT; break;
4568 case LEU: code1 = LTU; code2 = GTU; break;
4569 case GEU: code1 = GTU; code2 = LTU; break;
4570
4571 case EQ: code1 = NIL; code2 = NE; break;
4572 case NE: code2 = NIL; break;
4573
4574 default:
4575 abort ();
32b5b1aa 4576 }
e075ae69
RH
4577
4578 /*
4579 * a < b =>
4580 * if (hi(a) < hi(b)) goto true;
4581 * if (hi(a) > hi(b)) goto false;
4582 * if (lo(a) < lo(b)) goto true;
4583 * false:
4584 */
4585
4586 ix86_compare_op0 = hi[0];
4587 ix86_compare_op1 = hi[1];
4588
4589 if (code1 != NIL)
4590 ix86_expand_branch (code1, unordered, label);
4591 if (code2 != NIL)
4592 ix86_expand_branch (code2, unordered, label2);
4593
4594 ix86_compare_op0 = lo[0];
4595 ix86_compare_op1 = lo[1];
4596 ix86_expand_branch (code3, unordered, label);
4597
4598 if (code2 != NIL)
4599 emit_label (label2);
32b5b1aa 4600}
e075ae69 4601
32b5b1aa 4602int
e075ae69
RH
4603ix86_expand_setcc (code, unordered, dest)
4604 enum rtx_code code;
4605 int unordered;
4606 rtx dest;
32b5b1aa 4607{
e075ae69
RH
4608 rtx ret, tmp;
4609 int type;
4610
4611 if (GET_MODE (ix86_compare_op0) == DImode)
4612 return 0; /* FAIL */
4613
4614 /* Three modes of generation:
4615 0 -- destination does not overlap compare sources:
4616 clear dest first, emit strict_low_part setcc.
4617 1 -- destination does overlap compare sources:
4618 emit subreg setcc, zero extend.
4619 2 -- destination is in QImode:
4620 emit setcc only.
4621 */
4622
4623 type = 0;
e075ae69
RH
4624
4625 if (GET_MODE (dest) == QImode)
4626 type = 2;
4627 else if (reg_overlap_mentioned_p (dest, ix86_compare_op0)
a500c31b 4628 || reg_overlap_mentioned_p (dest, ix86_compare_op1))
e075ae69
RH
4629 type = 1;
4630
4631 if (type == 0)
4632 emit_move_insn (dest, const0_rtx);
4633
4634 ret = ix86_expand_compare (code, unordered);
4635 PUT_MODE (ret, QImode);
4636
4637 tmp = dest;
4638 if (type == 0)
32b5b1aa 4639 {
e075ae69
RH
4640 tmp = gen_lowpart (QImode, dest);
4641 tmp = gen_rtx_STRICT_LOW_PART (VOIDmode, tmp);
4642 }
4643 else if (type == 1)
4644 {
4645 if (!cse_not_expected)
4646 tmp = gen_reg_rtx (QImode);
4647 else
4648 tmp = gen_lowpart (QImode, dest);
4649 }
32b5b1aa 4650
e075ae69
RH
4651 emit_insn (gen_rtx_SET (VOIDmode, tmp, ret));
4652
4653 if (type == 1)
4654 {
4655 rtx clob;
4656
4657 tmp = gen_rtx_ZERO_EXTEND (GET_MODE (dest), tmp);
4658 tmp = gen_rtx_SET (VOIDmode, dest, tmp);
4659 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
4660 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
4661 emit_insn (tmp);
32b5b1aa 4662 }
e075ae69
RH
4663
4664 return 1; /* DONE */
32b5b1aa 4665}
e075ae69 4666
32b5b1aa 4667int
e075ae69
RH
4668ix86_expand_int_movcc (operands)
4669 rtx operands[];
32b5b1aa 4670{
e075ae69
RH
4671 enum rtx_code code = GET_CODE (operands[1]), compare_code;
4672 rtx compare_seq, compare_op;
32b5b1aa 4673
36583fea
JH
4674 /* When the compare code is not LTU or GEU, we can not use sbbl case.
4675 In case comparsion is done with immediate, we can convert it to LTU or
4676 GEU by altering the integer. */
4677
4678 if ((code == LEU || code == GTU)
4679 && GET_CODE (ix86_compare_op1) == CONST_INT
4680 && GET_MODE (operands[0]) != HImode
4681 && (unsigned int)INTVAL (ix86_compare_op1) != 0xffffffff
4682 && GET_CODE (operands[2]) == CONST_INT
4683 && GET_CODE (operands[3]) == CONST_INT)
4684 {
4685 if (code == LEU)
4686 code = LTU;
4687 else
4688 code = GEU;
4689 ix86_compare_op1 = GEN_INT (INTVAL (ix86_compare_op1) + 1);
4690 }
e075ae69
RH
4691 start_sequence ();
4692 compare_op = ix86_expand_compare (code, code == EQ || code == NE);
4693 compare_seq = gen_sequence ();
4694 end_sequence ();
4695
4696 compare_code = GET_CODE (compare_op);
4697
4698 /* Don't attempt mode expansion here -- if we had to expand 5 or 6
4699 HImode insns, we'd be swallowed in word prefix ops. */
4700
4701 if (GET_MODE (operands[0]) != HImode
4702 && GET_CODE (operands[2]) == CONST_INT
4703 && GET_CODE (operands[3]) == CONST_INT)
4704 {
4705 rtx out = operands[0];
4706 HOST_WIDE_INT ct = INTVAL (operands[2]);
4707 HOST_WIDE_INT cf = INTVAL (operands[3]);
4708 HOST_WIDE_INT diff;
4709
36583fea 4710 if (compare_code == LTU || compare_code == GEU)
e075ae69 4711 {
e075ae69
RH
4712
4713 /* Detect overlap between destination and compare sources. */
4714 rtx tmp = out;
4715
36583fea
JH
4716 /* To simplify rest of code, restrict to the GEU case. */
4717 if (compare_code == LTU)
4718 {
4719 int tmp = ct;
4720 ct = cf;
4721 cf = tmp;
4722 compare_code = reverse_condition (compare_code);
4723 code = reverse_condition (code);
4724 }
4725 diff = ct - cf;
4726
e075ae69 4727 if (reg_overlap_mentioned_p (out, ix86_compare_op0)
a500c31b 4728 || reg_overlap_mentioned_p (out, ix86_compare_op1))
e075ae69
RH
4729 tmp = gen_reg_rtx (SImode);
4730
4731 emit_insn (compare_seq);
4732 emit_insn (gen_x86_movsicc_0_m1 (tmp));
4733
36583fea
JH
4734 if (diff == 1)
4735 {
4736 /*
4737 * cmpl op0,op1
4738 * sbbl dest,dest
4739 * [addl dest, ct]
4740 *
4741 * Size 5 - 8.
4742 */
4743 if (ct)
4744 emit_insn (gen_addsi3 (out, out, GEN_INT (ct)));
4745 }
4746 else if (cf == -1)
4747 {
4748 /*
4749 * cmpl op0,op1
4750 * sbbl dest,dest
4751 * orl $ct, dest
4752 *
4753 * Size 8.
4754 */
4755 emit_insn (gen_iorsi3 (out, out, GEN_INT (ct)));
4756 }
4757 else if (diff == -1 && ct)
4758 {
4759 /*
4760 * cmpl op0,op1
4761 * sbbl dest,dest
4762 * xorl $-1, dest
4763 * [addl dest, cf]
4764 *
4765 * Size 8 - 11.
4766 */
4767 emit_insn (gen_one_cmplsi2 (tmp, tmp));
4768 if (cf)
4769 emit_insn (gen_addsi3 (out, out, GEN_INT (cf)));
4770 }
4771 else
4772 {
4773 /*
4774 * cmpl op0,op1
4775 * sbbl dest,dest
4776 * andl cf - ct, dest
4777 * [addl dest, ct]
4778 *
4779 * Size 8 - 11.
4780 */
4781 emit_insn (gen_andsi3 (out, out, GEN_INT (cf - ct)));
4782 if (ct)
4783 emit_insn (gen_addsi3 (out, out, GEN_INT (ct)));
4784 }
e075ae69
RH
4785
4786 if (tmp != out)
4787 emit_move_insn (out, tmp);
4788
4789 return 1; /* DONE */
4790 }
4791
4792 diff = ct - cf;
4793 if (diff < 0)
4794 {
4795 HOST_WIDE_INT tmp;
4796 tmp = ct, ct = cf, cf = tmp;
4797 diff = -diff;
4798 compare_code = reverse_condition (compare_code);
4799 code = reverse_condition (code);
4800 }
4801 if (diff == 1 || diff == 2 || diff == 4 || diff == 8
4802 || diff == 3 || diff == 5 || diff == 9)
4803 {
4804 /*
4805 * xorl dest,dest
4806 * cmpl op1,op2
4807 * setcc dest
4808 * lea cf(dest*(ct-cf)),dest
4809 *
4810 * Size 14.
4811 *
4812 * This also catches the degenerate setcc-only case.
4813 */
4814
4815 rtx tmp;
4816 int nops;
4817
4818 out = emit_store_flag (out, code, ix86_compare_op0,
4819 ix86_compare_op1, VOIDmode, 0, 1);
4820
4821 nops = 0;
4822 if (diff == 1)
4823 tmp = out;
4824 else
4825 {
4826 tmp = gen_rtx_MULT (SImode, out, GEN_INT (diff & ~1));
4827 nops++;
4828 if (diff & 1)
4829 {
4830 tmp = gen_rtx_PLUS (SImode, tmp, out);
4831 nops++;
4832 }
4833 }
4834 if (cf != 0)
4835 {
4836 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (cf));
4837 nops++;
4838 }
4839 if (tmp != out)
4840 {
4841 if (nops == 0)
4842 emit_move_insn (out, tmp);
4843 else if (nops == 1)
4844 {
4845 rtx clob;
4846
4847 clob = gen_rtx_REG (CCmode, FLAGS_REG);
4848 clob = gen_rtx_CLOBBER (VOIDmode, clob);
4849
4850 tmp = gen_rtx_SET (VOIDmode, out, tmp);
4851 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
4852 emit_insn (tmp);
4853 }
4854 else
4855 emit_insn (gen_rtx_SET (VOIDmode, out, tmp));
4856 }
4857 if (out != operands[0])
4858 emit_move_insn (operands[0], out);
4859
4860 return 1; /* DONE */
4861 }
4862
4863 /*
4864 * General case: Jumpful:
4865 * xorl dest,dest cmpl op1, op2
4866 * cmpl op1, op2 movl ct, dest
4867 * setcc dest jcc 1f
4868 * decl dest movl cf, dest
4869 * andl (cf-ct),dest 1:
4870 * addl ct,dest
4871 *
4872 * Size 20. Size 14.
4873 *
4874 * This is reasonably steep, but branch mispredict costs are
4875 * high on modern cpus, so consider failing only if optimizing
4876 * for space.
4877 *
4878 * %%% Parameterize branch_cost on the tuning architecture, then
4879 * use that. The 80386 couldn't care less about mispredicts.
4880 */
4881
4882 if (!optimize_size && !TARGET_CMOVE)
4883 {
4884 if (ct == 0)
4885 {
4886 ct = cf;
4887 cf = 0;
4888 compare_code = reverse_condition (compare_code);
4889 code = reverse_condition (code);
4890 }
4891
4892 out = emit_store_flag (out, code, ix86_compare_op0,
4893 ix86_compare_op1, VOIDmode, 0, 1);
4894
4895 emit_insn (gen_addsi3 (out, out, constm1_rtx));
4896 emit_insn (gen_andsi3 (out, out, GEN_INT (cf-ct)));
4897 if (ct != 0)
4898 emit_insn (gen_addsi3 (out, out, GEN_INT (ct)));
4899 if (out != operands[0])
4900 emit_move_insn (operands[0], out);
4901
4902 return 1; /* DONE */
4903 }
4904 }
4905
4906 if (!TARGET_CMOVE)
4907 {
4908 /* Try a few things more with specific constants and a variable. */
4909
78a0d70c 4910 optab op;
e075ae69
RH
4911 rtx var, orig_out, out, tmp;
4912
4913 if (optimize_size)
4914 return 0; /* FAIL */
4915
4916 /* If one of the two operands is an interesting constant, load a
4917 constant with the above and mask it in with a logical operation. */
4918
4919 if (GET_CODE (operands[2]) == CONST_INT)
4920 {
4921 var = operands[3];
4922 if (INTVAL (operands[2]) == 0)
4923 operands[3] = constm1_rtx, op = and_optab;
4924 else if (INTVAL (operands[2]) == -1)
4925 operands[3] = const0_rtx, op = ior_optab;
78a0d70c
ZW
4926 else
4927 return 0; /* FAIL */
e075ae69
RH
4928 }
4929 else if (GET_CODE (operands[3]) == CONST_INT)
4930 {
4931 var = operands[2];
4932 if (INTVAL (operands[3]) == 0)
4933 operands[2] = constm1_rtx, op = and_optab;
4934 else if (INTVAL (operands[3]) == -1)
4935 operands[2] = const0_rtx, op = ior_optab;
78a0d70c
ZW
4936 else
4937 return 0; /* FAIL */
e075ae69 4938 }
78a0d70c 4939 else
e075ae69
RH
4940 return 0; /* FAIL */
4941
4942 orig_out = operands[0];
4943 tmp = gen_reg_rtx (GET_MODE (orig_out));
4944 operands[0] = tmp;
4945
4946 /* Recurse to get the constant loaded. */
4947 if (ix86_expand_int_movcc (operands) == 0)
4948 return 0; /* FAIL */
4949
4950 /* Mask in the interesting variable. */
4951 out = expand_binop (GET_MODE (orig_out), op, var, tmp, orig_out, 0,
4952 OPTAB_WIDEN);
4953 if (out != orig_out)
4954 emit_move_insn (orig_out, out);
4955
4956 return 1; /* DONE */
4957 }
4958
4959 /*
4960 * For comparison with above,
4961 *
4962 * movl cf,dest
4963 * movl ct,tmp
4964 * cmpl op1,op2
4965 * cmovcc tmp,dest
4966 *
4967 * Size 15.
4968 */
4969
4970 if (! nonimmediate_operand (operands[2], GET_MODE (operands[0])))
4971 operands[2] = force_reg (GET_MODE (operands[0]), operands[2]);
4972 if (! nonimmediate_operand (operands[3], GET_MODE (operands[0])))
4973 operands[3] = force_reg (GET_MODE (operands[0]), operands[3]);
4974
4975 emit_insn (compare_seq);
4976 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4977 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
4978 compare_op, operands[2],
4979 operands[3])));
4980
4981 return 1; /* DONE */
e9a25f70 4982}
e075ae69 4983
32b5b1aa 4984int
e075ae69
RH
4985ix86_expand_fp_movcc (operands)
4986 rtx operands[];
32b5b1aa 4987{
e075ae69
RH
4988 enum rtx_code code;
4989 enum machine_mode mode;
4990 rtx tmp;
32b5b1aa 4991
e075ae69
RH
4992 /* The floating point conditional move instructions don't directly
4993 support conditions resulting from a signed integer comparison. */
32b5b1aa 4994
e075ae69
RH
4995 code = GET_CODE (operands[1]);
4996 switch (code)
4997 {
4998 case LT:
4999 case LE:
5000 case GE:
5001 case GT:
5002 tmp = gen_reg_rtx (QImode);
5003 ix86_expand_setcc (code, 0, tmp);
5004 code = NE;
5005 ix86_compare_op0 = tmp;
5006 ix86_compare_op1 = const0_rtx;
5007 break;
5008
5009 default:
5010 break;
5011 }
e9a25f70 5012
e075ae69
RH
5013 mode = SELECT_CC_MODE (code, ix86_compare_op0, ix86_compare_op1);
5014 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, FLAGS_REG),
5015 gen_rtx_COMPARE (mode,
5016 ix86_compare_op0,
5017 ix86_compare_op1)));
5018 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5019 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
5020 gen_rtx_fmt_ee (code, VOIDmode,
5021 gen_rtx_REG (mode, FLAGS_REG),
5022 const0_rtx),
5023 operands[2],
5024 operands[3])));
32b5b1aa 5025
e075ae69 5026 return 1;
32b5b1aa
SC
5027}
5028
2450a057
JH
5029/* Split operands 0 and 1 into SImode parts. Similar to split_di, but
5030 works for floating pointer parameters and nonoffsetable memories.
5031 For pushes, it returns just stack offsets; the values will be saved
5032 in the right order. Maximally three parts are generated. */
5033
5034static void
5035ix86_split_to_parts (operand, parts, mode)
5036 rtx operand;
5037 rtx *parts;
5038 enum machine_mode mode;
32b5b1aa 5039{
2450a057
JH
5040 int size = GET_MODE_SIZE (mode) / 4;
5041
5042 if (size < 2 || size > 3)
5043 abort ();
5044
d7a29404
JH
5045 /* Optimize constant pool reference to immediates. This is used by fp moves,
5046 that force all constants to memory to allow combining. */
5047
5048 if (GET_CODE (operand) == MEM
5049 && GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
5050 && CONSTANT_POOL_ADDRESS_P (XEXP (operand, 0)))
5051 operand = get_pool_constant (XEXP (operand, 0));
5052
2450a057 5053 if (GET_CODE (operand) == MEM && !offsettable_memref_p (operand))
e075ae69 5054 {
2450a057
JH
5055 /* The only non-offsetable memories we handle are pushes. */
5056 if (! push_operand (operand, VOIDmode))
5057 abort ();
5058
5059 PUT_MODE (operand, SImode);
5060 parts[0] = parts[1] = parts[2] = operand;
5061 }
5062 else
5063 {
5064 if (mode == DImode)
5065 split_di (&operand, 1, &parts[0], &parts[1]);
5066 else
e075ae69 5067 {
2450a057
JH
5068 if (REG_P (operand))
5069 {
5070 if (!reload_completed)
5071 abort ();
5072 parts[0] = gen_rtx_REG (SImode, REGNO (operand) + 0);
5073 parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
5074 if (size == 3)
5075 parts[2] = gen_rtx_REG (SImode, REGNO (operand) + 2);
5076 }
5077 else if (offsettable_memref_p (operand))
5078 {
5079 PUT_MODE (operand, SImode);
5080 parts[0] = operand;
5081 parts[1] = adj_offsettable_operand (operand, 4);
5082 if (size == 3)
5083 parts[2] = adj_offsettable_operand (operand, 8);
5084 }
5085 else if (GET_CODE (operand) == CONST_DOUBLE)
5086 {
5087 REAL_VALUE_TYPE r;
5088 long l[3];
5089
5090 REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
5091 switch (mode)
5092 {
5093 case XFmode:
5094 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
5095 parts[2] = GEN_INT (l[2]);
5096 break;
5097 case DFmode:
5098 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
5099 break;
5100 default:
5101 abort ();
5102 }
5103 parts[1] = GEN_INT (l[1]);
5104 parts[0] = GEN_INT (l[0]);
5105 }
5106 else
5107 abort ();
e075ae69 5108 }
2450a057
JH
5109 }
5110
5111 return;
5112}
5113
5114/* Emit insns to perform a move or push of DI, DF, and XF values.
5115 Return false when normal moves are needed; true when all required
5116 insns have been emitted. Operands 2-4 contain the input values
5117 int the correct order; operands 5-7 contain the output values. */
5118
5119int
5120ix86_split_long_move (operands1)
5121 rtx operands1[];
5122{
5123 rtx part[2][3];
5124 rtx operands[2];
5125 int size = GET_MODE_SIZE (GET_MODE (operands1[0])) / 4;
5126 int push = 0;
5127 int collisions = 0;
5128
5129 /* Make our own copy to avoid clobbering the operands. */
5130 operands[0] = copy_rtx (operands1[0]);
5131 operands[1] = copy_rtx (operands1[1]);
5132
5133 if (size < 2 || size > 3)
5134 abort ();
5135
5136 /* The only non-offsettable memory we handle is push. */
5137 if (push_operand (operands[0], VOIDmode))
5138 push = 1;
5139 else if (GET_CODE (operands[0]) == MEM
5140 && ! offsettable_memref_p (operands[0]))
5141 abort ();
5142
5143 ix86_split_to_parts (operands[0], part[0], GET_MODE (operands1[0]));
5144 ix86_split_to_parts (operands[1], part[1], GET_MODE (operands1[0]));
5145
5146 /* When emitting push, take care for source operands on the stack. */
5147 if (push && GET_CODE (operands[1]) == MEM
5148 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
5149 {
5150 if (size == 3)
5151 part[1][1] = part[1][2];
5152 part[1][0] = part[1][1];
5153 }
5154
5155 /* We need to do copy in the right order in case an address register
5156 of the source overlaps the destination. */
5157 if (REG_P (part[0][0]) && GET_CODE (part[1][0]) == MEM)
5158 {
5159 if (reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0)))
5160 collisions++;
5161 if (reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
5162 collisions++;
5163 if (size == 3
5164 && reg_overlap_mentioned_p (part[0][2], XEXP (part[1][0], 0)))
5165 collisions++;
5166
5167 /* Collision in the middle part can be handled by reordering. */
5168 if (collisions == 1 && size == 3
5169 && reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
e075ae69 5170 {
2450a057
JH
5171 rtx tmp;
5172 tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
5173 tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
5174 }
e075ae69 5175
2450a057
JH
5176 /* If there are more collisions, we can't handle it by reordering.
5177 Do an lea to the last part and use only one colliding move. */
5178 else if (collisions > 1)
5179 {
5180 collisions = 1;
5181 emit_insn (gen_rtx_SET (VOIDmode, part[0][size - 1],
5182 XEXP (part[1][0], 0)));
5183 part[1][0] = change_address (part[1][0], SImode, part[0][size - 1]);
5184 part[1][1] = adj_offsettable_operand (part[1][0], 4);
5185 if (size == 3)
5186 part[1][2] = adj_offsettable_operand (part[1][0], 8);
5187 }
5188 }
5189
5190 if (push)
5191 {
5192 if (size == 3)
5193 emit_insn (gen_push (part[1][2]));
5194 emit_insn (gen_push (part[1][1]));
5195 emit_insn (gen_push (part[1][0]));
5196 return 1;
5197 }
5198
5199 /* Choose correct order to not overwrite the source before it is copied. */
5200 if ((REG_P (part[0][0])
5201 && REG_P (part[1][1])
5202 && (REGNO (part[0][0]) == REGNO (part[1][1])
5203 || (size == 3
5204 && REGNO (part[0][0]) == REGNO (part[1][2]))))
5205 || (collisions > 0
5206 && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))))
5207 {
5208 if (size == 3)
5209 {
5210 operands1[2] = part[0][2];
5211 operands1[3] = part[0][1];
5212 operands1[4] = part[0][0];
5213 operands1[5] = part[1][2];
5214 operands1[6] = part[1][1];
5215 operands1[7] = part[1][0];
5216 }
5217 else
5218 {
5219 operands1[2] = part[0][1];
5220 operands1[3] = part[0][0];
5221 operands1[5] = part[1][1];
5222 operands1[6] = part[1][0];
5223 }
5224 }
5225 else
5226 {
5227 if (size == 3)
5228 {
5229 operands1[2] = part[0][0];
5230 operands1[3] = part[0][1];
5231 operands1[4] = part[0][2];
5232 operands1[5] = part[1][0];
5233 operands1[6] = part[1][1];
5234 operands1[7] = part[1][2];
5235 }
5236 else
5237 {
5238 operands1[2] = part[0][0];
5239 operands1[3] = part[0][1];
5240 operands1[5] = part[1][0];
5241 operands1[6] = part[1][1];
e075ae69
RH
5242 }
5243 }
32b5b1aa 5244
e9a25f70 5245 return 0;
32b5b1aa 5246}
32b5b1aa 5247
e075ae69
RH
5248void
5249ix86_split_ashldi (operands, scratch)
5250 rtx *operands, scratch;
32b5b1aa 5251{
e075ae69
RH
5252 rtx low[2], high[2];
5253 int count;
b985a30f 5254
e075ae69
RH
5255 if (GET_CODE (operands[2]) == CONST_INT)
5256 {
5257 split_di (operands, 2, low, high);
5258 count = INTVAL (operands[2]) & 63;
32b5b1aa 5259
e075ae69
RH
5260 if (count >= 32)
5261 {
5262 emit_move_insn (high[0], low[1]);
5263 emit_move_insn (low[0], const0_rtx);
b985a30f 5264
e075ae69
RH
5265 if (count > 32)
5266 emit_insn (gen_ashlsi3 (high[0], high[0], GEN_INT (count - 32)));
5267 }
5268 else
5269 {
5270 if (!rtx_equal_p (operands[0], operands[1]))
5271 emit_move_insn (operands[0], operands[1]);
5272 emit_insn (gen_x86_shld_1 (high[0], low[0], GEN_INT (count)));
5273 emit_insn (gen_ashlsi3 (low[0], low[0], GEN_INT (count)));
5274 }
5275 }
5276 else
5277 {
5278 if (!rtx_equal_p (operands[0], operands[1]))
5279 emit_move_insn (operands[0], operands[1]);
b985a30f 5280
e075ae69 5281 split_di (operands, 1, low, high);
b985a30f 5282
e075ae69
RH
5283 emit_insn (gen_x86_shld_1 (high[0], low[0], operands[2]));
5284 emit_insn (gen_ashlsi3 (low[0], low[0], operands[2]));
32b5b1aa 5285
e075ae69
RH
5286 if (TARGET_CMOVE && (! reload_completed || scratch))
5287 {
5288 if (! reload_completed)
5289 scratch = force_reg (SImode, const0_rtx);
5290 else
5291 emit_move_insn (scratch, const0_rtx);
5292
5293 emit_insn (gen_x86_shift_adj_1 (high[0], low[0], operands[2],
5294 scratch));
5295 }
5296 else
5297 emit_insn (gen_x86_shift_adj_2 (high[0], low[0], operands[2]));
5298 }
e9a25f70 5299}
32b5b1aa 5300
e075ae69
RH
5301void
5302ix86_split_ashrdi (operands, scratch)
5303 rtx *operands, scratch;
32b5b1aa 5304{
e075ae69
RH
5305 rtx low[2], high[2];
5306 int count;
32b5b1aa 5307
e075ae69
RH
5308 if (GET_CODE (operands[2]) == CONST_INT)
5309 {
5310 split_di (operands, 2, low, high);
5311 count = INTVAL (operands[2]) & 63;
32b5b1aa 5312
e075ae69
RH
5313 if (count >= 32)
5314 {
5315 emit_move_insn (low[0], high[1]);
32b5b1aa 5316
e075ae69
RH
5317 if (! reload_completed)
5318 emit_insn (gen_ashrsi3 (high[0], low[0], GEN_INT (31)));
5319 else
5320 {
5321 emit_move_insn (high[0], low[0]);
5322 emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (31)));
5323 }
5324
5325 if (count > 32)
5326 emit_insn (gen_ashrsi3 (low[0], low[0], GEN_INT (count - 32)));
5327 }
5328 else
5329 {
5330 if (!rtx_equal_p (operands[0], operands[1]))
5331 emit_move_insn (operands[0], operands[1]);
5332 emit_insn (gen_x86_shrd_1 (low[0], high[0], GEN_INT (count)));
5333 emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (count)));
5334 }
5335 }
5336 else
32b5b1aa 5337 {
e075ae69
RH
5338 if (!rtx_equal_p (operands[0], operands[1]))
5339 emit_move_insn (operands[0], operands[1]);
5340
5341 split_di (operands, 1, low, high);
5342
5343 emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2]));
5344 emit_insn (gen_ashrsi3 (high[0], high[0], operands[2]));
5345
5346 if (TARGET_CMOVE && (!reload_completed || scratch))
5347 {
5348 if (! reload_completed)
5349 scratch = gen_reg_rtx (SImode);
5350 emit_move_insn (scratch, high[0]);
5351 emit_insn (gen_ashrsi3 (scratch, scratch, GEN_INT (31)));
5352 emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
5353 scratch));
5354 }
5355 else
5356 emit_insn (gen_x86_shift_adj_3 (low[0], high[0], operands[2]));
32b5b1aa 5357 }
e075ae69 5358}
32b5b1aa 5359
e075ae69
RH
5360void
5361ix86_split_lshrdi (operands, scratch)
5362 rtx *operands, scratch;
5363{
5364 rtx low[2], high[2];
5365 int count;
32b5b1aa 5366
e075ae69 5367 if (GET_CODE (operands[2]) == CONST_INT)
32b5b1aa 5368 {
e075ae69
RH
5369 split_di (operands, 2, low, high);
5370 count = INTVAL (operands[2]) & 63;
5371
5372 if (count >= 32)
c7271385 5373 {
e075ae69
RH
5374 emit_move_insn (low[0], high[1]);
5375 emit_move_insn (high[0], const0_rtx);
32b5b1aa 5376
e075ae69
RH
5377 if (count > 32)
5378 emit_insn (gen_lshrsi3 (low[0], low[0], GEN_INT (count - 32)));
5379 }
5380 else
5381 {
5382 if (!rtx_equal_p (operands[0], operands[1]))
5383 emit_move_insn (operands[0], operands[1]);
5384 emit_insn (gen_x86_shrd_1 (low[0], high[0], GEN_INT (count)));
5385 emit_insn (gen_lshrsi3 (high[0], high[0], GEN_INT (count)));
5386 }
32b5b1aa 5387 }
e075ae69
RH
5388 else
5389 {
5390 if (!rtx_equal_p (operands[0], operands[1]))
5391 emit_move_insn (operands[0], operands[1]);
32b5b1aa 5392
e075ae69
RH
5393 split_di (operands, 1, low, high);
5394
5395 emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2]));
5396 emit_insn (gen_lshrsi3 (high[0], high[0], operands[2]));
5397
5398 /* Heh. By reversing the arguments, we can reuse this pattern. */
5399 if (TARGET_CMOVE && (! reload_completed || scratch))
5400 {
5401 if (! reload_completed)
5402 scratch = force_reg (SImode, const0_rtx);
5403 else
5404 emit_move_insn (scratch, const0_rtx);
5405
5406 emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
5407 scratch));
5408 }
5409 else
5410 emit_insn (gen_x86_shift_adj_2 (low[0], high[0], operands[2]));
5411 }
32b5b1aa 5412}
3f803cd9 5413
e075ae69
RH
5414/* Expand the appropriate insns for doing strlen if not just doing
5415 repnz; scasb
5416
5417 out = result, initialized with the start address
5418 align_rtx = alignment of the address.
5419 scratch = scratch register, initialized with the startaddress when
5420 not aligned, otherwise undefined
3f803cd9
SC
5421
5422 This is just the body. It needs the initialisations mentioned above and
5423 some address computing at the end. These things are done in i386.md. */
5424
e075ae69
RH
5425void
5426ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
5427 rtx out, align_rtx, scratch;
3f803cd9 5428{
e075ae69
RH
5429 int align;
5430 rtx tmp;
5431 rtx align_2_label = NULL_RTX;
5432 rtx align_3_label = NULL_RTX;
5433 rtx align_4_label = gen_label_rtx ();
5434 rtx end_0_label = gen_label_rtx ();
e075ae69
RH
5435 rtx mem;
5436 rtx flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
e2e52e1b 5437 rtx tmpreg = gen_reg_rtx (SImode);
e075ae69
RH
5438
5439 align = 0;
5440 if (GET_CODE (align_rtx) == CONST_INT)
5441 align = INTVAL (align_rtx);
3f803cd9 5442
e9a25f70 5443 /* Loop to check 1..3 bytes for null to get an aligned pointer. */
3f803cd9 5444
e9a25f70 5445 /* Is there a known alignment and is it less than 4? */
e075ae69 5446 if (align < 4)
3f803cd9 5447 {
e9a25f70 5448 /* Is there a known alignment and is it not 2? */
e075ae69 5449 if (align != 2)
3f803cd9 5450 {
e075ae69
RH
5451 align_3_label = gen_label_rtx (); /* Label when aligned to 3-byte */
5452 align_2_label = gen_label_rtx (); /* Label when aligned to 2-byte */
5453
5454 /* Leave just the 3 lower bits. */
5455 align_rtx = expand_binop (SImode, and_optab, scratch, GEN_INT (3),
5456 NULL_RTX, 0, OPTAB_WIDEN);
5457
5458 emit_insn (gen_cmpsi_0 (align_rtx, const0_rtx));
5459
5460 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
5461 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5462 gen_rtx_LABEL_REF (VOIDmode,
5463 align_4_label),
5464 pc_rtx);
5465 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
5466
5467 emit_insn (gen_cmpsi_1 (align_rtx, GEN_INT (2)));
5468
5469 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
5470 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5471 gen_rtx_LABEL_REF (VOIDmode,
5472 align_2_label),
5473 pc_rtx);
5474 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
5475
5476 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
5477 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5478 gen_rtx_LABEL_REF (VOIDmode,
5479 align_3_label),
5480 pc_rtx);
5481 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
3f803cd9
SC
5482 }
5483 else
5484 {
e9a25f70
JL
5485 /* Since the alignment is 2, we have to check 2 or 0 bytes;
5486 check if is aligned to 4 - byte. */
e9a25f70 5487
e075ae69
RH
5488 align_rtx = expand_binop (SImode, and_optab, scratch, GEN_INT (2),
5489 NULL_RTX, 0, OPTAB_WIDEN);
5490
5491 emit_insn (gen_cmpsi_0 (align_rtx, const0_rtx));
5492
5493 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
5494 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5495 gen_rtx_LABEL_REF (VOIDmode,
5496 align_4_label),
5497 pc_rtx);
5498 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
3f803cd9
SC
5499 }
5500
e075ae69 5501 mem = gen_rtx_MEM (QImode, out);
e9a25f70 5502
e075ae69 5503 /* Now compare the bytes. */
e9a25f70 5504
e075ae69
RH
5505 /* Compare the first n unaligned byte on a byte per byte basis. */
5506 emit_insn (gen_cmpqi_0 (mem, const0_rtx));
e9a25f70 5507
e075ae69
RH
5508 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
5509 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5510 gen_rtx_LABEL_REF (VOIDmode, end_0_label),
5511 pc_rtx);
5512 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
3f803cd9 5513
e075ae69
RH
5514 /* Increment the address. */
5515 emit_insn (gen_addsi3 (out, out, const1_rtx));
e9a25f70 5516
e075ae69
RH
5517 /* Not needed with an alignment of 2 */
5518 if (align != 2)
5519 {
5520 emit_label (align_2_label);
3f803cd9 5521
e075ae69 5522 emit_insn (gen_cmpqi_0 (mem, const0_rtx));
3f803cd9 5523
e075ae69
RH
5524 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
5525 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5526 gen_rtx_LABEL_REF (VOIDmode,
5527 end_0_label),
5528 pc_rtx);
5529 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
5530
5531 emit_insn (gen_addsi3 (out, out, const1_rtx));
5532
5533 emit_label (align_3_label);
5534 }
5535
5536 emit_insn (gen_cmpqi_0 (mem, const0_rtx));
e9a25f70 5537
e075ae69
RH
5538 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
5539 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5540 gen_rtx_LABEL_REF (VOIDmode, end_0_label),
5541 pc_rtx);
5542 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
5543
5544 emit_insn (gen_addsi3 (out, out, const1_rtx));
3f803cd9
SC
5545 }
5546
e075ae69
RH
5547 /* Generate loop to check 4 bytes at a time. It is not a good idea to
5548 align this loop. It gives only huge programs, but does not help to
5549 speed up. */
5550 emit_label (align_4_label);
3f803cd9 5551
e075ae69
RH
5552 mem = gen_rtx_MEM (SImode, out);
5553 emit_move_insn (scratch, mem);
e075ae69 5554 emit_insn (gen_addsi3 (out, out, GEN_INT (4)));
e075ae69 5555
e2e52e1b
JH
5556 /* This formula yields a nonzero result iff one of the bytes is zero.
5557 This saves three branches inside loop and many cycles. */
5558
5559 emit_insn (gen_addsi3 (tmpreg, scratch, GEN_INT (-0x01010101)));
5560 emit_insn (gen_one_cmplsi2 (scratch, scratch));
5561 emit_insn (gen_andsi3 (tmpreg, tmpreg, scratch));
5562 emit_insn (gen_andsi3 (tmpreg, tmpreg, GEN_INT (0x80808080)));
5563 emit_cmp_and_jump_insns (tmpreg, const0_rtx, EQ, 0, SImode, 1, 0, align_4_label);
5564
5565 if (TARGET_CMOVE)
5566 {
5567 rtx reg = gen_reg_rtx (SImode);
5568 emit_move_insn (reg, tmpreg);
5569 emit_insn (gen_lshrsi3 (reg, reg, GEN_INT (16)));
5570
5571 /* If zero is not in the first two bytes, move two bytes forward. */
5572 emit_insn (gen_testsi_1 (tmpreg, GEN_INT (0x8080)));
5573 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
5574 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
5575 emit_insn (gen_rtx_SET (VOIDmode, tmpreg,
5576 gen_rtx_IF_THEN_ELSE (SImode, tmp,
5577 reg,
5578 tmpreg)));
5579 /* Emit lea manually to avoid clobbering of flags. */
5580 emit_insn (gen_rtx_SET (SImode, reg,
5581 gen_rtx_PLUS (SImode, out, GEN_INT (2))));
5582
5583 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
5584 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
5585 emit_insn (gen_rtx_SET (VOIDmode, out,
5586 gen_rtx_IF_THEN_ELSE (SImode, tmp,
5587 reg,
5588 out)));
5589
5590 }
5591 else
5592 {
5593 rtx end_2_label = gen_label_rtx ();
5594 /* Is zero in the first two bytes? */
5595
5596 emit_insn (gen_testsi_1 (tmpreg, GEN_INT (0x8080)));
5597 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
5598 tmp = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
5599 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
5600 gen_rtx_LABEL_REF (VOIDmode, end_2_label),
5601 pc_rtx);
5602 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
5603 JUMP_LABEL (tmp) = end_2_label;
5604
5605 /* Not in the first two. Move two bytes forward. */
5606 emit_insn (gen_lshrsi3 (tmpreg, tmpreg, GEN_INT (16)));
5607 emit_insn (gen_addsi3 (out, out, GEN_INT (2)));
5608
5609 emit_label (end_2_label);
5610
5611 }
5612
5613 /* Avoid branch in fixing the byte. */
5614 tmpreg = gen_lowpart (QImode, tmpreg);
5615 emit_insn (gen_addqi3_cc (tmpreg, tmpreg, tmpreg));
5616 emit_insn (gen_subsi3_carry (out, out, GEN_INT (3)));
e075ae69
RH
5617
5618 emit_label (end_0_label);
5619}
5620\f
e075ae69
RH
5621/* Clear stack slot assignments remembered from previous functions.
5622 This is called from INIT_EXPANDERS once before RTL is emitted for each
5623 function. */
5624
36edd3cc
BS
5625static void
5626ix86_init_machine_status (p)
1526a060 5627 struct function *p;
e075ae69
RH
5628{
5629 enum machine_mode mode;
5630 int n;
36edd3cc
BS
5631 p->machine
5632 = (struct machine_function *) xmalloc (sizeof (struct machine_function));
e075ae69
RH
5633
5634 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
5635 mode = (enum machine_mode) ((int) mode + 1))
5636 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
5637 ix86_stack_locals[(int) mode][n] = NULL_RTX;
e075ae69
RH
5638}
5639
1526a060
BS
5640/* Mark machine specific bits of P for GC. */
5641static void
5642ix86_mark_machine_status (p)
5643 struct function *p;
5644{
5645 enum machine_mode mode;
5646 int n;
5647
5648 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
5649 mode = (enum machine_mode) ((int) mode + 1))
5650 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
5651 ggc_mark_rtx (p->machine->stack_locals[(int) mode][n]);
5652}
5653
e075ae69
RH
5654/* Return a MEM corresponding to a stack slot with mode MODE.
5655 Allocate a new slot if necessary.
5656
5657 The RTL for a function can have several slots available: N is
5658 which slot to use. */
5659
5660rtx
5661assign_386_stack_local (mode, n)
5662 enum machine_mode mode;
5663 int n;
5664{
5665 if (n < 0 || n >= MAX_386_STACK_LOCALS)
5666 abort ();
5667
5668 if (ix86_stack_locals[(int) mode][n] == NULL_RTX)
5669 ix86_stack_locals[(int) mode][n]
5670 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
5671
5672 return ix86_stack_locals[(int) mode][n];
5673}
5674\f
5675/* Calculate the length of the memory address in the instruction
5676 encoding. Does not include the one-byte modrm, opcode, or prefix. */
5677
5678static int
5679memory_address_length (addr)
5680 rtx addr;
5681{
5682 struct ix86_address parts;
5683 rtx base, index, disp;
5684 int len;
5685
5686 if (GET_CODE (addr) == PRE_DEC
5687 || GET_CODE (addr) == POST_INC)
5688 return 0;
3f803cd9 5689
e075ae69
RH
5690 if (! ix86_decompose_address (addr, &parts))
5691 abort ();
3f803cd9 5692
e075ae69
RH
5693 base = parts.base;
5694 index = parts.index;
5695 disp = parts.disp;
5696 len = 0;
3f803cd9 5697
e075ae69
RH
5698 /* Register Indirect. */
5699 if (base && !index && !disp)
5700 {
5701 /* Special cases: ebp and esp need the two-byte modrm form. */
5702 if (addr == stack_pointer_rtx
5703 || addr == arg_pointer_rtx
564d80f4
JH
5704 || addr == frame_pointer_rtx
5705 || addr == hard_frame_pointer_rtx)
e075ae69 5706 len = 1;
3f803cd9 5707 }
e9a25f70 5708
e075ae69
RH
5709 /* Direct Addressing. */
5710 else if (disp && !base && !index)
5711 len = 4;
5712
3f803cd9
SC
5713 else
5714 {
e075ae69
RH
5715 /* Find the length of the displacement constant. */
5716 if (disp)
5717 {
5718 if (GET_CODE (disp) == CONST_INT
5719 && CONST_OK_FOR_LETTER_P (INTVAL (disp), 'K'))
5720 len = 1;
5721 else
5722 len = 4;
5723 }
3f803cd9 5724
e075ae69
RH
5725 /* An index requires the two-byte modrm form. */
5726 if (index)
5727 len += 1;
3f803cd9
SC
5728 }
5729
e075ae69
RH
5730 return len;
5731}
79325812 5732
e075ae69
RH
5733int
5734ix86_attr_length_default (insn)
5735 rtx insn;
5736{
5737 enum attr_type type;
5738 int len = 0, i;
5739
5740 type = get_attr_type (insn);
5741 extract_insn (insn);
5742 switch (type)
5743 {
5744 case TYPE_INCDEC:
5745 case TYPE_SETCC:
5746 case TYPE_ICMOV:
5747 case TYPE_FMOV:
5748 case TYPE_FOP:
5749 case TYPE_FCMP:
5750 case TYPE_FOP1:
5751 case TYPE_FMUL:
5752 case TYPE_FDIV:
5753 case TYPE_FSGN:
5754 case TYPE_FPSPC:
5755 case TYPE_FCMOV:
5756 case TYPE_IBR:
5757 break;
7c7ef435
JH
5758 case TYPE_STR:
5759 case TYPE_CLD:
5760 len = 0;
3f803cd9 5761
e075ae69
RH
5762 case TYPE_ALU1:
5763 case TYPE_NEGNOT:
5764 case TYPE_ALU:
5765 case TYPE_ICMP:
5766 case TYPE_IMOVX:
5767 case TYPE_ISHIFT:
5768 case TYPE_IMUL:
5769 case TYPE_IDIV:
5770 case TYPE_PUSH:
5771 case TYPE_POP:
1ccbefce
RH
5772 for (i = recog_data.n_operands - 1; i >= 0; --i)
5773 if (CONSTANT_P (recog_data.operand[i]))
e075ae69 5774 {
1ccbefce
RH
5775 if (GET_CODE (recog_data.operand[i]) == CONST_INT
5776 && CONST_OK_FOR_LETTER_P (INTVAL (recog_data.operand[i]), 'K'))
e075ae69
RH
5777 len += 1;
5778 else
1ccbefce 5779 len += GET_MODE_SIZE (GET_MODE (recog_data.operand[0]));
e075ae69
RH
5780 }
5781 break;
5782
5783 case TYPE_IMOV:
1ccbefce
RH
5784 if (CONSTANT_P (recog_data.operand[1]))
5785 len += GET_MODE_SIZE (GET_MODE (recog_data.operand[0]));
e075ae69
RH
5786 break;
5787
5788 case TYPE_CALL:
6baf1cc8
BS
5789 if (constant_call_address_operand (recog_data.operand[0],
5790 GET_MODE (recog_data.operand[0])))
e075ae69
RH
5791 return 5;
5792 break;
3f803cd9 5793
e075ae69 5794 case TYPE_CALLV:
6baf1cc8
BS
5795 if (constant_call_address_operand (recog_data.operand[1],
5796 GET_MODE (recog_data.operand[1])))
e075ae69
RH
5797 return 5;
5798 break;
3f803cd9 5799
e075ae69 5800 case TYPE_LEA:
3071fab5
RH
5801 {
5802 /* Irritatingly, single_set doesn't work with REG_UNUSED present,
5803 as we'll get from running life_analysis during reg-stack when
1c71e60e
JH
5804 not optimizing. Not that it matters anyway, now that
5805 pro_epilogue_adjust_stack uses lea, and is by design not
5806 single_set. */
3071fab5
RH
5807 rtx set = PATTERN (insn);
5808 if (GET_CODE (set) == SET)
5809 ;
5810 else if (GET_CODE (set) == PARALLEL
1c71e60e 5811 && GET_CODE (XVECEXP (set, 0, 0)) == SET)
3071fab5
RH
5812 set = XVECEXP (set, 0, 0);
5813 else
5814 abort ();
5815
5816 len += memory_address_length (SET_SRC (set));
5817 goto just_opcode;
5818 }
3f803cd9 5819
e075ae69
RH
5820 case TYPE_OTHER:
5821 case TYPE_MULTI:
5822 return 15;
3f803cd9 5823
5d3c4797 5824 case TYPE_FXCH:
1ccbefce
RH
5825 if (STACK_TOP_P (recog_data.operand[0]))
5826 return 2 + (REGNO (recog_data.operand[1]) != FIRST_STACK_REG + 1);
5d3c4797 5827 else
1ccbefce 5828 return 2 + (REGNO (recog_data.operand[0]) != FIRST_STACK_REG + 1);
5d3c4797 5829
e075ae69
RH
5830 default:
5831 abort ();
5832 }
5833
1ccbefce
RH
5834 for (i = recog_data.n_operands - 1; i >= 0; --i)
5835 if (GET_CODE (recog_data.operand[i]) == MEM)
e075ae69 5836 {
1ccbefce 5837 len += memory_address_length (XEXP (recog_data.operand[i], 0));
e075ae69
RH
5838 break;
5839 }
5840
5841just_opcode:
5842 len += get_attr_length_opcode (insn);
5843 len += get_attr_length_prefix (insn);
5844
5845 return len;
3f803cd9 5846}
e075ae69
RH
5847\f
5848/* Return the maximum number of instructions a cpu can issue. */
b657fc39 5849
e075ae69
RH
5850int
5851ix86_issue_rate ()
b657fc39 5852{
e075ae69 5853 switch (ix86_cpu)
b657fc39 5854 {
e075ae69
RH
5855 case PROCESSOR_PENTIUM:
5856 case PROCESSOR_K6:
5857 return 2;
79325812 5858
e075ae69
RH
5859 case PROCESSOR_PENTIUMPRO:
5860 return 3;
b657fc39 5861
b657fc39 5862 default:
e075ae69 5863 return 1;
b657fc39 5864 }
b657fc39
L
5865}
5866
e075ae69
RH
5867/* A subroutine of ix86_adjust_cost -- return true iff INSN reads flags set
5868 by DEP_INSN and nothing set by DEP_INSN. */
b657fc39 5869
e075ae69
RH
5870static int
5871ix86_flags_dependant (insn, dep_insn, insn_type)
5872 rtx insn, dep_insn;
5873 enum attr_type insn_type;
5874{
5875 rtx set, set2;
b657fc39 5876
e075ae69
RH
5877 /* Simplify the test for uninteresting insns. */
5878 if (insn_type != TYPE_SETCC
5879 && insn_type != TYPE_ICMOV
5880 && insn_type != TYPE_FCMOV
5881 && insn_type != TYPE_IBR)
5882 return 0;
b657fc39 5883
e075ae69
RH
5884 if ((set = single_set (dep_insn)) != 0)
5885 {
5886 set = SET_DEST (set);
5887 set2 = NULL_RTX;
5888 }
5889 else if (GET_CODE (PATTERN (dep_insn)) == PARALLEL
5890 && XVECLEN (PATTERN (dep_insn), 0) == 2
5891 && GET_CODE (XVECEXP (PATTERN (dep_insn), 0, 0)) == SET
5892 && GET_CODE (XVECEXP (PATTERN (dep_insn), 0, 1)) == SET)
5893 {
5894 set = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
5895 set2 = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
5896 }
78a0d70c
ZW
5897 else
5898 return 0;
b657fc39 5899
78a0d70c
ZW
5900 if (GET_CODE (set) != REG || REGNO (set) != FLAGS_REG)
5901 return 0;
b657fc39 5902
78a0d70c
ZW
5903 /* This test is true if the dependant insn reads the flags but
5904 not any other potentially set register. */
5905 if (!reg_overlap_mentioned_p (set, PATTERN (insn)))
5906 return 0;
5907
5908 if (set2 && reg_overlap_mentioned_p (set2, PATTERN (insn)))
5909 return 0;
5910
5911 return 1;
e075ae69 5912}
b657fc39 5913
e075ae69
RH
5914/* A subroutine of ix86_adjust_cost -- return true iff INSN has a memory
5915 address with operands set by DEP_INSN. */
5916
5917static int
5918ix86_agi_dependant (insn, dep_insn, insn_type)
5919 rtx insn, dep_insn;
5920 enum attr_type insn_type;
5921{
5922 rtx addr;
5923
5924 if (insn_type == TYPE_LEA)
5925 addr = SET_SRC (single_set (insn));
5926 else
5927 {
5928 int i;
5929 extract_insn (insn);
1ccbefce
RH
5930 for (i = recog_data.n_operands - 1; i >= 0; --i)
5931 if (GET_CODE (recog_data.operand[i]) == MEM)
e075ae69 5932 {
1ccbefce 5933 addr = XEXP (recog_data.operand[i], 0);
e075ae69
RH
5934 goto found;
5935 }
5936 return 0;
5937 found:;
b657fc39
L
5938 }
5939
e075ae69 5940 return modified_in_p (addr, dep_insn);
b657fc39 5941}
a269a03c
JC
5942
5943int
e075ae69 5944ix86_adjust_cost (insn, link, dep_insn, cost)
a269a03c
JC
5945 rtx insn, link, dep_insn;
5946 int cost;
5947{
e075ae69
RH
5948 enum attr_type insn_type, dep_insn_type;
5949 rtx set, set2;
9b00189f 5950 int dep_insn_code_number;
a269a03c 5951
309ada50 5952 /* Anti and output depenancies have zero cost on all CPUs. */
e075ae69 5953 if (REG_NOTE_KIND (link) != 0)
309ada50 5954 return 0;
a269a03c 5955
9b00189f
JH
5956 dep_insn_code_number = recog_memoized (dep_insn);
5957
e075ae69 5958 /* If we can't recognize the insns, we can't really do anything. */
9b00189f 5959 if (dep_insn_code_number < 0 || recog_memoized (insn) < 0)
e075ae69 5960 return cost;
a269a03c 5961
1c71e60e
JH
5962 insn_type = get_attr_type (insn);
5963 dep_insn_type = get_attr_type (dep_insn);
9b00189f 5964
1c71e60e
JH
5965 /* Prologue and epilogue allocators can have a false dependency on ebp.
5966 This results in one cycle extra stall on Pentium prologue scheduling,
5967 so handle this important case manually. */
5968 if (dep_insn_code_number == CODE_FOR_pro_epilogue_adjust_stack
5969 && dep_insn_type == TYPE_ALU
9b00189f
JH
5970 && !reg_mentioned_p (stack_pointer_rtx, insn))
5971 return 0;
5972
a269a03c
JC
5973 switch (ix86_cpu)
5974 {
5975 case PROCESSOR_PENTIUM:
e075ae69
RH
5976 /* Address Generation Interlock adds a cycle of latency. */
5977 if (ix86_agi_dependant (insn, dep_insn, insn_type))
5978 cost += 1;
5979
5980 /* ??? Compares pair with jump/setcc. */
5981 if (ix86_flags_dependant (insn, dep_insn, insn_type))
5982 cost = 0;
5983
5984 /* Floating point stores require value to be ready one cycle ealier. */
5985 if (insn_type == TYPE_FMOV
5986 && get_attr_memory (insn) == MEMORY_STORE
5987 && !ix86_agi_dependant (insn, dep_insn, insn_type))
5988 cost += 1;
5989 break;
a269a03c 5990
e075ae69
RH
5991 case PROCESSOR_PENTIUMPRO:
5992 /* Since we can't represent delayed latencies of load+operation,
5993 increase the cost here for non-imov insns. */
5994 if (dep_insn_type != TYPE_IMOV
5995 && dep_insn_type != TYPE_FMOV
5996 && get_attr_memory (dep_insn) == MEMORY_LOAD)
5997 cost += 1;
5998
5999 /* INT->FP conversion is expensive. */
6000 if (get_attr_fp_int_src (dep_insn))
6001 cost += 5;
6002
6003 /* There is one cycle extra latency between an FP op and a store. */
6004 if (insn_type == TYPE_FMOV
6005 && (set = single_set (dep_insn)) != NULL_RTX
6006 && (set2 = single_set (insn)) != NULL_RTX
6007 && rtx_equal_p (SET_DEST (set), SET_SRC (set2))
6008 && GET_CODE (SET_DEST (set2)) == MEM)
6009 cost += 1;
6010 break;
a269a03c 6011
e075ae69
RH
6012 case PROCESSOR_K6:
6013 /* The esp dependency is resolved before the instruction is really
6014 finished. */
6015 if ((insn_type == TYPE_PUSH || insn_type == TYPE_POP)
6016 && (dep_insn_type == TYPE_PUSH || dep_insn_type == TYPE_POP))
6017 return 1;
a269a03c 6018
e075ae69
RH
6019 /* Since we can't represent delayed latencies of load+operation,
6020 increase the cost here for non-imov insns. */
6021 if (get_attr_memory (dep_insn) == MEMORY_LOAD)
6022 cost += (dep_insn_type != TYPE_IMOV) ? 2 : 1;
6023
6024 /* INT->FP conversion is expensive. */
6025 if (get_attr_fp_int_src (dep_insn))
6026 cost += 5;
a14003ee 6027 break;
e075ae69 6028
309ada50
JH
6029 case PROCESSOR_ATHLON:
6030 /* Address Generation Interlock cause problems on the Athlon CPU because
6031 the loads and stores are done in order so once one load or store has
6032 to wait, others must too, so penalize the AGIs slightly by one cycle.
6033 We might experiment with this value later. */
6034 if (ix86_agi_dependant (insn, dep_insn, insn_type))
6035 cost += 1;
6036
6037 /* Since we can't represent delayed latencies of load+operation,
6038 increase the cost here for non-imov insns. */
6039 if (dep_insn_type != TYPE_IMOV
6040 && dep_insn_type != TYPE_FMOV
6041 && get_attr_memory (dep_insn) == MEMORY_LOAD)
6042 cost += 2;
a269a03c 6043 default:
a269a03c
JC
6044 break;
6045 }
6046
6047 return cost;
6048}
0a726ef1 6049
e075ae69
RH
6050static union
6051{
6052 struct ppro_sched_data
6053 {
6054 rtx decode[3];
6055 int issued_this_cycle;
6056 } ppro;
6057} ix86_sched_data;
0a726ef1 6058
e075ae69
RH
6059static int
6060ix86_safe_length (insn)
6061 rtx insn;
6062{
6063 if (recog_memoized (insn) >= 0)
6064 return get_attr_length(insn);
6065 else
6066 return 128;
6067}
0a726ef1 6068
e075ae69
RH
6069static int
6070ix86_safe_length_prefix (insn)
6071 rtx insn;
6072{
6073 if (recog_memoized (insn) >= 0)
6074 return get_attr_length(insn);
6075 else
6076 return 0;
6077}
6078
6079static enum attr_memory
6080ix86_safe_memory (insn)
6081 rtx insn;
6082{
6083 if (recog_memoized (insn) >= 0)
6084 return get_attr_memory(insn);
6085 else
6086 return MEMORY_UNKNOWN;
6087}
0a726ef1 6088
e075ae69
RH
6089static enum attr_pent_pair
6090ix86_safe_pent_pair (insn)
6091 rtx insn;
6092{
6093 if (recog_memoized (insn) >= 0)
6094 return get_attr_pent_pair(insn);
6095 else
6096 return PENT_PAIR_NP;
6097}
0a726ef1 6098
e075ae69
RH
6099static enum attr_ppro_uops
6100ix86_safe_ppro_uops (insn)
6101 rtx insn;
6102{
6103 if (recog_memoized (insn) >= 0)
6104 return get_attr_ppro_uops (insn);
6105 else
6106 return PPRO_UOPS_MANY;
6107}
0a726ef1 6108
e075ae69
RH
6109static void
6110ix86_dump_ppro_packet (dump)
6111 FILE *dump;
0a726ef1 6112{
e075ae69 6113 if (ix86_sched_data.ppro.decode[0])
0a726ef1 6114 {
e075ae69
RH
6115 fprintf (dump, "PPRO packet: %d",
6116 INSN_UID (ix86_sched_data.ppro.decode[0]));
6117 if (ix86_sched_data.ppro.decode[1])
6118 fprintf (dump, " %d", INSN_UID (ix86_sched_data.ppro.decode[1]));
6119 if (ix86_sched_data.ppro.decode[2])
6120 fprintf (dump, " %d", INSN_UID (ix86_sched_data.ppro.decode[2]));
6121 fputc ('\n', dump);
6122 }
6123}
0a726ef1 6124
e075ae69 6125/* We're beginning a new block. Initialize data structures as necessary. */
0a726ef1 6126
e075ae69
RH
6127void
6128ix86_sched_init (dump, sched_verbose)
6129 FILE *dump ATTRIBUTE_UNUSED;
6130 int sched_verbose ATTRIBUTE_UNUSED;
6131{
6132 memset (&ix86_sched_data, 0, sizeof (ix86_sched_data));
6133}
6134
6135/* Shift INSN to SLOT, and shift everything else down. */
6136
6137static void
6138ix86_reorder_insn (insnp, slot)
6139 rtx *insnp, *slot;
6140{
6141 if (insnp != slot)
6142 {
6143 rtx insn = *insnp;
6144 do
6145 insnp[0] = insnp[1];
6146 while (++insnp != slot);
6147 *insnp = insn;
0a726ef1 6148 }
e075ae69
RH
6149}
6150
6151/* Find an instruction with given pairability and minimal amount of cycles
6152 lost by the fact that the CPU waits for both pipelines to finish before
6153 reading next instructions. Also take care that both instructions together
6154 can not exceed 7 bytes. */
6155
6156static rtx *
6157ix86_pent_find_pair (e_ready, ready, type, first)
6158 rtx *e_ready;
6159 rtx *ready;
6160 enum attr_pent_pair type;
6161 rtx first;
6162{
6163 int mincycles, cycles;
6164 enum attr_pent_pair tmp;
6165 enum attr_memory memory;
6166 rtx *insnp, *bestinsnp = NULL;
0a726ef1 6167
e075ae69
RH
6168 if (ix86_safe_length (first) > 7 + ix86_safe_length_prefix (first))
6169 return NULL;
0a726ef1 6170
e075ae69
RH
6171 memory = ix86_safe_memory (first);
6172 cycles = result_ready_cost (first);
6173 mincycles = INT_MAX;
6174
6175 for (insnp = e_ready; insnp >= ready && mincycles; --insnp)
6176 if ((tmp = ix86_safe_pent_pair (*insnp)) == type
6177 && ix86_safe_length (*insnp) <= 7 + ix86_safe_length_prefix (*insnp))
6ec6d558 6178 {
e075ae69
RH
6179 enum attr_memory second_memory;
6180 int secondcycles, currentcycles;
6181
6182 second_memory = ix86_safe_memory (*insnp);
6183 secondcycles = result_ready_cost (*insnp);
6184 currentcycles = abs (cycles - secondcycles);
6185
6186 if (secondcycles >= 1 && cycles >= 1)
6ec6d558 6187 {
e075ae69
RH
6188 /* Two read/modify/write instructions together takes two
6189 cycles longer. */
6190 if (memory == MEMORY_BOTH && second_memory == MEMORY_BOTH)
6191 currentcycles += 2;
6192
6193 /* Read modify/write instruction followed by read/modify
6194 takes one cycle longer. */
6195 if (memory == MEMORY_BOTH && second_memory == MEMORY_LOAD
6196 && tmp != PENT_PAIR_UV
6197 && ix86_safe_pent_pair (first) != PENT_PAIR_UV)
6198 currentcycles += 1;
6ec6d558 6199 }
e075ae69
RH
6200 if (currentcycles < mincycles)
6201 bestinsnp = insnp, mincycles = currentcycles;
6ec6d558 6202 }
0a726ef1 6203
e075ae69
RH
6204 return bestinsnp;
6205}
6206
78a0d70c 6207/* Subroutines of ix86_sched_reorder. */
e075ae69 6208
78a0d70c
ZW
6209void
6210ix86_sched_reorder_pentium (ready, e_ready)
e075ae69 6211 rtx *ready;
78a0d70c 6212 rtx *e_ready;
e075ae69 6213{
78a0d70c 6214 enum attr_pent_pair pair1, pair2;
e075ae69 6215 rtx *insnp;
e075ae69 6216
78a0d70c
ZW
6217 /* This wouldn't be necessary if Haifa knew that static insn ordering
6218 is important to which pipe an insn is issued to. So we have to make
6219 some minor rearrangements. */
e075ae69 6220
78a0d70c
ZW
6221 pair1 = ix86_safe_pent_pair (*e_ready);
6222
6223 /* If the first insn is non-pairable, let it be. */
6224 if (pair1 == PENT_PAIR_NP)
6225 return;
6226
6227 pair2 = PENT_PAIR_NP;
6228 insnp = 0;
6229
6230 /* If the first insn is UV or PV pairable, search for a PU
6231 insn to go with. */
6232 if (pair1 == PENT_PAIR_UV || pair1 == PENT_PAIR_PV)
e075ae69 6233 {
78a0d70c
ZW
6234 insnp = ix86_pent_find_pair (e_ready-1, ready,
6235 PENT_PAIR_PU, *e_ready);
6236 if (insnp)
6237 pair2 = PENT_PAIR_PU;
6238 }
e075ae69 6239
78a0d70c
ZW
6240 /* If the first insn is PU or UV pairable, search for a PV
6241 insn to go with. */
6242 if (pair2 == PENT_PAIR_NP
6243 && (pair1 == PENT_PAIR_PU || pair1 == PENT_PAIR_UV))
6244 {
6245 insnp = ix86_pent_find_pair (e_ready-1, ready,
6246 PENT_PAIR_PV, *e_ready);
6247 if (insnp)
6248 pair2 = PENT_PAIR_PV;
6249 }
e075ae69 6250
78a0d70c
ZW
6251 /* If the first insn is pairable, search for a UV
6252 insn to go with. */
6253 if (pair2 == PENT_PAIR_NP)
6254 {
6255 insnp = ix86_pent_find_pair (e_ready-1, ready,
6256 PENT_PAIR_UV, *e_ready);
6257 if (insnp)
6258 pair2 = PENT_PAIR_UV;
6259 }
e075ae69 6260
78a0d70c
ZW
6261 if (pair2 == PENT_PAIR_NP)
6262 return;
e075ae69 6263
78a0d70c
ZW
6264 /* Found something! Decide if we need to swap the order. */
6265 if (pair1 == PENT_PAIR_PV || pair2 == PENT_PAIR_PU
6266 || (pair1 == PENT_PAIR_UV && pair2 == PENT_PAIR_UV
6267 && ix86_safe_memory (*e_ready) == MEMORY_BOTH
6268 && ix86_safe_memory (*insnp) == MEMORY_LOAD))
6269 ix86_reorder_insn (insnp, e_ready);
6270 else
6271 ix86_reorder_insn (insnp, e_ready - 1);
6272}
e075ae69 6273
78a0d70c
ZW
6274void
6275ix86_sched_reorder_ppro (ready, e_ready)
6276 rtx *ready;
6277 rtx *e_ready;
6278{
6279 rtx decode[3];
6280 enum attr_ppro_uops cur_uops;
6281 int issued_this_cycle;
6282 rtx *insnp;
6283 int i;
e075ae69 6284
78a0d70c
ZW
6285 /* At this point .ppro.decode contains the state of the three
6286 decoders from last "cycle". That is, those insns that were
6287 actually independent. But here we're scheduling for the
6288 decoder, and we may find things that are decodable in the
6289 same cycle. */
e075ae69 6290
78a0d70c
ZW
6291 memcpy (decode, ix86_sched_data.ppro.decode, sizeof(decode));
6292 issued_this_cycle = 0;
e075ae69 6293
78a0d70c
ZW
6294 insnp = e_ready;
6295 cur_uops = ix86_safe_ppro_uops (*insnp);
0a726ef1 6296
78a0d70c
ZW
6297 /* If the decoders are empty, and we've a complex insn at the
6298 head of the priority queue, let it issue without complaint. */
6299 if (decode[0] == NULL)
6300 {
6301 if (cur_uops == PPRO_UOPS_MANY)
6302 {
6303 decode[0] = *insnp;
6304 goto ppro_done;
6305 }
6306
6307 /* Otherwise, search for a 2-4 uop unsn to issue. */
6308 while (cur_uops != PPRO_UOPS_FEW)
6309 {
6310 if (insnp == ready)
6311 break;
6312 cur_uops = ix86_safe_ppro_uops (*--insnp);
6313 }
6314
6315 /* If so, move it to the head of the line. */
6316 if (cur_uops == PPRO_UOPS_FEW)
6317 ix86_reorder_insn (insnp, e_ready);
0a726ef1 6318
78a0d70c
ZW
6319 /* Issue the head of the queue. */
6320 issued_this_cycle = 1;
6321 decode[0] = *e_ready--;
6322 }
fb693d44 6323
78a0d70c
ZW
6324 /* Look for simple insns to fill in the other two slots. */
6325 for (i = 1; i < 3; ++i)
6326 if (decode[i] == NULL)
6327 {
6328 if (ready >= e_ready)
6329 goto ppro_done;
fb693d44 6330
e075ae69
RH
6331 insnp = e_ready;
6332 cur_uops = ix86_safe_ppro_uops (*insnp);
78a0d70c
ZW
6333 while (cur_uops != PPRO_UOPS_ONE)
6334 {
6335 if (insnp == ready)
6336 break;
6337 cur_uops = ix86_safe_ppro_uops (*--insnp);
6338 }
fb693d44 6339
78a0d70c
ZW
6340 /* Found one. Move it to the head of the queue and issue it. */
6341 if (cur_uops == PPRO_UOPS_ONE)
e075ae69 6342 {
78a0d70c
ZW
6343 ix86_reorder_insn (insnp, e_ready);
6344 decode[i] = *e_ready--;
6345 issued_this_cycle++;
6346 continue;
6347 }
fb693d44 6348
78a0d70c
ZW
6349 /* ??? Didn't find one. Ideally, here we would do a lazy split
6350 of 2-uop insns, issue one and queue the other. */
6351 }
fb693d44 6352
78a0d70c
ZW
6353 ppro_done:
6354 if (issued_this_cycle == 0)
6355 issued_this_cycle = 1;
6356 ix86_sched_data.ppro.issued_this_cycle = issued_this_cycle;
6357}
fb693d44 6358
78a0d70c
ZW
6359
6360/* We are about to being issuing insns for this clock cycle.
6361 Override the default sort algorithm to better slot instructions. */
6362int
6363ix86_sched_reorder (dump, sched_verbose, ready, n_ready, clock_var)
6364 FILE *dump ATTRIBUTE_UNUSED;
6365 int sched_verbose ATTRIBUTE_UNUSED;
6366 rtx *ready;
6367 int n_ready;
6368 int clock_var ATTRIBUTE_UNUSED;
6369{
6370 rtx *e_ready = ready + n_ready - 1;
fb693d44 6371
78a0d70c
ZW
6372 if (n_ready < 2)
6373 goto out;
e075ae69 6374
78a0d70c
ZW
6375 switch (ix86_cpu)
6376 {
6377 default:
6378 break;
e075ae69 6379
78a0d70c
ZW
6380 case PROCESSOR_PENTIUM:
6381 ix86_sched_reorder_pentium (ready, e_ready);
6382 break;
e075ae69 6383
78a0d70c
ZW
6384 case PROCESSOR_PENTIUMPRO:
6385 ix86_sched_reorder_ppro (ready, e_ready);
e075ae69 6386 break;
fb693d44
RH
6387 }
6388
e075ae69
RH
6389out:
6390 return ix86_issue_rate ();
6391}
fb693d44 6392
e075ae69
RH
6393/* We are about to issue INSN. Return the number of insns left on the
6394 ready queue that can be issued this cycle. */
b222082e 6395
e075ae69
RH
6396int
6397ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
6398 FILE *dump;
6399 int sched_verbose;
6400 rtx insn;
6401 int can_issue_more;
6402{
6403 int i;
6404 switch (ix86_cpu)
fb693d44 6405 {
e075ae69
RH
6406 default:
6407 return can_issue_more - 1;
fb693d44 6408
e075ae69
RH
6409 case PROCESSOR_PENTIUMPRO:
6410 {
6411 enum attr_ppro_uops uops = ix86_safe_ppro_uops (insn);
fb693d44 6412
e075ae69
RH
6413 if (uops == PPRO_UOPS_MANY)
6414 {
6415 if (sched_verbose)
6416 ix86_dump_ppro_packet (dump);
6417 ix86_sched_data.ppro.decode[0] = insn;
6418 ix86_sched_data.ppro.decode[1] = NULL;
6419 ix86_sched_data.ppro.decode[2] = NULL;
6420 if (sched_verbose)
6421 ix86_dump_ppro_packet (dump);
6422 ix86_sched_data.ppro.decode[0] = NULL;
6423 }
6424 else if (uops == PPRO_UOPS_FEW)
6425 {
6426 if (sched_verbose)
6427 ix86_dump_ppro_packet (dump);
6428 ix86_sched_data.ppro.decode[0] = insn;
6429 ix86_sched_data.ppro.decode[1] = NULL;
6430 ix86_sched_data.ppro.decode[2] = NULL;
6431 }
6432 else
6433 {
6434 for (i = 0; i < 3; ++i)
6435 if (ix86_sched_data.ppro.decode[i] == NULL)
6436 {
6437 ix86_sched_data.ppro.decode[i] = insn;
6438 break;
6439 }
6440 if (i == 3)
6441 abort ();
6442 if (i == 2)
6443 {
6444 if (sched_verbose)
6445 ix86_dump_ppro_packet (dump);
6446 ix86_sched_data.ppro.decode[0] = NULL;
6447 ix86_sched_data.ppro.decode[1] = NULL;
6448 ix86_sched_data.ppro.decode[2] = NULL;
6449 }
6450 }
6451 }
6452 return --ix86_sched_data.ppro.issued_this_cycle;
6453 }
fb693d44 6454}
This page took 1.672743 seconds and 5 git commands to generate.