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