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