]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.c
i386.c (notice_update_cc): Clear cc_status.value2 in the case of UNSPEC 5 (bsf).
[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:
b657fc39
L
3100 if (cc_prev_status.flags & CC_NO_OVERFLOW)
3101 fputs ("ns", file);
3102 else
3103 fputs ("ge", file);
e9a25f70
JL
3104 return;
3105
3106 case GT:
3107 fputs ("g", file);
3108 return;
3109
3110 case LE:
3111 fputs ("le", file);
3112 return;
3113
3114 case LT:
b657fc39
L
3115 if (cc_prev_status.flags & CC_NO_OVERFLOW)
3116 fputs ("s", file);
3117 else
3118 fputs ("l", file);
e9a25f70
JL
3119 return;
3120
3121 case GEU:
3122 fputs ("ae", file);
3123 return;
3124
3125 case GTU:
3126 fputs ("a", file);
3127 return;
3128
3129 case LEU:
3130 fputs ("be", file);
3131 return;
3132
3133 case LTU:
3134 fputs ("b", file);
3135 return;
3136
3137 default:
3138 output_operand_lossage ("Invalid %%C operand");
3139 }
3140
fe25fea3 3141 else if (mode == MODE_FLOAT)
e9a25f70
JL
3142 switch (code)
3143 {
fe25fea3 3144 case NE:
e9a25f70
JL
3145 fputs (ieee ? (reverse_cc ? "ne" : "e") : "ne", file);
3146 return;
fe25fea3 3147 case EQ:
e9a25f70
JL
3148 fputs (ieee ? (reverse_cc ? "ne" : "e") : "e", file);
3149 return;
fe25fea3 3150 case GE:
e9a25f70
JL
3151 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3152 return;
fe25fea3 3153 case GT:
e9a25f70
JL
3154 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3155 return;
fe25fea3 3156 case LE:
e9a25f70
JL
3157 fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3158 return;
fe25fea3 3159 case LT:
e9a25f70
JL
3160 fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3161 return;
fe25fea3 3162 case GEU:
e9a25f70
JL
3163 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
3164 return;
fe25fea3 3165 case GTU:
e9a25f70
JL
3166 fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
3167 return;
fe25fea3 3168 case LEU:
e9a25f70
JL
3169 fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
3170 return;
fe25fea3 3171 case LTU:
e9a25f70
JL
3172 fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
3173 return;
3174 default:
3175 output_operand_lossage ("Invalid %%C operand");
fe25fea3 3176 }
e5cb57e8
SC
3177}
3178
2a2ab3f9 3179/* Meaning of CODE:
fe25fea3 3180 L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
e5cb57e8 3181 C -- print opcode suffix for set/cmov insn.
fe25fea3
SC
3182 c -- like C, but print reversed condition
3183 F -- print opcode suffix for fcmov insn.
3184 f -- like C, but print reversed condition
2a2ab3f9
JVA
3185 R -- print the prefix for register names.
3186 z -- print the opcode suffix for the size of the current operand.
3187 * -- print a star (in certain assembler syntax)
3188 w -- print the operand as if it's a "word" (HImode) even if it isn't.
3189 c -- don't print special prefixes before constant operands.
b08de47e 3190 J -- print the appropriate jump operand.
2d49677f
SC
3191 s -- print a shift double count, followed by the assemblers argument
3192 delimiter.
fe25fea3
SC
3193 b -- print the QImode name of the register for the indicated operand.
3194 %b0 would print %al if operands[0] is reg 0.
3195 w -- likewise, print the HImode name of the register.
3196 k -- likewise, print the SImode name of the register.
3197 h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
3198 y -- print "st(0)" instead of "st" as a register.
e9a25f70 3199 P -- print as a PIC constant */
2a2ab3f9
JVA
3200
3201void
3202print_operand (file, x, code)
3203 FILE *file;
3204 rtx x;
3205 int code;
3206{
3207 if (code)
3208 {
3209 switch (code)
3210 {
3211 case '*':
3212 if (USE_STAR)
3213 putc ('*', file);
3214 return;
3215
2a2ab3f9
JVA
3216 case 'L':
3217 PUT_OP_SIZE (code, 'l', file);
3218 return;
3219
3220 case 'W':
3221 PUT_OP_SIZE (code, 'w', file);
3222 return;
3223
3224 case 'B':
3225 PUT_OP_SIZE (code, 'b', file);
3226 return;
3227
3228 case 'Q':
3229 PUT_OP_SIZE (code, 'l', file);
3230 return;
3231
3232 case 'S':
3233 PUT_OP_SIZE (code, 's', file);
3234 return;
3235
5f1ec3e6
JVA
3236 case 'T':
3237 PUT_OP_SIZE (code, 't', file);
3238 return;
3239
2a2ab3f9
JVA
3240 case 'z':
3241 /* 387 opcodes don't get size suffixes if the operands are
3242 registers. */
3243
3244 if (STACK_REG_P (x))
3245 return;
3246
3247 /* this is the size of op from size of operand */
3248 switch (GET_MODE_SIZE (GET_MODE (x)))
3249 {
3250 case 1:
3251 PUT_OP_SIZE ('B', 'b', file);
3252 return;
3253
3254 case 2:
3255 PUT_OP_SIZE ('W', 'w', file);
3256 return;
3257
3258 case 4:
3259 if (GET_MODE (x) == SFmode)
3260 {
3261 PUT_OP_SIZE ('S', 's', file);
3262 return;
3263 }
3264 else
3265 PUT_OP_SIZE ('L', 'l', file);
3266 return;
3267
5f1ec3e6
JVA
3268 case 12:
3269 PUT_OP_SIZE ('T', 't', file);
3270 return;
3271
2a2ab3f9
JVA
3272 case 8:
3273 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
56c0e8fa
JVA
3274 {
3275#ifdef GAS_MNEMONICS
3276 PUT_OP_SIZE ('Q', 'q', file);
3277 return;
3278#else
3279 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
3280#endif
3281 }
2a2ab3f9
JVA
3282
3283 PUT_OP_SIZE ('Q', 'l', file);
3284 return;
3285 }
4af3895e
JVA
3286
3287 case 'b':
3288 case 'w':
3289 case 'k':
3290 case 'h':
3291 case 'y':
3292 case 'P':
5cb6195d 3293 case 'X':
4af3895e
JVA
3294 break;
3295
b08de47e
MM
3296 case 'J':
3297 switch (GET_CODE (x))
3298 {
c645b1c9
MM
3299 /* These conditions are appropriate for testing the result
3300 of an arithmetic operation, not for a compare operation.
3301 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
3302 CC_Z_IN_NOT_C false and not floating point. */
b08de47e
MM
3303 case NE: fputs ("jne", file); return;
3304 case EQ: fputs ("je", file); return;
c645b1c9 3305 case GE: fputs ("jns", file); return;
c645b1c9 3306 case LT: fputs ("js", file); return;
d784886d
RK
3307 case GEU: fputs ("jmp", file); return;
3308 case GTU: fputs ("jne", file); return;
3309 case LEU: fputs ("je", file); return;
3310 case LTU: fputs ("#branch never", file); return;
00c79232 3311
d784886d 3312 /* no matching branches for GT nor LE */
00c79232
ML
3313
3314 default:
3315 abort ();
b08de47e 3316 }
b08de47e 3317
2d49677f
SC
3318 case 's':
3319 if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
3320 {
3321 PRINT_OPERAND (file, x, 0);
3322 fputs (AS2C (,) + 1, file);
3323 }
e9a25f70 3324
2d49677f
SC
3325 return;
3326
1853aadd
RK
3327 /* This is used by the conditional move instructions. */
3328 case 'C':
c27d9c3b 3329 put_condition_code (GET_CODE (x), 0, MODE_INT, file);
1853aadd 3330 return;
fe25fea3 3331
e9a25f70 3332 /* Like above, but reverse condition */
fe25fea3 3333 case 'c':
c27d9c3b 3334 put_condition_code (GET_CODE (x), 1, MODE_INT, file); return;
fe25fea3
SC
3335
3336 case 'F':
c27d9c3b 3337 put_condition_code (GET_CODE (x), 0, MODE_FLOAT, file);
fe25fea3
SC
3338 return;
3339
e9a25f70 3340 /* Like above, but reverse condition */
fe25fea3 3341 case 'f':
c27d9c3b 3342 put_condition_code (GET_CODE (x), 1, MODE_FLOAT, file);
1853aadd 3343 return;
e5cb57e8 3344
4af3895e 3345 default:
68daafd4
JVA
3346 {
3347 char str[50];
3348
3349 sprintf (str, "invalid operand code `%c'", code);
3350 output_operand_lossage (str);
3351 }
2a2ab3f9
JVA
3352 }
3353 }
e9a25f70 3354
2a2ab3f9
JVA
3355 if (GET_CODE (x) == REG)
3356 {
3357 PRINT_REG (x, code, file);
3358 }
e9a25f70 3359
2a2ab3f9
JVA
3360 else if (GET_CODE (x) == MEM)
3361 {
3362 PRINT_PTR (x, file);
3363 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
3364 {
3365 if (flag_pic)
3366 output_pic_addr_const (file, XEXP (x, 0), code);
3367 else
3368 output_addr_const (file, XEXP (x, 0));
3369 }
3370 else
3371 output_address (XEXP (x, 0));
3372 }
e9a25f70 3373
2a2ab3f9
JVA
3374 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
3375 {
e9a25f70
JL
3376 REAL_VALUE_TYPE r;
3377 long l;
3378
5f1ec3e6
JVA
3379 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3380 REAL_VALUE_TO_TARGET_SINGLE (r, l);
4af3895e 3381 PRINT_IMMED_PREFIX (file);
52267fcb 3382 fprintf (file, "0x%lx", l);
5f1ec3e6 3383 }
e9a25f70 3384
5f1ec3e6
JVA
3385 /* These float cases don't actually occur as immediate operands. */
3386 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
3387 {
e9a25f70
JL
3388 REAL_VALUE_TYPE r;
3389 char dstr[30];
3390
5f1ec3e6
JVA
3391 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3392 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3393 fprintf (file, "%s", dstr);
2a2ab3f9 3394 }
e9a25f70 3395
5f1ec3e6 3396 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2a2ab3f9 3397 {
e9a25f70
JL
3398 REAL_VALUE_TYPE r;
3399 char dstr[30];
3400
5f1ec3e6
JVA
3401 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3402 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
3403 fprintf (file, "%s", dstr);
2a2ab3f9
JVA
3404 }
3405 else
3406 {
4af3895e 3407 if (code != 'P')
2a2ab3f9 3408 {
695dac07 3409 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2a2ab3f9
JVA
3410 PRINT_IMMED_PREFIX (file);
3411 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
3412 || GET_CODE (x) == LABEL_REF)
3413 PRINT_OFFSET_PREFIX (file);
3414 }
3415 if (flag_pic)
3416 output_pic_addr_const (file, x, code);
3417 else
3418 output_addr_const (file, x);
3419 }
3420}
3421\f
3422/* Print a memory operand whose address is ADDR. */
3423
3424void
3425print_operand_address (file, addr)
3426 FILE *file;
3427 register rtx addr;
3428{
3429 register rtx reg1, reg2, breg, ireg;
3430 rtx offset;
3431
3432 switch (GET_CODE (addr))
3433 {
3434 case REG:
3435 ADDR_BEG (file);
3436 fprintf (file, "%se", RP);
3437 fputs (hi_reg_name[REGNO (addr)], file);
3438 ADDR_END (file);
3439 break;
3440
3441 case PLUS:
3442 reg1 = 0;
3443 reg2 = 0;
3444 ireg = 0;
3445 breg = 0;
3446 offset = 0;
3447 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
3448 {
3449 offset = XEXP (addr, 0);
3450 addr = XEXP (addr, 1);
3451 }
3452 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
3453 {
3454 offset = XEXP (addr, 1);
3455 addr = XEXP (addr, 0);
3456 }
e9a25f70
JL
3457
3458 if (GET_CODE (addr) != PLUS)
3459 ;
2a2ab3f9 3460 else if (GET_CODE (XEXP (addr, 0)) == MULT)
e9a25f70 3461 reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
2a2ab3f9 3462 else if (GET_CODE (XEXP (addr, 1)) == MULT)
e9a25f70 3463 reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
2a2ab3f9 3464 else if (GET_CODE (XEXP (addr, 0)) == REG)
e9a25f70 3465 reg1 = XEXP (addr, 0), addr = XEXP (addr, 1);
2a2ab3f9 3466 else if (GET_CODE (XEXP (addr, 1)) == REG)
e9a25f70
JL
3467 reg1 = XEXP (addr, 1), addr = XEXP (addr, 0);
3468
2a2ab3f9
JVA
3469 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
3470 {
e9a25f70
JL
3471 if (reg1 == 0)
3472 reg1 = addr;
3473 else
3474 reg2 = addr;
3475
2a2ab3f9
JVA
3476 addr = 0;
3477 }
e9a25f70 3478
2a2ab3f9
JVA
3479 if (offset != 0)
3480 {
e9a25f70
JL
3481 if (addr != 0)
3482 abort ();
2a2ab3f9
JVA
3483 addr = offset;
3484 }
e9a25f70 3485
2a2ab3f9
JVA
3486 if ((reg1 && GET_CODE (reg1) == MULT)
3487 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
3488 {
3489 breg = reg2;
3490 ireg = reg1;
3491 }
3492 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
3493 {
3494 breg = reg1;
3495 ireg = reg2;
3496 }
3497
3498 if (ireg != 0 || breg != 0)
3499 {
3500 int scale = 1;
3501
3502 if (addr != 0)
3503 {
c399861d
MM
3504 if (flag_pic)
3505 output_pic_addr_const (file, addr, 0);
c399861d 3506 else if (GET_CODE (addr) == LABEL_REF)
2a2ab3f9
JVA
3507 output_asm_label (addr);
3508 else
c399861d 3509 output_addr_const (file, addr);
2a2ab3f9
JVA
3510 }
3511
3512 if (ireg != 0 && GET_CODE (ireg) == MULT)
3513 {
3514 scale = INTVAL (XEXP (ireg, 1));
3515 ireg = XEXP (ireg, 0);
3516 }
3517
3518 /* The stack pointer can only appear as a base register,
3519 never an index register, so exchange the regs if it is wrong. */
3520
3521 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
3522 {
3523 rtx tmp;
3524
3525 tmp = breg;
3526 breg = ireg;
3527 ireg = tmp;
3528 }
3529
3530 /* output breg+ireg*scale */
3531 PRINT_B_I_S (breg, ireg, scale, file);
3532 break;
3533 }
3534
3535 case MULT:
3536 {
3537 int scale;
e9a25f70 3538
2a2ab3f9
JVA
3539 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
3540 {
3541 scale = INTVAL (XEXP (addr, 0));
3542 ireg = XEXP (addr, 1);
3543 }
3544 else
3545 {
3546 scale = INTVAL (XEXP (addr, 1));
3547 ireg = XEXP (addr, 0);
3548 }
e9a25f70 3549
2a2ab3f9 3550 output_addr_const (file, const0_rtx);
e9a25f70 3551 PRINT_B_I_S (NULL_RTX, ireg, scale, file);
2a2ab3f9
JVA
3552 }
3553 break;
3554
3555 default:
3556 if (GET_CODE (addr) == CONST_INT
3557 && INTVAL (addr) < 0x8000
3558 && INTVAL (addr) >= -0x8000)
f64cecad 3559 fprintf (file, "%d", (int) INTVAL (addr));
2a2ab3f9
JVA
3560 else
3561 {
3562 if (flag_pic)
3563 output_pic_addr_const (file, addr, 0);
3564 else
3565 output_addr_const (file, addr);
3566 }
3567 }
3568}
3569\f
3570/* Set the cc_status for the results of an insn whose pattern is EXP.
3571 On the 80386, we assume that only test and compare insns, as well
5cb6195d 3572 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, BSF, ASHIFT,
2a2ab3f9 3573 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
4c0d89b5
RS
3574 Also, we assume that jumps, moves and sCOND don't affect the condition
3575 codes. All else clobbers the condition codes, by assumption.
3576
3577 We assume that ALL integer add, minus, etc. instructions effect the
3578 condition codes. This MUST be consistent with i386.md.
2a2ab3f9 3579
4c0d89b5
RS
3580 We don't record any float test or compare - the redundant test &
3581 compare check in final.c does not handle stack-like regs correctly. */
2a2ab3f9
JVA
3582
3583void
3584notice_update_cc (exp)
3585 rtx exp;
3586{
3587 if (GET_CODE (exp) == SET)
3588 {
3589 /* Jumps do not alter the cc's. */
3590 if (SET_DEST (exp) == pc_rtx)
3591 return;
e9a25f70 3592
2a2ab3f9
JVA
3593 /* Moving register or memory into a register:
3594 it doesn't alter the cc's, but it might invalidate
3595 the RTX's which we remember the cc's came from.
3596 (Note that moving a constant 0 or 1 MAY set the cc's). */
3597 if (REG_P (SET_DEST (exp))
4c0d89b5
RS
3598 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
3599 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2a2ab3f9
JVA
3600 {
3601 if (cc_status.value1
3602 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
3603 cc_status.value1 = 0;
e9a25f70 3604
2a2ab3f9
JVA
3605 if (cc_status.value2
3606 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
3607 cc_status.value2 = 0;
e9a25f70 3608
2a2ab3f9
JVA
3609 return;
3610 }
e9a25f70 3611
2a2ab3f9
JVA
3612 /* Moving register into memory doesn't alter the cc's.
3613 It may invalidate the RTX's which we remember the cc's came from. */
4c0d89b5
RS
3614 if (GET_CODE (SET_DEST (exp)) == MEM
3615 && (REG_P (SET_SRC (exp))
3616 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2a2ab3f9 3617 {
e9a25f70
JL
3618 if (cc_status.value1
3619 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2a2ab3f9 3620 cc_status.value1 = 0;
e9a25f70
JL
3621 if (cc_status.value2
3622 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2a2ab3f9 3623 cc_status.value2 = 0;
e9a25f70 3624
2a2ab3f9
JVA
3625 return;
3626 }
e9a25f70 3627
2a2ab3f9
JVA
3628 /* Function calls clobber the cc's. */
3629 else if (GET_CODE (SET_SRC (exp)) == CALL)
3630 {
3631 CC_STATUS_INIT;
3632 return;
3633 }
e9a25f70 3634
2a2ab3f9
JVA
3635 /* Tests and compares set the cc's in predictable ways. */
3636 else if (SET_DEST (exp) == cc0_rtx)
3637 {
3638 CC_STATUS_INIT;
3639 cc_status.value1 = SET_SRC (exp);
3640 return;
3641 }
e9a25f70 3642
2a2ab3f9
JVA
3643 /* Certain instructions effect the condition codes. */
3644 else if (GET_MODE (SET_SRC (exp)) == SImode
3645 || GET_MODE (SET_SRC (exp)) == HImode
3646 || GET_MODE (SET_SRC (exp)) == QImode)
3647 switch (GET_CODE (SET_SRC (exp)))
3648 {
e9a25f70 3649 case ASHIFTRT: case LSHIFTRT: case ASHIFT:
2a2ab3f9
JVA
3650 /* Shifts on the 386 don't set the condition codes if the
3651 shift count is zero. */
3652 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
3653 {
3654 CC_STATUS_INIT;
3655 break;
3656 }
e9a25f70 3657
2a2ab3f9
JVA
3658 /* We assume that the CONST_INT is non-zero (this rtx would
3659 have been deleted if it were zero. */
3660
3661 case PLUS: case MINUS: case NEG:
3662 case AND: case IOR: case XOR:
3663 cc_status.flags = CC_NO_OVERFLOW;
3664 cc_status.value1 = SET_SRC (exp);
3665 cc_status.value2 = SET_DEST (exp);
3666 break;
3667
ce193852
RH
3668 /* This is the bsf pattern used by ffs. */
3669 case UNSPEC:
3670 if (XINT (SET_SRC (exp), 1) == 5)
3671 {
3672 /* Only the Z flag is defined after bsf. */
3673 cc_status.flags
3674 = CC_NOT_POSITIVE | CC_NOT_NEGATIVE | CC_NO_OVERFLOW;
3675 cc_status.value1 = XVECEXP (SET_SRC (exp), 0, 0);
9d932d43 3676 cc_status.value2 = 0;
ce193852
RH
3677 break;
3678 }
3679 /* FALLTHRU */
3680
2a2ab3f9
JVA
3681 default:
3682 CC_STATUS_INIT;
3683 }
3684 else
3685 {
3686 CC_STATUS_INIT;
3687 }
3688 }
3689 else if (GET_CODE (exp) == PARALLEL
3690 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
3691 {
3692 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
3693 return;
3694 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
e9a25f70 3695
2a2ab3f9
JVA
3696 {
3697 CC_STATUS_INIT;
a8620236
SC
3698 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
3699 {
3700 cc_status.flags |= CC_IN_80387;
d6cc54f6 3701 if (0 && TARGET_CMOVE && stack_regs_mentioned_p
a8620236
SC
3702 (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1)))
3703 cc_status.flags |= CC_FCOMI;
3704 }
2247a58c 3705 else
4c0d89b5 3706 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2a2ab3f9
JVA
3707 return;
3708 }
e9a25f70 3709
2a2ab3f9
JVA
3710 CC_STATUS_INIT;
3711 }
3712 else
3713 {
3714 CC_STATUS_INIT;
3715 }
3716}
3717\f
3718/* Split one or more DImode RTL references into pairs of SImode
3719 references. The RTL can be REG, offsettable MEM, integer constant, or
3720 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
3721 split and "num" is its length. lo_half and hi_half are output arrays
3722 that parallel "operands". */
3723
3724void
3725split_di (operands, num, lo_half, hi_half)
3726 rtx operands[];
3727 int num;
3728 rtx lo_half[], hi_half[];
3729{
3730 while (num--)
3731 {
57dbca5e
BS
3732 rtx op = operands[num];
3733 if (GET_CODE (op) == REG)
2a2ab3f9 3734 {
57dbca5e
BS
3735 lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
3736 hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
2a2ab3f9 3737 }
57dbca5e
BS
3738 else if (CONSTANT_P (op))
3739 split_double (op, &lo_half[num], &hi_half[num]);
3740 else if (offsettable_memref_p (op))
2a2ab3f9 3741 {
57dbca5e
BS
3742 rtx lo_addr = XEXP (op, 0);
3743 rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
3744 lo_half[num] = change_address (op, SImode, lo_addr);
3745 hi_half[num] = change_address (op, SImode, hi_addr);
2a2ab3f9
JVA
3746 }
3747 else
3748 abort();
3749 }
3750}
3751\f
3752/* Return 1 if this is a valid binary operation on a 387.
3753 OP is the expression matched, and MODE is its mode. */
3754
3755int
3756binary_387_op (op, mode)
3757 register rtx op;
3758 enum machine_mode mode;
3759{
3760 if (mode != VOIDmode && mode != GET_MODE (op))
3761 return 0;
3762
3763 switch (GET_CODE (op))
3764 {
3765 case PLUS:
3766 case MINUS:
3767 case MULT:
3768 case DIV:
3769 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
3770
3771 default:
3772 return 0;
3773 }
3774}
3b3c6a3f 3775\f
2a2ab3f9
JVA
3776/* Return 1 if this is a valid shift or rotate operation on a 386.
3777 OP is the expression matched, and MODE is its mode. */
3778
3779int
3780shift_op (op, mode)
3781 register rtx op;
3782 enum machine_mode mode;
3783{
3784 rtx operand = XEXP (op, 0);
3785
3786 if (mode != VOIDmode && mode != GET_MODE (op))
3787 return 0;
3788
3789 if (GET_MODE (operand) != GET_MODE (op)
3790 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
3791 return 0;
3792
3793 return (GET_CODE (op) == ASHIFT
3794 || GET_CODE (op) == ASHIFTRT
3795 || GET_CODE (op) == LSHIFTRT
3796 || GET_CODE (op) == ROTATE
3797 || GET_CODE (op) == ROTATERT);
3798}
ac2afb64
JVA
3799
3800/* Return 1 if OP is COMPARE rtx with mode VOIDmode.
3801 MODE is not used. */
3802
3803int
3804VOIDmode_compare_op (op, mode)
3805 register rtx op;
3806 enum machine_mode mode;
3807{
3808 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
3809}
2a2ab3f9
JVA
3810\f
3811/* Output code to perform a 387 binary operation in INSN, one of PLUS,
3812 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
3813 is the expression of the binary operation. The output may either be
3814 emitted here, or returned to the caller, like all output_* functions.
3815
3816 There is no guarantee that the operands are the same mode, as they
3817 might be within FLOAT or FLOAT_EXTEND expressions. */
3818
3819char *
3820output_387_binary_op (insn, operands)
3821 rtx insn;
3822 rtx *operands;
3823{
3824 rtx temp;
3825 char *base_op;
3826 static char buf[100];
3827
3828 switch (GET_CODE (operands[3]))
3829 {
3830 case PLUS:
3831 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3832 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3833 base_op = "fiadd";
3834 else
3835 base_op = "fadd";
3836 break;
3837
3838 case MINUS:
3839 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3840 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3841 base_op = "fisub";
3842 else
3843 base_op = "fsub";
3844 break;
3845
3846 case MULT:
3847 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3848 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3849 base_op = "fimul";
3850 else
3851 base_op = "fmul";
3852 break;
3853
3854 case DIV:
3855 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3856 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
3857 base_op = "fidiv";
3858 else
3859 base_op = "fdiv";
3860 break;
3861
3862 default:
3863 abort ();
3864 }
3865
3866 strcpy (buf, base_op);
3867
3868 switch (GET_CODE (operands[3]))
3869 {
3870 case MULT:
3871 case PLUS:
3872 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
3873 {
3874 temp = operands[2];
3875 operands[2] = operands[1];
3876 operands[1] = temp;
3877 }
3878
3879 if (GET_CODE (operands[2]) == MEM)
3880 return strcat (buf, AS1 (%z2,%2));
3881
3882 if (NON_STACK_REG_P (operands[1]))
3883 {
3884 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
e9a25f70 3885 return "";
2a2ab3f9 3886 }
e9a25f70 3887
2a2ab3f9
JVA
3888 else if (NON_STACK_REG_P (operands[2]))
3889 {
3890 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
e9a25f70 3891 return "";
2a2ab3f9
JVA
3892 }
3893
3894 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
3895 {
3896 if (STACK_TOP_P (operands[0]))
3897 return strcat (buf, AS2 (p,%0,%2));
3898 else
3899 return strcat (buf, AS2 (p,%2,%0));
3900 }
2a2ab3f9
JVA
3901
3902 if (STACK_TOP_P (operands[0]))
3f6d0a8c 3903 return strcat (buf, AS2C (%y2,%0));
2a2ab3f9 3904 else
3f6d0a8c 3905 return strcat (buf, AS2C (%2,%0));
2a2ab3f9
JVA
3906
3907 case MINUS:
3908 case DIV:
3909 if (GET_CODE (operands[1]) == MEM)
3910 return strcat (buf, AS1 (r%z1,%1));
3911
3912 if (GET_CODE (operands[2]) == MEM)
3913 return strcat (buf, AS1 (%z2,%2));
3914
3915 if (NON_STACK_REG_P (operands[1]))
3916 {
3917 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
e9a25f70 3918 return "";
2a2ab3f9 3919 }
e9a25f70 3920
2a2ab3f9
JVA
3921 else if (NON_STACK_REG_P (operands[2]))
3922 {
3923 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
e9a25f70 3924 return "";
2a2ab3f9
JVA
3925 }
3926
3927 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
3928 abort ();
3929
3930 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
3931 {
3932 if (STACK_TOP_P (operands[0]))
3933 return strcat (buf, AS2 (p,%0,%2));
3934 else
3935 return strcat (buf, AS2 (rp,%2,%0));
3936 }
2a2ab3f9
JVA
3937
3938 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
6b28fd63
JL
3939 {
3940 if (STACK_TOP_P (operands[0]))
3941 return strcat (buf, AS2 (rp,%0,%1));
3942 else
3943 return strcat (buf, AS2 (p,%1,%0));
3944 }
2a2ab3f9
JVA
3945
3946 if (STACK_TOP_P (operands[0]))
3947 {
3948 if (STACK_TOP_P (operands[1]))
3f6d0a8c 3949 return strcat (buf, AS2C (%y2,%0));
2a2ab3f9
JVA
3950 else
3951 return strcat (buf, AS2 (r,%y1,%0));
3952 }
3953 else if (STACK_TOP_P (operands[1]))
3f6d0a8c 3954 return strcat (buf, AS2C (%1,%0));
2a2ab3f9
JVA
3955 else
3956 return strcat (buf, AS2 (r,%2,%0));
3957
3958 default:
3959 abort ();
3960 }
3961}
3962\f
3963/* Output code for INSN to convert a float to a signed int. OPERANDS
3964 are the insn operands. The output may be SFmode or DFmode and the
3965 input operand may be SImode or DImode. As a special case, make sure
3966 that the 387 stack top dies if the output mode is DImode, because the
3967 hardware requires this. */
3968
3969char *
3970output_fix_trunc (insn, operands)
3971 rtx insn;
3972 rtx *operands;
3973{
3974 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
305f097e 3975 rtx xops[2];
2a2ab3f9 3976
2e14a41b 3977 if (! STACK_TOP_P (operands[1]))
2a2ab3f9
JVA
3978 abort ();
3979
305f097e
JVA
3980 xops[0] = GEN_INT (12);
3981 xops[1] = operands[4];
3982
3983 output_asm_insn (AS1 (fnstc%W2,%2), operands);
3984 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
3985 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
3986 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
3987 output_asm_insn (AS1 (fldc%W3,%3), operands);
2a2ab3f9
JVA
3988
3989 if (NON_STACK_REG_P (operands[0]))
c27d9c3b 3990 output_to_reg (operands[0], stack_top_dies, operands[3]);
e9a25f70 3991
2a2ab3f9
JVA
3992 else if (GET_CODE (operands[0]) == MEM)
3993 {
2a2ab3f9
JVA
3994 if (stack_top_dies)
3995 output_asm_insn (AS1 (fistp%z0,%0), operands);
2e14a41b
JW
3996 else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
3997 {
3998 /* There is no DImode version of this without a stack pop, so
3999 we must emulate it. It doesn't matter much what the second
4000 instruction is, because the value being pushed on the FP stack
4001 is not used except for the following stack popping store.
4002 This case can only happen without optimization, so it doesn't
4003 matter that it is inefficient. */
4004 output_asm_insn (AS1 (fistp%z0,%0), operands);
4005 output_asm_insn (AS1 (fild%z0,%0), operands);
4006 }
2a2ab3f9
JVA
4007 else
4008 output_asm_insn (AS1 (fist%z0,%0), operands);
4009 }
4010 else
4011 abort ();
4012
305f097e 4013 return AS1 (fldc%W2,%2);
2a2ab3f9
JVA
4014}
4015\f
4016/* Output code for INSN to compare OPERANDS. The two operands might
4017 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
c572e5ba
JVA
4018 expression. If the compare is in mode CCFPEQmode, use an opcode that
4019 will not fault if a qNaN is present. */
2a2ab3f9
JVA
4020
4021char *
4022output_float_compare (insn, operands)
4023 rtx insn;
4024 rtx *operands;
4025{
4026 int stack_top_dies;
c572e5ba
JVA
4027 rtx body = XVECEXP (PATTERN (insn), 0, 0);
4028 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
32b5b1aa 4029 rtx tmp;
4f74d15b 4030
d6cc54f6 4031 if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
4f74d15b
SC
4032 {
4033 cc_status.flags |= CC_FCOMI;
4034 cc_prev_status.flags &= ~CC_TEST_AX;
4035 }
4036
32b5b1aa
SC
4037 if (! STACK_TOP_P (operands[0]))
4038 {
4039 tmp = operands[0];
4040 operands[0] = operands[1];
4041 operands[1] = tmp;
4042 cc_status.flags |= CC_REVERSED;
4043 }
4044
2a2ab3f9
JVA
4045 if (! STACK_TOP_P (operands[0]))
4046 abort ();
4047
4048 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
4049
4050 if (STACK_REG_P (operands[1])
4051 && stack_top_dies
4052 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4053 && REGNO (operands[1]) != FIRST_STACK_REG)
4054 {
4055 /* If both the top of the 387 stack dies, and the other operand
4056 is also a stack register that dies, then this must be a
4057 `fcompp' float compare */
4058
c572e5ba 4059 if (unordered_compare)
e9a25f70
JL
4060 {
4061 if (cc_status.flags & CC_FCOMI)
4062 {
4063 output_asm_insn (AS2 (fucomip,%y1,%0), operands);
4064 output_asm_insn (AS1 (fstp, %y0), operands);
4065 return "";
4066 }
4067 else
4068 output_asm_insn ("fucompp", operands);
4069 }
c572e5ba 4070 else
858a9ffc 4071 {
e9a25f70
JL
4072 if (cc_status.flags & CC_FCOMI)
4073 {
4074 output_asm_insn (AS2 (fcomip, %y1,%0), operands);
4075 output_asm_insn (AS1 (fstp, %y0), operands);
4076 return "";
4077 }
4078 else
4079 output_asm_insn ("fcompp", operands);
858a9ffc 4080 }
2a2ab3f9
JVA
4081 }
4082 else
4083 {
4084 static char buf[100];
4085
c572e5ba
JVA
4086 /* Decide if this is the integer or float compare opcode, or the
4087 unordered float compare. */
2a2ab3f9 4088
c572e5ba 4089 if (unordered_compare)
4f74d15b 4090 strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fucomi" : "fucom");
c572e5ba 4091 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
4f74d15b 4092 strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom");
2a2ab3f9
JVA
4093 else
4094 strcpy (buf, "ficom");
4095
4096 /* Modify the opcode if the 387 stack is to be popped. */
4097
4098 if (stack_top_dies)
4099 strcat (buf, "p");
4100
4101 if (NON_STACK_REG_P (operands[1]))
4102 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
4f74d15b 4103 else if (cc_status.flags & CC_FCOMI)
5703bb66 4104 {
858a9ffc 4105 output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
e9a25f70 4106 return "";
5703bb66 4107 }
2a2ab3f9
JVA
4108 else
4109 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
4110 }
4111
4112 /* Now retrieve the condition code. */
4113
c572e5ba
JVA
4114 return output_fp_cc0_set (insn);
4115}
4116\f
4117/* Output opcodes to transfer the results of FP compare or test INSN
4118 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
4119 result of the compare or test is unordered, no comparison operator
4120 succeeds except NE. Return an output template, if any. */
4121
4122char *
4123output_fp_cc0_set (insn)
4124 rtx insn;
4125{
4126 rtx xops[3];
c572e5ba
JVA
4127 rtx next;
4128 enum rtx_code code;
4129
f64cecad 4130 xops[0] = gen_rtx_REG (HImode, 0);
c572e5ba
JVA
4131 output_asm_insn (AS1 (fnsts%W0,%0), xops);
4132
4133 if (! TARGET_IEEE_FP)
32b5b1aa
SC
4134 {
4135 if (!(cc_status.flags & CC_REVERSED))
4136 {
4137 next = next_cc0_user (insn);
4138
4139 if (GET_CODE (next) == JUMP_INSN
4140 && GET_CODE (PATTERN (next)) == SET
4141 && SET_DEST (PATTERN (next)) == pc_rtx
4142 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
e9a25f70 4143 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
32b5b1aa 4144 else if (GET_CODE (PATTERN (next)) == SET)
e9a25f70 4145 code = GET_CODE (SET_SRC (PATTERN (next)));
32b5b1aa 4146 else
e9a25f70
JL
4147 return "sahf";
4148
4149 if (code == GT || code == LT || code == EQ || code == NE
4150 || code == LE || code == GE)
4151 {
4152 /* We will test eax directly. */
32b5b1aa 4153 cc_status.flags |= CC_TEST_AX;
e9a25f70 4154 return "";
32b5b1aa
SC
4155 }
4156 }
e9a25f70 4157
32b5b1aa
SC
4158 return "sahf";
4159 }
2a2ab3f9 4160
c572e5ba 4161 next = next_cc0_user (insn);
dd9611dc
JVA
4162 if (next == NULL_RTX)
4163 abort ();
c572e5ba
JVA
4164
4165 if (GET_CODE (next) == JUMP_INSN
4166 && GET_CODE (PATTERN (next)) == SET
4167 && SET_DEST (PATTERN (next)) == pc_rtx
4168 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
e9a25f70 4169 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
c572e5ba
JVA
4170 else if (GET_CODE (PATTERN (next)) == SET)
4171 {
fe25fea3
SC
4172 if (GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
4173 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
e9a25f70
JL
4174 else
4175 code = GET_CODE (SET_SRC (PATTERN (next)));
c572e5ba 4176 }
e9a25f70 4177
4f74d15b
SC
4178 else if (GET_CODE (PATTERN (next)) == PARALLEL
4179 && GET_CODE (XVECEXP (PATTERN (next), 0, 0)) == SET)
4180 {
4181 if (GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0))) == IF_THEN_ELSE)
e9a25f70
JL
4182 code = GET_CODE (XEXP (SET_SRC (XVECEXP (PATTERN (next), 0, 0)), 0));
4183 else
4184 code = GET_CODE (SET_SRC (XVECEXP (PATTERN (next), 0, 0)));
4f74d15b 4185 }
c572e5ba
JVA
4186 else
4187 abort ();
4188
f64cecad 4189 xops[0] = gen_rtx_REG (QImode, 0);
c572e5ba
JVA
4190
4191 switch (code)
4192 {
4193 case GT:
435defd1 4194 xops[1] = GEN_INT (0x45);
c572e5ba
JVA
4195 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4196 /* je label */
4197 break;
4198
4199 case LT:
435defd1
JVA
4200 xops[1] = GEN_INT (0x45);
4201 xops[2] = GEN_INT (0x01);
c572e5ba
JVA
4202 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4203 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4204 /* je label */
4205 break;
4206
4207 case GE:
435defd1 4208 xops[1] = GEN_INT (0x05);
c572e5ba
JVA
4209 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4210 /* je label */
4211 break;
4212
4213 case LE:
435defd1
JVA
4214 xops[1] = GEN_INT (0x45);
4215 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
4216 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4217 output_asm_insn (AS1 (dec%B0,%h0), xops);
4218 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4219 /* jb label */
4220 break;
4221
4222 case EQ:
435defd1
JVA
4223 xops[1] = GEN_INT (0x45);
4224 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
4225 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4226 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
4227 /* je label */
4228 break;
4229
4230 case NE:
435defd1
JVA
4231 xops[1] = GEN_INT (0x44);
4232 xops[2] = GEN_INT (0x40);
c572e5ba
JVA
4233 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
4234 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
4235 /* jne label */
4236 break;
4237
4238 case GTU:
4239 case LTU:
4240 case GEU:
4241 case LEU:
4242 default:
4243 abort ();
4244 }
e9a25f70
JL
4245
4246 return "";
2a2ab3f9 4247}
305f097e
JVA
4248\f
4249#define MAX_386_STACK_LOCALS 2
4250
4251static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
4252
ecbc4695
RS
4253/* Define the structure for the machine field in struct function. */
4254struct machine_function
4255{
4256 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
b94b5c16
JL
4257 rtx pic_label_rtx;
4258 char pic_label_name[256];
ecbc4695
RS
4259};
4260
4261/* Functions to save and restore i386_stack_locals.
4262 These will be called, via pointer variables,
4263 from push_function_context and pop_function_context. */
4264
4265void
4266save_386_machine_status (p)
4267 struct function *p;
4268{
b94b5c16
JL
4269 p->machine
4270 = (struct machine_function *) xmalloc (sizeof (struct machine_function));
dde866c6 4271 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
ecbc4695 4272 sizeof i386_stack_locals);
b94b5c16
JL
4273 p->machine->pic_label_rtx = pic_label_rtx;
4274 bcopy (pic_label_name, p->machine->pic_label_name, 256);
ecbc4695
RS
4275}
4276
4277void
4278restore_386_machine_status (p)
4279 struct function *p;
4280{
dde866c6 4281 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
ecbc4695 4282 sizeof i386_stack_locals);
b94b5c16
JL
4283 pic_label_rtx = p->machine->pic_label_rtx;
4284 bcopy (p->machine->pic_label_name, pic_label_name, 256);
ecbc4695 4285 free (p->machine);
b94b5c16 4286 p->machine = NULL;
ecbc4695
RS
4287}
4288
305f097e
JVA
4289/* Clear stack slot assignments remembered from previous functions.
4290 This is called from INIT_EXPANDERS once before RTL is emitted for each
ecbc4695 4291 function. */
305f097e
JVA
4292
4293void
4294clear_386_stack_locals ()
4295{
4296 enum machine_mode mode;
4297 int n;
4298
4299 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
4300 mode = (enum machine_mode) ((int) mode + 1))
4301 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
4302 i386_stack_locals[(int) mode][n] = NULL_RTX;
ecbc4695 4303
b94b5c16
JL
4304 pic_label_rtx = NULL_RTX;
4305 bzero (pic_label_name, 256);
ecbc4695
RS
4306 /* Arrange to save and restore i386_stack_locals around nested functions. */
4307 save_machine_status = save_386_machine_status;
4308 restore_machine_status = restore_386_machine_status;
305f097e
JVA
4309}
4310
4311/* Return a MEM corresponding to a stack slot with mode MODE.
4312 Allocate a new slot if necessary.
4313
4314 The RTL for a function can have several slots available: N is
4315 which slot to use. */
4316
4317rtx
4318assign_386_stack_local (mode, n)
4319 enum machine_mode mode;
4320 int n;
4321{
4322 if (n < 0 || n >= MAX_386_STACK_LOCALS)
4323 abort ();
4324
4325 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
4326 i386_stack_locals[(int) mode][n]
4327 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
4328
4329 return i386_stack_locals[(int) mode][n];
4330}
32b5b1aa
SC
4331\f
4332int is_mul(op,mode)
4333 register rtx op;
4334 enum machine_mode mode;
4335{
4336 return (GET_CODE (op) == MULT);
4337}
4338
4339int is_div(op,mode)
4340 register rtx op;
4341 enum machine_mode mode;
4342{
4343 return (GET_CODE (op) == DIV);
4344}
32b5b1aa
SC
4345\f
4346#ifdef NOTYET
4347/* Create a new copy of an rtx.
4348 Recursively copies the operands of the rtx,
4349 except for those few rtx codes that are sharable.
4350 Doesn't share CONST */
4351
4352rtx
4353copy_all_rtx (orig)
4354 register rtx orig;
4355{
4356 register rtx copy;
4357 register int i, j;
4358 register RTX_CODE code;
4359 register char *format_ptr;
4360
4361 code = GET_CODE (orig);
4362
4363 switch (code)
4364 {
4365 case REG:
4366 case QUEUED:
4367 case CONST_INT:
4368 case CONST_DOUBLE:
4369 case SYMBOL_REF:
4370 case CODE_LABEL:
4371 case PC:
4372 case CC0:
4373 case SCRATCH:
4374 /* SCRATCH must be shared because they represent distinct values. */
4375 return orig;
4376
4377#if 0
4378 case CONST:
4379 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
4380 a LABEL_REF, it isn't sharable. */
4381 if (GET_CODE (XEXP (orig, 0)) == PLUS
4382 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
4383 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
4384 return orig;
4385 break;
4386#endif
4387 /* A MEM with a constant address is not sharable. The problem is that
4388 the constant address may need to be reloaded. If the mem is shared,
4389 then reloading one copy of this mem will cause all copies to appear
4390 to have been reloaded. */
4391 }
4392
4393 copy = rtx_alloc (code);
4394 PUT_MODE (copy, GET_MODE (orig));
4395 copy->in_struct = orig->in_struct;
4396 copy->volatil = orig->volatil;
4397 copy->unchanging = orig->unchanging;
4398 copy->integrated = orig->integrated;
4399 /* intel1 */
4400 copy->is_spill_rtx = orig->is_spill_rtx;
4401
4402 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
4403
4404 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
4405 {
4406 switch (*format_ptr++)
4407 {
4408 case 'e':
4409 XEXP (copy, i) = XEXP (orig, i);
4410 if (XEXP (orig, i) != NULL)
4411 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
4412 break;
4413
4414 case '0':
4415 case 'u':
4416 XEXP (copy, i) = XEXP (orig, i);
4417 break;
4418
4419 case 'E':
4420 case 'V':
4421 XVEC (copy, i) = XVEC (orig, i);
4422 if (XVEC (orig, i) != NULL)
4423 {
4424 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
4425 for (j = 0; j < XVECLEN (copy, i); j++)
4426 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
4427 }
4428 break;
4429
4430 case 'w':
4431 XWINT (copy, i) = XWINT (orig, i);
4432 break;
4433
4434 case 'i':
4435 XINT (copy, i) = XINT (orig, i);
4436 break;
4437
4438 case 's':
4439 case 'S':
4440 XSTR (copy, i) = XSTR (orig, i);
4441 break;
4442
4443 default:
4444 abort ();
4445 }
4446 }
4447 return copy;
4448}
4449
4450\f
e9a25f70
JL
4451/* Try to rewrite a memory address to make it valid */
4452
32b5b1aa
SC
4453void
4454rewrite_address (mem_rtx)
4455 rtx mem_rtx;
4456{
4457 rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
4458 int scale = 1;
4459 int offset_adjust = 0;
4460 int was_only_offset = 0;
4461 rtx mem_addr = XEXP (mem_rtx, 0);
e9a25f70 4462 char *storage = oballoc (0);
32b5b1aa
SC
4463 int in_struct = 0;
4464 int is_spill_rtx = 0;
4465
4466 in_struct = MEM_IN_STRUCT_P (mem_rtx);
4467 is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
4468
e9a25f70
JL
4469 if (GET_CODE (mem_addr) == PLUS
4470 && GET_CODE (XEXP (mem_addr, 1)) == PLUS
4471 && GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
4472 {
4473 /* This part is utilized by the combiner. */
4474 ret_rtx
4475 = gen_rtx (PLUS, GET_MODE (mem_addr),
4476 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
4477 XEXP (mem_addr, 0), XEXP (XEXP (mem_addr, 1), 0)),
4478 XEXP (XEXP (mem_addr, 1), 1));
4479
32b5b1aa
SC
4480 if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
4481 {
4482 XEXP (mem_rtx, 0) = ret_rtx;
4483 RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
4484 return;
4485 }
e9a25f70 4486
32b5b1aa
SC
4487 obfree (storage);
4488 }
4489
e9a25f70
JL
4490 /* This part is utilized by loop.c.
4491 If the address contains PLUS (reg,const) and this pattern is invalid
4492 in this case - try to rewrite the address to make it valid. */
4493 storage = oballoc (0);
32b5b1aa 4494 index_rtx = base_rtx = offset_rtx = NULL;
e9a25f70
JL
4495
4496 /* Find the base index and offset elements of the memory address. */
32b5b1aa
SC
4497 if (GET_CODE (mem_addr) == PLUS)
4498 {
4499 if (GET_CODE (XEXP (mem_addr, 0)) == REG)
4500 {
4501 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
e9a25f70 4502 base_rtx = XEXP (mem_addr, 1), index_rtx = XEXP (mem_addr, 0);
32b5b1aa 4503 else
e9a25f70 4504 base_rtx = XEXP (mem_addr, 0), offset_rtx = XEXP (mem_addr, 1);
32b5b1aa 4505 }
e9a25f70 4506
32b5b1aa
SC
4507 else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
4508 {
4509 index_rtx = XEXP (mem_addr, 0);
4510 if (GET_CODE (XEXP (mem_addr, 1)) == REG)
e9a25f70 4511 base_rtx = XEXP (mem_addr, 1);
32b5b1aa 4512 else
e9a25f70 4513 offset_rtx = XEXP (mem_addr, 1);
32b5b1aa 4514 }
e9a25f70 4515
32b5b1aa
SC
4516 else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
4517 {
e9a25f70
JL
4518 if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS
4519 && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT
4520 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0))
4521 == REG)
4522 && (GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1))
4523 == CONST_INT)
4524 && (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1))
4525 == CONST_INT)
4526 && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG
4527 && GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
32b5b1aa
SC
4528 {
4529 index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
4530 offset_rtx = XEXP (mem_addr, 1);
4531 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4532 offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
4533 }
4534 else
4535 {
4536 offset_rtx = XEXP (mem_addr, 1);
4537 index_rtx = XEXP (XEXP (mem_addr, 0), 0);
4538 base_rtx = XEXP (XEXP (mem_addr, 0), 1);
4539 }
4540 }
e9a25f70 4541
32b5b1aa
SC
4542 else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
4543 {
4544 was_only_offset = 1;
4545 index_rtx = NULL;
4546 base_rtx = NULL;
4547 offset_rtx = XEXP (mem_addr, 1);
4548 offset_adjust = INTVAL (XEXP (mem_addr, 0));
4549 if (offset_adjust == 0)
4550 {
4551 XEXP (mem_rtx, 0) = offset_rtx;
4552 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4553 return;
4554 }
4555 }
4556 else
4557 {
4558 obfree (storage);
4559 return;
4560 }
4561 }
4562 else if (GET_CODE (mem_addr) == MULT)
e9a25f70 4563 index_rtx = mem_addr;
32b5b1aa
SC
4564 else
4565 {
4566 obfree (storage);
4567 return;
4568 }
e9a25f70
JL
4569
4570 if (index_rtx != 0 && GET_CODE (index_rtx) == MULT)
32b5b1aa
SC
4571 {
4572 if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
4573 {
4574 obfree (storage);
4575 return;
4576 }
e9a25f70 4577
32b5b1aa
SC
4578 scale_rtx = XEXP (index_rtx, 1);
4579 scale = INTVAL (scale_rtx);
4580 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4581 }
e9a25f70
JL
4582
4583 /* Now find which of the elements are invalid and try to fix them. */
32b5b1aa
SC
4584 if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
4585 {
4586 offset_adjust = INTVAL (index_rtx) * scale;
e9a25f70
JL
4587
4588 if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4589 offset_rtx = plus_constant (offset_rtx, offset_adjust);
4590 else if (offset_rtx == 0)
4591 offset_rtx = const0_rtx;
4592
32b5b1aa
SC
4593 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4594 XEXP (mem_rtx, 0) = offset_rtx;
4595 return;
4596 }
e9a25f70
JL
4597
4598 if (base_rtx && GET_CODE (base_rtx) == PLUS
4599 && GET_CODE (XEXP (base_rtx, 0)) == REG
4600 && GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
32b5b1aa
SC
4601 {
4602 offset_adjust += INTVAL (XEXP (base_rtx, 1));
4603 base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
4604 }
e9a25f70 4605
32b5b1aa
SC
4606 else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
4607 {
4608 offset_adjust += INTVAL (base_rtx);
4609 base_rtx = NULL;
4610 }
e9a25f70
JL
4611
4612 if (index_rtx && GET_CODE (index_rtx) == PLUS
4613 && GET_CODE (XEXP (index_rtx, 0)) == REG
4614 && GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
32b5b1aa
SC
4615 {
4616 offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
4617 index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
4618 }
e9a25f70 4619
32b5b1aa
SC
4620 if (index_rtx)
4621 {
e9a25f70
JL
4622 if (! LEGITIMATE_INDEX_P (index_rtx)
4623 && ! (index_rtx == stack_pointer_rtx && scale == 1
4624 && base_rtx == NULL))
32b5b1aa
SC
4625 {
4626 obfree (storage);
4627 return;
4628 }
4629 }
e9a25f70 4630
32b5b1aa
SC
4631 if (base_rtx)
4632 {
e9a25f70 4633 if (! LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
32b5b1aa
SC
4634 {
4635 obfree (storage);
4636 return;
4637 }
4638 }
e9a25f70 4639
32b5b1aa
SC
4640 if (offset_adjust != 0)
4641 {
e9a25f70
JL
4642 if (offset_rtx != 0 && CONSTANT_P (offset_rtx))
4643 offset_rtx = plus_constant (offset_rtx, offset_adjust);
32b5b1aa 4644 else
e9a25f70
JL
4645 offset_rtx = const0_rtx;
4646
32b5b1aa
SC
4647 if (index_rtx)
4648 {
4649 if (base_rtx)
4650 {
4651 if (scale != 1)
4652 {
e9a25f70
JL
4653 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
4654 gen_rtx (MULT, GET_MODE (index_rtx),
4655 index_rtx, scale_rtx),
4656 base_rtx);
4657
4658 if (GET_CODE (offset_rtx) != CONST_INT
4659 || INTVAL (offset_rtx) != 0)
4660 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4661 ret_rtx, offset_rtx);
32b5b1aa
SC
4662 }
4663 else
4664 {
e9a25f70
JL
4665 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4666 index_rtx, base_rtx);
4667
4668 if (GET_CODE (offset_rtx) != CONST_INT
4669 || INTVAL (offset_rtx) != 0)
4670 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4671 ret_rtx, offset_rtx);
32b5b1aa
SC
4672 }
4673 }
4674 else
4675 {
4676 if (scale != 1)
4677 {
e9a25f70
JL
4678 ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx),
4679 index_rtx, scale_rtx);
4680
4681 if (GET_CODE (offset_rtx) != CONST_INT
4682 || INTVAL (offset_rtx) != 0)
4683 ret_rtx = gen_rtx (PLUS, GET_MODE (ret_rtx),
4684 ret_rtx, offset_rtx);
32b5b1aa
SC
4685 }
4686 else
4687 {
e9a25f70
JL
4688 if (GET_CODE (offset_rtx) == CONST_INT
4689 && INTVAL (offset_rtx) == 0)
4690 ret_rtx = index_rtx;
32b5b1aa 4691 else
e9a25f70
JL
4692 ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx),
4693 index_rtx, offset_rtx);
32b5b1aa
SC
4694 }
4695 }
4696 }
4697 else
4698 {
4699 if (base_rtx)
4700 {
e9a25f70
JL
4701 if (GET_CODE (offset_rtx) == CONST_INT
4702 && INTVAL (offset_rtx) == 0)
4703 ret_rtx = base_rtx;
32b5b1aa 4704 else
e9a25f70
JL
4705 ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx,
4706 offset_rtx);
32b5b1aa
SC
4707 }
4708 else if (was_only_offset)
e9a25f70 4709 ret_rtx = offset_rtx;
32b5b1aa
SC
4710 else
4711 {
4712 obfree (storage);
4713 return;
4714 }
4715 }
e9a25f70 4716
32b5b1aa
SC
4717 XEXP (mem_rtx, 0) = ret_rtx;
4718 RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
4719 return;
4720 }
4721 else
4722 {
4723 obfree (storage);
4724 return;
4725 }
4726}
4727#endif /* NOTYET */
32b5b1aa 4728\f
e9a25f70
JL
4729/* Return 1 if the first insn to set cc before INSN also sets the register
4730 REG_RTX; otherwise return 0. */
32b5b1aa
SC
4731int
4732last_to_set_cc (reg_rtx, insn)
4733 rtx reg_rtx, insn;
4734{
4735 rtx prev_insn = PREV_INSN (insn);
4736
4737 while (prev_insn)
4738 {
4739 if (GET_CODE (prev_insn) == NOTE)
4740 ;
4741
4742 else if (GET_CODE (prev_insn) == INSN)
4743 {
4744 if (GET_CODE (PATTERN (prev_insn)) != SET)
4745 return (0);
4746
4747 if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
4748 {
4749 if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
4750 return (1);
4751
4752 return (0);
4753 }
4754
e9a25f70 4755 else if (! doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
32b5b1aa
SC
4756 return (0);
4757 }
4758
4759 else
4760 return (0);
4761
4762 prev_insn = PREV_INSN (prev_insn);
4763 }
4764
4765 return (0);
4766}
32b5b1aa
SC
4767\f
4768int
4769doesnt_set_condition_code (pat)
4770 rtx pat;
4771{
4772 switch (GET_CODE (pat))
4773 {
4774 case MEM:
4775 case REG:
e9a25f70 4776 return 1;
32b5b1aa
SC
4777
4778 default:
e9a25f70 4779 return 0;
32b5b1aa
SC
4780
4781 }
4782}
32b5b1aa
SC
4783\f
4784int
4785sets_condition_code (pat)
4786 rtx pat;
4787{
4788 switch (GET_CODE (pat))
4789 {
4790 case PLUS:
4791 case MINUS:
4792 case AND:
4793 case IOR:
4794 case XOR:
4795 case NOT:
4796 case NEG:
4797 case MULT:
4798 case DIV:
4799 case MOD:
4800 case UDIV:
4801 case UMOD:
e9a25f70 4802 return 1;
32b5b1aa
SC
4803
4804 default:
4805 return (0);
32b5b1aa
SC
4806 }
4807}
32b5b1aa
SC
4808\f
4809int
4810str_immediate_operand (op, mode)
4811 register rtx op;
4812 enum machine_mode mode;
4813{
4814 if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
e9a25f70 4815 return 1;
32b5b1aa 4816
e9a25f70
JL
4817 return 0;
4818}
32b5b1aa
SC
4819\f
4820int
4821is_fp_insn (insn)
4822 rtx insn;
4823{
4824 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4825 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4826 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4827 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode))
e9a25f70 4828 return 1;
32b5b1aa 4829
e9a25f70 4830 return 0;
32b5b1aa
SC
4831}
4832
e9a25f70
JL
4833/* Return 1 if the mode of the SET_DEST of insn is floating point
4834 and it is not an fld or a move from memory to memory.
4835 Otherwise return 0 */
4836
32b5b1aa
SC
4837int
4838is_fp_dest (insn)
4839 rtx insn;
4840{
4841 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4842 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4843 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4844 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4845 && GET_CODE (SET_DEST (PATTERN (insn))) == REG
4846 && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
4847 && GET_CODE (SET_SRC (insn)) != MEM)
e9a25f70 4848 return 1;
32b5b1aa 4849
e9a25f70 4850 return 0;
32b5b1aa
SC
4851}
4852
e9a25f70
JL
4853/* Return 1 if the mode of the SET_DEST of INSN is floating point and is
4854 memory and the source is a register. */
4855
32b5b1aa
SC
4856int
4857is_fp_store (insn)
4858 rtx insn;
4859{
4860 if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
4861 && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
4862 || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
4863 || GET_MODE (SET_DEST (PATTERN (insn))) == XFmode)
4864 && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
4865 && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
e9a25f70 4866 return 1;
32b5b1aa 4867
e9a25f70 4868 return 0;
32b5b1aa 4869}
32b5b1aa 4870\f
e9a25f70
JL
4871/* Return 1 if DEP_INSN sets a register which INSN uses as a base
4872 or index to reference memory.
4873 otherwise return 0 */
32b5b1aa
SC
4874
4875int
4876agi_dependent (insn, dep_insn)
4877 rtx insn, dep_insn;
4878{
4879 if (GET_CODE (dep_insn) == INSN
4880 && GET_CODE (PATTERN (dep_insn)) == SET
4881 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
e9a25f70 4882 return reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn);
32b5b1aa
SC
4883
4884 if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
4885 && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
4886 && push_operand (SET_DEST (PATTERN (dep_insn)),
4887 GET_MODE (SET_DEST (PATTERN (dep_insn)))))
e9a25f70 4888 return reg_mentioned_in_mem (stack_pointer_rtx, insn);
32b5b1aa 4889
e9a25f70
JL
4890 return 0;
4891}
32b5b1aa 4892\f
e9a25f70
JL
4893/* Return 1 if reg is used in rtl as a base or index for a memory ref
4894 otherwise return 0. */
32b5b1aa
SC
4895
4896int
4897reg_mentioned_in_mem (reg, rtl)
4898 rtx reg, rtl;
4899{
4900 register char *fmt;
e9a25f70 4901 register int i, j;
32b5b1aa
SC
4902 register enum rtx_code code;
4903
4904 if (rtl == NULL)
e9a25f70 4905 return 0;
32b5b1aa
SC
4906
4907 code = GET_CODE (rtl);
4908
4909 switch (code)
4910 {
4911 case HIGH:
4912 case CONST_INT:
4913 case CONST:
4914 case CONST_DOUBLE:
4915 case SYMBOL_REF:
4916 case LABEL_REF:
4917 case PC:
4918 case CC0:
4919 case SUBREG:
e9a25f70 4920 return 0;
00c79232 4921 default:
53949fac 4922 break;
32b5b1aa
SC
4923 }
4924
4925 if (code == MEM && reg_mentioned_p (reg, rtl))
e9a25f70 4926 return 1;
32b5b1aa
SC
4927
4928 fmt = GET_RTX_FORMAT (code);
4929 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4930 {
4931 if (fmt[i] == 'E')
c7271385
JL
4932 {
4933 for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
4934 if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
4935 return 1;
4936 }
32b5b1aa
SC
4937
4938 else if (fmt[i] == 'e' && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
4939 return 1;
4940 }
4941
e9a25f70 4942 return 0;
32b5b1aa 4943}
3f803cd9 4944\f
956d6950 4945/* Output the appropriate insns for doing strlen if not just doing repnz; scasb
3f803cd9
SC
4946
4947 operands[0] = result, initialized with the startaddress
4948 operands[1] = alignment of the address.
4949 operands[2] = scratch register, initialized with the startaddress when
4950 not aligned, otherwise undefined
4951
4952 This is just the body. It needs the initialisations mentioned above and
4953 some address computing at the end. These things are done in i386.md. */
4954
4955char *
4956output_strlen_unroll (operands)
4957 rtx operands[];
4958{
4959 rtx xops[18];
4960
4961 xops[0] = operands[0]; /* Result */
4962 /* operands[1]; * Alignment */
4963 xops[1] = operands[2]; /* Scratch */
4964 xops[2] = GEN_INT (0);
4965 xops[3] = GEN_INT (2);
4966 xops[4] = GEN_INT (3);
4967 xops[5] = GEN_INT (4);
4968 /* xops[6] = gen_label_rtx (); * label when aligned to 3-byte */
4969 /* xops[7] = gen_label_rtx (); * label when aligned to 2-byte */
4970 xops[8] = gen_label_rtx (); /* label of main loop */
e9a25f70
JL
4971
4972 if (TARGET_USE_Q_REG && QI_REG_P (xops[1]))
3f803cd9 4973 xops[9] = gen_label_rtx (); /* pentium optimisation */
e9a25f70 4974
3f803cd9
SC
4975 xops[10] = gen_label_rtx (); /* end label 2 */
4976 xops[11] = gen_label_rtx (); /* end label 1 */
4977 xops[12] = gen_label_rtx (); /* end label */
4978 /* xops[13] * Temporary used */
4979 xops[14] = GEN_INT (0xff);
4980 xops[15] = GEN_INT (0xff00);
4981 xops[16] = GEN_INT (0xff0000);
4982 xops[17] = GEN_INT (0xff000000);
4983
e9a25f70 4984 /* Loop to check 1..3 bytes for null to get an aligned pointer. */
3f803cd9 4985
e9a25f70 4986 /* Is there a known alignment and is it less than 4? */
3f803cd9
SC
4987 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) < 4)
4988 {
e9a25f70 4989 /* Is there a known alignment and is it not 2? */
3f803cd9
SC
4990 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
4991 {
e9a25f70
JL
4992 xops[6] = gen_label_rtx (); /* Label when aligned to 3-byte */
4993 xops[7] = gen_label_rtx (); /* Label when aligned to 2-byte */
3f803cd9 4994
e9a25f70
JL
4995 /* Leave just the 3 lower bits.
4996 If this is a q-register, then the high part is used later
4997 therefore use andl rather than andb. */
3f803cd9 4998 output_asm_insn (AS2 (and%L1,%4,%1), xops);
e9a25f70 4999
956d6950 5000 /* Is aligned to 4-byte address when zero */
3f803cd9 5001 output_asm_insn (AS1 (je,%l8), xops);
e9a25f70
JL
5002
5003 /* Side-effect even Parity when %eax == 3 */
3f803cd9
SC
5004 output_asm_insn (AS1 (jp,%6), xops);
5005
e9a25f70 5006 /* Is it aligned to 2 bytes ? */
3f803cd9
SC
5007 if (QI_REG_P (xops[1]))
5008 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
5009 else
5010 output_asm_insn (AS2 (cmp%L1,%3,%1), xops);
e9a25f70 5011
3f803cd9
SC
5012 output_asm_insn (AS1 (je,%7), xops);
5013 }
5014 else
5015 {
e9a25f70
JL
5016 /* Since the alignment is 2, we have to check 2 or 0 bytes;
5017 check if is aligned to 4 - byte. */
3f803cd9 5018 output_asm_insn (AS2 (and%L1,%3,%1), xops);
e9a25f70 5019
956d6950 5020 /* Is aligned to 4-byte address when zero */
3f803cd9
SC
5021 output_asm_insn (AS1 (je,%l8), xops);
5022 }
5023
f64cecad 5024 xops[13] = gen_rtx_MEM (QImode, xops[0]);
e9a25f70
JL
5025
5026 /* Now compare the bytes; compare with the high part of a q-reg
5027 gives shorter code. */
3f803cd9
SC
5028 if (QI_REG_P (xops[1]))
5029 {
e9a25f70 5030 /* Compare the first n unaligned byte on a byte per byte basis. */
3f803cd9 5031 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
e9a25f70
JL
5032
5033 /* When zero we reached the end. */
3f803cd9 5034 output_asm_insn (AS1 (je,%l12), xops);
e9a25f70
JL
5035
5036 /* Increment the address. */
3f803cd9
SC
5037 output_asm_insn (AS1 (inc%L0,%0), xops);
5038
e9a25f70 5039 /* Not needed with an alignment of 2 */
3f803cd9
SC
5040 if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 2)
5041 {
e9a25f70
JL
5042 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5043 CODE_LABEL_NUMBER (xops[7]));
3f803cd9
SC
5044 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5045 output_asm_insn (AS1 (je,%l12), xops);
5046 output_asm_insn (AS1 (inc%L0,%0), xops);
5047
e9a25f70
JL
5048 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5049 CODE_LABEL_NUMBER (xops[6]));
3f803cd9 5050 }
e9a25f70 5051
3f803cd9
SC
5052 output_asm_insn (AS2 (cmp%B1,%h1,%13), xops);
5053 }
5054 else
5055 {
5056 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5057 output_asm_insn (AS1 (je,%l12), xops);
5058 output_asm_insn (AS1 (inc%L0,%0), xops);
5059
e9a25f70
JL
5060 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5061 CODE_LABEL_NUMBER (xops[7]));
3f803cd9
SC
5062 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5063 output_asm_insn (AS1 (je,%l12), xops);
5064 output_asm_insn (AS1 (inc%L0,%0), xops);
5065
e9a25f70
JL
5066 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5067 CODE_LABEL_NUMBER (xops[6]));
3f803cd9
SC
5068 output_asm_insn (AS2 (cmp%B13,%2,%13), xops);
5069 }
e9a25f70 5070
3f803cd9
SC
5071 output_asm_insn (AS1 (je,%l12), xops);
5072 output_asm_insn (AS1 (inc%L0,%0), xops);
5073 }
5074
e9a25f70
JL
5075 /* Generate loop to check 4 bytes at a time. It is not a good idea to
5076 align this loop. It gives only huge programs, but does not help to
5077 speed up. */
3f803cd9
SC
5078 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[8]));
5079
f64cecad 5080 xops[13] = gen_rtx_MEM (SImode, xops[0]);
3f803cd9
SC
5081 output_asm_insn (AS2 (mov%L1,%13,%1), xops);
5082
5083 if (QI_REG_P (xops[1]))
5084 {
1853aadd
RK
5085 /* On i586 it is faster to combine the hi- and lo- part as
5086 a kind of lookahead. If anding both yields zero, then one
5087 of both *could* be zero, otherwise none of both is zero;
5088 this saves one instruction, on i486 this is slower
5089 tested with P-90, i486DX2-66, AMD486DX2-66 */
e9a25f70 5090 if (TARGET_PENTIUM)
3f803cd9
SC
5091 {
5092 output_asm_insn (AS2 (test%B1,%h1,%b1), xops);
5093 output_asm_insn (AS1 (jne,%l9), xops);
5094 }
5095
e9a25f70 5096 /* Check first byte. */
3f803cd9
SC
5097 output_asm_insn (AS2 (test%B1,%b1,%b1), xops);
5098 output_asm_insn (AS1 (je,%l12), xops);
5099
e9a25f70 5100 /* Check second byte. */
3f803cd9
SC
5101 output_asm_insn (AS2 (test%B1,%h1,%h1), xops);
5102 output_asm_insn (AS1 (je,%l11), xops);
5103
e9a25f70
JL
5104 if (TARGET_PENTIUM)
5105 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
5106 CODE_LABEL_NUMBER (xops[9]));
3f803cd9 5107 }
e9a25f70 5108
3f803cd9
SC
5109 else
5110 {
e9a25f70 5111 /* Check first byte. */
3f803cd9
SC
5112 output_asm_insn (AS2 (test%L1,%14,%1), xops);
5113 output_asm_insn (AS1 (je,%l12), xops);
5114
e9a25f70 5115 /* Check second byte. */
3f803cd9
SC
5116 output_asm_insn (AS2 (test%L1,%15,%1), xops);
5117 output_asm_insn (AS1 (je,%l11), xops);
5118 }
5119
e9a25f70 5120 /* Check third byte. */
3f803cd9
SC
5121 output_asm_insn (AS2 (test%L1,%16,%1), xops);
5122 output_asm_insn (AS1 (je,%l10), xops);
5123
e9a25f70 5124 /* Check fourth byte and increment address. */
3f803cd9
SC
5125 output_asm_insn (AS2 (add%L0,%5,%0), xops);
5126 output_asm_insn (AS2 (test%L1,%17,%1), xops);
5127 output_asm_insn (AS1 (jne,%l8), xops);
5128
e9a25f70 5129 /* Now generate fixups when the compare stops within a 4-byte word. */
3f803cd9
SC
5130 output_asm_insn (AS2 (sub%L0,%4,%0), xops);
5131
5132 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[10]));
5133 output_asm_insn (AS1 (inc%L0,%0), xops);
5134
5135 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[11]));
5136 output_asm_insn (AS1 (inc%L0,%0), xops);
5137
5138 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[12]));
5139
e9a25f70 5140 return "";
3f803cd9 5141}
b657fc39
L
5142
5143char *
5144output_fp_conditional_move (which_alternative, operands)
5145 int which_alternative;
5146 rtx operands[];
5147{
5148 int code = GET_CODE (operands[1]);
5149
5150 /* This is very tricky. We have to do it right. For a code segement
5151 like:
5152
5153 int foo;
5154 double bar;
5155 ....
5156 foo = foo - x;
5157 if (foo >= 0)
5158 bar = y;
5159
5160 final_scan_insn () may delete the insn which sets CC. We have to
5161 tell final_scan_insn () if it should be reinserted. When CODE is
5162 GT or LE, we have to check the CC_NO_OVERFLOW bit and return
5163 NULL_PTR to tell final to reinsert the test insn because the
5164 conditional move cannot be handled properly without it. */
5165 if ((code == GT || code == LE)
5166 && (cc_prev_status.flags & CC_NO_OVERFLOW))
5167 return NULL_PTR;
5168
5169 switch (which_alternative)
5170 {
5171 case 0:
5172 /* r <- cond ? arg : r */
5173 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5174 break;
5175
5176 case 1:
5177 /* r <- cond ? r : arg */
5178 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5179 break;
5180
5181 case 2:
5182 /* r <- cond ? r : arg */
5183 output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
5184 output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
5185 break;
5186
5187 default:
5188 abort ();
5189 }
5190
5191 return "";
5192}
5193
5194char *
5195output_int_conditional_move (which_alternative, operands)
5196 int which_alternative;
5197 rtx operands[];
5198{
5199 int code = GET_CODE (operands[1]);
5200 enum machine_mode mode;
5201 rtx xops[4];
5202
5203 /* This is very tricky. We have to do it right. For a code segement
5204 like:
5205
5206 int foo, bar;
5207 ....
5208 foo = foo - x;
5209 if (foo >= 0)
5210 bar = y;
5211
5212 final_scan_insn () may delete the insn which sets CC. We have to
5213 tell final_scan_insn () if it should be reinserted. When CODE is
5214 GT or LE, we have to check the CC_NO_OVERFLOW bit and return
5215 NULL_PTR to tell final to reinsert the test insn because the
5216 conditional move cannot be handled properly without it. */
5217 if ((code == GT || code == LE)
5218 && (cc_prev_status.flags & CC_NO_OVERFLOW))
5219 return NULL_PTR;
5220
5221 mode = GET_MODE (operands [0]);
5222 if (mode == DImode)
5223 {
5224 xops [0] = gen_rtx_SUBREG (SImode, operands [0], 1);
5225 xops [1] = operands [1];
5226 xops [2] = gen_rtx_SUBREG (SImode, operands [2], 1);
5227 xops [3] = gen_rtx_SUBREG (SImode, operands [3], 1);
5228 }
5229
5230 switch (which_alternative)
5231 {
5232 case 0:
5233 /* r <- cond ? arg : r */
5234 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
5235 if (mode == DImode)
5236 output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
5237 break;
5238
5239 case 1:
5240 /* r <- cond ? r : arg */
5241 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
5242 if (mode == DImode)
5243 output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
5244 break;
5245
5246 case 2:
5247 /* rm <- cond ? arg1 : arg2 */
5248 output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
5249 output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
5250 if (mode == DImode)
5251 {
5252 output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
5253 output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
5254 }
5255 break;
5256
5257 default:
5258 abort ();
5259 }
5260
5261 return "";
5262}
This page took 0.959633 seconds and 5 git commands to generate.