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