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