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