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