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