]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.c
x
[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
e9a25f70
JL
2182 if (pic_reg_used)
2183 load_pic_register (do_rtl);
77a989d1 2184
e9a25f70
JL
2185 /* If we are profiling, make sure no instructions are scheduled before
2186 the call to mcount. However, if -fpic, the above call will have
2187 done that. */
2188 if ((profile_flag || profile_block_flag)
2189 && ! pic_reg_used && do_rtl)
2190 emit_insn (gen_blockage ());
77a989d1
SC
2191}
2192
2a2ab3f9
JVA
2193/* Return 1 if it is appropriate to emit `ret' instructions in the
2194 body of a function. Do this only if the epilogue is simple, needing a
2195 couple of insns. Prior to reloading, we can't tell how many registers
79325812 2196 must be saved, so return 0 then. Return 0 if there is no frame
77a989d1 2197 marker to de-allocate.
2a2ab3f9
JVA
2198
2199 If NON_SAVING_SETJMP is defined and true, then it is not possible
2200 for the epilogue to be simple, so return 0. This is a special case
77a989d1
SC
2201 since NON_SAVING_SETJMP will not cause regs_ever_live to change
2202 until final, but jump_optimize may need to know sooner if a
2203 `return' is OK. */
2a2ab3f9
JVA
2204
2205int
77a989d1 2206ix86_can_use_return_insn_p ()
2a2ab3f9
JVA
2207{
2208 int regno;
2209 int nregs = 0;
2210 int reglimit = (frame_pointer_needed
2211 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
aae75261
JVA
2212 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
2213 || current_function_uses_const_pool);
2a2ab3f9
JVA
2214
2215#ifdef NON_SAVING_SETJMP
2216 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
2217 return 0;
2218#endif
2219
2220 if (! reload_completed)
2221 return 0;
2222
2223 for (regno = reglimit - 1; regno >= 0; regno--)
2224 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 2225 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9
JVA
2226 nregs++;
2227
2228 return nregs == 0 || ! frame_pointer_needed;
2229}
2230
2231/* This function generates the assembly code for function exit.
2232 FILE is an stdio stream to output the code to.
2233 SIZE is an int: how many units of temporary storage to deallocate. */
2234
e9a25f70
JL
2235void
2236function_epilogue (file, size)
bb5177ac
RL
2237 FILE *file ATTRIBUTE_UNUSED;
2238 int size ATTRIBUTE_UNUSED;
e9a25f70
JL
2239{
2240 return;
2241}
2242
79325812 2243/* Restore function stack, frame, and registers. */
e9a25f70 2244
2a2ab3f9 2245void
77a989d1 2246ix86_expand_epilogue ()
e9a25f70
JL
2247{
2248 ix86_epilogue (1);
2249}
2250
2251static void
2252ix86_epilogue (do_rtl)
2253 int do_rtl;
2a2ab3f9
JVA
2254{
2255 register int regno;
2256 register int nregs, limit;
2257 int offset;
2258 rtx xops[3];
aae75261
JVA
2259 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
2260 || current_function_uses_const_pool);
77a989d1 2261 long tsize = get_frame_size ();
2a2ab3f9
JVA
2262
2263 /* Compute the number of registers to pop */
2264
e9a25f70 2265 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
2a2ab3f9
JVA
2266
2267 nregs = 0;
2268
2269 for (regno = limit - 1; regno >= 0; regno--)
2270 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 2271 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9
JVA
2272 nregs++;
2273
e9a25f70 2274 /* sp is often unreliable so we must go off the frame pointer.
2a2ab3f9 2275
e9a25f70
JL
2276 In reality, we may not care if sp is unreliable, because we can restore
2277 the register relative to the frame pointer. In theory, since each move
2278 is the same speed as a pop, and we don't need the leal, this is faster.
2279 For now restore multiple registers the old way. */
2a2ab3f9 2280
e9a25f70 2281 offset = - tsize - (nregs * UNITS_PER_WORD);
2a2ab3f9
JVA
2282
2283 xops[2] = stack_pointer_rtx;
2284
00fc09e1
JW
2285 /* When -fpic, we must emit a scheduling barrier, so that the instruction
2286 that restores %ebx (which is PIC_OFFSET_TABLE_REGNUM), does not get
2287 moved before any instruction which implicitly uses the got. This
2288 includes any instruction which uses a SYMBOL_REF or a LABEL_REF.
2289
2290 Alternatively, this could be fixed by making the dependence on the
2291 PIC_OFFSET_TABLE_REGNUM explicit in the RTL. */
e9a25f70
JL
2292
2293 if (flag_pic || profile_flag || profile_block_flag)
00fc09e1
JW
2294 emit_insn (gen_blockage ());
2295
2a2ab3f9
JVA
2296 if (nregs > 1 || ! frame_pointer_needed)
2297 {
2298 if (frame_pointer_needed)
2299 {
77a989d1 2300 xops[0] = adj_offsettable_operand (AT_BP (QImode), offset);
e9a25f70
JL
2301 if (do_rtl)
2302 emit_insn (gen_movsi_lea (xops[2], XEXP (xops[0], 0)));
2303 else
2304 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
2a2ab3f9
JVA
2305 }
2306
2307 for (regno = 0; regno < limit; regno++)
2308 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 2309 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9 2310 {
f64cecad 2311 xops[0] = gen_rtx_REG (SImode, regno);
e9a25f70
JL
2312
2313 if (do_rtl)
2314 emit_insn (gen_pop (xops[0]));
2315 else
2316 output_asm_insn ("pop%L0 %0", xops);
2a2ab3f9
JVA
2317 }
2318 }
e9a25f70 2319
2a2ab3f9
JVA
2320 else
2321 for (regno = 0; regno < limit; regno++)
2322 if ((regs_ever_live[regno] && ! call_used_regs[regno])
aae75261 2323 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
2a2ab3f9 2324 {
f64cecad 2325 xops[0] = gen_rtx_REG (SImode, regno);
2a2ab3f9 2326 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
e9a25f70
JL
2327
2328 if (do_rtl)
2329 emit_move_insn (xops[0], xops[1]);
2330 else
2331 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
2332
2a2ab3f9
JVA
2333 offset += 4;
2334 }
2335
2336 if (frame_pointer_needed)
2337 {
c8c5cb99 2338 /* If not an i386, mov & pop is faster than "leave". */
2a2ab3f9 2339
3f803cd9 2340 if (TARGET_USE_LEAVE)
e9a25f70
JL
2341 {
2342 if (do_rtl)
2343 emit_insn (gen_leave());
2344 else
2345 output_asm_insn ("leave", xops);
2346 }
c8c5cb99 2347 else
2a2ab3f9
JVA
2348 {
2349 xops[0] = frame_pointer_rtx;
77a989d1 2350 xops[1] = stack_pointer_rtx;
e9a25f70
JL
2351
2352 if (do_rtl)
2353 {
2354 emit_insn (gen_epilogue_set_stack_ptr());
2355 emit_insn (gen_pop (xops[0]));
2356 }
2357 else
2358 {
2359 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
2360 output_asm_insn ("pop%L0 %0", xops);
2361 }
2362 }
2363 }
2364
77a989d1 2365 else if (tsize)
2a2ab3f9 2366 {
3403c6ca
UD
2367 /* Intel's docs say that for 4 or 8 bytes of stack frame one should
2368 use `pop' and not `add'. */
2369 int use_pop = tsize == 4;
e9a25f70 2370
3403c6ca
UD
2371 /* Use two pops only for the Pentium processors. */
2372 if (tsize == 8 && !TARGET_386 && !TARGET_486)
2373 {
2374 rtx retval = current_function_return_rtx;
2375
2376 xops[1] = gen_rtx_REG (SImode, 1); /* %edx */
2377
2378 /* This case is a bit more complex. Since we cannot pop into
2379 %ecx twice we need a second register. But this is only
2380 available if the return value is not of DImode in which
2381 case the %edx register is not available. */
2382 use_pop = (retval == NULL
2383 || ! reg_overlap_mentioned_p (xops[1], retval));
2384 }
2385
2386 if (use_pop)
2387 {
2388 xops[0] = gen_rtx_REG (SImode, 2); /* %ecx */
2389
2390 if (do_rtl)
2391 {
2392 /* We have to prevent the two pops here from being scheduled.
2393 GCC otherwise would try in some situation to put other
2394 instructions in between them which has a bad effect. */
2395 emit_insn (gen_blockage ());
2396 emit_insn (gen_pop (xops[0]));
2397 if (tsize == 8)
2398 emit_insn (gen_pop (xops[1]));
2399 }
2400 else
2401 {
2402 output_asm_insn ("pop%L0 %0", xops);
2403 if (tsize == 8)
2404 output_asm_insn ("pop%L1 %1", xops);
2405 }
2406 }
e9a25f70 2407 else
3403c6ca
UD
2408 {
2409 /* If there is no frame pointer, we must still release the frame. */
2410 xops[0] = GEN_INT (tsize);
2411
2412 if (do_rtl)
2413 emit_insn (gen_rtx (SET, VOIDmode, xops[2],
2414 gen_rtx (PLUS, SImode, xops[2], xops[0])));
2415 else
2416 output_asm_insn (AS2 (add%L2,%0,%2), xops);
2417 }
2a2ab3f9
JVA
2418 }
2419
68f654ec
RK
2420#ifdef FUNCTION_BLOCK_PROFILER_EXIT
2421 if (profile_block_flag == 2)
2422 {
2423 FUNCTION_BLOCK_PROFILER_EXIT(file);
2424 }
2425#endif
2426
2a2ab3f9
JVA
2427 if (current_function_pops_args && current_function_args_size)
2428 {
435defd1 2429 xops[1] = GEN_INT (current_function_pops_args);
2a2ab3f9
JVA
2430
2431 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
2432 asked to pop more, pop return address, do explicit add, and jump
2433 indirectly to the caller. */
2434
2435 if (current_function_pops_args >= 32768)
2436 {
2437 /* ??? Which register to use here? */
f64cecad 2438 xops[0] = gen_rtx_REG (SImode, 2);
e9a25f70
JL
2439
2440 if (do_rtl)
2441 {
2442 emit_insn (gen_pop (xops[0]));
2443 emit_insn (gen_rtx (SET, VOIDmode, xops[2],
2444 gen_rtx (PLUS, SImode, xops[1], xops[2])));
2445 emit_jump_insn (xops[0]);
2446 }
2447 else
2448 {
2449 output_asm_insn ("pop%L0 %0", xops);
2450 output_asm_insn (AS2 (add%L2,%1,%2), xops);
2451 output_asm_insn ("jmp %*%0", xops);
2452 }
2453 }
79325812 2454 else
e9a25f70
JL
2455 {
2456 if (do_rtl)
2457 emit_jump_insn (gen_return_pop_internal (xops[1]));
2458 else
2459 output_asm_insn ("ret %1", xops);
2a2ab3f9 2460 }
2a2ab3f9 2461 }
2a2ab3f9 2462 else
e9a25f70
JL
2463 {
2464 if (do_rtl)
2465 emit_jump_insn (gen_return_internal ());
2466 else
2467 output_asm_insn ("ret", xops);
2468 }
2a2ab3f9 2469}
3b3c6a3f
MM
2470\f
2471/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2472 that is a valid memory address for an instruction.
2473 The MODE argument is the machine mode for the MEM expression
2474 that wants to use this address.
2475
2476 On x86, legitimate addresses are:
2477 base movl (base),reg
2478 displacement movl disp,reg
2479 base + displacement movl disp(base),reg
2480 index + base movl (base,index),reg
2481 (index + base) + displacement movl disp(base,index),reg
2482 index*scale movl (,index,scale),reg
2483 index*scale + disp movl disp(,index,scale),reg
2484 index*scale + base movl (base,index,scale),reg
2485 (index*scale + base) + disp movl disp(base,index,scale),reg
2486
2487 In each case, scale can be 1, 2, 4, 8. */
2488
2489/* This is exactly the same as print_operand_addr, except that
2490 it recognizes addresses instead of printing them.
2491
2492 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
2493 convert common non-canonical forms to canonical form so that they will
2494 be recognized. */
2495
2496#define ADDR_INVALID(msg,insn) \
2497do { \
2498 if (TARGET_DEBUG_ADDR) \
2499 { \
2500 fprintf (stderr, msg); \
2501 debug_rtx (insn); \
2502 } \
2503} while (0)
2504
2505int
2506legitimate_address_p (mode, addr, strict)
2507 enum machine_mode mode;
2508 register rtx addr;
2509 int strict;
2510{
2511 rtx base = NULL_RTX;
2512 rtx indx = NULL_RTX;
2513 rtx scale = NULL_RTX;
2514 rtx disp = NULL_RTX;
2515
2516 if (TARGET_DEBUG_ADDR)
2517 {
2518 fprintf (stderr,
e9a25f70 2519 "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
3b3c6a3f
MM
2520 GET_MODE_NAME (mode), strict);
2521
2522 debug_rtx (addr);
2523 }
2524
2525 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
e9a25f70 2526 base = addr;
3b3c6a3f
MM
2527
2528 else if (GET_CODE (addr) == PLUS)
2529 {
2530 rtx op0 = XEXP (addr, 0);
2531 rtx op1 = XEXP (addr, 1);
2532 enum rtx_code code0 = GET_CODE (op0);
2533 enum rtx_code code1 = GET_CODE (op1);
2534
2535 if (code0 == REG || code0 == SUBREG)
2536 {
2537 if (code1 == REG || code1 == SUBREG)
2538 {
e9a25f70 2539 indx = op0; /* index + base */
3b3c6a3f
MM
2540 base = op1;
2541 }
2542
2543 else
2544 {
e9a25f70 2545 base = op0; /* base + displacement */
3b3c6a3f
MM
2546 disp = op1;
2547 }
2548 }
2549
2550 else if (code0 == MULT)
2551 {
2552 indx = XEXP (op0, 0);
2553 scale = XEXP (op0, 1);
2554
2555 if (code1 == REG || code1 == SUBREG)
e9a25f70 2556 base = op1; /* index*scale + base */
3b3c6a3f
MM
2557
2558 else
e9a25f70 2559 disp = op1; /* index*scale + disp */
3b3c6a3f
MM
2560 }
2561
2562 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
2563 {
2564 indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
2565 scale = XEXP (XEXP (op0, 0), 1);
2566 base = XEXP (op0, 1);
2567 disp = op1;
2568 }
2569
2570 else if (code0 == PLUS)
2571 {
e9a25f70 2572 indx = XEXP (op0, 0); /* index + base + disp */
3b3c6a3f
MM
2573 base = XEXP (op0, 1);
2574 disp = op1;
2575 }
2576
2577 else
2578 {
2579 ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
2580 return FALSE;
2581 }
2582 }
2583
2584 else if (GET_CODE (addr) == MULT)
2585 {
e9a25f70 2586 indx = XEXP (addr, 0); /* index*scale */
3b3c6a3f
MM
2587 scale = XEXP (addr, 1);
2588 }
2589
2590 else
e9a25f70 2591 disp = addr; /* displacement */
3b3c6a3f 2592
91f0226f
MM
2593 /* Allow arg pointer and stack pointer as index if there is not scaling */
2594 if (base && indx && !scale
2595 && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
2596 {
2597 rtx tmp = base;
2598 base = indx;
2599 indx = tmp;
2600 }
2601
e9a25f70
JL
2602 /* Validate base register:
2603
2604 Don't allow SUBREG's here, it can lead to spill failures when the base
3d771dfd
MM
2605 is one word out of a two word structure, which is represented internally
2606 as a DImode int. */
e9a25f70 2607
3b3c6a3f
MM
2608 if (base)
2609 {
3d771dfd 2610 if (GET_CODE (base) != REG)
3b3c6a3f 2611 {
3d771dfd
MM
2612 ADDR_INVALID ("Base is not a register.\n", base);
2613 return FALSE;
3b3c6a3f
MM
2614 }
2615
e9a25f70
JL
2616 if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
2617 || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
3b3c6a3f
MM
2618 {
2619 ADDR_INVALID ("Base is not valid.\n", base);
2620 return FALSE;
2621 }
2622 }
2623
e9a25f70
JL
2624 /* Validate index register:
2625
2626 Don't allow SUBREG's here, it can lead to spill failures when the index
3d771dfd
MM
2627 is one word out of a two word structure, which is represented internally
2628 as a DImode int. */
3b3c6a3f
MM
2629 if (indx)
2630 {
3d771dfd 2631 if (GET_CODE (indx) != REG)
3b3c6a3f 2632 {
3d771dfd
MM
2633 ADDR_INVALID ("Index is not a register.\n", indx);
2634 return FALSE;
3b3c6a3f
MM
2635 }
2636
e9a25f70
JL
2637 if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (indx))
2638 || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
3b3c6a3f
MM
2639 {
2640 ADDR_INVALID ("Index is not valid.\n", indx);
2641 return FALSE;
2642 }
2643 }
2644 else if (scale)
e9a25f70 2645 abort (); /* scale w/o index invalid */
3b3c6a3f 2646
e9a25f70 2647 /* Validate scale factor: */
3b3c6a3f
MM
2648 if (scale)
2649 {
2650 HOST_WIDE_INT value;
2651
2652 if (GET_CODE (scale) != CONST_INT)
2653 {
2654 ADDR_INVALID ("Scale is not valid.\n", scale);
2655 return FALSE;
2656 }
2657
2658 value = INTVAL (scale);
2659 if (value != 1 && value != 2 && value != 4 && value != 8)
2660 {
2661 ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
2662 return FALSE;
2663 }
2664 }
2665
32b5b1aa
SC
2666 /* Validate displacement
2667 Constant pool addresses must be handled special. They are
2668 considered legitimate addresses, but only if not used with regs.
2669 When printed, the output routines know to print the reference with the
2670 PIC reg, even though the PIC reg doesn't appear in the RTL. */
3b3c6a3f
MM
2671 if (disp)
2672 {
32b5b1aa
SC
2673 if (GET_CODE (disp) == SYMBOL_REF
2674 && CONSTANT_POOL_ADDRESS_P (disp)
e9a25f70
JL
2675 && base == 0
2676 && indx == 0)
32b5b1aa
SC
2677 ;
2678
2679 else if (!CONSTANT_ADDRESS_P (disp))
3b3c6a3f
MM
2680 {
2681 ADDR_INVALID ("Displacement is not valid.\n", disp);
2682 return FALSE;
2683 }
2684
32b5b1aa 2685 else if (GET_CODE (disp) == CONST_DOUBLE)
3b3c6a3f
MM
2686 {
2687 ADDR_INVALID ("Displacement is a const_double.\n", disp);
2688 return FALSE;
2689 }
2690
32b5b1aa
SC
2691 else if (flag_pic && SYMBOLIC_CONST (disp)
2692 && base != pic_offset_table_rtx
2693 && (indx != pic_offset_table_rtx || scale != NULL_RTX))
3b3c6a3f
MM
2694 {
2695 ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
2696 return FALSE;
2697 }
2698
32b5b1aa
SC
2699 else if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
2700 && (base != NULL_RTX || indx != NULL_RTX))
3b3c6a3f 2701 {
e9a25f70
JL
2702 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n",
2703 disp);
3b3c6a3f
MM
2704 return FALSE;
2705 }
2706 }
2707
2708 if (TARGET_DEBUG_ADDR)
2709 fprintf (stderr, "Address is valid.\n");
2710
2711 /* Everything looks valid, return true */
2712 return TRUE;
2713}
3b3c6a3f
MM
2714\f
2715/* Return a legitimate reference for ORIG (an address) using the
2716 register REG. If REG is 0, a new pseudo is generated.
2717
2718 There are three types of references that must be handled:
2719
2720 1. Global data references must load the address from the GOT, via
2721 the PIC reg. An insn is emitted to do this load, and the reg is
2722 returned.
2723
2724 2. Static data references must compute the address as an offset
2725 from the GOT, whose base is in the PIC reg. An insn is emitted to
2726 compute the address into a reg, and the reg is returned. Static
2727 data objects have SYMBOL_REF_FLAG set to differentiate them from
2728 global data objects.
2729
2730 3. Constant pool addresses must be handled special. They are
2731 considered legitimate addresses, but only if not used with regs.
2732 When printed, the output routines know to print the reference with the
2733 PIC reg, even though the PIC reg doesn't appear in the RTL.
2734
2735 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
2736 reg also appears in the address (except for constant pool references,
2737 noted above).
2738
2739 "switch" statements also require special handling when generating
2740 PIC code. See comments by the `casesi' insn in i386.md for details. */
2741
2742rtx
2743legitimize_pic_address (orig, reg)
2744 rtx orig;
2745 rtx reg;
2746{
2747 rtx addr = orig;
2748 rtx new = orig;
2749
2750 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
2751 {
2752 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
2753 reg = new = orig;
2754 else
2755 {
2756 if (reg == 0)
2757 reg = gen_reg_rtx (Pmode);
2758
c399861d
MM
2759 if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
2760 || GET_CODE (addr) == LABEL_REF)
3b3c6a3f
MM
2761 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
2762 else
f64cecad 2763 new = gen_rtx_MEM (Pmode,
e9a25f70 2764 gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig));
3b3c6a3f
MM
2765
2766 emit_move_insn (reg, new);
2767 }
2768 current_function_uses_pic_offset_table = 1;
2769 return reg;
2770 }
e9a25f70 2771
3b3c6a3f
MM
2772 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
2773 {
2774 rtx base;
2775
2776 if (GET_CODE (addr) == CONST)
2777 {
2778 addr = XEXP (addr, 0);
2779 if (GET_CODE (addr) != PLUS)
2780 abort ();
2781 }
2782
2783 if (XEXP (addr, 0) == pic_offset_table_rtx)
2784 return orig;
2785
2786 if (reg == 0)
2787 reg = gen_reg_rtx (Pmode);
2788
2789 base = legitimize_pic_address (XEXP (addr, 0), reg);
2790 addr = legitimize_pic_address (XEXP (addr, 1),
2791 base == reg ? NULL_RTX : reg);
2792
2793 if (GET_CODE (addr) == CONST_INT)
2794 return plus_constant (base, INTVAL (addr));
2795
2796 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
2797 {
2798 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
2799 addr = XEXP (addr, 1);
2800 }
e9a25f70
JL
2801
2802 return gen_rtx (PLUS, Pmode, base, addr);
3b3c6a3f
MM
2803 }
2804 return new;
2805}
2806\f
3b3c6a3f
MM
2807/* Emit insns to move operands[1] into operands[0]. */
2808
2809void
2810emit_pic_move (operands, mode)
2811 rtx *operands;
bb5177ac 2812 enum machine_mode mode ATTRIBUTE_UNUSED;
3b3c6a3f
MM
2813{
2814 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
2815
2816 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
e9a25f70 2817 operands[1] = force_reg (SImode, operands[1]);
3b3c6a3f
MM
2818 else
2819 operands[1] = legitimize_pic_address (operands[1], temp);
2820}
3b3c6a3f
MM
2821\f
2822/* Try machine-dependent ways of modifying an illegitimate address
2823 to be legitimate. If we find one, return the new, valid address.
2824 This macro is used in only one place: `memory_address' in explow.c.
2825
2826 OLDX is the address as it was before break_out_memory_refs was called.
2827 In some cases it is useful to look at this to decide what needs to be done.
2828
2829 MODE and WIN are passed so that this macro can use
2830 GO_IF_LEGITIMATE_ADDRESS.
2831
2832 It is always safe for this macro to do nothing. It exists to recognize
2833 opportunities to optimize the output.
2834
2835 For the 80386, we handle X+REG by loading X into a register R and
2836 using R+REG. R will go in a general reg and indexing will be used.
2837 However, if REG is a broken-out memory address or multiplication,
2838 nothing needs to be done because REG can certainly go in a general reg.
2839
2840 When -fpic is used, special handling is needed for symbolic references.
2841 See comments by legitimize_pic_address in i386.c for details. */
2842
2843rtx
2844legitimize_address (x, oldx, mode)
2845 register rtx x;
bb5177ac 2846 register rtx oldx ATTRIBUTE_UNUSED;
3b3c6a3f
MM
2847 enum machine_mode mode;
2848{
2849 int changed = 0;
2850 unsigned log;
2851
2852 if (TARGET_DEBUG_ADDR)
2853 {
e9a25f70
JL
2854 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n",
2855 GET_MODE_NAME (mode));
3b3c6a3f
MM
2856 debug_rtx (x);
2857 }
2858
2859 if (flag_pic && SYMBOLIC_CONST (x))
2860 return legitimize_pic_address (x, 0);
2861
2862 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2863 if (GET_CODE (x) == ASHIFT
2864 && GET_CODE (XEXP (x, 1)) == CONST_INT
2865 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2866 {
2867 changed = 1;
e9a25f70 2868 x = gen_rtx (MULT, Pmode, force_reg (Pmode, XEXP (x, 0)),
3b3c6a3f
MM
2869 GEN_INT (1 << log));
2870 }
2871
2872 if (GET_CODE (x) == PLUS)
2873 {
e9a25f70
JL
2874 /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
2875
3b3c6a3f
MM
2876 if (GET_CODE (XEXP (x, 0)) == ASHIFT
2877 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2878 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2879 {
2880 changed = 1;
2881 XEXP (x, 0) = gen_rtx (MULT, Pmode,
2882 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2883 GEN_INT (1 << log));
2884 }
2885
2886 if (GET_CODE (XEXP (x, 1)) == ASHIFT
2887 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2888 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2889 {
2890 changed = 1;
2891 XEXP (x, 1) = gen_rtx (MULT, Pmode,
2892 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2893 GEN_INT (1 << log));
2894 }
2895
e9a25f70 2896 /* Put multiply first if it isn't already. */
3b3c6a3f
MM
2897 if (GET_CODE (XEXP (x, 1)) == MULT)
2898 {
2899 rtx tmp = XEXP (x, 0);
2900 XEXP (x, 0) = XEXP (x, 1);
2901 XEXP (x, 1) = tmp;
2902 changed = 1;
2903 }
2904
2905 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2906 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2907 created by virtual register instantiation, register elimination, and
2908 similar optimizations. */
2909 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2910 {
2911 changed = 1;
2912 x = gen_rtx (PLUS, Pmode,
e9a25f70
JL
2913 gen_rtx (PLUS, Pmode, XEXP (x, 0),
2914 XEXP (XEXP (x, 1), 0)),
3b3c6a3f
MM
2915 XEXP (XEXP (x, 1), 1));
2916 }
2917
e9a25f70
JL
2918 /* Canonicalize
2919 (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
3b3c6a3f
MM
2920 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2921 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2922 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2923 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2924 && CONSTANT_P (XEXP (x, 1)))
2925 {
00c79232
ML
2926 rtx constant;
2927 rtx other = NULL_RTX;
3b3c6a3f
MM
2928
2929 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2930 {
2931 constant = XEXP (x, 1);
2932 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2933 }
2934 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2935 {
2936 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2937 other = XEXP (x, 1);
2938 }
2939 else
2940 constant = 0;
2941
2942 if (constant)
2943 {
2944 changed = 1;
2945 x = gen_rtx (PLUS, Pmode,
2946 gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
2947 XEXP (XEXP (XEXP (x, 0), 1), 0)),
2948 plus_constant (other, INTVAL (constant)));
2949 }
2950 }
2951
2952 if (changed && legitimate_address_p (mode, x, FALSE))
2953 return x;
2954
2955 if (GET_CODE (XEXP (x, 0)) == MULT)
2956 {
2957 changed = 1;
2958 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2959 }
2960
2961 if (GET_CODE (XEXP (x, 1)) == MULT)
2962 {
2963 changed = 1;
2964 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2965 }
2966
2967 if (changed
2968 && GET_CODE (XEXP (x, 1)) == REG
2969 && GET_CODE (XEXP (x, 0)) == REG)
2970 return x;
2971
2972 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2973 {
2974 changed = 1;
2975 x = legitimize_pic_address (x, 0);
2976 }
2977
2978 if (changed && legitimate_address_p (mode, x, FALSE))
2979 return x;
2980
2981 if (GET_CODE (XEXP (x, 0)) == REG)
2982 {
2983 register rtx temp = gen_reg_rtx (Pmode);
2984 register rtx val = force_operand (XEXP (x, 1), temp);
2985 if (val != temp)
2986 emit_move_insn (temp, val);
2987
2988 XEXP (x, 1) = temp;
2989 return x;
2990 }
2991
2992 else if (GET_CODE (XEXP (x, 1)) == REG)
2993 {
2994 register rtx temp = gen_reg_rtx (Pmode);
2995 register rtx val = force_operand (XEXP (x, 0), temp);
2996 if (val != temp)
2997 emit_move_insn (temp, val);
2998
2999 XEXP (x, 0) = temp;
3000 return x;
3001 }
3002 }
3003
3004 return x;
3005}
2a2ab3f9
JVA
3006\f
3007/* Print an integer constant expression in assembler syntax. Addition
3008 and subtraction are the only arithmetic that may appear in these
3009 expressions. FILE is the stdio stream to write to, X is the rtx, and
3010 CODE is the operand print code from the output string. */
3011
3012static void
3013output_pic_addr_const (file, x, code)
3014 FILE *file;
3015 rtx x;
3016 int code;
3017{
3018 char buf[256];
3019
3020 switch (GET_CODE (x))
3021 {
3022 case PC:
3023 if (flag_pic)
3024 putc ('.', file);
3025 else
3026 abort ();
3027 break;
3028
3029 case SYMBOL_REF:
3030 case LABEL_REF:
3031 if (GET_CODE (x) == SYMBOL_REF)
3032 assemble_name (file, XSTR (x, 0));
3033 else
3034 {
3035 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
3036 CODE_LABEL_NUMBER (XEXP (x, 0)));
3037 assemble_name (asm_out_file, buf);
3038 }
3039
5cb6195d
RH
3040 if (code == 'X')
3041 ; /* No suffix, dammit. */
3042 else if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
2a2ab3f9
JVA
3043 fprintf (file, "@GOTOFF(%%ebx)");
3044 else if (code == 'P')
3045 fprintf (file, "@PLT");
c399861d
MM
3046 else if (GET_CODE (x) == LABEL_REF)
3047 fprintf (file, "@GOTOFF");
3048 else if (! SYMBOL_REF_FLAG (x))
2a2ab3f9
JVA
3049 fprintf (file, "@GOT");
3050 else
3051 fprintf (file, "@GOTOFF");
3052
3053 break;
3054
3055 case CODE_LABEL:
3056 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
3057 assemble_name (asm_out_file, buf);
3058 break;
3059
3060 case CONST_INT:
f64cecad 3061 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2a2ab3f9
JVA
3062 break;
3063
3064 case CONST:
3065 /* This used to output parentheses around the expression,
3066 but that does not work on the 386 (either ATT or BSD assembler). */
3067 output_pic_addr_const (file, XEXP (x, 0), code);
3068 break;
3069
3070 case CONST_DOUBLE:
3071 if (GET_MODE (x) == VOIDmode)
3072 {
3073 /* We can use %d if the number is <32 bits and positive. */
3074 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
f64cecad
JC
3075 fprintf (file, "0x%lx%08lx",
3076 (unsigned long) CONST_DOUBLE_HIGH (x),
3077 (unsigned long) CONST_DOUBLE_LOW (x));
2a2ab3f9 3078 else
f64cecad 3079 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
2a2ab3f9
JVA
3080 }
3081 else
3082 /* We can't handle floating point constants;
3083 PRINT_OPERAND must handle them. */
3084 output_operand_lossage ("floating constant misused");
3085 break;
3086
3087 case PLUS:
e9a25f70 3088 /* Some assemblers need integer constants to appear first. */
2a2ab3f9
JVA
3089 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
3090 {
2a2ab3f9 3091 output_pic_addr_const (file, XEXP (x, 0), code);
e9a25f70
JL
3092 if (INTVAL (XEXP (x, 1)) >= 0)
3093 fprintf (file, "+");
3094 output_pic_addr_const (file, XEXP (x, 1), code);
2a2ab3f9
JVA
3095 }
3096 else
3097 {
2a2ab3f9 3098 output_pic_addr_const (file, XEXP (x, 1), code);
e9a25f70
JL
3099 if (INTVAL (XEXP (x, 0)) >= 0)
3100 fprintf (file, "+");
3101 output_pic_addr_const (file, XEXP (x, 0), code);
2a2ab3f9
JVA
3102 }
3103 break;
3104
3105 case MINUS:
3106 output_pic_addr_const (file, XEXP (x, 0), code);
3107 fprintf (file, "-");
3108 output_pic_addr_const (file, XEXP (x, 1), code);
3109 break;
3110
3111 default:
3112 output_operand_lossage ("invalid expression as operand");
3113 }
3114}
3115\f
e9a25f70 3116/* Append the correct conditional move suffix which corresponds to CODE. */
e5cb57e8
SC
3117
3118static void
c27d9c3b 3119put_condition_code (code, reverse_cc, mode, file)
fe25fea3 3120 enum rtx_code code;
c27d9c3b 3121 int reverse_cc;
fe25fea3
SC
3122 enum mode_class mode;
3123 FILE * file;
e5cb57e8 3124{
e9a25f70
JL
3125 int ieee = (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
3126 && ! (cc_prev_status.flags & CC_FCOMI));
c27d9c3b
SC
3127 if (reverse_cc && ! ieee)
3128 code = reverse_condition (code);
3129
fe25fea3 3130 if (mode == MODE_INT)
e9a25f70
JL
3131 switch (code)
3132 {
79325812 3133 case NE:
e9a25f70
JL
3134 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
3135 fputs ("b", file);
3136 else
3137 fputs ("ne", file);
3138 return;
3139
3140 case EQ:
3141 if (cc_prev_status.flags & CC_Z_IN_NOT_C)
3142 fputs ("ae", file);
3143 else
3144 fputs ("e", file);
3145 return;
3146
3147 case GE:
b657fc39
L
3148 if (cc_prev_status.flags & CC_NO_OVERFLOW)
3149 fputs ("ns", file);
3150 else
3151 fputs ("ge", file);
e9a25f70
JL
3152 return;
3153
3154 case GT:
3155 fputs ("g", file);
3156 return;
3157
3158 case LE:
3159 fputs ("le", file);
3160 return;
3161
3162 case LT:
b657fc39
L
3163 if (cc_prev_status.flags & CC_NO_OVERFLOW)
3164 fputs ("s", file);
3165 else
3166 fputs ("l", file);
e9a25f70
JL
3167 return;
3168
3169 case GEU:
3170 fputs ("ae", file);
3171 return;
3172
3173 case GTU:
3174 fputs ("a", file);
3175 return;
3176
3177 case LEU:
3178 fputs ("be", file);
3179 return;
3180
3181 case LTU:
3182 fputs ("b", file);
3183 return;
3184
3185 default:
3186 output_operand_lossage ("Invalid %%C operand");
3187 }
3188
fe25fea3 3189 else if (mode == MODE_FLOAT)
e9a25f70
JL
3190 switch (code)
3191 {
79325812 3192 case NE:
e9a25f70
JL
3193 fputs (ieee ? (reverse_cc ? "ne" : "e") : "ne", file);
3194 return;
79325812 3195 case EQ:
e9a25f70
JL
3196 fputs (ieee ? (reverse_cc ? "ne" : "e") : "e", file);
3197 return;
79325812 3198 case GE:
e9a25f70
JL
3199 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3200 return;
79325812 3201 case GT:
e9a25f70
JL
3202 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3203 return;
79325812 3204 case LE:
e9a25f70
JL
3205 fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3206 return;
79325812 3207 case LT:
e9a25f70
JL
3208 fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3209 return;
79325812 3210 case GEU:
e9a25f70
JL
3211 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3212 return;
79325812 3213 case GTU:
e9a25f70
JL
3214 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3215 return;
79325812 3216 case LEU:
e9a25f70
JL
3217 fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3218 return;
79325812 3219 case LTU:
e9a25f70
JL
3220 fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3221 return;
3222 default:
3223 output_operand_lossage ("Invalid %%C operand");
fe25fea3 3224 }
e5cb57e8
SC
3225}
3226
2a2ab3f9 3227/* Meaning of CODE:
fe25fea3 3228 L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
e5cb57e8 3229 C -- print opcode suffix for set/cmov insn.
fe25fea3
SC
3230 c -- like C, but print reversed condition
3231 F -- print opcode suffix for fcmov insn.
3232 f -- like C, but print reversed condition
2a2ab3f9
JVA
3233 R -- print the prefix for register names.
3234 z -- print the opcode suffix for the size of the current operand.
3235 * -- print a star (in certain assembler syntax)
3236 w -- print the operand as if it's a "word" (HImode) even if it isn't.
3237 c -- don't print special prefixes before constant operands.
b08de47e 3238 J -- print the appropriate jump operand.
2d49677f
SC
3239 s -- print a shift double count, followed by the assemblers argument
3240 delimiter.
fe25fea3
SC
3241 b -- print the QImode name of the register for the indicated operand.
3242 %b0 would print %al if operands[0] is reg 0.
3243 w -- likewise, print the HImode name of the register.
3244 k -- likewise, print the SImode name of the register.
3245 h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
3246 y -- print "st(0)" instead of "st" as a register.
e9a25f70 3247 P -- print as a PIC constant */
2a2ab3f9
JVA
3248
3249void
3250print_operand (file, x, code)
3251 FILE *file;
3252 rtx x;
3253 int code;
3254{
3255 if (code)
3256 {
3257 switch (code)
3258 {
3259 case '*':
3260 if (USE_STAR)
3261 putc ('*', file);
3262 return;
3263
2a2ab3f9
JVA
3264 case 'L':
3265 PUT_OP_SIZE (code, 'l', file);
3266 return;
3267
3268 case 'W':
3269 PUT_OP_SIZE (code, 'w', file);
3270 return;
3271
3272 case 'B':
3273 PUT_OP_SIZE (code, 'b', file);
3274 return;
3275
3276 case 'Q':
3277 PUT_OP_SIZE (code, 'l', file);
3278 return;
3279
3280 case 'S':
3281 PUT_OP_SIZE (code, 's', file);
3282 return;
3283
5f1ec3e6
JVA
3284 case 'T':
3285 PUT_OP_SIZE (code, 't', file);
3286 return;
3287
2a2ab3f9
JVA
3288 case 'z':
3289 /* 387 opcodes don't get size suffixes if the operands are
3290 registers. */
3291
3292 if (STACK_REG_P (x))
3293 return;
3294
3295 /* this is the size of op from size of operand */
3296 switch (GET_MODE_SIZE (GET_MODE (x)))
3297 {
3298 case 1:
3299 PUT_OP_SIZE ('B', 'b', file);
3300 return;
3301
3302 case 2:
3303 PUT_OP_SIZE ('W', 'w', file);
3304 return;
3305
3306 case 4:
3307 if (GET_MODE (x) == SFmode)
3308 {
3309 PUT_OP_SIZE ('S', 's', file);
3310 return;
3311 }
3312 else
3313 PUT_OP_SIZE ('L', 'l', file);
3314 return;
3315
5f1ec3e6
JVA
3316 case 12:
3317 PUT_OP_SIZE ('T', 't', file);
3318 return;
3319
2a2ab3f9
JVA
3320 case 8:
3321 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
56c0e8fa
JVA
3322 {
3323#ifdef GAS_MNEMONICS
3324 PUT_OP_SIZE ('Q', 'q', file);
3325 return;
3326#else
3327 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
3328#endif
3329 }
2a2ab3f9
JVA
3330
3331 PUT_OP_SIZE ('Q', 'l', file);
3332 return;
3333 }
4af3895e
JVA
3334
3335 case 'b':
3336 case 'w':
3337 case 'k':
3338 case 'h':
3339 case 'y':
3340 case 'P':
5cb6195d 3341 case 'X':
4af3895e
JVA
3342 break;
3343
b08de47e
MM
3344 case 'J':
3345 switch (GET_CODE (x))
3346 {
c645b1c9
MM
3347 /* These conditions are appropriate for testing the result
3348 of an arithmetic operation, not for a compare operation.
3349 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
3350 CC_Z_IN_NOT_C false and not floating point. */
b08de47e
MM
3351 case NE: fputs ("jne", file); return;
3352 case EQ: fputs ("je", file); return;
c645b1c9 3353 case GE: fputs ("jns", file); return;
c645b1c9 3354 case LT: fputs ("js", file); return;
d784886d
RK
3355 case GEU: fputs ("jmp", file); return;
3356 case GTU: fputs ("jne", file); return;
3357 case LEU: fputs ("je", file); return;
3358 case LTU: fputs ("#branch never", file); return;
79325812 3359
d784886d 3360 /* no matching branches for GT nor LE */
79325812 3361
00c79232
ML
3362 default:
3363 abort ();
b08de47e 3364 }
b08de47e 3365
2d49677f
SC
3366 case 's':
3367 if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
3368 {
3369 PRINT_OPERAND (file, x, 0);
3370 fputs (AS2C (,) + 1, file);
3371 }
e9a25f70 3372
2d49677f
SC
3373 return;
3374
1853aadd
RK
3375 /* This is used by the conditional move instructions. */
3376 case 'C':
c27d9c3b 3377 put_condition_code (GET_CODE (x), 0, MODE_INT, file);
1853aadd 3378 return;
fe25fea3 3379
e9a25f70 3380 /* Like above, but reverse condition */
fe25fea3 3381 case 'c':
c27d9c3b 3382 put_condition_code (GET_CODE (x), 1, MODE_INT, file); return;
fe25fea3
SC
3383
3384 case 'F':
c27d9c3b 3385 put_condition_code (GET_CODE (x), 0, MODE_FLOAT, file);
fe25fea3
SC
3386 return;
3387
e9a25f70 3388 /* Like above, but reverse condition */
fe25fea3 3389 case 'f':
c27d9c3b 3390 put_condition_code (GET_CODE (x), 1, MODE_FLOAT, file);
1853aadd 3391 return;
e5cb57e8 3392
4af3895e 3393 default:
68daafd4
JVA
3394 {
3395 char str[50];
3396
3397 sprintf (str, "invalid operand code `%c'", code);
3398 output_operand_lossage (str);
3399 }
2a2ab3f9
JVA
3400 }
3401 }
e9a25f70 3402
2a2ab3f9
JVA
3403 if (GET_CODE (x) == REG)
3404 {
3405 PRINT_REG (x, code, file);
3406 }
e9a25f70 3407
2a2ab3f9
JVA
3408 else if (GET_CODE (x) == MEM)
3409 {
3410 PRINT_PTR (x, file);
3411 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
3412 {
3413 if (flag_pic)
3414 output_pic_addr_const (file, XEXP (x, 0), code);
3415 else
3416 output_addr_const (file, XEXP (x, 0));
3417 }
3418 else
3419 output_address (XEXP (x, 0));
3420 }
e9a25f70 3421
2a2ab3f9
JVA
3422 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
3423 {
e9a25f70
JL
3424 REAL_VALUE_TYPE r;
3425 long l;
3426
5f1ec3e6
JVA
3427 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3428 REAL_VALUE_TO_TARGET_SINGLE (r, l);
4af3895e 3429 PRINT_IMMED_PREFIX (file);
52267fcb 3430 fprintf (file, "0x%lx", l);
5f1ec3e6 3431 }
e9a25f70 3432
5f1ec3e6
JVA
3433 /* These float cases don't actually occur as immediate operands. */
3434 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
3435 {
e9a25f70
JL
3436 REAL_VALUE_TYPE r;
3437 char dstr[30];
3438
5f1ec3e6
JVA
3439 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3440 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3441 fprintf (file, "%s", dstr);
2a2ab3f9 3442 }
e9a25f70 3443
5f1ec3e6 3444 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2a2ab3f9 3445 {
e9a25f70
JL
3446 REAL_VALUE_TYPE r;
3447 char dstr[30];
3448
5f1ec3e6
JVA
3449 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3450 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3451 fprintf (file, "%s", dstr);
2a2ab3f9 3452 }
79325812 3453 else
2a2ab3f9 3454 {
4af3895e 3455 if (code != 'P')
2a2ab3f9 3456 {
695dac07 3457 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2a2ab3f9
JVA
3458 PRINT_IMMED_PREFIX (file);
3459 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
3460 || GET_CODE (x) == LABEL_REF)
3461 PRINT_OFFSET_PREFIX (file);
3462 }
3463 if (flag_pic)
3464 output_pic_addr_const (file, x, code);
3465 else
3466 output_addr_const (file, x);
3467 }
3468}
3469\f
3470/* Print a memory operand whose address is ADDR. */
3471
3472void
3473print_operand_address (file, addr)
3474 FILE *file;
3475 register rtx addr;
3476{
3477 register rtx reg1, reg2, breg, ireg;
3478 rtx offset;
3479
3480 switch (GET_CODE (addr))
3481 {
3482 case REG:
3483 ADDR_BEG (file);
3484 fprintf (file, "%se", RP);
3485 fputs (hi_reg_name[REGNO (addr)], file);
3486 ADDR_END (file);
3487 break;
3488
3489 case PLUS:
3490 reg1 = 0;
3491 reg2 = 0;
3492 ireg = 0;
3493 breg = 0;
3494 offset = 0;
3495 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3496 {
3497 offset = XEXP (addr, 0);
3498 addr = XEXP (addr, 1);
3499 }
3500 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3501 {
3502 offset = XEXP (addr, 1);
3503 addr = XEXP (addr, 0);
3504 }
e9a25f70
JL
3505
3506 if (GET_CODE (addr) != PLUS)
3507 ;
2a2ab3f9 3508 else if (GET_CODE (XEXP (addr, 0)) == MULT)
e9a25f70 3509 reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
2a2ab3f9 3510 else if (GET_CODE (XEXP (addr, 1)) == MULT)
e9a25f70 3511 reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
2a2ab3f9 3512 else if (GET_CODE (XEXP (addr, 0)) == REG)
e9a25f70 3513 reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
2a2ab3f9 3514 else if (GET_CODE (XEXP (addr, 1)) == REG)
e9a25f70
JL
3515 reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3516
2a2ab3f9
JVA
3517 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
3518 {
e9a25f70
JL
3519 if (reg1 == 0)
3520 reg1 = addr;
3521 else
3522 reg2 = addr;
3523
2a2ab3f9
JVA
3524 addr = 0;
3525 }
e9a25f70 3526
2a2ab3f9
JVA
3527 if (offset != 0)
3528 {
e9a25f70
JL
3529 if (addr != 0)
3530 abort ();
2a2ab3f9
JVA
3531 addr = offset;
3532 }
e9a25f70 3533
2a2ab3f9
JVA
3534 if ((reg1 && GET_CODE (reg1) == MULT)
3535 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3536 {
3537 breg = reg2;
3538 ireg = reg1;
3539 }
3540 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3541 {
3542 breg = reg1;
3543 ireg = reg2;
3544 }
3545
3546 if (ireg != 0 || breg != 0)
3547 {
3548 int scale = 1;
3549
3550 if (addr != 0)
3551 {
c399861d
MM
3552 if (flag_pic)
3553 output_pic_addr_const (file, addr, 0);
c399861d 3554 else if (GET_CODE (addr) == LABEL_REF)
2a2ab3f9
JVA
3555 output_asm_label (addr);
3556 else
c399861d 3557 output_addr_const (file, addr);
2a2ab3f9
JVA
3558 }
3559
3560 if (ireg != 0 && GET_CODE (ireg) == MULT)
3561 {
3562 scale = INTVAL (XEXP (ireg, 1));
3563 ireg = XEXP (ireg, 0);
3564 }
3565
3566 /* The stack pointer can only appear as a base register,
3567 never an index register, so exchange the regs if it is wrong. */
3568
3569 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
3570 {
3571 rtx tmp;
3572
3573 tmp = breg;
3574 breg = ireg;
3575 ireg = tmp;
3576 }
3577
3578 /* output breg+ireg*scale */
3579 PRINT_B_I_S (breg, ireg, scale, file);
3580 break;
3581 }
3582
3583 case MULT:
3584 {
3585 int scale;
e9a25f70 3586
2a2ab3f9
JVA
3587 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
3588 {
3589 scale = INTVAL (XEXP (addr, 0));
3590 ireg = XEXP (addr, 1);
3591 }
3592 else
3593 {
3594 scale = INTVAL (XEXP (addr, 1));
3595 ireg = XEXP (addr, 0);
3596 }
e9a25f70 3597
2a2ab3f9 3598 output_addr_const (file, const0_rtx);
e9a25f70 3599 PRINT_B_I_S (NULL_RTX, ireg, scale, file);
2a2ab3f9
JVA
3600 }
3601 break;
3602
3603 default:
3604 if (GET_CODE (addr) == CONST_INT
3605 && INTVAL (addr) < 0x8000
3606 && INTVAL (addr) >= -0x8000)
f64cecad 3607 fprintf (file, "%d", (int) INTVAL (addr));
2a2ab3f9
JVA
3608 else
3609 {
3610 if (flag_pic)
3611 output_pic_addr_const (file, addr, 0);
3612 else
3613 output_addr_const (file, addr);
3614 }
3615 }
3616}
3617\f
3618/* Set the cc_status for the results of an insn whose pattern is EXP.
3619 On the 80386, we assume that only test and compare insns, as well
5cb6195d 3620 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, BSF, ASHIFT,
2a2ab3f9 3621 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
4c0d89b5
RS
3622 Also, we assume that jumps, moves and sCOND don't affect the condition
3623 codes. All else clobbers the condition codes, by assumption.
3624
3625 We assume that ALL integer add, minus, etc. instructions effect the
3626 condition codes. This MUST be consistent with i386.md.
2a2ab3f9 3627
4c0d89b5
RS
3628 We don't record any float test or compare - the redundant test &
3629 compare check in final.c does not handle stack-like regs correctly. */
2a2ab3f9
JVA
3630
3631void
3632notice_update_cc (exp)
3633 rtx exp;
3634{
3635 if (GET_CODE (exp) == SET)
3636 {
3637 /* Jumps do not alter the cc's. */
3638 if (SET_DEST (exp) == pc_rtx)
3639 return;
e9a25f70 3640
2a2ab3f9
JVA
3641 /* Moving register or memory into a register:
3642 it doesn't alter the cc's, but it might invalidate
3643 the RTX's which we remember the cc's came from.
3644 (Note that moving a constant 0 or 1 MAY set the cc's). */
3645 if (REG_P (SET_DEST (exp))
4c0d89b5 3646 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
9c8c5afb
JW
3647 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'
3648 || (GET_CODE (SET_SRC (exp)) == IF_THEN_ELSE
3649 && GET_MODE_CLASS (GET_MODE (SET_DEST (exp))) == MODE_INT)))
2a2ab3f9
JVA
3650 {
3651 if (cc_status.value1
3652 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3653 cc_status.value1 = 0;
e9a25f70 3654
2a2ab3f9
JVA
3655 if (cc_status.value2
3656 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3657 cc_status.value2 = 0;
e9a25f70 3658
2a2ab3f9
JVA
3659 return;
3660 }
e9a25f70 3661
2a2ab3f9
JVA
3662 /* Moving register into memory doesn't alter the cc's.
3663 It may invalidate the RTX's which we remember the cc's came from. */
4c0d89b5
RS
3664 if (GET_CODE (SET_DEST (exp)) == MEM
3665 && (REG_P (SET_SRC (exp))
3666 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2a2ab3f9 3667 {
e9a25f70
JL
3668 if (cc_status.value1
3669 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2a2ab3f9 3670 cc_status.value1 = 0;
e9a25f70
JL
3671 if (cc_status.value2
3672 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2a2ab3f9 3673 cc_status.value2 = 0;
e9a25f70 3674
2a2ab3f9
JVA
3675 return;
3676 }
e9a25f70 3677
2a2ab3f9
JVA
3678 /* Function calls clobber the cc's. */
3679 else if (GET_CODE (SET_SRC (exp)) == CALL)
3680 {
3681 CC_STATUS_INIT;
3682 return;
3683 }
e9a25f70 3684
2a2ab3f9
JVA
3685 /* Tests and compares set the cc's in predictable ways. */
3686 else if (SET_DEST (exp) == cc0_rtx)
3687 {
3688 CC_STATUS_INIT;
3689 cc_status.value1 = SET_SRC (exp);
3690 return;
3691 }
e9a25f70 3692
2a2ab3f9
JVA
3693 /* Certain instructions effect the condition codes. */
3694 else if (GET_MODE (SET_SRC (exp)) == SImode
3695 || GET_MODE (SET_SRC (exp)) == HImode
3696 || GET_MODE (SET_SRC (exp)) == QImode)
3697 switch (GET_CODE (SET_SRC (exp)))
3698 {
e9a25f70 3699 case ASHIFTRT: case LSHIFTRT: case ASHIFT:
2a2ab3f9
JVA
3700 /* Shifts on the 386 don't set the condition codes if the
3701 shift count is zero. */
3702 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
3703 {
3704 CC_STATUS_INIT;
3705 break;
3706 }
e9a25f70 3707
2a2ab3f9
JVA
3708 /* We assume that the CONST_INT is non-zero (this rtx would
3709 have been deleted if it were zero. */
3710
3711 case PLUS: case MINUS: case NEG:
3712 case AND: case IOR: case XOR:
3713 cc_status.flags = CC_NO_OVERFLOW;
3714 cc_status.value1 = SET_SRC (exp);
3715 cc_status.value2 = SET_DEST (exp);
3716 break;
3717
ce193852
RH
3718 /* This is the bsf pattern used by ffs. */
3719 case UNSPEC:
3720 if (XINT (SET_SRC (exp), 1) == 5)
3721 {
3722 /* Only the Z flag is defined after bsf. */
3723 cc_status.flags
3724 = CC_NOT_POSITIVE | CC_NOT_NEGATIVE | CC_NO_OVERFLOW;
3725 cc_status.value1 = XVECEXP (SET_SRC (exp), 0, 0);
9d932d43 3726 cc_status.value2 = 0;
ce193852
RH
3727 break;
3728 }
3729 /* FALLTHRU */
3730
2a2ab3f9
JVA
3731 default:
3732 CC_STATUS_INIT;
3733 }
3734 else
3735 {
3736 CC_STATUS_INIT;
3737 }
3738 }
3739 else if (GET_CODE (exp) == PARALLEL
3740 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
3741 {
3742 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
3743 return;
3744 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
e9a25f70 3745
2a2ab3f9
JVA
3746 {
3747 CC_STATUS_INIT;
a8620236
SC
3748 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
3749 {
3750 cc_status.flags |= CC_IN_80387;
d6cc54f6 3751 if (0 && TARGET_CMOVE && stack_regs_mentioned_p
a8620236
SC
3752 (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1)))
3753 cc_status.flags |= CC_FCOMI;
3754 }
2247a58c 3755 else
4c0d89b5 3756 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2a2ab3f9
JVA
3757 return;
3758 }
e9a25f70 3759
2a2ab3f9
JVA
3760 CC_STATUS_INIT;
3761 }
3762 else
3763 {
3764 CC_STATUS_INIT;
3765 }
3766}
3767\f
3768/* Split one or more DImode RTL references into pairs of SImode
3769 references. The RTL can be REG, offsettable MEM, integer constant, or
3770 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3771 split and "num" is its length. lo_half and hi_half are output arrays
3772 that parallel "operands". */
3773
3774void
3775split_di (operands, num, lo_half, hi_half)
3776 rtx operands[];
3777 int num;
3778 rtx lo_half[], hi_half[];
3779{
3780 while (num--)
3781 {
57dbca5e
BS
3782 rtx op = operands[num];
3783 if (GET_CODE (op) == REG)
2a2ab3f9 3784 {
57dbca5e
BS
3785 lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
3786 hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
2a2ab3f9 3787 }
57dbca5e
BS
3788 else if (CONSTANT_P (op))
3789 split_double (op, &lo_half[num], &hi_half[num]);
3790 else if (offsettable_memref_p (op))
2a2ab3f9 3791 {
57dbca5e
BS
3792 rtx lo_addr = XEXP (op, 0);
3793 rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
3794 lo_half[num] = change_address (op, SImode, lo_addr);
3795 hi_half[num] = change_address (op, SImode, hi_addr);
2a2ab3f9
JVA
3796 }
3797 else
3798 abort();
3799 }
3800}
3801\f
3802/* Return 1 if this is a valid binary operation on a 387.
3803 OP is the expression matched, and MODE is its mode. */
3804
3805int
3806binary_387_op (op, mode)
3807 register rtx op;
3808 enum machine_mode mode;
3809{
3810 if (mode != VOIDmode && mode != GET_MODE (op))
3811 return 0;
3812
3813 switch (GET_CODE (op))
3814 {
3815 case PLUS:
3816 case MINUS:
3817 case MULT:
3818 case DIV:
3819 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3820
3821 default:
3822 return 0;
3823 }
3824}
3b3c6a3f 3825\f
2a2ab3f9
JVA
3826/* Return 1 if this is a valid shift or rotate operation on a 386.
3827 OP is the expression matched, and MODE is its mode. */
3828
3829int
3830shift_op (op, mode)
3831 register rtx op;
3832 enum machine_mode mode;
3833{
3834 rtx operand = XEXP (op, 0);
3835
3836 if (mode != VOIDmode && mode != GET_MODE (op))
3837 return 0;
3838
3839 if (GET_MODE (operand) != GET_MODE (op)
3840 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3841 return 0;
3842
3843 return (GET_CODE (op) == ASHIFT
3844 || GET_CODE (op) == ASHIFTRT
3845 || GET_CODE (op) == LSHIFTRT
3846 || GET_CODE (op) == ROTATE
3847 || GET_CODE (op) == ROTATERT);
3848}
ac2afb64
JVA
3849
3850/* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3851 MODE is not used. */
3852
3853int
3854VOIDmode_compare_op (op, mode)
3855 register rtx op;
bb5177ac 3856 enum machine_mode mode ATTRIBUTE_UNUSED;
ac2afb64
JVA
3857{
3858 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3859}
2a2ab3f9
JVA
3860\f
3861/* Output code to perform a 387 binary operation in INSN, one of PLUS,
3862 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3863 is the expression of the binary operation. The output may either be
3864 emitted here, or returned to the caller, like all output_* functions.
3865
3866 There is no guarantee that the operands are the same mode, as they
3867 might be within FLOAT or FLOAT_EXTEND expressions. */
3868
3869char *
3870output_387_binary_op (insn, operands)
3871 rtx insn;
3872 rtx *operands;
3873{
3874 rtx temp;
3875 char *base_op;
3876 static char buf[100];
3877
3878 switch (GET_CODE (operands[3]))
3879 {
3880 case PLUS:
3881 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3882 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3883 base_op = "fiadd";
3884 else
3885 base_op = "fadd";
3886 break;
3887
3888 case MINUS:
3889 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3890 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3891 base_op = "fisub";
3892 else
3893 base_op = "fsub";
3894 break;
3895
3896 case MULT:
3897 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3898 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3899 base_op = "fimul";
3900 else
3901 base_op = "fmul";
3902 break;
3903
3904 case DIV:
3905 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3906 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3907 base_op = "fidiv";
3908 else
3909 base_op = "fdiv";
3910 break;
3911
3912 default:
3913 abort ();
3914 }
3915
3916 strcpy (buf, base_op);
3917
3918 switch (GET_CODE (operands[3]))
3919 {
3920 case MULT:
3921 case PLUS:
3922 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3923 {
3924 temp = operands[2];
3925 operands[2] = operands[1];
3926 operands[1] = temp;
3927 }
3928
3929 if (GET_CODE (operands[2]) == MEM)
3930 return strcat (buf, AS1 (%z2,%2));
3931
3932 if (NON_STACK_REG_P (operands[1]))
3933 {
3934 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
e9a25f70 3935 return "";
2a2ab3f9 3936 }
e9a25f70 3937
2a2ab3f9
JVA
3938 else if (NON_STACK_REG_P (operands[2]))
3939 {
3940 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
e9a25f70 3941 return "";
2a2ab3f9
JVA
3942 }
3943
3944 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
3945 {
3946 if (STACK_TOP_P (operands[0]))
3947 return strcat (buf, AS2 (p,%0,%2));
3948 else
3949 return strcat (buf, AS2 (p,%2,%0));
3950 }
2a2ab3f9
JVA
3951
3952 if (STACK_TOP_P (operands[0]))
3f6d0a8c 3953 return strcat (buf, AS2C (%y2,%0));
2a2ab3f9 3954 else
3f6d0a8c 3955 return strcat (buf, AS2C (%2,%0));
2a2ab3f9
JVA
3956
3957 case MINUS:
3958 case DIV:
3959 if (GET_CODE (operands[1]) == MEM)
3960 return strcat (buf, AS1 (r%z1,%1));
3961
3962 if (GET_CODE (operands[2]) == MEM)
3963 return strcat (buf, AS1 (%z2,%2));
3964
3965 if (NON_STACK_REG_P (operands[1]))
3966 {
3967 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
e9a25f70 3968 return "";
2a2ab3f9 3969 }
e9a25f70 3970
2a2ab3f9
JVA
3971 else if (NON_STACK_REG_P (operands[2]))
3972 {
3973 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
e9a25f70 3974 return "";
2a2ab3f9
JVA
3975 }
3976
3977 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3978 abort ();
3979
3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
3981 {
3982 if (STACK_TOP_P (operands[0]))
3983 return strcat (buf, AS2 (p,%0,%2));
3984 else
3985 return strcat (buf, AS2 (rp,%2,%0));
3986 }
2a2ab3f9
JVA
3987
3988 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
6b28fd63
JL
3989 {
3990 if (STACK_TOP_P (operands[0]))
3991 return strcat (buf, AS2 (rp,%0,%1));
3992 else
3993 return strcat (buf, AS2 (p,%1,%0));
3994 }
2a2ab3f9
JVA
3995
3996 if (STACK_TOP_P (operands[0]))
3997 {
3998 if (STACK_TOP_P (operands[1]))
3f6d0a8c 3999 return strcat (buf, AS2C (%y2,%0));
2a2ab3f9
JVA
4000 else
4001 return strcat (buf, AS2 (r,%y1,%0));
4002 }
4003 else if (STACK_TOP_P (operands[1]))
3f6d0a8c 4004 return strcat (buf, AS2C (%1,%0));
2a2ab3f9
JVA
4005 else
4006 return strcat (buf, AS2 (r,%2,%0));
4007
4008 default:
4009 abort ();
4010 }
4011}
4012\f
4013/* Output code for INSN to convert a float to a signed int. OPERANDS
4014 are the insn operands. The output may be SFmode or DFmode and the
4015 input operand may be SImode or DImode. As a special case, make sure
4016 that the 387 stack top dies if the output mode is DImode, because the
4017 hardware requires this. */
4018
4019char *
4020output_fix_trunc (insn, operands)
4021 rtx insn;
4022 rtx *operands;
4023{
4024 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
305f097e 4025 rtx xops[2];
2a2ab3f9 4026
2e14a41b 4027 if (! STACK_TOP_P (operands[1]))
2a2ab3f9
JVA
4028 abort ();
4029
305f097e
JVA
4030 xops[0] = GEN_INT (12);
4031 xops[1] = operands[4];
4032
4033 output_asm_insn (AS1 (fnstc%W2,%2), operands);
4034 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
4035 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
4036 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
4037 output_asm_insn (AS1 (fldc%W3,%3), operands);
2a2ab3f9
JVA
4038
4039 if (NON_STACK_REG_P (operands[0]))
c27d9c3b 4040 output_to_reg (operands[0], stack_top_dies, operands[3]);
e9a25f70 4041
2a2ab3f9
JVA
4042 else if (GET_CODE (operands[0]) == MEM)
4043 {
2a2ab3f9
JVA
4044 if (stack_top_dies)
4045 output_asm_insn (AS1 (fistp%z0,%0), operands);
2e14a41b
JW
4046 else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
4047 {
4048 /* There is no DImode version of this without a stack pop, so
4049 we must emulate it. It doesn't matter much what the second
4050 instruction is, because the value being pushed on the FP stack
4051 is not used except for the following stack popping store.
4052 This case can only happen without optimization, so it doesn't
4053 matter that it is inefficient. */
4054 output_asm_insn (AS1 (fistp%z0,%0), operands);
4055 output_asm_insn (AS1 (fild%z0,%0), operands);
4056 }
2a2ab3f9
JVA
4057 else
4058 output_asm_insn (AS1 (fist%z0,%0), operands);
4059 }
4060 else
4061 abort ();
4062
305f097e 4063 return AS1 (fldc%W2,%2);
2a2ab3f9
JVA
4064}
4065\f
4066/* Output code for INSN to compare OPERANDS. The two operands might
4067 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
c572e5ba
JVA
4068 expression. If the compare is in mode CCFPEQmode, use an opcode that
4069 will not fault if a qNaN is present. */
2a2ab3f9
JVA
4070
4071char *
4072output_float_compare (insn, operands)
4073 rtx insn;
4074 rtx *operands;
4075{
4076 int stack_top_dies;
c572e5ba
JVA
4077 rtx body = XVECEXP (PATTERN (insn), 0, 0);
4078 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
32b5b1aa 4079 rtx tmp;
4f74d15b 4080
d6cc54f6 4081 if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
4f74d15b
SC
4082 {
4083 cc_status.flags |= CC_FCOMI;
4084 cc_prev_status.flags &= ~CC_TEST_AX;
4085 }
4086
32b5b1aa
SC
4087 if (! STACK_TOP_P (operands[0]))
4088 {
4089 tmp = operands[0];
4090 operands[0] = operands[1];
4091 operands[1] = tmp;
4092 cc_status.flags |= CC_REVERSED;
4093 }
79325812 4094
2a2ab3f9
JVA
4095 if (! STACK_TOP_P (operands[0]))
4096 abort ();
4097
4098 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4099
4100 if (STACK_REG_P (operands[1])
4101 && stack_top_dies
4102 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4103 && REGNO (operands[1]) != FIRST_STACK_REG)
4104 {
4105 /* If both the top of the 387 stack dies, and the other operand
4106 is also a stack register that dies, then this must be a
4107 `fcompp' float compare */
4108
c572e5ba 4109 if (unordered_compare)
e9a25f70
JL
4110 {
4111 if (cc_status.flags & CC_FCOMI)
4112 {
4113 output_asm_insn (AS2 (fucomip,%y1,%0), operands);
4114 output_asm_insn (AS1 (fstp, %y0), operands);
4115 return "";
4116 }
4117 else
4118 output_asm_insn ("fucompp", operands);
4119 }
c572e5ba 4120 else
858a9ffc 4121 {
e9a25f70
JL
4122 if (cc_status.flags & CC_FCOMI)
4123 {
4124 output_asm_insn (AS2 (fcomip, %y1,%0), operands);
4125 output_asm_insn (AS1 (fstp, %y0), operands);
4126 return "";
4127 }
4128 else
4129 output_asm_insn ("fcompp", operands);
858a9ffc 4130 }
2a2ab3f9
JVA
4131 }
4132 else
4133 {
4134 static char buf[100];
4135
c572e5ba
JVA
4136 /* Decide if this is the integer or float compare opcode, or the
4137 unordered float compare. */
2a2ab3f9 4138
c572e5ba 4139 if (unordered_compare)
4f74d15b 4140 strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fucomi" : "fucom");
c572e5ba 4141 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
4f74d15b 4142 strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom");
2a2ab3f9
JVA
4143 else
4144 strcpy (buf, "ficom");
4145
4146 /* Modify the opcode if the 387 stack is to be popped. */
4147
4148 if (stack_top_dies)
4149 strcat (buf, "p");
4150
4151 if (NON_STACK_REG_P (operands[1]))
4152 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
79325812 4153 else if (cc_status.flags & CC_FCOMI)
5703bb66 4154 {
858a9ffc 4155 output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
e9a25f70 4156 return "";
5703bb66 4157 }
2a2ab3f9
JVA
4158 else
4159 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
4160 }
4161
4162 /* Now retrieve the condition code. */
4163
c572e5ba
JVA
4164 return output_fp_cc0_set (insn);
4165}
4166\f
4167/* Output opcodes to transfer the results of FP compare or test INSN
4168 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
4169 result of the compare or test is unordered, no comparison operator
4170 succeeds except NE. Return an output template, if any. */
4171
4172char *
4173output_fp_cc0_set (insn)
4174 rtx insn;
4175{
4176 rtx xops[3];
c572e5ba
JVA
4177 rtx next;
4178 enum rtx_code code;
4179
f64cecad 4180 xops[0] = gen_rtx_REG (HImode, 0);
c572e5ba
JVA
4181 output_asm_insn (AS1 (fnsts%W0,%0), xops);
4182
4183 if (! TARGET_IEEE_FP)
32b5b1aa
SC
4184 {
4185 if (!(cc_status.flags & CC_REVERSED))
4186 {
4187 next = next_cc0_user (insn);
79325812 4188
32b5b1aa
SC
4189 if (GET_CODE (next) == JUMP_INSN
4190 && GET_CODE (PATTERN (next)) == SET
4191 && SET_DEST (PATTERN (next)) == pc_rtx
4192 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
e9a25f70 4193 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
32b5b1aa 4194 else if (GET_CODE (PATTERN (next)) == SET)
e9a25f70 4195 code = GET_CODE (SET_SRC (PATTERN (next)));
32b5b1aa 4196 else
e9a25f70
JL
4197 return "sahf";
4198
4199 if (code == GT || code == LT || code == EQ || code == NE
4200 || code == LE || code == GE)
4201 {
4202 /* We will test eax directly. */
32b5b1aa 4203 cc_status.flags |= CC_TEST_AX;
e9a25f70 4204 return "";
32b5b1aa
SC
4205 }
4206 }
e9a25f70 4207
32b5b1aa
SC
4208 return "sahf";
4209 }
2a2ab3f9 4210
c572e5ba 4211 next = next_cc0_user (insn);
dd9611dc
JVA
4212 if (next == NULL_RTX)
4213 abort ();
c572e5ba
JVA
4214
4215 if (GET_CODE (next) == JUMP_INSN
4216 && GET_CODE (PATTERN (next)) == SET
4217 && SET_DEST (PATTERN (next)) == pc_rtx
4218 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
e9a25f70 4219 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
c572e5ba
JVA
4220 else if (GET_CODE (PATTERN (next)) == SET)
4221 {
fe25fea3
SC
4222 if (GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4223 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
e9a25f70
JL
4224 else
4225 code = GET_CODE (SET_SRC (PATTERN (next)));
c572e5ba 4226 }
e9a25f70 4227
4f74d15b
SC
4228 else if (GET_CODE (PATTERN (next)) == PARALLEL
4229 && GET_CODE (XVECEXP (PATTERN (next), 0, 0)) == SET)
4230 {
4231 if (GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0))) == IF_THEN_ELSE)
e9a25f70
JL
4232 code = GET_CODE (XEXP (SET_SRC (XVECEXP (PATTERN (next), 0, 0)), 0));
4233 else
4234 code = GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0)));
4f74d15b 4235 }
c572e5ba
JVA
4236 else
4237 abort ();
4238
f64cecad 4239 xops[0] = gen_rtx_REG (QImode, 0);
c572e5ba
JVA
4240
4241 switch (code)
4242 {
4243 case GT:
435defd1 4244 xops[1] = GEN_INT (0x45);
c572e5ba
JVA
4245 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4246 /* je label */
4247 break;
4248
4249 case LT:
435defd1
JVA
4250 xops[1] = GEN_INT (0x45);
4251 xops[2] = GEN_INT (0x01);
c572e5ba
JVA
4252 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4253 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4254 /* je label */
4255 break;
4256
4257 case GE:
435defd1 4258 xops[1] = GEN_INT (0x05);
c572e5ba
JVA
4259 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4260 /* je label */
4261 break;
4262
4263 case LE:
435defd1
JVA
4264 xops[1] = GEN_INT (0x45);
4265 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
4266 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4267 output_asm_insn (AS1 (dec%B0,%h0), xops);
4268 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4269 /* jb label */
4270 break;
4271
4272 case EQ:
435defd1
JVA
4273 xops[1] = GEN_INT (0x45);
4274 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
4275 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4276 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4277 /* je label */
4278 break;
4279
4280 case NE:
435defd1
JVA
4281 xops[1] = GEN_INT (0x44);
4282 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
4283 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4284 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
4285 /* jne label */
4286 break;
4287
4288 case GTU:
4289 case LTU:
4290 case GEU:
4291 case LEU:
4292 default:
4293 abort ();
4294 }
e9a25f70
JL
4295
4296 return "";
2a2ab3f9 4297}
305f097e
JVA
4298\f
4299#define MAX_386_STACK_LOCALS 2
4300
4301static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4302
ecbc4695
RS
4303/* Define the structure for the machine field in struct function. */
4304struct machine_function
4305{
4306 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
b94b5c16
JL
4307 rtx pic_label_rtx;
4308 char pic_label_name[256];
ecbc4695
RS
4309};
4310
4311/* Functions to save and restore i386_stack_locals.
4312 These will be called, via pointer variables,
4313 from push_function_context and pop_function_context. */
4314
4315void
4316save_386_machine_status (p)
4317 struct function *p;
4318{
b94b5c16
JL
4319 p->machine
4320 = (struct machine_function *) xmalloc (sizeof (struct machine_function));
dde866c6 4321 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
ecbc4695 4322 sizeof i386_stack_locals);
b94b5c16
JL
4323 p->machine->pic_label_rtx = pic_label_rtx;
4324 bcopy (pic_label_name, p->machine->pic_label_name, 256);
ecbc4695
RS
4325}
4326
4327void
4328restore_386_machine_status (p)
4329 struct function *p;
4330{
dde866c6 4331 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
ecbc4695 4332 sizeof i386_stack_locals);
b94b5c16
JL
4333 pic_label_rtx = p->machine->pic_label_rtx;
4334 bcopy (p->machine->pic_label_name, pic_label_name, 256);
ecbc4695 4335 free (p->machine);
b94b5c16 4336 p->machine = NULL;
ecbc4695
RS
4337}
4338
305f097e
JVA
4339/* Clear stack slot assignments remembered from previous functions.
4340 This is called from INIT_EXPANDERS once before RTL is emitted for each
ecbc4695 4341 function. */
305f097e
JVA
4342
4343void
4344clear_386_stack_locals ()
4345{
4346 enum machine_mode mode;
4347 int n;
4348
4349 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
4350 mode = (enum machine_mode) ((int) mode + 1))
4351 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
4352 i386_stack_locals[(int) mode][n] = NULL_RTX;
ecbc4695 4353
b94b5c16
JL
4354 pic_label_rtx = NULL_RTX;
4355 bzero (pic_label_name, 256);
ecbc4695
RS
4356 /* Arrange to save and restore i386_stack_locals around nested functions. */
4357 save_machine_status = save_386_machine_status;
4358 restore_machine_status = restore_386_machine_status;
305f097e
JVA
4359}
4360
4361/* Return a MEM corresponding to a stack slot with mode MODE.
4362 Allocate a new slot if necessary.
4363
4364 The RTL for a function can have several slots available: N is
4365 which slot to use. */
4366
4367rtx
4368assign_386_stack_local (mode, n)
4369 enum machine_mode mode;
4370 int n;
4371{
4372 if (n < 0 || n >= MAX_386_STACK_LOCALS)
4373 abort ();
4374
4375 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
4376 i386_stack_locals[(int) mode][n]
4377 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
4378
4379 return i386_stack_locals[(int) mode][n];
4380}
32b5b1aa
SC
4381\f
4382int is_mul(op,mode)
4383 register rtx op;
bb5177ac 4384 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4385{
4386 return (GET_CODE (op) == MULT);
4387}
4388
4389int is_div(op,mode)
4390 register rtx op;
bb5177ac 4391 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4392{
4393 return (GET_CODE (op) == DIV);
4394}
32b5b1aa
SC
4395\f
4396#ifdef NOTYET
4397/* Create a new copy of an rtx.
4398 Recursively copies the operands of the rtx,
4399 except for those few rtx codes that are sharable.
4400 Doesn't share CONST */
4401
4402rtx
4403copy_all_rtx (orig)
4404 register rtx orig;
4405{
4406 register rtx copy;
4407 register int i, j;
4408 register RTX_CODE code;
4409 register char *format_ptr;
4410
4411 code = GET_CODE (orig);
4412
4413 switch (code)
4414 {
4415 case REG:
4416 case QUEUED:
4417 case CONST_INT:
4418 case CONST_DOUBLE:
4419 case SYMBOL_REF:
4420 case CODE_LABEL:
4421 case PC:
4422 case CC0:
4423 case SCRATCH:
4424 /* SCRATCH must be shared because they represent distinct values. */
4425 return orig;
4426
4427#if 0
4428 case CONST:
4429 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
4430 a LABEL_REF, it isn't sharable. */
4431 if (GET_CODE (XEXP (orig, 0)) == PLUS
4432 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
4433 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
4434 return orig;
4435 break;
4436#endif
4437 /* A MEM with a constant address is not sharable. The problem is that
4438 the constant address may need to be reloaded. If the mem is shared,
4439 then reloading one copy of this mem will cause all copies to appear
4440 to have been reloaded. */
4441 }
4442
4443 copy = rtx_alloc (code);
4444 PUT_MODE (copy, GET_MODE (orig));
4445 copy->in_struct = orig->in_struct;
4446 copy->volatil = orig->volatil;
4447 copy->unchanging = orig->unchanging;
4448 copy->integrated = orig->integrated;
4449 /* intel1 */
4450 copy->is_spill_rtx = orig->is_spill_rtx;
79325812 4451
32b5b1aa
SC
4452 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
4453
4454 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
4455 {
4456 switch (*format_ptr++)
4457 {
4458 case 'e':
4459 XEXP (copy, i) = XEXP (orig, i);
4460 if (XEXP (orig, i) != NULL)
4461 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
4462 break;
4463
4464 case '0':
4465 case 'u':
4466 XEXP (copy, i) = XEXP (orig, i);
4467 break;
4468
4469 case 'E':
4470 case 'V':
4471 XVEC (copy, i) = XVEC (orig, i);
4472 if (XVEC (orig, i) != NULL)
4473 {
4474 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
4475 for (j = 0; j < XVECLEN (copy, i); j++)
4476 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
4477 }
4478 break;
4479
4480 case 'w':
4481 XWINT (copy, i) = XWINT (orig, i);
4482 break;
4483
4484 case 'i':
4485 XINT (copy, i) = XINT (orig, i);
4486 break;
4487
4488 case 's':
4489 case 'S':
4490 XSTR (copy, i) = XSTR (orig, i);
4491 break;
4492
4493 default:
4494 abort ();
4495 }
4496 }
4497 return copy;
4498}
4499
4500\f
e9a25f70
JL
4501/* Try to rewrite a memory address to make it valid */
4502
79325812 4503void
32b5b1aa
SC
4504rewrite_address (mem_rtx)
4505 rtx mem_rtx;
4506{
4507 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
4508 int scale = 1;
4509 int offset_adjust = 0;
4510 int was_only_offset = 0;
4511 rtx mem_addr = XEXP (mem_rtx, 0);
e9a25f70 4512 char *storage = oballoc (0);
32b5b1aa
SC
4513 int in_struct = 0;
4514 int is_spill_rtx = 0;
4515
4516 in_struct = MEM_IN_STRUCT_P (mem_rtx);
4517 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
4518
e9a25f70
JL
4519 if (GET_CODE (mem_addr) == PLUS
4520 && GET_CODE (XEXP (mem_addr, 1)) == PLUS
4521 && GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
4522 {
4523 /* This part is utilized by the combiner. */
4524 ret_rtx
4525 = gen_rtx (PLUS, GET_MODE (mem_addr),
4526 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
4527 XEXP (mem_addr, 0), XEXP (XEXP (mem_addr, 1), 0)),
4528 XEXP (XEXP (mem_addr, 1), 1));
4529
32b5b1aa
SC
4530 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
4531 {
4532 XEXP (mem_rtx, 0) = ret_rtx;
4533 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
4534 return;
4535 }
e9a25f70 4536
32b5b1aa
SC
4537 obfree (storage);
4538 }
4539
79325812 4540 /* This part is utilized by loop.c.
e9a25f70
JL
4541 If the address contains PLUS (reg,const) and this pattern is invalid
4542 in this case - try to rewrite the address to make it valid. */
4543 storage = oballoc (0);
32b5b1aa 4544 index_rtx = base_rtx = offset_rtx = NULL;
e9a25f70
JL
4545
4546 /* Find the base index and offset elements of the memory address. */
32b5b1aa
SC
4547 if (GET_CODE (mem_addr) == PLUS)
4548 {
4549 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
4550 {
4551 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
e9a25f70 4552 base_rtx = XEXP (mem_addr, 1), index_rtx = XEXP (mem_addr, 0);
32b5b1aa 4553 else
e9a25f70 4554 base_rtx = XEXP (mem_addr, 0), offset_rtx = XEXP (mem_addr, 1);
32b5b1aa 4555 }
e9a25f70 4556
32b5b1aa
SC
4557 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
4558 {
4559 index_rtx = XEXP (mem_addr, 0);
4560 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
e9a25f70 4561 base_rtx = XEXP (mem_addr, 1);
32b5b1aa 4562 else
e9a25f70 4563 offset_rtx = XEXP (mem_addr, 1);
32b5b1aa 4564 }
e9a25f70 4565
32b5b1aa
SC
4566 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
4567 {
e9a25f70
JL
4568 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS
4569 && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT
4570 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0))
4571 == REG)
4572 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1))
4573 == CONST_INT)
4574 && (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1))
4575 == CONST_INT)
4576 && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG
4577 && GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
32b5b1aa
SC
4578 {
4579 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
4580 offset_rtx = XEXP (mem_addr, 1);
4581 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4582 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
4583 }
4584 else
4585 {
4586 offset_rtx = XEXP (mem_addr, 1);
4587 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
4588 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4589 }
4590 }
e9a25f70 4591
32b5b1aa
SC
4592 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
4593 {
4594 was_only_offset = 1;
4595 index_rtx = NULL;
4596 base_rtx = NULL;
4597 offset_rtx = XEXP (mem_addr, 1);
4598 offset_adjust = INTVAL (XEXP (mem_addr, 0));
4599 if (offset_adjust == 0)
4600 {
4601 XEXP (mem_rtx, 0) = offset_rtx;
4602 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4603 return;
4604 }
4605 }
4606 else
4607 {
4608 obfree (storage);
4609 return;
4610 }
4611 }
4612 else if (GET_CODE (mem_addr) == MULT)
e9a25f70 4613 index_rtx = mem_addr;
32b5b1aa
SC
4614 else
4615 {
4616 obfree (storage);
4617 return;
4618 }
e9a25f70
JL
4619
4620 if (index_rtx != 0 && GET_CODE (index_rtx) == MULT)
32b5b1aa
SC
4621 {
4622 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
4623 {
4624 obfree (storage);
4625 return;
4626 }
e9a25f70 4627
32b5b1aa
SC
4628 scale_rtx = XEXP (index_rtx, 1);
4629 scale = INTVAL (scale_rtx);
4630 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4631 }
e9a25f70
JL
4632
4633 /* Now find which of the elements are invalid and try to fix them. */
32b5b1aa
SC
4634 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
4635 {
4636 offset_adjust = INTVAL (index_rtx) * scale;
e9a25f70
JL
4637
4638 if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4639 offset_rtx = plus_constant (offset_rtx, offset_adjust);
4640 else if (offset_rtx == 0)
4641 offset_rtx = const0_rtx;
4642
32b5b1aa
SC
4643 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4644 XEXP (mem_rtx, 0) = offset_rtx;
4645 return;
4646 }
e9a25f70
JL
4647
4648 if (base_rtx && GET_CODE (base_rtx) == PLUS
4649 && GET_CODE (XEXP (base_rtx, 0)) == REG
4650 && GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
32b5b1aa
SC
4651 {
4652 offset_adjust += INTVAL (XEXP (base_rtx, 1));
4653 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
4654 }
e9a25f70 4655
32b5b1aa
SC
4656 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
4657 {
4658 offset_adjust += INTVAL (base_rtx);
4659 base_rtx = NULL;
4660 }
e9a25f70
JL
4661
4662 if (index_rtx && GET_CODE (index_rtx) == PLUS
4663 && GET_CODE (XEXP (index_rtx, 0)) == REG
4664 && GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
32b5b1aa
SC
4665 {
4666 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
4667 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4668 }
e9a25f70 4669
32b5b1aa
SC
4670 if (index_rtx)
4671 {
e9a25f70
JL
4672 if (! LEGITIMATE_INDEX_P (index_rtx)
4673 && ! (index_rtx == stack_pointer_rtx && scale == 1
4674 && base_rtx == NULL))
32b5b1aa
SC
4675 {
4676 obfree (storage);
4677 return;
4678 }
4679 }
e9a25f70 4680
32b5b1aa
SC
4681 if (base_rtx)
4682 {
e9a25f70 4683 if (! LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
32b5b1aa
SC
4684 {
4685 obfree (storage);
4686 return;
4687 }
4688 }
e9a25f70 4689
32b5b1aa
SC
4690 if (offset_adjust != 0)
4691 {
e9a25f70
JL
4692 if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4693 offset_rtx = plus_constant (offset_rtx, offset_adjust);
32b5b1aa 4694 else
e9a25f70
JL
4695 offset_rtx = const0_rtx;
4696
32b5b1aa
SC
4697 if (index_rtx)
4698 {
4699 if (base_rtx)
4700 {
4701 if (scale != 1)
4702 {
e9a25f70
JL
4703 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
4704 gen_rtx (MULT, GET_MODE (index_rtx),
4705 index_rtx, scale_rtx),
4706 base_rtx);
4707
4708 if (GET_CODE (offset_rtx) != CONST_INT
4709 || INTVAL (offset_rtx) != 0)
4710 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4711 ret_rtx, offset_rtx);
32b5b1aa
SC
4712 }
4713 else
4714 {
e9a25f70
JL
4715 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4716 index_rtx, base_rtx);
4717
4718 if (GET_CODE (offset_rtx) != CONST_INT
4719 || INTVAL (offset_rtx) != 0)
4720 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4721 ret_rtx, offset_rtx);
32b5b1aa
SC
4722 }
4723 }
4724 else
4725 {
4726 if (scale != 1)
4727 {
e9a25f70
JL
4728 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx),
4729 index_rtx, scale_rtx);
4730
4731 if (GET_CODE (offset_rtx) != CONST_INT
4732 || INTVAL (offset_rtx) != 0)
4733 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4734 ret_rtx, offset_rtx);
32b5b1aa
SC
4735 }
4736 else
4737 {
e9a25f70
JL
4738 if (GET_CODE (offset_rtx) == CONST_INT
4739 && INTVAL (offset_rtx) == 0)
4740 ret_rtx = index_rtx;
32b5b1aa 4741 else
e9a25f70
JL
4742 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4743 index_rtx, offset_rtx);
32b5b1aa
SC
4744 }
4745 }
4746 }
4747 else
4748 {
4749 if (base_rtx)
4750 {
e9a25f70
JL
4751 if (GET_CODE (offset_rtx) == CONST_INT
4752 && INTVAL (offset_rtx) == 0)
4753 ret_rtx = base_rtx;
32b5b1aa 4754 else
e9a25f70
JL
4755 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx,
4756 offset_rtx);
32b5b1aa
SC
4757 }
4758 else if (was_only_offset)
e9a25f70 4759 ret_rtx = offset_rtx;
32b5b1aa
SC
4760 else
4761 {
4762 obfree (storage);
4763 return;
4764 }
4765 }
e9a25f70 4766
32b5b1aa
SC
4767 XEXP (mem_rtx, 0) = ret_rtx;
4768 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4769 return;
4770 }
4771 else
4772 {
4773 obfree (storage);
4774 return;
4775 }
4776}
4777#endif /* NOTYET */
32b5b1aa 4778\f
e9a25f70
JL
4779/* Return 1 if the first insn to set cc before INSN also sets the register
4780 REG_RTX; otherwise return 0. */
32b5b1aa
SC
4781int
4782last_to_set_cc (reg_rtx, insn)
4783 rtx reg_rtx, insn;
4784{
4785 rtx prev_insn = PREV_INSN (insn);
4786
4787 while (prev_insn)
4788 {
4789 if (GET_CODE (prev_insn) == NOTE)
4790 ;
4791
4792 else if (GET_CODE (prev_insn) == INSN)
4793 {
4794 if (GET_CODE (PATTERN (prev_insn)) != SET)
4795 return (0);
4796
4797 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4798 {
4799 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4800 return (1);
4801
4802 return (0);
4803 }
4804
e9a25f70 4805 else if (! doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
32b5b1aa
SC
4806 return (0);
4807 }
4808
4809 else
4810 return (0);
4811
4812 prev_insn = PREV_INSN (prev_insn);
4813 }
4814
4815 return (0);
4816}
32b5b1aa
SC
4817\f
4818int
4819doesnt_set_condition_code (pat)
4820 rtx pat;
4821{
4822 switch (GET_CODE (pat))
4823 {
4824 case MEM:
4825 case REG:
e9a25f70 4826 return 1;
32b5b1aa
SC
4827
4828 default:
e9a25f70 4829 return 0;
32b5b1aa
SC
4830
4831 }
4832}
32b5b1aa
SC
4833\f
4834int
4835sets_condition_code (pat)
4836 rtx pat;
4837{
4838 switch (GET_CODE (pat))
4839 {
4840 case PLUS:
4841 case MINUS:
4842 case AND:
4843 case IOR:
4844 case XOR:
4845 case NOT:
4846 case NEG:
4847 case MULT:
4848 case DIV:
4849 case MOD:
4850 case UDIV:
4851 case UMOD:
e9a25f70 4852 return 1;
32b5b1aa
SC
4853
4854 default:
4855 return (0);
32b5b1aa
SC
4856 }
4857}
32b5b1aa
SC
4858\f
4859int
4860str_immediate_operand (op, mode)
4861 register rtx op;
bb5177ac 4862 enum machine_mode mode ATTRIBUTE_UNUSED;
32b5b1aa
SC
4863{
4864 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
e9a25f70 4865 return 1;
32b5b1aa 4866
e9a25f70
JL
4867 return 0;
4868}
32b5b1aa
SC
4869\f
4870int
4871is_fp_insn (insn)
4872 rtx insn;
4873{
4874 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4875 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4876 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4877 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
e9a25f70 4878 return 1;
32b5b1aa 4879
e9a25f70 4880 return 0;
32b5b1aa
SC
4881}
4882
e9a25f70
JL
4883/* Return 1 if the mode of the SET_DEST of insn is floating point
4884 and it is not an fld or a move from memory to memory.
4885 Otherwise return 0 */
4886
32b5b1aa
SC
4887int
4888is_fp_dest (insn)
4889 rtx insn;
4890{
4891 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4892 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4893 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4894 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4895 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4896 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
48d4389d 4897 && GET_CODE (SET_SRC (PATTERN (insn))) != MEM)
e9a25f70 4898 return 1;
32b5b1aa 4899
e9a25f70 4900 return 0;
32b5b1aa
SC
4901}
4902
e9a25f70
JL
4903/* Return 1 if the mode of the SET_DEST of INSN is floating point and is
4904 memory and the source is a register. */
4905
32b5b1aa
SC
4906int
4907is_fp_store (insn)
4908 rtx insn;
4909{
4910 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4911 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4912 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4913 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4914 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4915 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
e9a25f70 4916 return 1;
32b5b1aa 4917
e9a25f70 4918 return 0;
32b5b1aa 4919}
32b5b1aa 4920\f
e9a25f70
JL
4921/* Return 1 if DEP_INSN sets a register which INSN uses as a base
4922 or index to reference memory.
4923 otherwise return 0 */
32b5b1aa
SC
4924
4925int
4926agi_dependent (insn, dep_insn)
4927 rtx insn, dep_insn;
4928{
4929 if (GET_CODE (dep_insn) == INSN
4930 && GET_CODE (PATTERN (dep_insn)) == SET
4931 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
e9a25f70 4932 return reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn);
32b5b1aa
SC
4933
4934 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4935 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4936 && push_operand (SET_DEST (PATTERN (dep_insn)),
4937 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
e9a25f70 4938 return reg_mentioned_in_mem (stack_pointer_rtx, insn);
32b5b1aa 4939
e9a25f70
JL
4940 return 0;
4941}
32b5b1aa 4942\f
e9a25f70
JL
4943/* Return 1 if reg is used in rtl as a base or index for a memory ref
4944 otherwise return 0. */
32b5b1aa
SC
4945
4946int
4947reg_mentioned_in_mem (reg, rtl)
4948 rtx reg, rtl;
4949{
4950 register char *fmt;
e9a25f70 4951 register int i, j;
32b5b1aa
SC
4952 register enum rtx_code code;
4953
4954 if (rtl == NULL)
e9a25f70 4955 return 0;
32b5b1aa
SC
4956
4957 code = GET_CODE (rtl);
4958
4959 switch (code)
4960 {
4961 case HIGH:
4962 case CONST_INT:
4963 case CONST:
4964 case CONST_DOUBLE:
4965 case SYMBOL_REF:
4966 case LABEL_REF:
4967 case PC:
4968 case CC0:
4969 case SUBREG:
e9a25f70 4970 return 0;
00c79232 4971 default:
53949fac 4972 break;
32b5b1aa
SC
4973 }
4974
4975 if (code == MEM && reg_mentioned_p (reg, rtl))
e9a25f70 4976 return 1;
32b5b1aa
SC
4977
4978 fmt = GET_RTX_FORMAT (code);
4979 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4980 {
4981 if (fmt[i] == 'E')
c7271385
JL
4982 {
4983 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4984 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4985 return 1;
4986 }
32b5b1aa
SC
4987
4988 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4989 return 1;
4990 }
4991
e9a25f70 4992 return 0;
32b5b1aa 4993}
3f803cd9 4994\f
956d6950 4995/* Output the appropriate insns for doing strlen if not just doing repnz; scasb
3f803cd9
SC
4996
4997 operands[0] = result, initialized with the startaddress
4998 operands[1] = alignment of the address.
4999 operands[2] = scratch register, initialized with the startaddress when
5000 not aligned, otherwise undefined
5001
5002 This is just the body. It needs the initialisations mentioned above and
5003 some address computing at the end. These things are done in i386.md. */
5004
5005char *
5006output_strlen_unroll (operands)
5007 rtx operands[];
5008{
5009 rtx xops[18];
5010
5011 xops[0] = operands[0]; /* Result */
5012 /* operands[1]; * Alignment */
5013 xops[1] = operands[2]; /* Scratch */
5014 xops[2] = GEN_INT (0);
5015 xops[3] = GEN_INT (2);
5016 xops[4] = GEN_INT (3);
5017 xops[5] = GEN_INT (4);
5018 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
5019 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
5020 xops[8] = gen_label_rtx (); /* label of main loop */
e9a25f70
JL
5021
5022 if (TARGET_USE_Q_REG && QI_REG_P (xops[1]))
3f803cd9 5023 xops[9] = gen_label_rtx (); /* pentium optimisation */
e9a25f70 5024
3f803cd9
SC
5025 xops[10] = gen_label_rtx (); /* end label 2 */
5026 xops[11] = gen_label_rtx (); /* end label 1 */
5027 xops[12] = gen_label_rtx (); /* end label */
5028 /* xops[13] * Temporary used */
5029 xops[14] = GEN_INT (0xff);
5030 xops[15] = GEN_INT (0xff00);
5031 xops[16] = GEN_INT (0xff0000);
5032 xops[17] = GEN_INT (0xff000000);
5033
e9a25f70 5034 /* Loop to check 1..3 bytes for null to get an aligned pointer. */
3f803cd9 5035
e9a25f70 5036 /* Is there a known alignment and is it less than 4? */
3f803cd9
SC
5037 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
5038 {
e9a25f70 5039 /* Is there a known alignment and is it not 2? */
3f803cd9
SC
5040 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5041 {
e9a25f70
JL
5042 xops[6] = gen_label_rtx (); /* Label when aligned to 3-byte */
5043 xops[7] = gen_label_rtx (); /* Label when aligned to 2-byte */
3f803cd9 5044
e9a25f70
JL
5045 /* Leave just the 3 lower bits.
5046 If this is a q-register, then the high part is used later
5047 therefore use andl rather than andb. */
3f803cd9 5048 output_asm_insn (AS2 (and%L1,%4,%1), xops);
e9a25f70 5049
956d6950 5050 /* Is aligned to 4-byte address when zero */
3f803cd9 5051 output_asm_insn (AS1 (je,%l8), xops);
e9a25f70
JL
5052
5053 /* Side-effect even Parity when %eax == 3 */
3f803cd9
SC
5054 output_asm_insn (AS1 (jp,%6), xops);
5055
e9a25f70 5056 /* Is it aligned to 2 bytes ? */
3f803cd9
SC
5057 if (QI_REG_P (xops[1]))
5058 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5059 else
5060 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
e9a25f70 5061
3f803cd9
SC
5062 output_asm_insn (AS1 (je,%7), xops);
5063 }
5064 else
5065 {
e9a25f70
JL
5066 /* Since the alignment is 2, we have to check 2 or 0 bytes;
5067 check if is aligned to 4 - byte. */
3f803cd9 5068 output_asm_insn (AS2 (and%L1,%3,%1), xops);
e9a25f70 5069
956d6950 5070 /* Is aligned to 4-byte address when zero */
3f803cd9
SC
5071 output_asm_insn (AS1 (je,%l8), xops);
5072 }
5073
f64cecad 5074 xops[13] = gen_rtx_MEM (QImode, xops[0]);
e9a25f70
JL
5075
5076 /* Now compare the bytes; compare with the high part of a q-reg
5077 gives shorter code. */
3f803cd9
SC
5078 if (QI_REG_P (xops[1]))
5079 {
e9a25f70 5080 /* Compare the first n unaligned byte on a byte per byte basis. */
3f803cd9 5081 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
e9a25f70
JL
5082
5083 /* When zero we reached the end. */
3f803cd9 5084 output_asm_insn (AS1 (je,%l12), xops);
e9a25f70
JL
5085
5086 /* Increment the address. */
3f803cd9
SC
5087 output_asm_insn (AS1 (inc%L0,%0), xops);
5088
e9a25f70 5089 /* Not needed with an alignment of 2 */
3f803cd9
SC
5090 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5091 {
e9a25f70
JL
5092 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5093 CODE_LABEL_NUMBER (xops[7]));
3f803cd9
SC
5094 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5095 output_asm_insn (AS1 (je,%l12), xops);
5096 output_asm_insn (AS1 (inc%L0,%0), xops);
5097
e9a25f70
JL
5098 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5099 CODE_LABEL_NUMBER (xops[6]));
3f803cd9 5100 }
e9a25f70 5101
3f803cd9
SC
5102 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5103 }
5104 else
5105 {
5106 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5107 output_asm_insn (AS1 (je,%l12), xops);
5108 output_asm_insn (AS1 (inc%L0,%0), xops);
5109
e9a25f70
JL
5110 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5111 CODE_LABEL_NUMBER (xops[7]));
3f803cd9
SC
5112 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5113 output_asm_insn (AS1 (je,%l12), xops);
5114 output_asm_insn (AS1 (inc%L0,%0), xops);
5115
e9a25f70
JL
5116 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5117 CODE_LABEL_NUMBER (xops[6]));
3f803cd9
SC
5118 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5119 }
e9a25f70 5120
3f803cd9
SC
5121 output_asm_insn (AS1 (je,%l12), xops);
5122 output_asm_insn (AS1 (inc%L0,%0), xops);
5123 }
5124
e9a25f70
JL
5125 /* Generate loop to check 4 bytes at a time. It is not a good idea to
5126 align this loop. It gives only huge programs, but does not help to
5127 speed up. */
3f803cd9
SC
5128 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
5129
f64cecad 5130 xops[13] = gen_rtx_MEM (SImode, xops[0]);
3f803cd9
SC
5131 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
5132
5133 if (QI_REG_P (xops[1]))
5134 {
1853aadd
RK
5135 /* On i586 it is faster to combine the hi- and lo- part as
5136 a kind of lookahead. If anding both yields zero, then one
5137 of both *could* be zero, otherwise none of both is zero;
5138 this saves one instruction, on i486 this is slower
5139 tested with P-90, i486DX2-66, AMD486DX2-66 */
e9a25f70 5140 if (TARGET_PENTIUM)
3f803cd9
SC
5141 {
5142 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
5143 output_asm_insn (AS1 (jne,%l9), xops);
5144 }
5145
e9a25f70 5146 /* Check first byte. */
3f803cd9
SC
5147 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
5148 output_asm_insn (AS1 (je,%l12), xops);
5149
e9a25f70 5150 /* Check second byte. */
3f803cd9
SC
5151 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
5152 output_asm_insn (AS1 (je,%l11), xops);
5153
e9a25f70
JL
5154 if (TARGET_PENTIUM)
5155 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5156 CODE_LABEL_NUMBER (xops[9]));
3f803cd9 5157 }
e9a25f70 5158
3f803cd9
SC
5159 else
5160 {
e9a25f70 5161 /* Check first byte. */
3f803cd9
SC
5162 output_asm_insn (AS2 (test%L1,%14,%1), xops);
5163 output_asm_insn (AS1 (je,%l12), xops);
5164
e9a25f70 5165 /* Check second byte. */
3f803cd9
SC
5166 output_asm_insn (AS2 (test%L1,%15,%1), xops);
5167 output_asm_insn (AS1 (je,%l11), xops);
5168 }
5169
e9a25f70 5170 /* Check third byte. */
3f803cd9
SC
5171 output_asm_insn (AS2 (test%L1,%16,%1), xops);
5172 output_asm_insn (AS1 (je,%l10), xops);
79325812 5173
e9a25f70 5174 /* Check fourth byte and increment address. */
3f803cd9
SC
5175 output_asm_insn (AS2 (add%L0,%5,%0), xops);
5176 output_asm_insn (AS2 (test%L1,%17,%1), xops);
5177 output_asm_insn (AS1 (jne,%l8), xops);
5178
e9a25f70 5179 /* Now generate fixups when the compare stops within a 4-byte word. */
3f803cd9
SC
5180 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
5181
5182 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
5183 output_asm_insn (AS1 (inc%L0,%0), xops);
5184
5185 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
5186 output_asm_insn (AS1 (inc%L0,%0), xops);
5187
5188 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));
5189
e9a25f70 5190 return "";
3f803cd9 5191}
b657fc39
L
5192
5193char *
5194output_fp_conditional_move (which_alternative, operands)
5195 int which_alternative;
5196 rtx operands[];
5197{
b657fc39
L
5198 switch (which_alternative)
5199 {
5200 case 0:
5201 /* r <- cond ? arg : r */
5202 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5203 break;
79325812 5204
b657fc39
L
5205 case 1:
5206 /* r <- cond ? r : arg */
5207 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5208 break;
5209
5210 case 2:
5211 /* r <- cond ? r : arg */
5212 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5213 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5214 break;
5215
5216 default:
5217 abort ();
5218 }
5219
5220 return "";
5221}
5222
5223char *
5224output_int_conditional_move (which_alternative, operands)
5225 int which_alternative;
5226 rtx operands[];
5227{
5228 int code = GET_CODE (operands[1]);
5229 enum machine_mode mode;
5230 rtx xops[4];
5231
5232 /* This is very tricky. We have to do it right. For a code segement
5233 like:
5234
5235 int foo, bar;
5236 ....
5237 foo = foo - x;
5238 if (foo >= 0)
5239 bar = y;
5240
5241 final_scan_insn () may delete the insn which sets CC. We have to
5242 tell final_scan_insn () if it should be reinserted. When CODE is
5243 GT or LE, we have to check the CC_NO_OVERFLOW bit and return
5244 NULL_PTR to tell final to reinsert the test insn because the
5245 conditional move cannot be handled properly without it. */
5246 if ((code == GT || code == LE)
5247 && (cc_prev_status.flags & CC_NO_OVERFLOW))
5248 return NULL_PTR;
5249
5250 mode = GET_MODE (operands [0]);
5251 if (mode == DImode)
5252 {
5253 xops [0] = gen_rtx_SUBREG (SImode, operands [0], 1);
5254 xops [1] = operands [1];
5255 xops [2] = gen_rtx_SUBREG (SImode, operands [2], 1);
5256 xops [3] = gen_rtx_SUBREG (SImode, operands [3], 1);
5257 }
5258
5259 switch (which_alternative)
5260 {
5261 case 0:
5262 /* r <- cond ? arg : r */
5263 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
5264 if (mode == DImode)
5265 output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
5266 break;
5267
5268 case 1:
5269 /* r <- cond ? r : arg */
5270 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
5271 if (mode == DImode)
5272 output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
5273 break;
5274
5275 case 2:
5276 /* rm <- cond ? arg1 : arg2 */
5277 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
5278 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
5279 if (mode == DImode)
5280 {
5281 output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
5282 output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
5283 }
5284 break;
5285
5286 default:
5287 abort ();
5288 }
5289
5290 return "";
5291}
This page took 1.117861 seconds and 5 git commands to generate.