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