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