]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.c
(i386_return_pops_args): Don't need a FUNDECL to check for type
[gcc.git] / gcc / config / i386 / i386.c
1 /* Subroutines for insn-output.c for Intel X86.
2 Copyright (C) 1988, 1992, 1994, 1995 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 "function.h"
37
38 #ifdef EXTRA_CONSTRAINT
39 /* If EXTRA_CONSTRAINT is defined, then the 'S'
40 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
41 asm statements that need 'S' for class SIREG will break. */
42 error EXTRA_CONSTRAINT conflicts with S constraint letter
43 /* The previous line used to be #error, but some compilers barf
44 even if the conditional was untrue. */
45 #endif
46
47 #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
48
49 extern FILE *asm_out_file;
50 extern char *strcat ();
51
52 char *singlemove_string ();
53 char *output_move_const_single ();
54 char *output_fp_cc0_set ();
55
56 char *hi_reg_name[] = HI_REGISTER_NAMES;
57 char *qi_reg_name[] = QI_REGISTER_NAMES;
58 char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
59
60 /* Array of the smallest class containing reg number REGNO, indexed by
61 REGNO. Used by REGNO_REG_CLASS in i386.h. */
62
63 enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
64 {
65 /* ax, dx, cx, bx */
66 AREG, DREG, CREG, BREG,
67 /* si, di, bp, sp */
68 SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
69 /* FP registers */
70 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
71 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
72 /* arg pointer */
73 INDEX_REGS
74 };
75
76 /* Test and compare insns in i386.md store the information needed to
77 generate branch and scc insns here. */
78
79 struct rtx_def *i386_compare_op0 = NULL_RTX;
80 struct rtx_def *i386_compare_op1 = NULL_RTX;
81 struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
82
83 /* Register allocation order */
84 char *i386_reg_alloc_order;
85 static char regs_allocated[FIRST_PSEUDO_REGISTER];
86
87 /* # of registers to use to pass arguments. */
88 char *i386_regparm_string; /* # registers to use to pass args */
89 int i386_regparm; /* i386_regparm_string as a number */
90
91 /* Alignment to use for loops and jumps */
92 char *i386_align_loops_string; /* power of two alignment for loops */
93 char *i386_align_jumps_string; /* power of two alignment for non-loop jumps */
94 char *i386_align_funcs_string; /* power of two alignment for functions */
95
96 int i386_align_loops; /* power of two alignment for loops */
97 int i386_align_jumps; /* power of two alignment for non-loop jumps */
98 int i386_align_funcs; /* power of two alignment for functions */
99
100 \f
101 /* Sometimes certain combinations of command options do not make
102 sense on a particular target machine. You can define a macro
103 `OVERRIDE_OPTIONS' to take account of this. This macro, if
104 defined, is executed once just after all the command options have
105 been parsed.
106
107 Don't use this macro to turn on various extra optimizations for
108 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
109
110 void
111 override_options ()
112 {
113 int ch, i, regno;
114 char *p;
115 int def_align;
116
117 #ifdef SUBTARGET_OVERRIDE_OPTIONS
118 SUBTARGET_OVERRIDE_OPTIONS;
119 #endif
120
121 /* Validate registers in register allocation order */
122 if (i386_reg_alloc_order)
123 {
124 for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
125 {
126 switch (ch)
127 {
128 case 'a': regno = 0; break;
129 case 'd': regno = 1; break;
130 case 'c': regno = 2; break;
131 case 'b': regno = 3; break;
132 case 'S': regno = 4; break;
133 case 'D': regno = 5; break;
134 case 'B': regno = 6; break;
135
136 default: fatal ("Register '%c' is unknown", ch);
137 }
138
139 if (regs_allocated[regno])
140 fatal ("Register '%c' was already specified in the allocation order", ch);
141
142 regs_allocated[regno] = 1;
143 }
144 }
145
146 /* Validate -mregparm= value */
147 if (i386_regparm_string)
148 {
149 i386_regparm = atoi (i386_regparm_string);
150 if (i386_regparm < 0 || i386_regparm > REGPARM_MAX)
151 fatal ("-mregparm=%d is not between 0 and %d", i386_regparm, REGPARM_MAX);
152 }
153
154 def_align = (TARGET_386) ? 2 : 4;
155
156 /* Validate -malign-loops= value, or provide default */
157 if (i386_align_loops_string)
158 {
159 i386_align_loops = atoi (i386_align_loops_string);
160 if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN)
161 fatal ("-malign-loops=%d is not between 0 and %d",
162 i386_align_loops, MAX_CODE_ALIGN);
163 }
164 else
165 i386_align_loops = 2;
166
167 /* Validate -malign-jumps= value, or provide default */
168 if (i386_align_jumps_string)
169 {
170 i386_align_jumps = atoi (i386_align_jumps_string);
171 if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN)
172 fatal ("-malign-jumps=%d is not between 0 and %d",
173 i386_align_jumps, MAX_CODE_ALIGN);
174 }
175 else
176 i386_align_jumps = def_align;
177
178 /* Validate -malign-functions= value, or provide default */
179 if (i386_align_funcs_string)
180 {
181 i386_align_funcs = atoi (i386_align_funcs_string);
182 if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN)
183 fatal ("-malign-functions=%d is not between 0 and %d",
184 i386_align_funcs, MAX_CODE_ALIGN);
185 }
186 else
187 i386_align_funcs = def_align;
188 }
189 \f
190 /* A C statement (sans semicolon) to choose the order in which to
191 allocate hard registers for pseudo-registers local to a basic
192 block.
193
194 Store the desired register order in the array `reg_alloc_order'.
195 Element 0 should be the register to allocate first; element 1, the
196 next register; and so on.
197
198 The macro body should not assume anything about the contents of
199 `reg_alloc_order' before execution of the macro.
200
201 On most machines, it is not necessary to define this macro. */
202
203 void
204 order_regs_for_local_alloc ()
205 {
206 int i, ch, order, regno;
207
208 /* User specified the register allocation order */
209 if (i386_reg_alloc_order)
210 {
211 for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
212 {
213 switch (ch)
214 {
215 case 'a': regno = 0; break;
216 case 'd': regno = 1; break;
217 case 'c': regno = 2; break;
218 case 'b': regno = 3; break;
219 case 'S': regno = 4; break;
220 case 'D': regno = 5; break;
221 case 'B': regno = 6; break;
222 }
223
224 reg_alloc_order[order++] = regno;
225 }
226
227 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
228 {
229 if (!regs_allocated[i])
230 reg_alloc_order[order++] = i;
231 }
232 }
233
234 /* If users did not specify a register allocation order, favor eax
235 normally except if DImode variables are used, in which case
236 favor edx before eax, which seems to cause less spill register
237 not found messages. */
238 else
239 {
240 rtx insn;
241
242 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
243 reg_alloc_order[i] = i;
244
245 if (optimize)
246 {
247 int use_dca = FALSE;
248
249 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
250 {
251 if (GET_CODE (insn) == INSN)
252 {
253 rtx set = NULL_RTX;
254 rtx pattern = PATTERN (insn);
255
256 if (GET_CODE (pattern) == SET)
257 set = pattern;
258
259 else if ((GET_CODE (pattern) == PARALLEL
260 || GET_CODE (pattern) == SEQUENCE)
261 && GET_CODE (XVECEXP (pattern, 0, 0)) == SET)
262 set = XVECEXP (pattern, 0, 0);
263
264 if (set && GET_MODE (SET_SRC (set)) == DImode)
265 {
266 use_dca = TRUE;
267 break;
268 }
269 }
270 }
271
272 if (use_dca)
273 {
274 reg_alloc_order[0] = 1; /* edx */
275 reg_alloc_order[1] = 2; /* ecx */
276 reg_alloc_order[2] = 0; /* eax */
277 }
278 }
279 }
280 }
281
282 \f
283 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
284 attribute for DECL. The attributes in ATTRIBUTES have previously been
285 assigned to DECL. */
286
287 int
288 i386_valid_decl_attribute_p (decl, attributes, identifier, args)
289 tree decl;
290 tree attributes;
291 tree identifier;
292 tree args;
293 {
294 return 0;
295 }
296
297 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
298 attribute for TYPE. The attributes in ATTRIBUTES have previously been
299 assigned to TYPE. */
300
301 int
302 i386_valid_type_attribute_p (type, attributes, identifier, args)
303 tree type;
304 tree attributes;
305 tree identifier;
306 tree args;
307 {
308 if (TREE_CODE (type) != FUNCTION_TYPE
309 && TREE_CODE (type) != FIELD_DECL
310 && TREE_CODE (type) != TYPE_DECL)
311 return 0;
312
313 /* Stdcall attribute says callee is responsible for popping arguments
314 if they are not variable. */
315 if (is_attribute_p ("stdcall", identifier))
316 return (args == NULL_TREE);
317
318 /* Cdecl attribute says the callee is a normal C declaration */
319 if (is_attribute_p ("cdecl", identifier))
320 return (args == NULL_TREE);
321
322 /* Regparm attribute specifies how many integer arguments are to be
323 passed in registers */
324 if (is_attribute_p ("regparm", identifier))
325 {
326 tree cst;
327
328 if (!args || TREE_CODE (args) != TREE_LIST
329 || TREE_CHAIN (args) != NULL_TREE
330 || TREE_VALUE (args) == NULL_TREE)
331 return 0;
332
333 cst = TREE_VALUE (args);
334 if (TREE_CODE (cst) != INTEGER_CST)
335 return 0;
336
337 if (TREE_INT_CST_HIGH (cst) != 0
338 || TREE_INT_CST_LOW (cst) < 0
339 || TREE_INT_CST_LOW (cst) > REGPARM_MAX)
340 return 0;
341
342 return 1;
343 }
344
345 return 0;
346 }
347
348 /* Return 0 if the attributes for two types are incompatible, 1 if they
349 are compatible, and 2 if they are nearly compatible (which causes a
350 warning to be generated). */
351
352 int
353 i386_comp_type_attributes (type1, type2)
354 tree type1;
355 tree type2;
356 {
357 return 1;
358 }
359
360 \f
361 /* Value is the number of bytes of arguments automatically
362 popped when returning from a subroutine call.
363 FUNDECL is the declaration node of the function (as a tree),
364 FUNTYPE is the data type of the function (as a tree),
365 or for a library call it is an identifier node for the subroutine name.
366 SIZE is the number of bytes of arguments passed on the stack.
367
368 On the 80386, the RTD insn may be used to pop them if the number
369 of args is fixed, but if the number is variable then the caller
370 must pop them all. RTD can't be used for library calls now
371 because the library is compiled with the Unix compiler.
372 Use of RTD is a selectable option, since it is incompatible with
373 standard Unix calling sequences. If the option is not selected,
374 the caller must always pop the args.
375
376 The attribute stdcall is equivalent to RTD on a per module basis. */
377
378 int
379 i386_return_pops_args (fundecl, funtype, size)
380 tree fundecl;
381 tree funtype;
382 int size;
383 {
384 int rtd = TARGET_RTD;
385
386 if (TREE_CODE (funtype) == IDENTIFIER_NODE)
387 return 0;
388
389 /* Cdecl functions override -mrtd, and never pop the stack */
390 if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype)))
391 return 0;
392
393 /* Stdcall functions will pop the stack if not variable args */
394 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
395 rtd = 1;
396
397 if (rtd)
398 {
399 if (TYPE_ARG_TYPES (funtype) == NULL_TREE
400 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node))
401 return size;
402
403 if (aggregate_value_p (TREE_TYPE (funtype)))
404 return GET_MODE_SIZE (Pmode);
405 }
406
407 return 0;
408 }
409
410 \f
411 /* Argument support functions. */
412
413 /* Initialize a variable CUM of type CUMULATIVE_ARGS
414 for a call to a function whose data type is FNTYPE.
415 For a library call, FNTYPE is 0. */
416
417 void
418 init_cumulative_args (cum, fntype, libname)
419 CUMULATIVE_ARGS *cum; /* argument info to initialize */
420 tree fntype; /* tree ptr for function decl */
421 rtx libname; /* SYMBOL_REF of library name or 0 */
422 {
423 static CUMULATIVE_ARGS zero_cum;
424 tree param, next_param;
425
426 if (TARGET_DEBUG_ARG)
427 {
428 fprintf (stderr, "\ninit_cumulative_args (");
429 if (fntype)
430 {
431 tree ret_type = TREE_TYPE (fntype);
432 fprintf (stderr, "fntype code = %s, ret code = %s",
433 tree_code_name[ (int)TREE_CODE (fntype) ],
434 tree_code_name[ (int)TREE_CODE (ret_type) ]);
435 }
436 else
437 fprintf (stderr, "no fntype");
438
439 if (libname)
440 fprintf (stderr, ", libname = %s", XSTR (libname, 0));
441 }
442
443 *cum = zero_cum;
444
445 /* Set up the number of registers to use for passing arguments. */
446 cum->nregs = i386_regparm;
447 if (fntype)
448 {
449 tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
450 if (attr)
451 cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
452 }
453
454 /* Determine if this function has variable arguments. This is
455 indicated by the last argument being 'void_type_mode' if there
456 are no variable arguments. If there are variable arguments, then
457 we won't pass anything in registers */
458
459 if (cum->nregs)
460 {
461 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
462 param != (tree)0;
463 param = next_param)
464 {
465 next_param = TREE_CHAIN (param);
466 if (next_param == (tree)0 && TREE_VALUE (param) != void_type_node)
467 cum->nregs = 0;
468 }
469 }
470
471 if (TARGET_DEBUG_ARG)
472 fprintf (stderr, ", nregs=%d )\n", cum->nregs);
473
474 return;
475 }
476
477 /* Update the data in CUM to advance over an argument
478 of mode MODE and data type TYPE.
479 (TYPE is null for libcalls where that information may not be available.) */
480
481 void
482 function_arg_advance (cum, mode, type, named)
483 CUMULATIVE_ARGS *cum; /* current arg information */
484 enum machine_mode mode; /* current arg mode */
485 tree type; /* type of the argument or 0 if lib support */
486 int named; /* whether or not the argument was named */
487 {
488 int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
489 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
490
491 if (TARGET_DEBUG_ARG)
492 fprintf (stderr,
493 "function_adv( size=%d, words=%2d, nregs=%d, mode=%4s, named=%d )\n\n",
494 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
495
496 cum->words += words;
497 cum->nregs -= words;
498 cum->regno += words;
499
500 if (cum->nregs <= 0)
501 {
502 cum->nregs = 0;
503 cum->regno = 0;
504 }
505
506 return;
507 }
508
509 /* Define where to put the arguments to a function.
510 Value is zero to push the argument on the stack,
511 or a hard register in which to store the argument.
512
513 MODE is the argument's machine mode.
514 TYPE is the data type of the argument (as a tree).
515 This is null for libcalls where that information may
516 not be available.
517 CUM is a variable of type CUMULATIVE_ARGS which gives info about
518 the preceding args and about the function being called.
519 NAMED is nonzero if this argument is a named parameter
520 (otherwise it is an extra parameter matching an ellipsis). */
521
522 struct rtx_def *
523 function_arg (cum, mode, type, named)
524 CUMULATIVE_ARGS *cum; /* current arg information */
525 enum machine_mode mode; /* current arg mode */
526 tree type; /* type of the argument or 0 if lib support */
527 int named; /* != 0 for normal args, == 0 for ... args */
528 {
529 rtx ret = NULL_RTX;
530 int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
531 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
532
533 switch (mode)
534 {
535 default: /* for now, pass fp/complex values on the stack */
536 break;
537
538 case BLKmode:
539 case DImode:
540 case SImode:
541 case HImode:
542 case QImode:
543 if (words <= cum->nregs)
544 ret = gen_rtx (REG, mode, cum->regno);
545 break;
546 }
547
548 if (TARGET_DEBUG_ARG)
549 {
550 fprintf (stderr,
551 "function_arg( size=%d, words=%2d, nregs=%d, mode=%4s, named=%d",
552 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
553
554 if (ret)
555 fprintf (stderr, ", reg=%%e%s", reg_names[ REGNO(ret) ]);
556 else
557 fprintf (stderr, ", stack");
558
559 fprintf (stderr, " )\n");
560 }
561
562 return ret;
563 }
564
565 /* For an arg passed partly in registers and partly in memory,
566 this is the number of registers used.
567 For args passed entirely in registers or entirely in memory, zero. */
568
569 int
570 function_arg_partial_nregs (cum, mode, type, named)
571 CUMULATIVE_ARGS *cum; /* current arg information */
572 enum machine_mode mode; /* current arg mode */
573 tree type; /* type of the argument or 0 if lib support */
574 int named; /* != 0 for normal args, == 0 for ... args */
575 {
576 return 0;
577 }
578
579 \f
580 /* Output an insn whose source is a 386 integer register. SRC is the
581 rtx for the register, and TEMPLATE is the op-code template. SRC may
582 be either SImode or DImode.
583
584 The template will be output with operands[0] as SRC, and operands[1]
585 as a pointer to the top of the 386 stack. So a call from floatsidf2
586 would look like this:
587
588 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
589
590 where %z0 corresponds to the caller's operands[1], and is used to
591 emit the proper size suffix.
592
593 ??? Extend this to handle HImode - a 387 can load and store HImode
594 values directly. */
595
596 void
597 output_op_from_reg (src, template)
598 rtx src;
599 char *template;
600 {
601 rtx xops[4];
602 int size = GET_MODE_SIZE (GET_MODE (src));
603
604 xops[0] = src;
605 xops[1] = AT_SP (Pmode);
606 xops[2] = GEN_INT (size);
607 xops[3] = stack_pointer_rtx;
608
609 if (size > UNITS_PER_WORD)
610 {
611 rtx high;
612 if (size > 2 * UNITS_PER_WORD)
613 {
614 high = gen_rtx (REG, SImode, REGNO (src) + 2);
615 output_asm_insn (AS1 (push%L0,%0), &high);
616 }
617 high = gen_rtx (REG, SImode, REGNO (src) + 1);
618 output_asm_insn (AS1 (push%L0,%0), &high);
619 }
620 output_asm_insn (AS1 (push%L0,%0), &src);
621
622 output_asm_insn (template, xops);
623
624 output_asm_insn (AS2 (add%L3,%2,%3), xops);
625 }
626 \f
627 /* Output an insn to pop an value from the 387 top-of-stack to 386
628 register DEST. The 387 register stack is popped if DIES is true. If
629 the mode of DEST is an integer mode, a `fist' integer store is done,
630 otherwise a `fst' float store is done. */
631
632 void
633 output_to_reg (dest, dies)
634 rtx dest;
635 int dies;
636 {
637 rtx xops[4];
638 int size = GET_MODE_SIZE (GET_MODE (dest));
639
640 xops[0] = AT_SP (Pmode);
641 xops[1] = stack_pointer_rtx;
642 xops[2] = GEN_INT (size);
643 xops[3] = dest;
644
645 output_asm_insn (AS2 (sub%L1,%2,%1), xops);
646
647 if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
648 {
649 if (dies)
650 output_asm_insn (AS1 (fistp%z3,%y0), xops);
651 else
652 output_asm_insn (AS1 (fist%z3,%y0), xops);
653 }
654 else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
655 {
656 if (dies)
657 output_asm_insn (AS1 (fstp%z3,%y0), xops);
658 else
659 {
660 if (GET_MODE (dest) == XFmode)
661 {
662 output_asm_insn (AS1 (fstp%z3,%y0), xops);
663 output_asm_insn (AS1 (fld%z3,%y0), xops);
664 }
665 else
666 output_asm_insn (AS1 (fst%z3,%y0), xops);
667 }
668 }
669 else
670 abort ();
671
672 output_asm_insn (AS1 (pop%L0,%0), &dest);
673
674 if (size > UNITS_PER_WORD)
675 {
676 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
677 output_asm_insn (AS1 (pop%L0,%0), &dest);
678 if (size > 2 * UNITS_PER_WORD)
679 {
680 dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
681 output_asm_insn (AS1 (pop%L0,%0), &dest);
682 }
683 }
684 }
685 \f
686 char *
687 singlemove_string (operands)
688 rtx *operands;
689 {
690 rtx x;
691 if (GET_CODE (operands[0]) == MEM
692 && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
693 {
694 if (XEXP (x, 0) != stack_pointer_rtx)
695 abort ();
696 return "push%L1 %1";
697 }
698 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
699 {
700 return output_move_const_single (operands);
701 }
702 else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
703 return AS2 (mov%L0,%1,%0);
704 else if (CONSTANT_P (operands[1]))
705 return AS2 (mov%L0,%1,%0);
706 else
707 {
708 output_asm_insn ("push%L1 %1", operands);
709 return "pop%L0 %0";
710 }
711 }
712 \f
713 /* Return a REG that occurs in ADDR with coefficient 1.
714 ADDR can be effectively incremented by incrementing REG. */
715
716 static rtx
717 find_addr_reg (addr)
718 rtx addr;
719 {
720 while (GET_CODE (addr) == PLUS)
721 {
722 if (GET_CODE (XEXP (addr, 0)) == REG)
723 addr = XEXP (addr, 0);
724 else if (GET_CODE (XEXP (addr, 1)) == REG)
725 addr = XEXP (addr, 1);
726 else if (CONSTANT_P (XEXP (addr, 0)))
727 addr = XEXP (addr, 1);
728 else if (CONSTANT_P (XEXP (addr, 1)))
729 addr = XEXP (addr, 0);
730 else
731 abort ();
732 }
733 if (GET_CODE (addr) == REG)
734 return addr;
735 abort ();
736 }
737
738 \f
739 /* Output an insn to add the constant N to the register X. */
740
741 static void
742 asm_add (n, x)
743 int n;
744 rtx x;
745 {
746 rtx xops[2];
747 xops[0] = x;
748
749 if (n == -1)
750 output_asm_insn (AS1 (dec%L0,%0), xops);
751 else if (n == 1)
752 output_asm_insn (AS1 (inc%L0,%0), xops);
753 else if (n < 0)
754 {
755 xops[1] = GEN_INT (-n);
756 output_asm_insn (AS2 (sub%L0,%1,%0), xops);
757 }
758 else if (n > 0)
759 {
760 xops[1] = GEN_INT (n);
761 output_asm_insn (AS2 (add%L0,%1,%0), xops);
762 }
763 }
764
765 \f
766 /* Output assembler code to perform a doubleword move insn
767 with operands OPERANDS. */
768
769 char *
770 output_move_double (operands)
771 rtx *operands;
772 {
773 enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
774 rtx latehalf[2];
775 rtx middlehalf[2];
776 rtx xops[2];
777 rtx addreg0 = 0, addreg1 = 0;
778 int dest_overlapped_low = 0;
779 int size = GET_MODE_SIZE (GET_MODE (operands[0]));
780
781 middlehalf[0] = 0;
782 middlehalf[1] = 0;
783
784 /* First classify both operands. */
785
786 if (REG_P (operands[0]))
787 optype0 = REGOP;
788 else if (offsettable_memref_p (operands[0]))
789 optype0 = OFFSOP;
790 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
791 optype0 = POPOP;
792 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
793 optype0 = PUSHOP;
794 else if (GET_CODE (operands[0]) == MEM)
795 optype0 = MEMOP;
796 else
797 optype0 = RNDOP;
798
799 if (REG_P (operands[1]))
800 optype1 = REGOP;
801 else if (CONSTANT_P (operands[1]))
802 optype1 = CNSTOP;
803 else if (offsettable_memref_p (operands[1]))
804 optype1 = OFFSOP;
805 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
806 optype1 = POPOP;
807 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
808 optype1 = PUSHOP;
809 else if (GET_CODE (operands[1]) == MEM)
810 optype1 = MEMOP;
811 else
812 optype1 = RNDOP;
813
814 /* Check for the cases that the operand constraints are not
815 supposed to allow to happen. Abort if we get one,
816 because generating code for these cases is painful. */
817
818 if (optype0 == RNDOP || optype1 == RNDOP)
819 abort ();
820
821 /* If one operand is decrementing and one is incrementing
822 decrement the former register explicitly
823 and change that operand into ordinary indexing. */
824
825 if (optype0 == PUSHOP && optype1 == POPOP)
826 {
827 /* ??? Can this ever happen on i386? */
828 operands[0] = XEXP (XEXP (operands[0], 0), 0);
829 asm_add (-size, operands[0]);
830 if (GET_MODE (operands[1]) == XFmode)
831 operands[0] = gen_rtx (MEM, XFmode, operands[0]);
832 else if (GET_MODE (operands[0]) == DFmode)
833 operands[0] = gen_rtx (MEM, DFmode, operands[0]);
834 else
835 operands[0] = gen_rtx (MEM, DImode, operands[0]);
836 optype0 = OFFSOP;
837 }
838
839 if (optype0 == POPOP && optype1 == PUSHOP)
840 {
841 /* ??? Can this ever happen on i386? */
842 operands[1] = XEXP (XEXP (operands[1], 0), 0);
843 asm_add (-size, operands[1]);
844 if (GET_MODE (operands[1]) == XFmode)
845 operands[1] = gen_rtx (MEM, XFmode, operands[1]);
846 else if (GET_MODE (operands[1]) == DFmode)
847 operands[1] = gen_rtx (MEM, DFmode, operands[1]);
848 else
849 operands[1] = gen_rtx (MEM, DImode, operands[1]);
850 optype1 = OFFSOP;
851 }
852
853 /* If an operand is an unoffsettable memory ref, find a register
854 we can increment temporarily to make it refer to the second word. */
855
856 if (optype0 == MEMOP)
857 addreg0 = find_addr_reg (XEXP (operands[0], 0));
858
859 if (optype1 == MEMOP)
860 addreg1 = find_addr_reg (XEXP (operands[1], 0));
861
862 /* Ok, we can do one word at a time.
863 Normally we do the low-numbered word first,
864 but if either operand is autodecrementing then we
865 do the high-numbered word first.
866
867 In either case, set up in LATEHALF the operands to use
868 for the high-numbered word and in some cases alter the
869 operands in OPERANDS to be suitable for the low-numbered word. */
870
871 if (size == 12)
872 {
873 if (optype0 == REGOP)
874 {
875 middlehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
876 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
877 }
878 else if (optype0 == OFFSOP)
879 {
880 middlehalf[0] = adj_offsettable_operand (operands[0], 4);
881 latehalf[0] = adj_offsettable_operand (operands[0], 8);
882 }
883 else
884 {
885 middlehalf[0] = operands[0];
886 latehalf[0] = operands[0];
887 }
888
889 if (optype1 == REGOP)
890 {
891 middlehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
892 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
893 }
894 else if (optype1 == OFFSOP)
895 {
896 middlehalf[1] = adj_offsettable_operand (operands[1], 4);
897 latehalf[1] = adj_offsettable_operand (operands[1], 8);
898 }
899 else if (optype1 == CNSTOP)
900 {
901 if (GET_CODE (operands[1]) == CONST_DOUBLE)
902 {
903 REAL_VALUE_TYPE r; long l[3];
904
905 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
906 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
907 operands[1] = GEN_INT (l[0]);
908 middlehalf[1] = GEN_INT (l[1]);
909 latehalf[1] = GEN_INT (l[2]);
910 }
911 else if (CONSTANT_P (operands[1]))
912 /* No non-CONST_DOUBLE constant should ever appear here. */
913 abort ();
914 }
915 else
916 {
917 middlehalf[1] = operands[1];
918 latehalf[1] = operands[1];
919 }
920 }
921 else /* size is not 12: */
922 {
923 if (optype0 == REGOP)
924 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
925 else if (optype0 == OFFSOP)
926 latehalf[0] = adj_offsettable_operand (operands[0], 4);
927 else
928 latehalf[0] = operands[0];
929
930 if (optype1 == REGOP)
931 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
932 else if (optype1 == OFFSOP)
933 latehalf[1] = adj_offsettable_operand (operands[1], 4);
934 else if (optype1 == CNSTOP)
935 split_double (operands[1], &operands[1], &latehalf[1]);
936 else
937 latehalf[1] = operands[1];
938 }
939
940 /* If insn is effectively movd N (sp),-(sp) then we will do the
941 high word first. We should use the adjusted operand 1
942 (which is N+4 (sp) or N+8 (sp))
943 for the low word and middle word as well,
944 to compensate for the first decrement of sp. */
945 if (optype0 == PUSHOP
946 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
947 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
948 middlehalf[1] = operands[1] = latehalf[1];
949
950 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
951 if the upper part of reg N does not appear in the MEM, arrange to
952 emit the move late-half first. Otherwise, compute the MEM address
953 into the upper part of N and use that as a pointer to the memory
954 operand. */
955 if (optype0 == REGOP
956 && (optype1 == OFFSOP || optype1 == MEMOP))
957 {
958 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
959 && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
960 {
961 /* If both halves of dest are used in the src memory address,
962 compute the address into latehalf of dest. */
963 compadr:
964 xops[0] = latehalf[0];
965 xops[1] = XEXP (operands[1], 0);
966 output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
967 if( GET_MODE (operands[1]) == XFmode )
968 {
969 /* abort (); */
970 operands[1] = gen_rtx (MEM, XFmode, latehalf[0]);
971 middlehalf[1] = adj_offsettable_operand (operands[1], size-8);
972 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
973 }
974 else
975 {
976 operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
977 latehalf[1] = adj_offsettable_operand (operands[1], size-4);
978 }
979 }
980 else if (size == 12
981 && reg_mentioned_p (middlehalf[0], XEXP (operands[1], 0)))
982 {
983 /* Check for two regs used by both source and dest. */
984 if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
985 || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
986 goto compadr;
987
988 /* JRV says this can't happen: */
989 if (addreg0 || addreg1)
990 abort();
991
992 /* Only the middle reg conflicts; simply put it last. */
993 output_asm_insn (singlemove_string (operands), operands);
994 output_asm_insn (singlemove_string (latehalf), latehalf);
995 output_asm_insn (singlemove_string (middlehalf), middlehalf);
996 return "";
997 }
998 else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
999 /* If the low half of dest is mentioned in the source memory
1000 address, the arrange to emit the move late half first. */
1001 dest_overlapped_low = 1;
1002 }
1003
1004 /* If one or both operands autodecrementing,
1005 do the two words, high-numbered first. */
1006
1007 /* Likewise, the first move would clobber the source of the second one,
1008 do them in the other order. This happens only for registers;
1009 such overlap can't happen in memory unless the user explicitly
1010 sets it up, and that is an undefined circumstance. */
1011
1012 /*
1013 if (optype0 == PUSHOP || optype1 == PUSHOP
1014 || (optype0 == REGOP && optype1 == REGOP
1015 && REGNO (operands[0]) == REGNO (latehalf[1]))
1016 || dest_overlapped_low)
1017 */
1018 if (optype0 == PUSHOP || optype1 == PUSHOP
1019 || (optype0 == REGOP && optype1 == REGOP
1020 && ((middlehalf[1] && REGNO (operands[0]) == REGNO (middlehalf[1]))
1021 || REGNO (operands[0]) == REGNO (latehalf[1])))
1022 || dest_overlapped_low)
1023 {
1024 /* Make any unoffsettable addresses point at high-numbered word. */
1025 if (addreg0)
1026 asm_add (size-4, addreg0);
1027 if (addreg1)
1028 asm_add (size-4, addreg1);
1029
1030 /* Do that word. */
1031 output_asm_insn (singlemove_string (latehalf), latehalf);
1032
1033 /* Undo the adds we just did. */
1034 if (addreg0)
1035 asm_add (-4, addreg0);
1036 if (addreg1)
1037 asm_add (-4, addreg1);
1038
1039 if (size == 12)
1040 {
1041 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1042 if (addreg0)
1043 asm_add (-4, addreg0);
1044 if (addreg1)
1045 asm_add (-4, addreg1);
1046 }
1047
1048 /* Do low-numbered word. */
1049 return singlemove_string (operands);
1050 }
1051
1052 /* Normal case: do the two words, low-numbered first. */
1053
1054 output_asm_insn (singlemove_string (operands), operands);
1055
1056 /* Do the middle one of the three words for long double */
1057 if (size == 12)
1058 {
1059 if (addreg0)
1060 asm_add (4, addreg0);
1061 if (addreg1)
1062 asm_add (4, addreg1);
1063
1064 output_asm_insn (singlemove_string (middlehalf), middlehalf);
1065 }
1066
1067 /* Make any unoffsettable addresses point at high-numbered word. */
1068 if (addreg0)
1069 asm_add (4, addreg0);
1070 if (addreg1)
1071 asm_add (4, addreg1);
1072
1073 /* Do that word. */
1074 output_asm_insn (singlemove_string (latehalf), latehalf);
1075
1076 /* Undo the adds we just did. */
1077 if (addreg0)
1078 asm_add (4-size, addreg0);
1079 if (addreg1)
1080 asm_add (4-size, addreg1);
1081
1082 return "";
1083 }
1084
1085 \f
1086 #define MAX_TMPS 2 /* max temporary registers used */
1087
1088 /* Output the appropriate code to move push memory on the stack */
1089
1090 char *
1091 output_move_pushmem (operands, insn, length, tmp_start, n_operands)
1092 rtx operands[];
1093 rtx insn;
1094 int length;
1095 int tmp_start;
1096 int n_operands;
1097 {
1098
1099 struct {
1100 char *load;
1101 char *push;
1102 rtx xops[2];
1103 } tmp_info[MAX_TMPS];
1104
1105 rtx src = operands[1];
1106 int max_tmps = 0;
1107 int offset = 0;
1108 int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src);
1109 int stack_offset = 0;
1110 int i, num_tmps;
1111 rtx xops[1];
1112
1113 if (!offsettable_memref_p (src))
1114 fatal_insn ("Source is not offsettable", insn);
1115
1116 if ((length & 3) != 0)
1117 fatal_insn ("Pushing non-word aligned size", insn);
1118
1119 /* Figure out which temporary registers we have available */
1120 for (i = tmp_start; i < n_operands; i++)
1121 {
1122 if (GET_CODE (operands[i]) == REG)
1123 {
1124 if (reg_overlap_mentioned_p (operands[i], src))
1125 continue;
1126
1127 tmp_info[ max_tmps++ ].xops[1] = operands[i];
1128 if (max_tmps == MAX_TMPS)
1129 break;
1130 }
1131 }
1132
1133 if (max_tmps == 0)
1134 for (offset = length - 4; offset >= 0; offset -= 4)
1135 {
1136 xops[0] = adj_offsettable_operand (src, offset + stack_offset);
1137 output_asm_insn (AS1(push%L0,%0), xops);
1138 if (stack_p)
1139 stack_offset += 4;
1140 }
1141
1142 else
1143 for (offset = length - 4; offset >= 0; )
1144 {
1145 for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++)
1146 {
1147 tmp_info[num_tmps].load = AS2(mov%L0,%0,%1);
1148 tmp_info[num_tmps].push = AS1(push%L0,%1);
1149 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (src, offset + stack_offset);
1150 offset -= 4;
1151 }
1152
1153 for (i = 0; i < num_tmps; i++)
1154 output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1155
1156 for (i = 0; i < num_tmps; i++)
1157 output_asm_insn (tmp_info[i].push, tmp_info[i].xops);
1158
1159 if (stack_p)
1160 stack_offset += 4*num_tmps;
1161 }
1162
1163 return "";
1164 }
1165
1166 \f
1167
1168 /* Output the appropriate code to move data between two memory locations */
1169
1170 char *
1171 output_move_memory (operands, insn, length, tmp_start, n_operands)
1172 rtx operands[];
1173 rtx insn;
1174 int length;
1175 int tmp_start;
1176 int n_operands;
1177 {
1178 struct {
1179 char *load;
1180 char *store;
1181 rtx xops[3];
1182 } tmp_info[MAX_TMPS];
1183
1184 rtx dest = operands[0];
1185 rtx src = operands[1];
1186 rtx qi_tmp = NULL_RTX;
1187 int max_tmps = 0;
1188 int offset = 0;
1189 int i, num_tmps;
1190 rtx xops[3];
1191
1192 if (GET_CODE (dest) == MEM
1193 && GET_CODE (XEXP (dest, 0)) == PRE_INC
1194 && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
1195 return output_move_pushmem (operands, insn, length, tmp_start, n_operands);
1196
1197 if (!offsettable_memref_p (src))
1198 fatal_insn ("Source is not offsettable", insn);
1199
1200 if (!offsettable_memref_p (dest))
1201 fatal_insn ("Destination is not offsettable", insn);
1202
1203 /* Figure out which temporary registers we have available */
1204 for (i = tmp_start; i < n_operands; i++)
1205 {
1206 if (GET_CODE (operands[i]) == REG)
1207 {
1208 if ((length & 1) != 0 && !qi_tmp && QI_REG_P (operands[i]))
1209 qi_tmp = operands[i];
1210
1211 if (reg_overlap_mentioned_p (operands[i], dest))
1212 fatal_insn ("Temporary register overlaps the destination", insn);
1213
1214 if (reg_overlap_mentioned_p (operands[i], src))
1215 fatal_insn ("Temporary register overlaps the source", insn);
1216
1217 tmp_info[ max_tmps++ ].xops[2] = operands[i];
1218 if (max_tmps == MAX_TMPS)
1219 break;
1220 }
1221 }
1222
1223 if (max_tmps == 0)
1224 fatal_insn ("No scratch registers were found to do memory->memory moves", insn);
1225
1226 if ((length & 1) != 0)
1227 {
1228 if (!qi_tmp)
1229 fatal_insn ("No byte register found when moving odd # of bytes.", insn);
1230 }
1231
1232 while (length > 1)
1233 {
1234 for (num_tmps = 0; num_tmps < max_tmps; num_tmps++)
1235 {
1236 if (length >= 4)
1237 {
1238 tmp_info[num_tmps].load = AS2(mov%L0,%1,%2);
1239 tmp_info[num_tmps].store = AS2(mov%L0,%2,%0);
1240 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
1241 tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
1242 offset += 4;
1243 length -= 4;
1244 }
1245 else if (length >= 2)
1246 {
1247 tmp_info[num_tmps].load = AS2(mov%W0,%1,%2);
1248 tmp_info[num_tmps].store = AS2(mov%W0,%2,%0);
1249 tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
1250 tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
1251 offset += 2;
1252 length -= 2;
1253 }
1254 else
1255 break;
1256 }
1257
1258 for (i = 0; i < num_tmps; i++)
1259 output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
1260
1261 for (i = 0; i < num_tmps; i++)
1262 output_asm_insn (tmp_info[i].store, tmp_info[i].xops);
1263 }
1264
1265 if (length == 1)
1266 {
1267 xops[0] = adj_offsettable_operand (dest, offset);
1268 xops[1] = adj_offsettable_operand (src, offset);
1269 xops[2] = qi_tmp;
1270 output_asm_insn (AS2(mov%B0,%1,%2), xops);
1271 output_asm_insn (AS2(mov%B0,%2,%0), xops);
1272 }
1273
1274 return "";
1275 }
1276
1277 \f
1278 int
1279 standard_80387_constant_p (x)
1280 rtx x;
1281 {
1282 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
1283 REAL_VALUE_TYPE d;
1284 jmp_buf handler;
1285 int is0, is1;
1286
1287 if (setjmp (handler))
1288 return 0;
1289
1290 set_float_handler (handler);
1291 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1292 is0 = REAL_VALUES_EQUAL (d, dconst0);
1293 is1 = REAL_VALUES_EQUAL (d, dconst1);
1294 set_float_handler (NULL_PTR);
1295
1296 if (is0)
1297 return 1;
1298
1299 if (is1)
1300 return 2;
1301
1302 /* Note that on the 80387, other constants, such as pi,
1303 are much slower to load as standard constants
1304 than to load from doubles in memory! */
1305 #endif
1306
1307 return 0;
1308 }
1309
1310 char *
1311 output_move_const_single (operands)
1312 rtx *operands;
1313 {
1314 if (FP_REG_P (operands[0]))
1315 {
1316 int conval = standard_80387_constant_p (operands[1]);
1317
1318 if (conval == 1)
1319 return "fldz";
1320
1321 if (conval == 2)
1322 return "fld1";
1323 }
1324 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1325 {
1326 REAL_VALUE_TYPE r; long l;
1327
1328 if (GET_MODE (operands[1]) == XFmode)
1329 abort ();
1330
1331 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1332 REAL_VALUE_TO_TARGET_SINGLE (r, l);
1333 operands[1] = GEN_INT (l);
1334 }
1335 return singlemove_string (operands);
1336 }
1337 \f
1338 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
1339 reference and a constant. */
1340
1341 int
1342 symbolic_operand (op, mode)
1343 register rtx op;
1344 enum machine_mode mode;
1345 {
1346 switch (GET_CODE (op))
1347 {
1348 case SYMBOL_REF:
1349 case LABEL_REF:
1350 return 1;
1351 case CONST:
1352 op = XEXP (op, 0);
1353 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1354 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1355 && GET_CODE (XEXP (op, 1)) == CONST_INT);
1356 default:
1357 return 0;
1358 }
1359 }
1360
1361 /* Test for a valid operand for a call instruction.
1362 Don't allow the arg pointer register or virtual regs
1363 since they may change into reg + const, which the patterns
1364 can't handle yet. */
1365
1366 int
1367 call_insn_operand (op, mode)
1368 rtx op;
1369 enum machine_mode mode;
1370 {
1371 if (GET_CODE (op) == MEM
1372 && ((CONSTANT_ADDRESS_P (XEXP (op, 0))
1373 /* This makes a difference for PIC. */
1374 && general_operand (XEXP (op, 0), Pmode))
1375 || (GET_CODE (XEXP (op, 0)) == REG
1376 && XEXP (op, 0) != arg_pointer_rtx
1377 && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1378 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1379 return 1;
1380 return 0;
1381 }
1382
1383 /* Like call_insn_operand but allow (mem (symbol_ref ...))
1384 even if pic. */
1385
1386 int
1387 expander_call_insn_operand (op, mode)
1388 rtx op;
1389 enum machine_mode mode;
1390 {
1391 if (GET_CODE (op) == MEM
1392 && (CONSTANT_ADDRESS_P (XEXP (op, 0))
1393 || (GET_CODE (XEXP (op, 0)) == REG
1394 && XEXP (op, 0) != arg_pointer_rtx
1395 && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
1396 && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
1397 return 1;
1398 return 0;
1399 }
1400
1401 /* Return 1 if OP is a comparison operator that can use the condition code
1402 generated by an arithmetic operation. */
1403
1404 int
1405 arithmetic_comparison_operator (op, mode)
1406 register rtx op;
1407 enum machine_mode mode;
1408 {
1409 enum rtx_code code;
1410
1411 if (mode != VOIDmode && mode != GET_MODE (op))
1412 return 0;
1413 code = GET_CODE (op);
1414 if (GET_RTX_CLASS (code) != '<')
1415 return 0;
1416
1417 return (code != GT && code != LE);
1418 }
1419 \f
1420 /* Returns 1 if OP contains a symbol reference */
1421
1422 int
1423 symbolic_reference_mentioned_p (op)
1424 rtx op;
1425 {
1426 register char *fmt;
1427 register int i;
1428
1429 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
1430 return 1;
1431
1432 fmt = GET_RTX_FORMAT (GET_CODE (op));
1433 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
1434 {
1435 if (fmt[i] == 'E')
1436 {
1437 register int j;
1438
1439 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
1440 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
1441 return 1;
1442 }
1443 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
1444 return 1;
1445 }
1446
1447 return 0;
1448 }
1449 \f
1450 /* This function generates the assembly code for function entry.
1451 FILE is an stdio stream to output the code to.
1452 SIZE is an int: how many units of temporary storage to allocate. */
1453
1454 void
1455 function_prologue (file, size)
1456 FILE *file;
1457 int size;
1458 {
1459 register int regno;
1460 int limit;
1461 rtx xops[4];
1462 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1463 || current_function_uses_const_pool);
1464
1465 xops[0] = stack_pointer_rtx;
1466 xops[1] = frame_pointer_rtx;
1467 xops[2] = GEN_INT (size);
1468 if (frame_pointer_needed)
1469 {
1470 output_asm_insn ("push%L1 %1", xops);
1471 output_asm_insn (AS2 (mov%L0,%0,%1), xops);
1472 }
1473
1474 if (size)
1475 output_asm_insn (AS2 (sub%L0,%2,%0), xops);
1476
1477 /* Note If use enter it is NOT reversed args.
1478 This one is not reversed from intel!!
1479 I think enter is slower. Also sdb doesn't like it.
1480 But if you want it the code is:
1481 {
1482 xops[3] = const0_rtx;
1483 output_asm_insn ("enter %2,%3", xops);
1484 }
1485 */
1486 limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1487 for (regno = limit - 1; regno >= 0; regno--)
1488 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1489 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1490 {
1491 xops[0] = gen_rtx (REG, SImode, regno);
1492 output_asm_insn ("push%L0 %0", xops);
1493 }
1494
1495 if (pic_reg_used)
1496 {
1497 xops[0] = pic_offset_table_rtx;
1498 xops[1] = (rtx) gen_label_rtx ();
1499
1500 output_asm_insn (AS1 (call,%P1), xops);
1501 ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
1502 output_asm_insn (AS1 (pop%L0,%0), xops);
1503 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
1504 }
1505 }
1506
1507 /* Return 1 if it is appropriate to emit `ret' instructions in the
1508 body of a function. Do this only if the epilogue is simple, needing a
1509 couple of insns. Prior to reloading, we can't tell how many registers
1510 must be saved, so return 0 then.
1511
1512 If NON_SAVING_SETJMP is defined and true, then it is not possible
1513 for the epilogue to be simple, so return 0. This is a special case
1514 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
1515 final, but jump_optimize may need to know sooner if a `return' is OK. */
1516
1517 int
1518 simple_386_epilogue ()
1519 {
1520 int regno;
1521 int nregs = 0;
1522 int reglimit = (frame_pointer_needed
1523 ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
1524 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1525 || current_function_uses_const_pool);
1526
1527 #ifdef NON_SAVING_SETJMP
1528 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
1529 return 0;
1530 #endif
1531
1532 if (! reload_completed)
1533 return 0;
1534
1535 for (regno = reglimit - 1; regno >= 0; regno--)
1536 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1537 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1538 nregs++;
1539
1540 return nregs == 0 || ! frame_pointer_needed;
1541 }
1542
1543 \f
1544 /* This function generates the assembly code for function exit.
1545 FILE is an stdio stream to output the code to.
1546 SIZE is an int: how many units of temporary storage to deallocate. */
1547
1548 void
1549 function_epilogue (file, size)
1550 FILE *file;
1551 int size;
1552 {
1553 register int regno;
1554 register int nregs, limit;
1555 int offset;
1556 rtx xops[3];
1557 int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
1558 || current_function_uses_const_pool);
1559
1560 /* Compute the number of registers to pop */
1561
1562 limit = (frame_pointer_needed
1563 ? FRAME_POINTER_REGNUM
1564 : STACK_POINTER_REGNUM);
1565
1566 nregs = 0;
1567
1568 for (regno = limit - 1; regno >= 0; regno--)
1569 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1570 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1571 nregs++;
1572
1573 /* sp is often unreliable so we must go off the frame pointer,
1574 */
1575
1576 /* In reality, we may not care if sp is unreliable, because we can
1577 restore the register relative to the frame pointer. In theory,
1578 since each move is the same speed as a pop, and we don't need the
1579 leal, this is faster. For now restore multiple registers the old
1580 way. */
1581
1582 offset = -size - (nregs * UNITS_PER_WORD);
1583
1584 xops[2] = stack_pointer_rtx;
1585
1586 if (nregs > 1 || ! frame_pointer_needed)
1587 {
1588 if (frame_pointer_needed)
1589 {
1590 xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
1591 output_asm_insn (AS2 (lea%L2,%0,%2), xops);
1592 }
1593
1594 for (regno = 0; regno < limit; regno++)
1595 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1596 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1597 {
1598 xops[0] = gen_rtx (REG, SImode, regno);
1599 output_asm_insn ("pop%L0 %0", xops);
1600 }
1601 }
1602 else
1603 for (regno = 0; regno < limit; regno++)
1604 if ((regs_ever_live[regno] && ! call_used_regs[regno])
1605 || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
1606 {
1607 xops[0] = gen_rtx (REG, SImode, regno);
1608 xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
1609 output_asm_insn (AS2 (mov%L0,%1,%0), xops);
1610 offset += 4;
1611 }
1612
1613 if (frame_pointer_needed)
1614 {
1615 /* On i486, mov & pop is faster than "leave". */
1616
1617 if (!TARGET_386)
1618 {
1619 xops[0] = frame_pointer_rtx;
1620 output_asm_insn (AS2 (mov%L2,%0,%2), xops);
1621 output_asm_insn ("pop%L0 %0", xops);
1622 }
1623 else
1624 output_asm_insn ("leave", xops);
1625 }
1626 else if (size)
1627 {
1628 /* If there is no frame pointer, we must still release the frame. */
1629
1630 xops[0] = GEN_INT (size);
1631 output_asm_insn (AS2 (add%L2,%0,%2), xops);
1632 }
1633
1634 if (current_function_pops_args && current_function_args_size)
1635 {
1636 xops[1] = GEN_INT (current_function_pops_args);
1637
1638 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
1639 asked to pop more, pop return address, do explicit add, and jump
1640 indirectly to the caller. */
1641
1642 if (current_function_pops_args >= 32768)
1643 {
1644 /* ??? Which register to use here? */
1645 xops[0] = gen_rtx (REG, SImode, 2);
1646 output_asm_insn ("pop%L0 %0", xops);
1647 output_asm_insn (AS2 (add%L2,%1,%2), xops);
1648 output_asm_insn ("jmp %*%0", xops);
1649 }
1650 else
1651 output_asm_insn ("ret %1", xops);
1652 }
1653 else
1654 output_asm_insn ("ret", xops);
1655 }
1656
1657 \f
1658 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
1659 that is a valid memory address for an instruction.
1660 The MODE argument is the machine mode for the MEM expression
1661 that wants to use this address.
1662
1663 On x86, legitimate addresses are:
1664 base movl (base),reg
1665 displacement movl disp,reg
1666 base + displacement movl disp(base),reg
1667 index + base movl (base,index),reg
1668 (index + base) + displacement movl disp(base,index),reg
1669 index*scale movl (,index,scale),reg
1670 index*scale + disp movl disp(,index,scale),reg
1671 index*scale + base movl (base,index,scale),reg
1672 (index*scale + base) + disp movl disp(base,index,scale),reg
1673
1674 In each case, scale can be 1, 2, 4, 8. */
1675
1676 /* This is exactly the same as print_operand_addr, except that
1677 it recognizes addresses instead of printing them.
1678
1679 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
1680 convert common non-canonical forms to canonical form so that they will
1681 be recognized. */
1682
1683 #define ADDR_INVALID(msg,insn) \
1684 do { \
1685 if (TARGET_DEBUG_ADDR) \
1686 { \
1687 fprintf (stderr, msg); \
1688 debug_rtx (insn); \
1689 } \
1690 } while (0)
1691
1692 int
1693 legitimate_address_p (mode, addr, strict)
1694 enum machine_mode mode;
1695 register rtx addr;
1696 int strict;
1697 {
1698 rtx base = NULL_RTX;
1699 rtx indx = NULL_RTX;
1700 rtx scale = NULL_RTX;
1701 rtx disp = NULL_RTX;
1702
1703 if (TARGET_DEBUG_ADDR)
1704 {
1705 fprintf (stderr,
1706 "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
1707 GET_MODE_NAME (mode), strict);
1708
1709 debug_rtx (addr);
1710 }
1711
1712 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
1713 base = addr; /* base reg */
1714
1715 else if (GET_CODE (addr) == PLUS)
1716 {
1717 rtx op0 = XEXP (addr, 0);
1718 rtx op1 = XEXP (addr, 1);
1719 enum rtx_code code0 = GET_CODE (op0);
1720 enum rtx_code code1 = GET_CODE (op1);
1721
1722 if (code0 == REG || code0 == SUBREG)
1723 {
1724 if (code1 == REG || code1 == SUBREG)
1725 {
1726 indx = op0; /* index + base */
1727 base = op1;
1728 }
1729
1730 else
1731 {
1732 base = op0; /* base + displacement */
1733 disp = op1;
1734 }
1735 }
1736
1737 else if (code0 == MULT)
1738 {
1739 indx = XEXP (op0, 0);
1740 scale = XEXP (op0, 1);
1741
1742 if (code1 == REG || code1 == SUBREG)
1743 base = op1; /* index*scale + base */
1744
1745 else
1746 disp = op1; /* index*scale + disp */
1747 }
1748
1749 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
1750 {
1751 indx = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
1752 scale = XEXP (XEXP (op0, 0), 1);
1753 base = XEXP (op0, 1);
1754 disp = op1;
1755 }
1756
1757 else if (code0 == PLUS)
1758 {
1759 indx = XEXP (op0, 0); /* index + base + disp */
1760 base = XEXP (op0, 1);
1761 disp = op1;
1762 }
1763
1764 else
1765 {
1766 ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
1767 return FALSE;
1768 }
1769 }
1770
1771 else if (GET_CODE (addr) == MULT)
1772 {
1773 indx = XEXP (addr, 0); /* index*scale */
1774 scale = XEXP (addr, 1);
1775 }
1776
1777 else
1778 disp = addr; /* displacement */
1779
1780 /* Allow arg pointer and stack pointer as index if there is not scaling */
1781 if (base && indx && !scale
1782 && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
1783 {
1784 rtx tmp = base;
1785 base = indx;
1786 indx = tmp;
1787 }
1788
1789 /* Validate base register */
1790 /* Don't allow SUBREG's here, it can lead to spill failures when the base
1791 is one word out of a two word structure, which is represented internally
1792 as a DImode int. */
1793 if (base)
1794 {
1795 if (GET_CODE (base) != REG)
1796 {
1797 ADDR_INVALID ("Base is not a register.\n", base);
1798 return FALSE;
1799 }
1800
1801 if ((strict && !REG_OK_FOR_BASE_STRICT_P (base))
1802 || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
1803 {
1804 ADDR_INVALID ("Base is not valid.\n", base);
1805 return FALSE;
1806 }
1807 }
1808
1809 /* Validate index register */
1810 /* Don't allow SUBREG's here, it can lead to spill failures when the index
1811 is one word out of a two word structure, which is represented internally
1812 as a DImode int. */
1813 if (indx)
1814 {
1815 if (GET_CODE (indx) != REG)
1816 {
1817 ADDR_INVALID ("Index is not a register.\n", indx);
1818 return FALSE;
1819 }
1820
1821 if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
1822 || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
1823 {
1824 ADDR_INVALID ("Index is not valid.\n", indx);
1825 return FALSE;
1826 }
1827 }
1828 else if (scale)
1829 abort (); /* scale w/o index invalid */
1830
1831 /* Validate scale factor */
1832 if (scale)
1833 {
1834 HOST_WIDE_INT value;
1835
1836 if (GET_CODE (scale) != CONST_INT)
1837 {
1838 ADDR_INVALID ("Scale is not valid.\n", scale);
1839 return FALSE;
1840 }
1841
1842 value = INTVAL (scale);
1843 if (value != 1 && value != 2 && value != 4 && value != 8)
1844 {
1845 ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
1846 return FALSE;
1847 }
1848 }
1849
1850 /* Validate displacement */
1851 if (disp)
1852 {
1853 if (!CONSTANT_ADDRESS_P (disp))
1854 {
1855 ADDR_INVALID ("Displacement is not valid.\n", disp);
1856 return FALSE;
1857 }
1858
1859 if (GET_CODE (disp) == CONST_DOUBLE)
1860 {
1861 ADDR_INVALID ("Displacement is a const_double.\n", disp);
1862 return FALSE;
1863 }
1864
1865 if (flag_pic && SYMBOLIC_CONST (disp) && base != pic_offset_table_rtx
1866 && (indx != pic_offset_table_rtx || scale != NULL_RTX))
1867 {
1868 ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
1869 return FALSE;
1870 }
1871
1872 if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
1873 && (base != NULL_RTX || indx != NULL_RTX))
1874 {
1875 ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
1876 return FALSE;
1877 }
1878 }
1879
1880 if (TARGET_DEBUG_ADDR)
1881 fprintf (stderr, "Address is valid.\n");
1882
1883 /* Everything looks valid, return true */
1884 return TRUE;
1885 }
1886
1887 \f
1888 /* Return a legitimate reference for ORIG (an address) using the
1889 register REG. If REG is 0, a new pseudo is generated.
1890
1891 There are three types of references that must be handled:
1892
1893 1. Global data references must load the address from the GOT, via
1894 the PIC reg. An insn is emitted to do this load, and the reg is
1895 returned.
1896
1897 2. Static data references must compute the address as an offset
1898 from the GOT, whose base is in the PIC reg. An insn is emitted to
1899 compute the address into a reg, and the reg is returned. Static
1900 data objects have SYMBOL_REF_FLAG set to differentiate them from
1901 global data objects.
1902
1903 3. Constant pool addresses must be handled special. They are
1904 considered legitimate addresses, but only if not used with regs.
1905 When printed, the output routines know to print the reference with the
1906 PIC reg, even though the PIC reg doesn't appear in the RTL.
1907
1908 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
1909 reg also appears in the address (except for constant pool references,
1910 noted above).
1911
1912 "switch" statements also require special handling when generating
1913 PIC code. See comments by the `casesi' insn in i386.md for details. */
1914
1915 rtx
1916 legitimize_pic_address (orig, reg)
1917 rtx orig;
1918 rtx reg;
1919 {
1920 rtx addr = orig;
1921 rtx new = orig;
1922
1923 if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
1924 {
1925 if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
1926 reg = new = orig;
1927 else
1928 {
1929 if (reg == 0)
1930 reg = gen_reg_rtx (Pmode);
1931
1932 if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
1933 || GET_CODE (addr) == LABEL_REF)
1934 new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
1935 else
1936 new = gen_rtx (MEM, Pmode,
1937 gen_rtx (PLUS, Pmode,
1938 pic_offset_table_rtx, orig));
1939
1940 emit_move_insn (reg, new);
1941 }
1942 current_function_uses_pic_offset_table = 1;
1943 return reg;
1944 }
1945 else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1946 {
1947 rtx base;
1948
1949 if (GET_CODE (addr) == CONST)
1950 {
1951 addr = XEXP (addr, 0);
1952 if (GET_CODE (addr) != PLUS)
1953 abort ();
1954 }
1955
1956 if (XEXP (addr, 0) == pic_offset_table_rtx)
1957 return orig;
1958
1959 if (reg == 0)
1960 reg = gen_reg_rtx (Pmode);
1961
1962 base = legitimize_pic_address (XEXP (addr, 0), reg);
1963 addr = legitimize_pic_address (XEXP (addr, 1),
1964 base == reg ? NULL_RTX : reg);
1965
1966 if (GET_CODE (addr) == CONST_INT)
1967 return plus_constant (base, INTVAL (addr));
1968
1969 if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
1970 {
1971 base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
1972 addr = XEXP (addr, 1);
1973 }
1974 return gen_rtx (PLUS, Pmode, base, addr);
1975 }
1976 return new;
1977 }
1978 \f
1979
1980 /* Emit insns to move operands[1] into operands[0]. */
1981
1982 void
1983 emit_pic_move (operands, mode)
1984 rtx *operands;
1985 enum machine_mode mode;
1986 {
1987 rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
1988
1989 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
1990 operands[1] = (rtx) force_reg (SImode, operands[1]);
1991 else
1992 operands[1] = legitimize_pic_address (operands[1], temp);
1993 }
1994
1995 \f
1996 /* Try machine-dependent ways of modifying an illegitimate address
1997 to be legitimate. If we find one, return the new, valid address.
1998 This macro is used in only one place: `memory_address' in explow.c.
1999
2000 OLDX is the address as it was before break_out_memory_refs was called.
2001 In some cases it is useful to look at this to decide what needs to be done.
2002
2003 MODE and WIN are passed so that this macro can use
2004 GO_IF_LEGITIMATE_ADDRESS.
2005
2006 It is always safe for this macro to do nothing. It exists to recognize
2007 opportunities to optimize the output.
2008
2009 For the 80386, we handle X+REG by loading X into a register R and
2010 using R+REG. R will go in a general reg and indexing will be used.
2011 However, if REG is a broken-out memory address or multiplication,
2012 nothing needs to be done because REG can certainly go in a general reg.
2013
2014 When -fpic is used, special handling is needed for symbolic references.
2015 See comments by legitimize_pic_address in i386.c for details. */
2016
2017 rtx
2018 legitimize_address (x, oldx, mode)
2019 register rtx x;
2020 register rtx oldx;
2021 enum machine_mode mode;
2022 {
2023 int changed = 0;
2024 unsigned log;
2025
2026 if (TARGET_DEBUG_ADDR)
2027 {
2028 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
2029 debug_rtx (x);
2030 }
2031
2032 if (flag_pic && SYMBOLIC_CONST (x))
2033 return legitimize_pic_address (x, 0);
2034
2035 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2036 if (GET_CODE (x) == ASHIFT
2037 && GET_CODE (XEXP (x, 1)) == CONST_INT
2038 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
2039 {
2040 changed = 1;
2041 x = gen_rtx (MULT, Pmode,
2042 force_reg (Pmode, XEXP (x, 0)),
2043 GEN_INT (1 << log));
2044 }
2045
2046 if (GET_CODE (x) == PLUS)
2047 {
2048 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
2049 if (GET_CODE (XEXP (x, 0)) == ASHIFT
2050 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2051 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
2052 {
2053 changed = 1;
2054 XEXP (x, 0) = gen_rtx (MULT, Pmode,
2055 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
2056 GEN_INT (1 << log));
2057 }
2058
2059 if (GET_CODE (XEXP (x, 1)) == ASHIFT
2060 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2061 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
2062 {
2063 changed = 1;
2064 XEXP (x, 1) = gen_rtx (MULT, Pmode,
2065 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
2066 GEN_INT (1 << log));
2067 }
2068
2069 /* Put multiply first if it isn't already */
2070 if (GET_CODE (XEXP (x, 1)) == MULT)
2071 {
2072 rtx tmp = XEXP (x, 0);
2073 XEXP (x, 0) = XEXP (x, 1);
2074 XEXP (x, 1) = tmp;
2075 changed = 1;
2076 }
2077
2078 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
2079 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
2080 created by virtual register instantiation, register elimination, and
2081 similar optimizations. */
2082 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
2083 {
2084 changed = 1;
2085 x = gen_rtx (PLUS, Pmode,
2086 gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
2087 XEXP (XEXP (x, 1), 1));
2088 }
2089
2090 /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
2091 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
2092 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
2093 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2094 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
2095 && CONSTANT_P (XEXP (x, 1)))
2096 {
2097 rtx constant, other;
2098
2099 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2100 {
2101 constant = XEXP (x, 1);
2102 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
2103 }
2104 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
2105 {
2106 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
2107 other = XEXP (x, 1);
2108 }
2109 else
2110 constant = 0;
2111
2112 if (constant)
2113 {
2114 changed = 1;
2115 x = gen_rtx (PLUS, Pmode,
2116 gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
2117 XEXP (XEXP (XEXP (x, 0), 1), 0)),
2118 plus_constant (other, INTVAL (constant)));
2119 }
2120 }
2121
2122 if (changed && legitimate_address_p (mode, x, FALSE))
2123 return x;
2124
2125 if (GET_CODE (XEXP (x, 0)) == MULT)
2126 {
2127 changed = 1;
2128 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
2129 }
2130
2131 if (GET_CODE (XEXP (x, 1)) == MULT)
2132 {
2133 changed = 1;
2134 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
2135 }
2136
2137 if (changed
2138 && GET_CODE (XEXP (x, 1)) == REG
2139 && GET_CODE (XEXP (x, 0)) == REG)
2140 return x;
2141
2142 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
2143 {
2144 changed = 1;
2145 x = legitimize_pic_address (x, 0);
2146 }
2147
2148 if (changed && legitimate_address_p (mode, x, FALSE))
2149 return x;
2150
2151 if (GET_CODE (XEXP (x, 0)) == REG)
2152 {
2153 register rtx temp = gen_reg_rtx (Pmode);
2154 register rtx val = force_operand (XEXP (x, 1), temp);
2155 if (val != temp)
2156 emit_move_insn (temp, val);
2157
2158 XEXP (x, 1) = temp;
2159 return x;
2160 }
2161
2162 else if (GET_CODE (XEXP (x, 1)) == REG)
2163 {
2164 register rtx temp = gen_reg_rtx (Pmode);
2165 register rtx val = force_operand (XEXP (x, 0), temp);
2166 if (val != temp)
2167 emit_move_insn (temp, val);
2168
2169 XEXP (x, 0) = temp;
2170 return x;
2171 }
2172 }
2173
2174 return x;
2175 }
2176
2177 \f
2178 /* Print an integer constant expression in assembler syntax. Addition
2179 and subtraction are the only arithmetic that may appear in these
2180 expressions. FILE is the stdio stream to write to, X is the rtx, and
2181 CODE is the operand print code from the output string. */
2182
2183 static void
2184 output_pic_addr_const (file, x, code)
2185 FILE *file;
2186 rtx x;
2187 int code;
2188 {
2189 char buf[256];
2190
2191 switch (GET_CODE (x))
2192 {
2193 case PC:
2194 if (flag_pic)
2195 putc ('.', file);
2196 else
2197 abort ();
2198 break;
2199
2200 case SYMBOL_REF:
2201 case LABEL_REF:
2202 if (GET_CODE (x) == SYMBOL_REF)
2203 assemble_name (file, XSTR (x, 0));
2204 else
2205 {
2206 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
2207 CODE_LABEL_NUMBER (XEXP (x, 0)));
2208 assemble_name (asm_out_file, buf);
2209 }
2210
2211 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
2212 fprintf (file, "@GOTOFF(%%ebx)");
2213 else if (code == 'P')
2214 fprintf (file, "@PLT");
2215 else if (GET_CODE (x) == LABEL_REF)
2216 fprintf (file, "@GOTOFF");
2217 else if (! SYMBOL_REF_FLAG (x))
2218 fprintf (file, "@GOT");
2219 else
2220 fprintf (file, "@GOTOFF");
2221
2222 break;
2223
2224 case CODE_LABEL:
2225 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
2226 assemble_name (asm_out_file, buf);
2227 break;
2228
2229 case CONST_INT:
2230 fprintf (file, "%d", INTVAL (x));
2231 break;
2232
2233 case CONST:
2234 /* This used to output parentheses around the expression,
2235 but that does not work on the 386 (either ATT or BSD assembler). */
2236 output_pic_addr_const (file, XEXP (x, 0), code);
2237 break;
2238
2239 case CONST_DOUBLE:
2240 if (GET_MODE (x) == VOIDmode)
2241 {
2242 /* We can use %d if the number is <32 bits and positive. */
2243 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
2244 fprintf (file, "0x%x%08x",
2245 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
2246 else
2247 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
2248 }
2249 else
2250 /* We can't handle floating point constants;
2251 PRINT_OPERAND must handle them. */
2252 output_operand_lossage ("floating constant misused");
2253 break;
2254
2255 case PLUS:
2256 /* Some assemblers need integer constants to appear last (eg masm). */
2257 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
2258 {
2259 output_pic_addr_const (file, XEXP (x, 1), code);
2260 if (INTVAL (XEXP (x, 0)) >= 0)
2261 fprintf (file, "+");
2262 output_pic_addr_const (file, XEXP (x, 0), code);
2263 }
2264 else
2265 {
2266 output_pic_addr_const (file, XEXP (x, 0), code);
2267 if (INTVAL (XEXP (x, 1)) >= 0)
2268 fprintf (file, "+");
2269 output_pic_addr_const (file, XEXP (x, 1), code);
2270 }
2271 break;
2272
2273 case MINUS:
2274 output_pic_addr_const (file, XEXP (x, 0), code);
2275 fprintf (file, "-");
2276 output_pic_addr_const (file, XEXP (x, 1), code);
2277 break;
2278
2279 default:
2280 output_operand_lossage ("invalid expression as operand");
2281 }
2282 }
2283 \f
2284 /* Meaning of CODE:
2285 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
2286 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
2287 R -- print the prefix for register names.
2288 z -- print the opcode suffix for the size of the current operand.
2289 * -- print a star (in certain assembler syntax)
2290 w -- print the operand as if it's a "word" (HImode) even if it isn't.
2291 c -- don't print special prefixes before constant operands.
2292 J -- print the appropriate jump operand.
2293 */
2294
2295 void
2296 print_operand (file, x, code)
2297 FILE *file;
2298 rtx x;
2299 int code;
2300 {
2301 if (code)
2302 {
2303 switch (code)
2304 {
2305 case '*':
2306 if (USE_STAR)
2307 putc ('*', file);
2308 return;
2309
2310 case 'L':
2311 PUT_OP_SIZE (code, 'l', file);
2312 return;
2313
2314 case 'W':
2315 PUT_OP_SIZE (code, 'w', file);
2316 return;
2317
2318 case 'B':
2319 PUT_OP_SIZE (code, 'b', file);
2320 return;
2321
2322 case 'Q':
2323 PUT_OP_SIZE (code, 'l', file);
2324 return;
2325
2326 case 'S':
2327 PUT_OP_SIZE (code, 's', file);
2328 return;
2329
2330 case 'T':
2331 PUT_OP_SIZE (code, 't', file);
2332 return;
2333
2334 case 'z':
2335 /* 387 opcodes don't get size suffixes if the operands are
2336 registers. */
2337
2338 if (STACK_REG_P (x))
2339 return;
2340
2341 /* this is the size of op from size of operand */
2342 switch (GET_MODE_SIZE (GET_MODE (x)))
2343 {
2344 case 1:
2345 PUT_OP_SIZE ('B', 'b', file);
2346 return;
2347
2348 case 2:
2349 PUT_OP_SIZE ('W', 'w', file);
2350 return;
2351
2352 case 4:
2353 if (GET_MODE (x) == SFmode)
2354 {
2355 PUT_OP_SIZE ('S', 's', file);
2356 return;
2357 }
2358 else
2359 PUT_OP_SIZE ('L', 'l', file);
2360 return;
2361
2362 case 12:
2363 PUT_OP_SIZE ('T', 't', file);
2364 return;
2365
2366 case 8:
2367 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2368 {
2369 #ifdef GAS_MNEMONICS
2370 PUT_OP_SIZE ('Q', 'q', file);
2371 return;
2372 #else
2373 PUT_OP_SIZE ('Q', 'l', file); /* Fall through */
2374 #endif
2375 }
2376
2377 PUT_OP_SIZE ('Q', 'l', file);
2378 return;
2379 }
2380
2381 case 'b':
2382 case 'w':
2383 case 'k':
2384 case 'h':
2385 case 'y':
2386 case 'P':
2387 break;
2388
2389 case 'J':
2390 switch (GET_CODE (x))
2391 {
2392 /* These conditions are appropriate for testing the result
2393 of an arithmetic operation, not for a compare operation.
2394 Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
2395 CC_Z_IN_NOT_C false and not floating point. */
2396 case NE: fputs ("jne", file); return;
2397 case EQ: fputs ("je", file); return;
2398 case GE: fputs ("jns", file); return;
2399 case LT: fputs ("js", file); return;
2400 case GEU: fputs ("jmp", file); return;
2401 case GTU: fputs ("jne", file); return;
2402 case LEU: fputs ("je", file); return;
2403 case LTU: fputs ("#branch never", file); return;
2404
2405 /* no matching branches for GT nor LE */
2406 }
2407 abort ();
2408
2409 default:
2410 {
2411 char str[50];
2412
2413 sprintf (str, "invalid operand code `%c'", code);
2414 output_operand_lossage (str);
2415 }
2416 }
2417 }
2418 if (GET_CODE (x) == REG)
2419 {
2420 PRINT_REG (x, code, file);
2421 }
2422 else if (GET_CODE (x) == MEM)
2423 {
2424 PRINT_PTR (x, file);
2425 if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
2426 {
2427 if (flag_pic)
2428 output_pic_addr_const (file, XEXP (x, 0), code);
2429 else
2430 output_addr_const (file, XEXP (x, 0));
2431 }
2432 else
2433 output_address (XEXP (x, 0));
2434 }
2435 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
2436 {
2437 REAL_VALUE_TYPE r; long l;
2438 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2439 REAL_VALUE_TO_TARGET_SINGLE (r, l);
2440 PRINT_IMMED_PREFIX (file);
2441 fprintf (file, "0x%x", l);
2442 }
2443 /* These float cases don't actually occur as immediate operands. */
2444 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
2445 {
2446 REAL_VALUE_TYPE r; char dstr[30];
2447 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2448 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2449 fprintf (file, "%s", dstr);
2450 }
2451 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
2452 {
2453 REAL_VALUE_TYPE r; char dstr[30];
2454 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2455 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
2456 fprintf (file, "%s", dstr);
2457 }
2458 else
2459 {
2460 if (code != 'P')
2461 {
2462 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
2463 PRINT_IMMED_PREFIX (file);
2464 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
2465 || GET_CODE (x) == LABEL_REF)
2466 PRINT_OFFSET_PREFIX (file);
2467 }
2468 if (flag_pic)
2469 output_pic_addr_const (file, x, code);
2470 else
2471 output_addr_const (file, x);
2472 }
2473 }
2474 \f
2475 /* Print a memory operand whose address is ADDR. */
2476
2477 void
2478 print_operand_address (file, addr)
2479 FILE *file;
2480 register rtx addr;
2481 {
2482 register rtx reg1, reg2, breg, ireg;
2483 rtx offset;
2484
2485 switch (GET_CODE (addr))
2486 {
2487 case REG:
2488 ADDR_BEG (file);
2489 fprintf (file, "%se", RP);
2490 fputs (hi_reg_name[REGNO (addr)], file);
2491 ADDR_END (file);
2492 break;
2493
2494 case PLUS:
2495 reg1 = 0;
2496 reg2 = 0;
2497 ireg = 0;
2498 breg = 0;
2499 offset = 0;
2500 if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
2501 {
2502 offset = XEXP (addr, 0);
2503 addr = XEXP (addr, 1);
2504 }
2505 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
2506 {
2507 offset = XEXP (addr, 1);
2508 addr = XEXP (addr, 0);
2509 }
2510 if (GET_CODE (addr) != PLUS) ;
2511 else if (GET_CODE (XEXP (addr, 0)) == MULT)
2512 {
2513 reg1 = XEXP (addr, 0);
2514 addr = XEXP (addr, 1);
2515 }
2516 else if (GET_CODE (XEXP (addr, 1)) == MULT)
2517 {
2518 reg1 = XEXP (addr, 1);
2519 addr = XEXP (addr, 0);
2520 }
2521 else if (GET_CODE (XEXP (addr, 0)) == REG)
2522 {
2523 reg1 = XEXP (addr, 0);
2524 addr = XEXP (addr, 1);
2525 }
2526 else if (GET_CODE (XEXP (addr, 1)) == REG)
2527 {
2528 reg1 = XEXP (addr, 1);
2529 addr = XEXP (addr, 0);
2530 }
2531 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
2532 {
2533 if (reg1 == 0) reg1 = addr;
2534 else reg2 = addr;
2535 addr = 0;
2536 }
2537 if (offset != 0)
2538 {
2539 if (addr != 0) abort ();
2540 addr = offset;
2541 }
2542 if ((reg1 && GET_CODE (reg1) == MULT)
2543 || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
2544 {
2545 breg = reg2;
2546 ireg = reg1;
2547 }
2548 else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
2549 {
2550 breg = reg1;
2551 ireg = reg2;
2552 }
2553
2554 if (ireg != 0 || breg != 0)
2555 {
2556 int scale = 1;
2557
2558 if (addr != 0)
2559 {
2560 if (flag_pic)
2561 output_pic_addr_const (file, addr, 0);
2562
2563 else if (GET_CODE (addr) == LABEL_REF)
2564 output_asm_label (addr);
2565
2566 else
2567 output_addr_const (file, addr);
2568 }
2569
2570 if (ireg != 0 && GET_CODE (ireg) == MULT)
2571 {
2572 scale = INTVAL (XEXP (ireg, 1));
2573 ireg = XEXP (ireg, 0);
2574 }
2575
2576 /* The stack pointer can only appear as a base register,
2577 never an index register, so exchange the regs if it is wrong. */
2578
2579 if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
2580 {
2581 rtx tmp;
2582
2583 tmp = breg;
2584 breg = ireg;
2585 ireg = tmp;
2586 }
2587
2588 /* output breg+ireg*scale */
2589 PRINT_B_I_S (breg, ireg, scale, file);
2590 break;
2591 }
2592
2593 case MULT:
2594 {
2595 int scale;
2596 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
2597 {
2598 scale = INTVAL (XEXP (addr, 0));
2599 ireg = XEXP (addr, 1);
2600 }
2601 else
2602 {
2603 scale = INTVAL (XEXP (addr, 1));
2604 ireg = XEXP (addr, 0);
2605 }
2606 output_addr_const (file, const0_rtx);
2607 PRINT_B_I_S ((rtx) 0, ireg, scale, file);
2608 }
2609 break;
2610
2611 default:
2612 if (GET_CODE (addr) == CONST_INT
2613 && INTVAL (addr) < 0x8000
2614 && INTVAL (addr) >= -0x8000)
2615 fprintf (file, "%d", INTVAL (addr));
2616 else
2617 {
2618 if (flag_pic)
2619 output_pic_addr_const (file, addr, 0);
2620 else
2621 output_addr_const (file, addr);
2622 }
2623 }
2624 }
2625 \f
2626 /* Set the cc_status for the results of an insn whose pattern is EXP.
2627 On the 80386, we assume that only test and compare insns, as well
2628 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
2629 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
2630 Also, we assume that jumps, moves and sCOND don't affect the condition
2631 codes. All else clobbers the condition codes, by assumption.
2632
2633 We assume that ALL integer add, minus, etc. instructions effect the
2634 condition codes. This MUST be consistent with i386.md.
2635
2636 We don't record any float test or compare - the redundant test &
2637 compare check in final.c does not handle stack-like regs correctly. */
2638
2639 void
2640 notice_update_cc (exp)
2641 rtx exp;
2642 {
2643 if (GET_CODE (exp) == SET)
2644 {
2645 /* Jumps do not alter the cc's. */
2646 if (SET_DEST (exp) == pc_rtx)
2647 return;
2648 /* Moving register or memory into a register:
2649 it doesn't alter the cc's, but it might invalidate
2650 the RTX's which we remember the cc's came from.
2651 (Note that moving a constant 0 or 1 MAY set the cc's). */
2652 if (REG_P (SET_DEST (exp))
2653 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
2654 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2655 {
2656 if (cc_status.value1
2657 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
2658 cc_status.value1 = 0;
2659 if (cc_status.value2
2660 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
2661 cc_status.value2 = 0;
2662 return;
2663 }
2664 /* Moving register into memory doesn't alter the cc's.
2665 It may invalidate the RTX's which we remember the cc's came from. */
2666 if (GET_CODE (SET_DEST (exp)) == MEM
2667 && (REG_P (SET_SRC (exp))
2668 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
2669 {
2670 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
2671 cc_status.value1 = 0;
2672 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
2673 cc_status.value2 = 0;
2674 return;
2675 }
2676 /* Function calls clobber the cc's. */
2677 else if (GET_CODE (SET_SRC (exp)) == CALL)
2678 {
2679 CC_STATUS_INIT;
2680 return;
2681 }
2682 /* Tests and compares set the cc's in predictable ways. */
2683 else if (SET_DEST (exp) == cc0_rtx)
2684 {
2685 CC_STATUS_INIT;
2686 cc_status.value1 = SET_SRC (exp);
2687 return;
2688 }
2689 /* Certain instructions effect the condition codes. */
2690 else if (GET_MODE (SET_SRC (exp)) == SImode
2691 || GET_MODE (SET_SRC (exp)) == HImode
2692 || GET_MODE (SET_SRC (exp)) == QImode)
2693 switch (GET_CODE (SET_SRC (exp)))
2694 {
2695 case ASHIFTRT: case LSHIFTRT:
2696 case ASHIFT:
2697 /* Shifts on the 386 don't set the condition codes if the
2698 shift count is zero. */
2699 if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
2700 {
2701 CC_STATUS_INIT;
2702 break;
2703 }
2704 /* We assume that the CONST_INT is non-zero (this rtx would
2705 have been deleted if it were zero. */
2706
2707 case PLUS: case MINUS: case NEG:
2708 case AND: case IOR: case XOR:
2709 cc_status.flags = CC_NO_OVERFLOW;
2710 cc_status.value1 = SET_SRC (exp);
2711 cc_status.value2 = SET_DEST (exp);
2712 break;
2713
2714 default:
2715 CC_STATUS_INIT;
2716 }
2717 else
2718 {
2719 CC_STATUS_INIT;
2720 }
2721 }
2722 else if (GET_CODE (exp) == PARALLEL
2723 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
2724 {
2725 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
2726 return;
2727 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
2728 {
2729 CC_STATUS_INIT;
2730 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
2731 cc_status.flags |= CC_IN_80387;
2732 else
2733 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
2734 return;
2735 }
2736 CC_STATUS_INIT;
2737 }
2738 else
2739 {
2740 CC_STATUS_INIT;
2741 }
2742 }
2743 \f
2744 /* Split one or more DImode RTL references into pairs of SImode
2745 references. The RTL can be REG, offsettable MEM, integer constant, or
2746 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
2747 split and "num" is its length. lo_half and hi_half are output arrays
2748 that parallel "operands". */
2749
2750 void
2751 split_di (operands, num, lo_half, hi_half)
2752 rtx operands[];
2753 int num;
2754 rtx lo_half[], hi_half[];
2755 {
2756 while (num--)
2757 {
2758 if (GET_CODE (operands[num]) == REG)
2759 {
2760 lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
2761 hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
2762 }
2763 else if (CONSTANT_P (operands[num]))
2764 {
2765 split_double (operands[num], &lo_half[num], &hi_half[num]);
2766 }
2767 else if (offsettable_memref_p (operands[num]))
2768 {
2769 lo_half[num] = operands[num];
2770 hi_half[num] = adj_offsettable_operand (operands[num], 4);
2771 }
2772 else
2773 abort();
2774 }
2775 }
2776 \f
2777 /* Return 1 if this is a valid binary operation on a 387.
2778 OP is the expression matched, and MODE is its mode. */
2779
2780 int
2781 binary_387_op (op, mode)
2782 register rtx op;
2783 enum machine_mode mode;
2784 {
2785 if (mode != VOIDmode && mode != GET_MODE (op))
2786 return 0;
2787
2788 switch (GET_CODE (op))
2789 {
2790 case PLUS:
2791 case MINUS:
2792 case MULT:
2793 case DIV:
2794 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
2795
2796 default:
2797 return 0;
2798 }
2799 }
2800
2801 \f
2802 /* Return 1 if this is a valid shift or rotate operation on a 386.
2803 OP is the expression matched, and MODE is its mode. */
2804
2805 int
2806 shift_op (op, mode)
2807 register rtx op;
2808 enum machine_mode mode;
2809 {
2810 rtx operand = XEXP (op, 0);
2811
2812 if (mode != VOIDmode && mode != GET_MODE (op))
2813 return 0;
2814
2815 if (GET_MODE (operand) != GET_MODE (op)
2816 || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
2817 return 0;
2818
2819 return (GET_CODE (op) == ASHIFT
2820 || GET_CODE (op) == ASHIFTRT
2821 || GET_CODE (op) == LSHIFTRT
2822 || GET_CODE (op) == ROTATE
2823 || GET_CODE (op) == ROTATERT);
2824 }
2825
2826 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
2827 MODE is not used. */
2828
2829 int
2830 VOIDmode_compare_op (op, mode)
2831 register rtx op;
2832 enum machine_mode mode;
2833 {
2834 return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
2835 }
2836 \f
2837 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
2838 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
2839 is the expression of the binary operation. The output may either be
2840 emitted here, or returned to the caller, like all output_* functions.
2841
2842 There is no guarantee that the operands are the same mode, as they
2843 might be within FLOAT or FLOAT_EXTEND expressions. */
2844
2845 char *
2846 output_387_binary_op (insn, operands)
2847 rtx insn;
2848 rtx *operands;
2849 {
2850 rtx temp;
2851 char *base_op;
2852 static char buf[100];
2853
2854 switch (GET_CODE (operands[3]))
2855 {
2856 case PLUS:
2857 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2858 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2859 base_op = "fiadd";
2860 else
2861 base_op = "fadd";
2862 break;
2863
2864 case MINUS:
2865 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2866 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2867 base_op = "fisub";
2868 else
2869 base_op = "fsub";
2870 break;
2871
2872 case MULT:
2873 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2874 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2875 base_op = "fimul";
2876 else
2877 base_op = "fmul";
2878 break;
2879
2880 case DIV:
2881 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2882 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
2883 base_op = "fidiv";
2884 else
2885 base_op = "fdiv";
2886 break;
2887
2888 default:
2889 abort ();
2890 }
2891
2892 strcpy (buf, base_op);
2893
2894 switch (GET_CODE (operands[3]))
2895 {
2896 case MULT:
2897 case PLUS:
2898 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
2899 {
2900 temp = operands[2];
2901 operands[2] = operands[1];
2902 operands[1] = temp;
2903 }
2904
2905 if (GET_CODE (operands[2]) == MEM)
2906 return strcat (buf, AS1 (%z2,%2));
2907
2908 if (NON_STACK_REG_P (operands[1]))
2909 {
2910 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
2911 RET;
2912 }
2913 else if (NON_STACK_REG_P (operands[2]))
2914 {
2915 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
2916 RET;
2917 }
2918
2919 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
2920 return strcat (buf, AS2 (p,%2,%0));
2921
2922 if (STACK_TOP_P (operands[0]))
2923 return strcat (buf, AS2C (%y2,%0));
2924 else
2925 return strcat (buf, AS2C (%2,%0));
2926
2927 case MINUS:
2928 case DIV:
2929 if (GET_CODE (operands[1]) == MEM)
2930 return strcat (buf, AS1 (r%z1,%1));
2931
2932 if (GET_CODE (operands[2]) == MEM)
2933 return strcat (buf, AS1 (%z2,%2));
2934
2935 if (NON_STACK_REG_P (operands[1]))
2936 {
2937 output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
2938 RET;
2939 }
2940 else if (NON_STACK_REG_P (operands[2]))
2941 {
2942 output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
2943 RET;
2944 }
2945
2946 if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
2947 abort ();
2948
2949 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
2950 return strcat (buf, AS2 (rp,%2,%0));
2951
2952 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2953 return strcat (buf, AS2 (p,%1,%0));
2954
2955 if (STACK_TOP_P (operands[0]))
2956 {
2957 if (STACK_TOP_P (operands[1]))
2958 return strcat (buf, AS2C (%y2,%0));
2959 else
2960 return strcat (buf, AS2 (r,%y1,%0));
2961 }
2962 else if (STACK_TOP_P (operands[1]))
2963 return strcat (buf, AS2C (%1,%0));
2964 else
2965 return strcat (buf, AS2 (r,%2,%0));
2966
2967 default:
2968 abort ();
2969 }
2970 }
2971 \f
2972 /* Output code for INSN to convert a float to a signed int. OPERANDS
2973 are the insn operands. The output may be SFmode or DFmode and the
2974 input operand may be SImode or DImode. As a special case, make sure
2975 that the 387 stack top dies if the output mode is DImode, because the
2976 hardware requires this. */
2977
2978 char *
2979 output_fix_trunc (insn, operands)
2980 rtx insn;
2981 rtx *operands;
2982 {
2983 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
2984 rtx xops[2];
2985
2986 if (! STACK_TOP_P (operands[1]) ||
2987 (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
2988 abort ();
2989
2990 xops[0] = GEN_INT (12);
2991 xops[1] = operands[4];
2992
2993 output_asm_insn (AS1 (fnstc%W2,%2), operands);
2994 output_asm_insn (AS2 (mov%L2,%2,%4), operands);
2995 output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
2996 output_asm_insn (AS2 (mov%L4,%4,%3), operands);
2997 output_asm_insn (AS1 (fldc%W3,%3), operands);
2998
2999 if (NON_STACK_REG_P (operands[0]))
3000 output_to_reg (operands[0], stack_top_dies);
3001 else if (GET_CODE (operands[0]) == MEM)
3002 {
3003 if (stack_top_dies)
3004 output_asm_insn (AS1 (fistp%z0,%0), operands);
3005 else
3006 output_asm_insn (AS1 (fist%z0,%0), operands);
3007 }
3008 else
3009 abort ();
3010
3011 return AS1 (fldc%W2,%2);
3012 }
3013 \f
3014 /* Output code for INSN to compare OPERANDS. The two operands might
3015 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
3016 expression. If the compare is in mode CCFPEQmode, use an opcode that
3017 will not fault if a qNaN is present. */
3018
3019 char *
3020 output_float_compare (insn, operands)
3021 rtx insn;
3022 rtx *operands;
3023 {
3024 int stack_top_dies;
3025 rtx body = XVECEXP (PATTERN (insn), 0, 0);
3026 int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
3027
3028 if (! STACK_TOP_P (operands[0]))
3029 abort ();
3030
3031 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
3032
3033 if (STACK_REG_P (operands[1])
3034 && stack_top_dies
3035 && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
3036 && REGNO (operands[1]) != FIRST_STACK_REG)
3037 {
3038 /* If both the top of the 387 stack dies, and the other operand
3039 is also a stack register that dies, then this must be a
3040 `fcompp' float compare */
3041
3042 if (unordered_compare)
3043 output_asm_insn ("fucompp", operands);
3044 else
3045 output_asm_insn ("fcompp", operands);
3046 }
3047 else
3048 {
3049 static char buf[100];
3050
3051 /* Decide if this is the integer or float compare opcode, or the
3052 unordered float compare. */
3053
3054 if (unordered_compare)
3055 strcpy (buf, "fucom");
3056 else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
3057 strcpy (buf, "fcom");
3058 else
3059 strcpy (buf, "ficom");
3060
3061 /* Modify the opcode if the 387 stack is to be popped. */
3062
3063 if (stack_top_dies)
3064 strcat (buf, "p");
3065
3066 if (NON_STACK_REG_P (operands[1]))
3067 output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
3068 else
3069 output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
3070 }
3071
3072 /* Now retrieve the condition code. */
3073
3074 return output_fp_cc0_set (insn);
3075 }
3076 \f
3077 /* Output opcodes to transfer the results of FP compare or test INSN
3078 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
3079 result of the compare or test is unordered, no comparison operator
3080 succeeds except NE. Return an output template, if any. */
3081
3082 char *
3083 output_fp_cc0_set (insn)
3084 rtx insn;
3085 {
3086 rtx xops[3];
3087 rtx unordered_label;
3088 rtx next;
3089 enum rtx_code code;
3090
3091 xops[0] = gen_rtx (REG, HImode, 0);
3092 output_asm_insn (AS1 (fnsts%W0,%0), xops);
3093
3094 if (! TARGET_IEEE_FP)
3095 return "sahf";
3096
3097 next = next_cc0_user (insn);
3098 if (next == NULL_RTX)
3099 abort ();
3100
3101 if (GET_CODE (next) == JUMP_INSN
3102 && GET_CODE (PATTERN (next)) == SET
3103 && SET_DEST (PATTERN (next)) == pc_rtx
3104 && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
3105 {
3106 code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
3107 }
3108 else if (GET_CODE (PATTERN (next)) == SET)
3109 {
3110 code = GET_CODE (SET_SRC (PATTERN (next)));
3111 }
3112 else
3113 abort ();
3114
3115 xops[0] = gen_rtx (REG, QImode, 0);
3116
3117 switch (code)
3118 {
3119 case GT:
3120 xops[1] = GEN_INT (0x45);
3121 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3122 /* je label */
3123 break;
3124
3125 case LT:
3126 xops[1] = GEN_INT (0x45);
3127 xops[2] = GEN_INT (0x01);
3128 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3129 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3130 /* je label */
3131 break;
3132
3133 case GE:
3134 xops[1] = GEN_INT (0x05);
3135 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3136 /* je label */
3137 break;
3138
3139 case LE:
3140 xops[1] = GEN_INT (0x45);
3141 xops[2] = GEN_INT (0x40);
3142 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3143 output_asm_insn (AS1 (dec%B0,%h0), xops);
3144 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3145 /* jb label */
3146 break;
3147
3148 case EQ:
3149 xops[1] = GEN_INT (0x45);
3150 xops[2] = GEN_INT (0x40);
3151 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3152 output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
3153 /* je label */
3154 break;
3155
3156 case NE:
3157 xops[1] = GEN_INT (0x44);
3158 xops[2] = GEN_INT (0x40);
3159 output_asm_insn (AS2 (and%B0,%1,%h0), xops);
3160 output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
3161 /* jne label */
3162 break;
3163
3164 case GTU:
3165 case LTU:
3166 case GEU:
3167 case LEU:
3168 default:
3169 abort ();
3170 }
3171 RET;
3172 }
3173 \f
3174 #define MAX_386_STACK_LOCALS 2
3175
3176 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3177
3178 /* Define the structure for the machine field in struct function. */
3179 struct machine_function
3180 {
3181 rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
3182 };
3183
3184 /* Functions to save and restore i386_stack_locals.
3185 These will be called, via pointer variables,
3186 from push_function_context and pop_function_context. */
3187
3188 void
3189 save_386_machine_status (p)
3190 struct function *p;
3191 {
3192 p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
3193 bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
3194 sizeof i386_stack_locals);
3195 }
3196
3197 void
3198 restore_386_machine_status (p)
3199 struct function *p;
3200 {
3201 bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
3202 sizeof i386_stack_locals);
3203 free (p->machine);
3204 }
3205
3206 /* Clear stack slot assignments remembered from previous functions.
3207 This is called from INIT_EXPANDERS once before RTL is emitted for each
3208 function. */
3209
3210 void
3211 clear_386_stack_locals ()
3212 {
3213 enum machine_mode mode;
3214 int n;
3215
3216 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
3217 mode = (enum machine_mode) ((int) mode + 1))
3218 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
3219 i386_stack_locals[(int) mode][n] = NULL_RTX;
3220
3221 /* Arrange to save and restore i386_stack_locals around nested functions. */
3222 save_machine_status = save_386_machine_status;
3223 restore_machine_status = restore_386_machine_status;
3224 }
3225
3226 /* Return a MEM corresponding to a stack slot with mode MODE.
3227 Allocate a new slot if necessary.
3228
3229 The RTL for a function can have several slots available: N is
3230 which slot to use. */
3231
3232 rtx
3233 assign_386_stack_local (mode, n)
3234 enum machine_mode mode;
3235 int n;
3236 {
3237 if (n < 0 || n >= MAX_386_STACK_LOCALS)
3238 abort ();
3239
3240 if (i386_stack_locals[(int) mode][n] == NULL_RTX)
3241 i386_stack_locals[(int) mode][n]
3242 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
3243
3244 return i386_stack_locals[(int) mode][n];
3245 }
This page took 0.433656 seconds and 6 git commands to generate.