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