]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.c
* 5nosinte.ads: Get definition of "int" from Interfaces.C.
[gcc.git] / gcc / config / i386 / i386.c
CommitLineData
e075ae69 1/* Subroutines used for code generation on IA-32.
8752c357 2 Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
4592bdcb 3 Free Software Foundation, Inc.
2a2ab3f9
JVA
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
97aadbb9 19the Free Software Foundation, 59 Temple Place - Suite 330,
0f290768 20Boston, MA 02111-1307, USA. */
2a2ab3f9 21
2a2ab3f9 22#include "config.h"
bb5177ac 23#include "system.h"
2a2ab3f9 24#include "rtl.h"
6baf1cc8
BS
25#include "tree.h"
26#include "tm_p.h"
2a2ab3f9
JVA
27#include "regs.h"
28#include "hard-reg-set.h"
29#include "real.h"
30#include "insn-config.h"
31#include "conditions.h"
2a2ab3f9
JVA
32#include "output.h"
33#include "insn-attr.h"
2a2ab3f9 34#include "flags.h"
a8ffcc81 35#include "except.h"
ecbc4695 36#include "function.h"
00c79232 37#include "recog.h"
ced8dd8c 38#include "expr.h"
e78d8e51 39#include "optabs.h"
f103890b 40#include "toplev.h"
e075ae69 41#include "basic-block.h"
1526a060 42#include "ggc.h"
672a6f42
NB
43#include "target.h"
44#include "target-def.h"
2a2ab3f9 45
8dfe5673
RK
46#ifndef CHECK_STACK_LIMIT
47#define CHECK_STACK_LIMIT -1
48#endif
49
2ab0437e 50/* Processor costs (relative to an add) */
8b60264b 51static const
2ab0437e
JH
52struct processor_costs size_cost = { /* costs for tunning for size */
53 2, /* cost of an add instruction */
54 3, /* cost of a lea instruction */
55 2, /* variable shift costs */
56 3, /* constant shift costs */
57 3, /* cost of starting a multiply */
58 0, /* cost of multiply per each bit set */
59 3, /* cost of a divide/mod */
44cf5b6a
JH
60 3, /* cost of movsx */
61 3, /* cost of movzx */
2ab0437e
JH
62 0, /* "large" insn */
63 2, /* MOVE_RATIO */
64 2, /* cost for loading QImode using movzbl */
65 {2, 2, 2}, /* cost of loading integer registers
66 in QImode, HImode and SImode.
67 Relative to reg-reg move (2). */
68 {2, 2, 2}, /* cost of storing integer registers */
69 2, /* cost of reg,reg fld/fst */
70 {2, 2, 2}, /* cost of loading fp registers
71 in SFmode, DFmode and XFmode */
72 {2, 2, 2}, /* cost of loading integer registers */
73 3, /* cost of moving MMX register */
74 {3, 3}, /* cost of loading MMX registers
75 in SImode and DImode */
76 {3, 3}, /* cost of storing MMX registers
77 in SImode and DImode */
78 3, /* cost of moving SSE register */
79 {3, 3, 3}, /* cost of loading SSE registers
80 in SImode, DImode and TImode */
81 {3, 3, 3}, /* cost of storing SSE registers
82 in SImode, DImode and TImode */
83 3, /* MMX or SSE register to integer */
f4365627
JH
84 0, /* size of prefetch block */
85 0, /* number of parallel prefetches */
2ab0437e 86};
32b5b1aa 87/* Processor costs (relative to an add) */
8b60264b 88static const
32b5b1aa 89struct processor_costs i386_cost = { /* 386 specific costs */
e9a25f70 90 1, /* cost of an add instruction */
32b5b1aa
SC
91 1, /* cost of a lea instruction */
92 3, /* variable shift costs */
93 2, /* constant shift costs */
94 6, /* cost of starting a multiply */
95 1, /* cost of multiply per each bit set */
e075ae69 96 23, /* cost of a divide/mod */
44cf5b6a
JH
97 3, /* cost of movsx */
98 2, /* cost of movzx */
96e7ae40 99 15, /* "large" insn */
e2e52e1b 100 3, /* MOVE_RATIO */
7c6b971d 101 4, /* cost for loading QImode using movzbl */
96e7ae40
JH
102 {2, 4, 2}, /* cost of loading integer registers
103 in QImode, HImode and SImode.
0f290768 104 Relative to reg-reg move (2). */
96e7ae40
JH
105 {2, 4, 2}, /* cost of storing integer registers */
106 2, /* cost of reg,reg fld/fst */
107 {8, 8, 8}, /* cost of loading fp registers
108 in SFmode, DFmode and XFmode */
fa79946e
JH
109 {8, 8, 8}, /* cost of loading integer registers */
110 2, /* cost of moving MMX register */
111 {4, 8}, /* cost of loading MMX registers
112 in SImode and DImode */
113 {4, 8}, /* cost of storing MMX registers
114 in SImode and DImode */
115 2, /* cost of moving SSE register */
116 {4, 8, 16}, /* cost of loading SSE registers
117 in SImode, DImode and TImode */
118 {4, 8, 16}, /* cost of storing SSE registers
119 in SImode, DImode and TImode */
120 3, /* MMX or SSE register to integer */
f4365627
JH
121 0, /* size of prefetch block */
122 0, /* number of parallel prefetches */
32b5b1aa
SC
123};
124
8b60264b 125static const
32b5b1aa
SC
126struct processor_costs i486_cost = { /* 486 specific costs */
127 1, /* cost of an add instruction */
128 1, /* cost of a lea instruction */
129 3, /* variable shift costs */
130 2, /* constant shift costs */
131 12, /* cost of starting a multiply */
132 1, /* cost of multiply per each bit set */
e075ae69 133 40, /* cost of a divide/mod */
44cf5b6a
JH
134 3, /* cost of movsx */
135 2, /* cost of movzx */
96e7ae40 136 15, /* "large" insn */
e2e52e1b 137 3, /* MOVE_RATIO */
7c6b971d 138 4, /* cost for loading QImode using movzbl */
96e7ae40
JH
139 {2, 4, 2}, /* cost of loading integer registers
140 in QImode, HImode and SImode.
0f290768 141 Relative to reg-reg move (2). */
96e7ae40
JH
142 {2, 4, 2}, /* cost of storing integer registers */
143 2, /* cost of reg,reg fld/fst */
144 {8, 8, 8}, /* cost of loading fp registers
145 in SFmode, DFmode and XFmode */
fa79946e
JH
146 {8, 8, 8}, /* cost of loading integer registers */
147 2, /* cost of moving MMX register */
148 {4, 8}, /* cost of loading MMX registers
149 in SImode and DImode */
150 {4, 8}, /* cost of storing MMX registers
151 in SImode and DImode */
152 2, /* cost of moving SSE register */
153 {4, 8, 16}, /* cost of loading SSE registers
154 in SImode, DImode and TImode */
155 {4, 8, 16}, /* cost of storing SSE registers
156 in SImode, DImode and TImode */
f4365627
JH
157 3, /* MMX or SSE register to integer */
158 0, /* size of prefetch block */
159 0, /* number of parallel prefetches */
32b5b1aa
SC
160};
161
8b60264b 162static const
e5cb57e8 163struct processor_costs pentium_cost = {
32b5b1aa
SC
164 1, /* cost of an add instruction */
165 1, /* cost of a lea instruction */
856b07a1 166 4, /* variable shift costs */
e5cb57e8 167 1, /* constant shift costs */
856b07a1
SC
168 11, /* cost of starting a multiply */
169 0, /* cost of multiply per each bit set */
e075ae69 170 25, /* cost of a divide/mod */
44cf5b6a
JH
171 3, /* cost of movsx */
172 2, /* cost of movzx */
96e7ae40 173 8, /* "large" insn */
e2e52e1b 174 6, /* MOVE_RATIO */
7c6b971d 175 6, /* cost for loading QImode using movzbl */
96e7ae40
JH
176 {2, 4, 2}, /* cost of loading integer registers
177 in QImode, HImode and SImode.
0f290768 178 Relative to reg-reg move (2). */
96e7ae40
JH
179 {2, 4, 2}, /* cost of storing integer registers */
180 2, /* cost of reg,reg fld/fst */
181 {2, 2, 6}, /* cost of loading fp registers
182 in SFmode, DFmode and XFmode */
fa79946e
JH
183 {4, 4, 6}, /* cost of loading integer registers */
184 8, /* cost of moving MMX register */
185 {8, 8}, /* cost of loading MMX registers
186 in SImode and DImode */
187 {8, 8}, /* cost of storing MMX registers
188 in SImode and DImode */
189 2, /* cost of moving SSE register */
190 {4, 8, 16}, /* cost of loading SSE registers
191 in SImode, DImode and TImode */
192 {4, 8, 16}, /* cost of storing SSE registers
193 in SImode, DImode and TImode */
f4365627
JH
194 3, /* MMX or SSE register to integer */
195 0, /* size of prefetch block */
196 0, /* number of parallel prefetches */
32b5b1aa
SC
197};
198
8b60264b 199static const
856b07a1
SC
200struct processor_costs pentiumpro_cost = {
201 1, /* cost of an add instruction */
202 1, /* cost of a lea instruction */
e075ae69 203 1, /* variable shift costs */
856b07a1 204 1, /* constant shift costs */
369e59b1 205 4, /* cost of starting a multiply */
856b07a1 206 0, /* cost of multiply per each bit set */
e075ae69 207 17, /* cost of a divide/mod */
44cf5b6a
JH
208 1, /* cost of movsx */
209 1, /* cost of movzx */
96e7ae40 210 8, /* "large" insn */
e2e52e1b 211 6, /* MOVE_RATIO */
7c6b971d 212 2, /* cost for loading QImode using movzbl */
96e7ae40
JH
213 {4, 4, 4}, /* cost of loading integer registers
214 in QImode, HImode and SImode.
0f290768 215 Relative to reg-reg move (2). */
96e7ae40
JH
216 {2, 2, 2}, /* cost of storing integer registers */
217 2, /* cost of reg,reg fld/fst */
218 {2, 2, 6}, /* cost of loading fp registers
219 in SFmode, DFmode and XFmode */
fa79946e
JH
220 {4, 4, 6}, /* cost of loading integer registers */
221 2, /* cost of moving MMX register */
222 {2, 2}, /* cost of loading MMX registers
223 in SImode and DImode */
224 {2, 2}, /* cost of storing MMX registers
225 in SImode and DImode */
226 2, /* cost of moving SSE register */
227 {2, 2, 8}, /* cost of loading SSE registers
228 in SImode, DImode and TImode */
229 {2, 2, 8}, /* cost of storing SSE registers
230 in SImode, DImode and TImode */
f4365627
JH
231 3, /* MMX or SSE register to integer */
232 32, /* size of prefetch block */
233 6, /* number of parallel prefetches */
856b07a1
SC
234};
235
8b60264b 236static const
a269a03c
JC
237struct processor_costs k6_cost = {
238 1, /* cost of an add instruction */
e075ae69 239 2, /* cost of a lea instruction */
a269a03c
JC
240 1, /* variable shift costs */
241 1, /* constant shift costs */
73fe76e4 242 3, /* cost of starting a multiply */
a269a03c 243 0, /* cost of multiply per each bit set */
e075ae69 244 18, /* cost of a divide/mod */
44cf5b6a
JH
245 2, /* cost of movsx */
246 2, /* cost of movzx */
96e7ae40 247 8, /* "large" insn */
e2e52e1b 248 4, /* MOVE_RATIO */
7c6b971d 249 3, /* cost for loading QImode using movzbl */
96e7ae40
JH
250 {4, 5, 4}, /* cost of loading integer registers
251 in QImode, HImode and SImode.
0f290768 252 Relative to reg-reg move (2). */
96e7ae40
JH
253 {2, 3, 2}, /* cost of storing integer registers */
254 4, /* cost of reg,reg fld/fst */
255 {6, 6, 6}, /* cost of loading fp registers
256 in SFmode, DFmode and XFmode */
fa79946e
JH
257 {4, 4, 4}, /* cost of loading integer registers */
258 2, /* cost of moving MMX register */
259 {2, 2}, /* cost of loading MMX registers
260 in SImode and DImode */
261 {2, 2}, /* cost of storing MMX registers
262 in SImode and DImode */
263 2, /* cost of moving SSE register */
264 {2, 2, 8}, /* cost of loading SSE registers
265 in SImode, DImode and TImode */
266 {2, 2, 8}, /* cost of storing SSE registers
267 in SImode, DImode and TImode */
f4365627
JH
268 6, /* MMX or SSE register to integer */
269 32, /* size of prefetch block */
270 1, /* number of parallel prefetches */
a269a03c
JC
271};
272
8b60264b 273static const
309ada50
JH
274struct processor_costs athlon_cost = {
275 1, /* cost of an add instruction */
0b5107cf 276 2, /* cost of a lea instruction */
309ada50
JH
277 1, /* variable shift costs */
278 1, /* constant shift costs */
279 5, /* cost of starting a multiply */
280 0, /* cost of multiply per each bit set */
0b5107cf 281 42, /* cost of a divide/mod */
44cf5b6a
JH
282 1, /* cost of movsx */
283 1, /* cost of movzx */
309ada50 284 8, /* "large" insn */
e2e52e1b 285 9, /* MOVE_RATIO */
309ada50
JH
286 4, /* cost for loading QImode using movzbl */
287 {4, 5, 4}, /* cost of loading integer registers
288 in QImode, HImode and SImode.
0f290768 289 Relative to reg-reg move (2). */
309ada50
JH
290 {2, 3, 2}, /* cost of storing integer registers */
291 4, /* cost of reg,reg fld/fst */
0b5107cf 292 {6, 6, 20}, /* cost of loading fp registers
309ada50 293 in SFmode, DFmode and XFmode */
fa79946e
JH
294 {4, 4, 16}, /* cost of loading integer registers */
295 2, /* cost of moving MMX register */
296 {2, 2}, /* cost of loading MMX registers
297 in SImode and DImode */
298 {2, 2}, /* cost of storing MMX registers
299 in SImode and DImode */
300 2, /* cost of moving SSE register */
301 {2, 2, 8}, /* cost of loading SSE registers
302 in SImode, DImode and TImode */
303 {2, 2, 8}, /* cost of storing SSE registers
304 in SImode, DImode and TImode */
f4365627
JH
305 6, /* MMX or SSE register to integer */
306 64, /* size of prefetch block */
307 6, /* number of parallel prefetches */
309ada50
JH
308};
309
8b60264b 310static const
b4e89e2d
JH
311struct processor_costs pentium4_cost = {
312 1, /* cost of an add instruction */
313 1, /* cost of a lea instruction */
314 8, /* variable shift costs */
315 8, /* constant shift costs */
316 30, /* cost of starting a multiply */
317 0, /* cost of multiply per each bit set */
318 112, /* cost of a divide/mod */
44cf5b6a
JH
319 1, /* cost of movsx */
320 1, /* cost of movzx */
b4e89e2d
JH
321 16, /* "large" insn */
322 6, /* MOVE_RATIO */
323 2, /* cost for loading QImode using movzbl */
324 {4, 5, 4}, /* cost of loading integer registers
325 in QImode, HImode and SImode.
326 Relative to reg-reg move (2). */
327 {2, 3, 2}, /* cost of storing integer registers */
328 2, /* cost of reg,reg fld/fst */
329 {2, 2, 6}, /* cost of loading fp registers
330 in SFmode, DFmode and XFmode */
331 {4, 4, 6}, /* cost of loading integer registers */
332 2, /* cost of moving MMX register */
333 {2, 2}, /* cost of loading MMX registers
334 in SImode and DImode */
335 {2, 2}, /* cost of storing MMX registers
336 in SImode and DImode */
337 12, /* cost of moving SSE register */
338 {12, 12, 12}, /* cost of loading SSE registers
339 in SImode, DImode and TImode */
340 {2, 2, 8}, /* cost of storing SSE registers
341 in SImode, DImode and TImode */
342 10, /* MMX or SSE register to integer */
f4365627
JH
343 64, /* size of prefetch block */
344 6, /* number of parallel prefetches */
b4e89e2d
JH
345};
346
8b60264b 347const struct processor_costs *ix86_cost = &pentium_cost;
32b5b1aa 348
a269a03c
JC
349/* Processor feature/optimization bitmasks. */
350#define m_386 (1<<PROCESSOR_I386)
351#define m_486 (1<<PROCESSOR_I486)
352#define m_PENT (1<<PROCESSOR_PENTIUM)
353#define m_PPRO (1<<PROCESSOR_PENTIUMPRO)
354#define m_K6 (1<<PROCESSOR_K6)
309ada50 355#define m_ATHLON (1<<PROCESSOR_ATHLON)
b4e89e2d 356#define m_PENT4 (1<<PROCESSOR_PENTIUM4)
a269a03c 357
309ada50 358const int x86_use_leave = m_386 | m_K6 | m_ATHLON;
b4e89e2d 359const int x86_push_memory = m_386 | m_K6 | m_ATHLON | m_PENT4;
a269a03c 360const int x86_zero_extend_with_and = m_486 | m_PENT;
b4e89e2d 361const int x86_movx = m_ATHLON | m_PPRO | m_PENT4 /* m_386 | m_K6 */;
e075ae69 362const int x86_double_with_add = ~m_386;
a269a03c 363const int x86_use_bit_test = m_386;
e2e52e1b 364const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON | m_K6;
b4e89e2d 365const int x86_cmove = m_PPRO | m_ATHLON | m_PENT4;
47f339cf 366const int x86_3dnow_a = m_ATHLON;
b4e89e2d 367const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON | m_PENT4;
ef6257cd 368const int x86_branch_hints = m_PENT4;
b4e89e2d 369const int x86_use_sahf = m_PPRO | m_K6 | m_PENT4;
e075ae69
RH
370const int x86_partial_reg_stall = m_PPRO;
371const int x86_use_loop = m_K6;
309ada50 372const int x86_use_fiop = ~(m_PPRO | m_ATHLON | m_PENT);
e075ae69
RH
373const int x86_use_mov0 = m_K6;
374const int x86_use_cltd = ~(m_PENT | m_K6);
375const int x86_read_modify_write = ~m_PENT;
376const int x86_read_modify = ~(m_PENT | m_PPRO);
377const int x86_split_long_moves = m_PPRO;
e9e80858 378const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486;
b4e89e2d 379const int x86_single_stringop = m_386 | m_PENT4;
d9f32422
JH
380const int x86_qimode_math = ~(0);
381const int x86_promote_qi_regs = 0;
382const int x86_himode_math = ~(m_PPRO);
383const int x86_promote_hi_regs = m_PPRO;
b4e89e2d
JH
384const int x86_sub_esp_4 = m_ATHLON | m_PPRO | m_PENT4;
385const int x86_sub_esp_8 = m_ATHLON | m_PPRO | m_386 | m_486 | m_PENT4;
386const int x86_add_esp_4 = m_ATHLON | m_K6 | m_PENT4;
387const int x86_add_esp_8 = m_ATHLON | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4;
388const int x86_integer_DFmode_moves = ~(m_ATHLON | m_PENT4);
389const int x86_partial_reg_dependency = m_ATHLON | m_PENT4;
390const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4;
c6036a37
JH
391const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO;
392const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
393const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
b972dd02 394const int x86_decompose_lea = m_PENT4;
a269a03c 395
6ab16dd9
JH
396/* In case the avreage insn count for single function invocation is
397 lower than this constant, emit fast (but longer) prologue and
398 epilogue code. */
399#define FAST_PROLOGUE_INSN_COUNT 30
400/* Set by prologue expander and used by epilogue expander to determine
401 the style used. */
402static int use_fast_prologue_epilogue;
403
564d80f4 404#define AT_BP(mode) (gen_rtx_MEM ((mode), hard_frame_pointer_rtx))
2a2ab3f9 405
83182544
KG
406static const char *const hi_reg_name[] = HI_REGISTER_NAMES; /* names for 16 bit regs */
407static const char *const qi_reg_name[] = QI_REGISTER_NAMES; /* names for 8 bit regs (low) */
408static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES; /* names for 8 bit regs (high) */
4c0d89b5
RS
409
410/* Array of the smallest class containing reg number REGNO, indexed by
0f290768 411 REGNO. Used by REGNO_REG_CLASS in i386.h. */
4c0d89b5 412
e075ae69 413enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
4c0d89b5
RS
414{
415 /* ax, dx, cx, bx */
ab408a86 416 AREG, DREG, CREG, BREG,
4c0d89b5 417 /* si, di, bp, sp */
e075ae69 418 SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
4c0d89b5
RS
419 /* FP registers */
420 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
79325812 421 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
4c0d89b5 422 /* arg pointer */
83774849 423 NON_Q_REGS,
564d80f4 424 /* flags, fpsr, dirflag, frame */
a7180f70
BS
425 NO_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
426 SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
427 SSE_REGS, SSE_REGS,
428 MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
3d117b30
JH
429 MMX_REGS, MMX_REGS,
430 NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
431 NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
432 SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
433 SSE_REGS, SSE_REGS,
4c0d89b5 434};
c572e5ba 435
3d117b30 436/* The "default" register map used in 32bit mode. */
83774849 437
0f290768 438int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
83774849
RH
439{
440 0, 2, 1, 3, 6, 7, 4, 5, /* general regs */
441 12, 13, 14, 15, 16, 17, 18, 19, /* fp regs */
3d117b30 442 -1, -1, -1, -1, -1, /* arg, flags, fpsr, dir, frame */
a7180f70
BS
443 21, 22, 23, 24, 25, 26, 27, 28, /* SSE */
444 29, 30, 31, 32, 33, 34, 35, 36, /* MMX */
3d117b30
JH
445 -1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */
446 -1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
83774849
RH
447};
448
53c17031
JH
449static int x86_64_int_parameter_registers[6] = {5 /*RDI*/, 4 /*RSI*/,
450 1 /*RDX*/, 2 /*RCX*/,
451 FIRST_REX_INT_REG /*R8 */,
452 FIRST_REX_INT_REG + 1 /*R9 */};
453static int x86_64_int_return_registers[4] = {0 /*RAX*/, 1 /*RDI*/, 5, 4};
454
0f7fa3d0
JH
455/* The "default" register map used in 64bit mode. */
456int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
457{
458 0, 1, 2, 3, 4, 5, 6, 7, /* general regs */
459 33, 34, 35, 36, 37, 38, 39, 40 /* fp regs */
460 -1, -1, -1, -1, -1, /* arg, flags, fpsr, dir, frame */
461 17, 18, 19, 20, 21, 22, 23, 24, /* SSE */
462 41, 42, 43, 44, 45, 46, 47, 48, /* MMX */
463 8,9,10,11,12,13,14,15, /* extended integer registers */
464 25, 26, 27, 28, 29, 30, 31, 32, /* extended SSE registers */
465};
466
83774849
RH
467/* Define the register numbers to be used in Dwarf debugging information.
468 The SVR4 reference port C compiler uses the following register numbers
469 in its Dwarf output code:
470 0 for %eax (gcc regno = 0)
471 1 for %ecx (gcc regno = 2)
472 2 for %edx (gcc regno = 1)
473 3 for %ebx (gcc regno = 3)
474 4 for %esp (gcc regno = 7)
475 5 for %ebp (gcc regno = 6)
476 6 for %esi (gcc regno = 4)
477 7 for %edi (gcc regno = 5)
478 The following three DWARF register numbers are never generated by
479 the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
480 believes these numbers have these meanings.
481 8 for %eip (no gcc equivalent)
482 9 for %eflags (gcc regno = 17)
483 10 for %trapno (no gcc equivalent)
484 It is not at all clear how we should number the FP stack registers
485 for the x86 architecture. If the version of SDB on x86/svr4 were
486 a bit less brain dead with respect to floating-point then we would
487 have a precedent to follow with respect to DWARF register numbers
488 for x86 FP registers, but the SDB on x86/svr4 is so completely
489 broken with respect to FP registers that it is hardly worth thinking
490 of it as something to strive for compatibility with.
491 The version of x86/svr4 SDB I have at the moment does (partially)
492 seem to believe that DWARF register number 11 is associated with
493 the x86 register %st(0), but that's about all. Higher DWARF
494 register numbers don't seem to be associated with anything in
495 particular, and even for DWARF regno 11, SDB only seems to under-
496 stand that it should say that a variable lives in %st(0) (when
497 asked via an `=' command) if we said it was in DWARF regno 11,
498 but SDB still prints garbage when asked for the value of the
499 variable in question (via a `/' command).
500 (Also note that the labels SDB prints for various FP stack regs
501 when doing an `x' command are all wrong.)
502 Note that these problems generally don't affect the native SVR4
503 C compiler because it doesn't allow the use of -O with -g and
504 because when it is *not* optimizing, it allocates a memory
505 location for each floating-point variable, and the memory
506 location is what gets described in the DWARF AT_location
507 attribute for the variable in question.
508 Regardless of the severe mental illness of the x86/svr4 SDB, we
509 do something sensible here and we use the following DWARF
510 register numbers. Note that these are all stack-top-relative
511 numbers.
512 11 for %st(0) (gcc regno = 8)
513 12 for %st(1) (gcc regno = 9)
514 13 for %st(2) (gcc regno = 10)
515 14 for %st(3) (gcc regno = 11)
516 15 for %st(4) (gcc regno = 12)
517 16 for %st(5) (gcc regno = 13)
518 17 for %st(6) (gcc regno = 14)
519 18 for %st(7) (gcc regno = 15)
520*/
0f290768 521int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
83774849
RH
522{
523 0, 2, 1, 3, 6, 7, 5, 4, /* general regs */
524 11, 12, 13, 14, 15, 16, 17, 18, /* fp regs */
3f3f2124 525 -1, 9, -1, -1, -1, /* arg, flags, fpsr, dir, frame */
a7180f70
BS
526 21, 22, 23, 24, 25, 26, 27, 28, /* SSE registers */
527 29, 30, 31, 32, 33, 34, 35, 36, /* MMX registers */
3f3f2124
JH
528 -1, -1, -1, -1, -1, -1, -1, -1, /* extemded integer registers */
529 -1, -1, -1, -1, -1, -1, -1, -1, /* extemded SSE registers */
83774849
RH
530};
531
c572e5ba
JVA
532/* Test and compare insns in i386.md store the information needed to
533 generate branch and scc insns here. */
534
e075ae69
RH
535struct rtx_def *ix86_compare_op0 = NULL_RTX;
536struct rtx_def *ix86_compare_op1 = NULL_RTX;
f5316dfe 537
7a2e09f4 538#define MAX_386_STACK_LOCALS 3
8362f420
JH
539/* Size of the register save area. */
540#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
36edd3cc
BS
541
542/* Define the structure for the machine field in struct function. */
543struct machine_function
544{
545 rtx stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
8362f420 546 int save_varrargs_registers;
6fca22eb 547 int accesses_prev_frame;
36edd3cc
BS
548};
549
01d939e8 550#define ix86_stack_locals (cfun->machine->stack_locals)
8362f420 551#define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
36edd3cc 552
4dd2ac2c
JH
553/* Structure describing stack frame layout.
554 Stack grows downward:
555
556 [arguments]
557 <- ARG_POINTER
558 saved pc
559
560 saved frame pointer if frame_pointer_needed
561 <- HARD_FRAME_POINTER
562 [saved regs]
563
564 [padding1] \
565 )
566 [va_arg registers] (
567 > to_allocate <- FRAME_POINTER
568 [frame] (
569 )
570 [padding2] /
571 */
572struct ix86_frame
573{
574 int nregs;
575 int padding1;
8362f420 576 int va_arg_size;
4dd2ac2c
JH
577 HOST_WIDE_INT frame;
578 int padding2;
579 int outgoing_arguments_size;
8362f420 580 int red_zone_size;
4dd2ac2c
JH
581
582 HOST_WIDE_INT to_allocate;
583 /* The offsets relative to ARG_POINTER. */
584 HOST_WIDE_INT frame_pointer_offset;
585 HOST_WIDE_INT hard_frame_pointer_offset;
586 HOST_WIDE_INT stack_pointer_offset;
587};
588
c93e80a5
JH
589/* Used to enable/disable debugging features. */
590const char *ix86_debug_arg_string, *ix86_debug_addr_string;
6189a572
JH
591/* Code model option as passed by user. */
592const char *ix86_cmodel_string;
c93e80a5
JH
593/* Asm dialect. */
594const char *ix86_asm_string;
595enum cmodel ix86_asm_dialect = ASM_ATT;
6189a572
JH
596/* Parsed value. */
597enum cmodel ix86_cmodel;
598
c8c5cb99 599/* which cpu are we scheduling for */
e42ea7f9 600enum processor_type ix86_cpu;
c8c5cb99 601
965f5423
JH
602/* which unit we are generating floating point math for */
603enum fpmath_unit ix86_fpmath;
604
c8c5cb99 605/* which instruction set architecture to use. */
c942177e 606int ix86_arch;
c8c5cb99
SC
607
608/* Strings to hold which cpu and instruction set architecture to use. */
9c23aa47
ZW
609const char *ix86_cpu_string; /* for -mcpu=<xxx> */
610const char *ix86_arch_string; /* for -march=<xxx> */
965f5423 611const char *ix86_fpmath_string; /* for -mfpmath=<xxx> */
c8c5cb99 612
0f290768 613/* # of registers to use to pass arguments. */
e075ae69 614const char *ix86_regparm_string;
e9a25f70 615
f4365627
JH
616/* true if sse prefetch instruction is not NOOP. */
617int x86_prefetch_sse;
618
e075ae69
RH
619/* ix86_regparm_string as a number */
620int ix86_regparm;
e9a25f70
JL
621
622/* Alignment to use for loops and jumps: */
623
0f290768 624/* Power of two alignment for loops. */
e075ae69 625const char *ix86_align_loops_string;
e9a25f70 626
0f290768 627/* Power of two alignment for non-loop jumps. */
e075ae69 628const char *ix86_align_jumps_string;
e9a25f70 629
3af4bd89 630/* Power of two alignment for stack boundary in bytes. */
e075ae69 631const char *ix86_preferred_stack_boundary_string;
3af4bd89
JH
632
633/* Preferred alignment for stack boundary in bits. */
e075ae69 634int ix86_preferred_stack_boundary;
3af4bd89 635
e9a25f70 636/* Values 1-5: see jump.c */
e075ae69
RH
637int ix86_branch_cost;
638const char *ix86_branch_cost_string;
e9a25f70 639
0f290768 640/* Power of two alignment for functions. */
e075ae69 641const char *ix86_align_funcs_string;
623fe810
RH
642
643/* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */
644static char internal_label_prefix[16];
645static int internal_label_prefix_len;
e075ae69 646\f
623fe810 647static int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
f6da8bc3
KG
648static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
649static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
e075ae69 650 int, int, FILE *));
f6da8bc3 651static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
3a3677ff
RH
652static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
653 rtx *, rtx *));
f6da8bc3
KG
654static rtx gen_push PARAMS ((rtx));
655static int memory_address_length PARAMS ((rtx addr));
656static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type));
657static int ix86_agi_dependant PARAMS ((rtx, rtx, enum attr_type));
658static int ix86_safe_length PARAMS ((rtx));
659static enum attr_memory ix86_safe_memory PARAMS ((rtx));
660static enum attr_pent_pair ix86_safe_pent_pair PARAMS ((rtx));
661static enum attr_ppro_uops ix86_safe_ppro_uops PARAMS ((rtx));
662static void ix86_dump_ppro_packet PARAMS ((FILE *));
663static void ix86_reorder_insn PARAMS ((rtx *, rtx *));
664static rtx * ix86_pent_find_pair PARAMS ((rtx *, rtx *, enum attr_pent_pair,
e075ae69 665 rtx));
f6da8bc3
KG
666static void ix86_init_machine_status PARAMS ((struct function *));
667static void ix86_mark_machine_status PARAMS ((struct function *));
37b15744 668static void ix86_free_machine_status PARAMS ((struct function *));
2b589241 669static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode));
f6da8bc3 670static int ix86_safe_length_prefix PARAMS ((rtx));
0903fcab
JH
671static int ix86_nsaved_regs PARAMS((void));
672static void ix86_emit_save_regs PARAMS((void));
c6036a37 673static void ix86_emit_save_regs_using_mov PARAMS ((rtx, HOST_WIDE_INT));
37a58036 674static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, int));
0e4970d7 675static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
c6991660
KG
676static void ix86_sched_reorder_pentium PARAMS((rtx *, rtx *));
677static void ix86_sched_reorder_ppro PARAMS((rtx *, rtx *));
55efb413 678static HOST_WIDE_INT ix86_GOT_alias_set PARAMS ((void));
0945b39d 679static void ix86_adjust_counter PARAMS ((rtx, HOST_WIDE_INT));
0945b39d
JH
680static rtx ix86_expand_aligntest PARAMS ((rtx, int));
681static void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx));
c237e94a
ZW
682static int ix86_issue_rate PARAMS ((void));
683static int ix86_adjust_cost PARAMS ((rtx, rtx, rtx, int));
684static void ix86_sched_init PARAMS ((FILE *, int, int));
685static int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
686static int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
e075ae69
RH
687
688struct ix86_address
689{
690 rtx base, index, disp;
691 HOST_WIDE_INT scale;
692};
b08de47e 693
e075ae69 694static int ix86_decompose_address PARAMS ((rtx, struct ix86_address *));
bd793c65
BS
695
696struct builtin_description;
8b60264b
KG
697static rtx ix86_expand_sse_comi PARAMS ((const struct builtin_description *,
698 tree, rtx));
699static rtx ix86_expand_sse_compare PARAMS ((const struct builtin_description *,
700 tree, rtx));
bd793c65
BS
701static rtx ix86_expand_unop1_builtin PARAMS ((enum insn_code, tree, rtx));
702static rtx ix86_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx, int));
703static rtx ix86_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
704static rtx ix86_expand_store_builtin PARAMS ((enum insn_code, tree, int));
705static rtx safe_vector_operand PARAMS ((rtx, enum machine_mode));
c0c102a9
JH
706static enum rtx_code ix86_fp_compare_code_to_integer PARAMS ((enum rtx_code));
707static void ix86_fp_comparison_codes PARAMS ((enum rtx_code code,
708 enum rtx_code *,
709 enum rtx_code *,
710 enum rtx_code *));
9e7adcb3
JH
711static rtx ix86_expand_fp_compare PARAMS ((enum rtx_code, rtx, rtx, rtx,
712 rtx *, rtx *));
713static int ix86_fp_comparison_arithmetics_cost PARAMS ((enum rtx_code code));
714static int ix86_fp_comparison_fcomi_cost PARAMS ((enum rtx_code code));
715static int ix86_fp_comparison_sahf_cost PARAMS ((enum rtx_code code));
716static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
37a58036 717static int ix86_save_reg PARAMS ((int, int));
4dd2ac2c 718static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
8d8e52be 719static int ix86_comp_type_attributes PARAMS ((tree, tree));
91d231cb
JM
720const struct attribute_spec ix86_attribute_table[];
721static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
722static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
7c262518 723
2cc07db4
RH
724#ifdef DO_GLOBAL_CTORS_BODY
725static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
726#endif
e56feed6 727
53c17031
JH
728/* Register class used for passing given 64bit part of the argument.
729 These represent classes as documented by the PS ABI, with the exception
730 of SSESF, SSEDF classes, that are basically SSE class, just gcc will
731 use SF or DFmode move instead of DImode to avoid reformating penalties.
732
733 Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
734 whenever possible (upper half does contain padding).
735 */
736enum x86_64_reg_class
737 {
738 X86_64_NO_CLASS,
739 X86_64_INTEGER_CLASS,
740 X86_64_INTEGERSI_CLASS,
741 X86_64_SSE_CLASS,
742 X86_64_SSESF_CLASS,
743 X86_64_SSEDF_CLASS,
744 X86_64_SSEUP_CLASS,
745 X86_64_X87_CLASS,
746 X86_64_X87UP_CLASS,
747 X86_64_MEMORY_CLASS
748 };
749const char * const x86_64_reg_class_name[] =
750 {"no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup", "x87", "x87up", "no"};
751
752#define MAX_CLASSES 4
753static int classify_argument PARAMS ((enum machine_mode, tree,
754 enum x86_64_reg_class [MAX_CLASSES],
755 int));
756static int examine_argument PARAMS ((enum machine_mode, tree, int, int *,
757 int *));
758static rtx construct_container PARAMS ((enum machine_mode, tree, int, int, int,
759 int *, int));
760static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
761 enum x86_64_reg_class));
672a6f42
NB
762\f
763/* Initialize the GCC target structure. */
91d231cb
JM
764#undef TARGET_ATTRIBUTE_TABLE
765#define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
672a6f42 766#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
f5f4be42
NB
767# undef TARGET_MERGE_DECL_ATTRIBUTES
768# define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
672a6f42
NB
769#endif
770
8d8e52be
JM
771#undef TARGET_COMP_TYPE_ATTRIBUTES
772#define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
773
f6155fda
SS
774#undef TARGET_INIT_BUILTINS
775#define TARGET_INIT_BUILTINS ix86_init_builtins
776
777#undef TARGET_EXPAND_BUILTIN
778#define TARGET_EXPAND_BUILTIN ix86_expand_builtin
779
08c148a8
NB
780#if defined (OSF_OS) || defined (TARGET_OSF1ELF)
781 static void ix86_osf_output_function_prologue PARAMS ((FILE *,
782 HOST_WIDE_INT));
783# undef TARGET_ASM_FUNCTION_PROLOGUE
784# define TARGET_ASM_FUNCTION_PROLOGUE ix86_osf_output_function_prologue
785#endif
786
17b53c33
NB
787#undef TARGET_ASM_OPEN_PAREN
788#define TARGET_ASM_OPEN_PAREN ""
789#undef TARGET_ASM_CLOSE_PAREN
790#define TARGET_ASM_CLOSE_PAREN ""
791
301d03af
RS
792#undef TARGET_ASM_ALIGNED_HI_OP
793#define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
794#undef TARGET_ASM_ALIGNED_SI_OP
795#define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
796#ifdef ASM_QUAD
797#undef TARGET_ASM_ALIGNED_DI_OP
798#define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
799#endif
800
801#undef TARGET_ASM_UNALIGNED_HI_OP
802#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
803#undef TARGET_ASM_UNALIGNED_SI_OP
804#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
805#undef TARGET_ASM_UNALIGNED_DI_OP
806#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
807
c237e94a
ZW
808#undef TARGET_SCHED_ADJUST_COST
809#define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
810#undef TARGET_SCHED_ISSUE_RATE
811#define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
812#undef TARGET_SCHED_VARIABLE_ISSUE
813#define TARGET_SCHED_VARIABLE_ISSUE ix86_variable_issue
814#undef TARGET_SCHED_INIT
815#define TARGET_SCHED_INIT ix86_sched_init
816#undef TARGET_SCHED_REORDER
817#define TARGET_SCHED_REORDER ix86_sched_reorder
818
f6897b10 819struct gcc_target targetm = TARGET_INITIALIZER;
e075ae69 820\f
f5316dfe
MM
821/* Sometimes certain combinations of command options do not make
822 sense on a particular target machine. You can define a macro
823 `OVERRIDE_OPTIONS' to take account of this. This macro, if
824 defined, is executed once just after all the command options have
825 been parsed.
826
827 Don't use this macro to turn on various extra optimizations for
828 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
829
830void
831override_options ()
832{
400500c4 833 int i;
e075ae69
RH
834 /* Comes from final.c -- no real reason to change it. */
835#define MAX_CODE_ALIGN 16
f5316dfe 836
c8c5cb99
SC
837 static struct ptt
838 {
8b60264b
KG
839 const struct processor_costs *cost; /* Processor costs */
840 const int target_enable; /* Target flags to enable. */
841 const int target_disable; /* Target flags to disable. */
842 const int align_loop; /* Default alignments. */
2cca7283 843 const int align_loop_max_skip;
8b60264b 844 const int align_jump;
2cca7283 845 const int align_jump_max_skip;
8b60264b
KG
846 const int align_func;
847 const int branch_cost;
e075ae69 848 }
0f290768 849 const processor_target_table[PROCESSOR_max] =
e075ae69 850 {
2cca7283
JH
851 {&i386_cost, 0, 0, 4, 3, 4, 3, 4, 1},
852 {&i486_cost, 0, 0, 16, 15, 16, 15, 16, 1},
853 {&pentium_cost, 0, 0, 16, 7, 16, 7, 16, 1},
854 {&pentiumpro_cost, 0, 0, 16, 15, 16, 7, 16, 1},
855 {&k6_cost, 0, 0, 32, 7, 32, 7, 32, 1},
856 {&athlon_cost, 0, 0, 16, 7, 64, 7, 16, 1},
857 {&pentium4_cost, 0, 0, 0, 0, 0, 0, 0, 1}
e075ae69
RH
858 };
859
f4365627 860 static const char * const cpu_names[] = TARGET_CPU_DEFAULT_NAMES;
e075ae69
RH
861 static struct pta
862 {
8b60264b
KG
863 const char *const name; /* processor name or nickname. */
864 const enum processor_type processor;
0dd0e980
JH
865 const enum pta_flags
866 {
867 PTA_SSE = 1,
868 PTA_SSE2 = 2,
869 PTA_MMX = 4,
f4365627 870 PTA_PREFETCH_SSE = 8,
0dd0e980
JH
871 PTA_3DNOW = 16,
872 PTA_3DNOW_A = 64
873 } flags;
e075ae69 874 }
0f290768 875 const processor_alias_table[] =
e075ae69 876 {
0dd0e980
JH
877 {"i386", PROCESSOR_I386, 0},
878 {"i486", PROCESSOR_I486, 0},
879 {"i586", PROCESSOR_PENTIUM, 0},
880 {"pentium", PROCESSOR_PENTIUM, 0},
881 {"pentium-mmx", PROCESSOR_PENTIUM, PTA_MMX},
882 {"i686", PROCESSOR_PENTIUMPRO, 0},
883 {"pentiumpro", PROCESSOR_PENTIUMPRO, 0},
884 {"pentium2", PROCESSOR_PENTIUMPRO, PTA_MMX},
f4365627 885 {"pentium3", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_PREFETCH_SSE},
0dd0e980 886 {"pentium4", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2 |
f4365627 887 PTA_MMX | PTA_PREFETCH_SSE},
0dd0e980
JH
888 {"k6", PROCESSOR_K6, PTA_MMX},
889 {"k6-2", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
890 {"k6-3", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
f4365627 891 {"athlon", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
0dd0e980 892 | PTA_3DNOW_A},
f4365627 893 {"athlon-tbird", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE
0dd0e980 894 | PTA_3DNOW | PTA_3DNOW_A},
f4365627 895 {"athlon-4", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
0dd0e980 896 | PTA_3DNOW_A | PTA_SSE},
f4365627 897 {"athlon-xp", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
0dd0e980 898 | PTA_3DNOW_A | PTA_SSE},
f4365627 899 {"athlon-mp", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
0dd0e980 900 | PTA_3DNOW_A | PTA_SSE},
3af4bd89 901 };
c8c5cb99 902
0f290768 903 int const pta_size = sizeof (processor_alias_table) / sizeof (struct pta);
c8c5cb99 904
f5316dfe
MM
905#ifdef SUBTARGET_OVERRIDE_OPTIONS
906 SUBTARGET_OVERRIDE_OPTIONS;
907#endif
908
f4365627
JH
909 if (!ix86_cpu_string && ix86_arch_string)
910 ix86_cpu_string = ix86_arch_string;
911 if (!ix86_cpu_string)
912 ix86_cpu_string = cpu_names [TARGET_CPU_DEFAULT];
913 if (!ix86_arch_string)
914 ix86_arch_string = TARGET_64BIT ? "athlon-4" : "i386";
e075ae69 915
6189a572
JH
916 if (ix86_cmodel_string != 0)
917 {
918 if (!strcmp (ix86_cmodel_string, "small"))
919 ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
920 else if (flag_pic)
c725bd79 921 sorry ("code model %s not supported in PIC mode", ix86_cmodel_string);
6189a572
JH
922 else if (!strcmp (ix86_cmodel_string, "32"))
923 ix86_cmodel = CM_32;
924 else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic)
925 ix86_cmodel = CM_KERNEL;
926 else if (!strcmp (ix86_cmodel_string, "medium") && !flag_pic)
927 ix86_cmodel = CM_MEDIUM;
928 else if (!strcmp (ix86_cmodel_string, "large") && !flag_pic)
929 ix86_cmodel = CM_LARGE;
930 else
931 error ("bad value (%s) for -mcmodel= switch", ix86_cmodel_string);
932 }
933 else
934 {
935 ix86_cmodel = CM_32;
936 if (TARGET_64BIT)
937 ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
938 }
c93e80a5
JH
939 if (ix86_asm_string != 0)
940 {
941 if (!strcmp (ix86_asm_string, "intel"))
942 ix86_asm_dialect = ASM_INTEL;
943 else if (!strcmp (ix86_asm_string, "att"))
944 ix86_asm_dialect = ASM_ATT;
945 else
946 error ("bad value (%s) for -masm= switch", ix86_asm_string);
947 }
6189a572 948 if ((TARGET_64BIT == 0) != (ix86_cmodel == CM_32))
c725bd79 949 error ("code model `%s' not supported in the %s bit mode",
6189a572
JH
950 ix86_cmodel_string, TARGET_64BIT ? "64" : "32");
951 if (ix86_cmodel == CM_LARGE)
c725bd79 952 sorry ("code model `large' not supported yet");
0c2dc519 953 if ((TARGET_64BIT != 0) != ((target_flags & MASK_64BIT) != 0))
c725bd79 954 sorry ("%i-bit mode not compiled in",
0c2dc519 955 (target_flags & MASK_64BIT) ? 64 : 32);
6189a572 956
f4365627
JH
957 for (i = 0; i < pta_size; i++)
958 if (! strcmp (ix86_arch_string, processor_alias_table[i].name))
959 {
960 ix86_arch = processor_alias_table[i].processor;
961 /* Default cpu tuning to the architecture. */
962 ix86_cpu = ix86_arch;
963 if (processor_alias_table[i].flags & PTA_MMX
964 && !(target_flags & MASK_MMX_SET))
965 target_flags |= MASK_MMX;
966 if (processor_alias_table[i].flags & PTA_3DNOW
967 && !(target_flags & MASK_3DNOW_SET))
968 target_flags |= MASK_3DNOW;
969 if (processor_alias_table[i].flags & PTA_3DNOW_A
970 && !(target_flags & MASK_3DNOW_A_SET))
971 target_flags |= MASK_3DNOW_A;
972 if (processor_alias_table[i].flags & PTA_SSE
973 && !(target_flags & MASK_SSE_SET))
974 target_flags |= MASK_SSE;
975 if (processor_alias_table[i].flags & PTA_SSE2
976 && !(target_flags & MASK_SSE2_SET))
977 target_flags |= MASK_SSE2;
978 if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
979 x86_prefetch_sse = true;
980 break;
981 }
400500c4 982
f4365627
JH
983 if (i == pta_size)
984 error ("bad value (%s) for -march= switch", ix86_arch_string);
e075ae69 985
f4365627
JH
986 for (i = 0; i < pta_size; i++)
987 if (! strcmp (ix86_cpu_string, processor_alias_table[i].name))
988 {
989 ix86_cpu = processor_alias_table[i].processor;
990 break;
991 }
992 if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
993 x86_prefetch_sse = true;
994 if (i == pta_size)
995 error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
e075ae69 996
2ab0437e
JH
997 if (optimize_size)
998 ix86_cost = &size_cost;
999 else
1000 ix86_cost = processor_target_table[ix86_cpu].cost;
e075ae69
RH
1001 target_flags |= processor_target_table[ix86_cpu].target_enable;
1002 target_flags &= ~processor_target_table[ix86_cpu].target_disable;
1003
36edd3cc
BS
1004 /* Arrange to set up i386_stack_locals for all functions. */
1005 init_machine_status = ix86_init_machine_status;
1526a060 1006 mark_machine_status = ix86_mark_machine_status;
37b15744 1007 free_machine_status = ix86_free_machine_status;
36edd3cc 1008
0f290768 1009 /* Validate -mregparm= value. */
e075ae69 1010 if (ix86_regparm_string)
b08de47e 1011 {
400500c4
RK
1012 i = atoi (ix86_regparm_string);
1013 if (i < 0 || i > REGPARM_MAX)
1014 error ("-mregparm=%d is not between 0 and %d", i, REGPARM_MAX);
1015 else
1016 ix86_regparm = i;
b08de47e 1017 }
0d7d98ee
JH
1018 else
1019 if (TARGET_64BIT)
1020 ix86_regparm = REGPARM_MAX;
b08de47e 1021
3e18fdf6 1022 /* If the user has provided any of the -malign-* options,
a4f31c00 1023 warn and use that value only if -falign-* is not set.
3e18fdf6 1024 Remove this code in GCC 3.2 or later. */
e075ae69 1025 if (ix86_align_loops_string)
b08de47e 1026 {
3e18fdf6
GK
1027 warning ("-malign-loops is obsolete, use -falign-loops");
1028 if (align_loops == 0)
1029 {
1030 i = atoi (ix86_align_loops_string);
1031 if (i < 0 || i > MAX_CODE_ALIGN)
1032 error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
1033 else
1034 align_loops = 1 << i;
1035 }
b08de47e 1036 }
3af4bd89 1037
e075ae69 1038 if (ix86_align_jumps_string)
b08de47e 1039 {
3e18fdf6
GK
1040 warning ("-malign-jumps is obsolete, use -falign-jumps");
1041 if (align_jumps == 0)
1042 {
1043 i = atoi (ix86_align_jumps_string);
1044 if (i < 0 || i > MAX_CODE_ALIGN)
1045 error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
1046 else
1047 align_jumps = 1 << i;
1048 }
b08de47e 1049 }
b08de47e 1050
e075ae69 1051 if (ix86_align_funcs_string)
b08de47e 1052 {
3e18fdf6
GK
1053 warning ("-malign-functions is obsolete, use -falign-functions");
1054 if (align_functions == 0)
1055 {
1056 i = atoi (ix86_align_funcs_string);
1057 if (i < 0 || i > MAX_CODE_ALIGN)
1058 error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
1059 else
1060 align_functions = 1 << i;
1061 }
b08de47e 1062 }
3af4bd89 1063
3e18fdf6
GK
1064 /* Default align_* from the processor table. */
1065#define abs(n) (n < 0 ? -n : n)
1066 if (align_loops == 0)
2cca7283
JH
1067 {
1068 align_loops = processor_target_table[ix86_cpu].align_loop;
1069 align_loops_max_skip = processor_target_table[ix86_cpu].align_loop_max_skip;
1070 }
3e18fdf6 1071 if (align_jumps == 0)
2cca7283
JH
1072 {
1073 align_jumps = processor_target_table[ix86_cpu].align_jump;
1074 align_jumps_max_skip = processor_target_table[ix86_cpu].align_jump_max_skip;
1075 }
3e18fdf6 1076 if (align_functions == 0)
2cca7283
JH
1077 {
1078 align_functions = processor_target_table[ix86_cpu].align_func;
1079 }
3e18fdf6 1080
e4c0478d 1081 /* Validate -mpreferred-stack-boundary= value, or provide default.
fbb83b43
AO
1082 The default of 128 bits is for Pentium III's SSE __m128, but we
1083 don't want additional code to keep the stack aligned when
1084 optimizing for code size. */
1085 ix86_preferred_stack_boundary = (optimize_size
1086 ? TARGET_64BIT ? 64 : 32
1087 : 128);
e075ae69 1088 if (ix86_preferred_stack_boundary_string)
3af4bd89 1089 {
400500c4 1090 i = atoi (ix86_preferred_stack_boundary_string);
c6257c5d
AO
1091 if (i < (TARGET_64BIT ? 3 : 2) || i > 12)
1092 error ("-mpreferred-stack-boundary=%d is not between %d and 12", i,
0d7d98ee 1093 TARGET_64BIT ? 3 : 2);
400500c4
RK
1094 else
1095 ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
3af4bd89 1096 }
77a989d1 1097
0f290768 1098 /* Validate -mbranch-cost= value, or provide default. */
e075ae69
RH
1099 ix86_branch_cost = processor_target_table[ix86_cpu].branch_cost;
1100 if (ix86_branch_cost_string)
804a8ee0 1101 {
400500c4
RK
1102 i = atoi (ix86_branch_cost_string);
1103 if (i < 0 || i > 5)
1104 error ("-mbranch-cost=%d is not between 0 and 5", i);
1105 else
1106 ix86_branch_cost = i;
804a8ee0 1107 }
804a8ee0 1108
e9a25f70
JL
1109 /* Keep nonleaf frame pointers. */
1110 if (TARGET_OMIT_LEAF_FRAME_POINTER)
77a989d1 1111 flag_omit_frame_pointer = 1;
e075ae69
RH
1112
1113 /* If we're doing fast math, we don't care about comparison order
1114 wrt NaNs. This lets us use a shorter comparison sequence. */
de6c5979 1115 if (flag_unsafe_math_optimizations)
e075ae69
RH
1116 target_flags &= ~MASK_IEEE_FP;
1117
14f73b5a
JH
1118 if (TARGET_64BIT)
1119 {
1120 if (TARGET_ALIGN_DOUBLE)
c725bd79 1121 error ("-malign-double makes no sense in the 64bit mode");
14f73b5a 1122 if (TARGET_RTD)
c725bd79 1123 error ("-mrtd calling convention not supported in the 64bit mode");
14f73b5a 1124 /* Enable by default the SSE and MMX builtins. */
965f5423
JH
1125 target_flags |= (MASK_SSE2 | MASK_SSE | MASK_MMX | MASK_128BIT_LONG_DOUBLE);
1126 ix86_fpmath = FPMATH_SSE;
14f73b5a 1127 }
965f5423
JH
1128 else
1129 ix86_fpmath = FPMATH_387;
1130
1131 if (ix86_fpmath_string != 0)
1132 {
1133 if (! strcmp (ix86_fpmath_string, "387"))
1134 ix86_fpmath = FPMATH_387;
1135 else if (! strcmp (ix86_fpmath_string, "sse"))
1136 {
1137 if (!TARGET_SSE)
1138 {
1139 warning ("SSE instruction set disabled, using 387 arithmetics");
1140 ix86_fpmath = FPMATH_387;
1141 }
1142 else
1143 ix86_fpmath = FPMATH_SSE;
1144 }
1145 else if (! strcmp (ix86_fpmath_string, "387,sse")
1146 || ! strcmp (ix86_fpmath_string, "sse,387"))
1147 {
1148 if (!TARGET_SSE)
1149 {
1150 warning ("SSE instruction set disabled, using 387 arithmetics");
1151 ix86_fpmath = FPMATH_387;
1152 }
1153 else if (!TARGET_80387)
1154 {
1155 warning ("387 instruction set disabled, using SSE arithmetics");
1156 ix86_fpmath = FPMATH_SSE;
1157 }
1158 else
1159 ix86_fpmath = FPMATH_SSE | FPMATH_387;
1160 }
1161 else
1162 error ("bad value (%s) for -mfpmath= switch", ix86_fpmath_string);
1163 }
14f73b5a 1164
a7180f70
BS
1165 /* It makes no sense to ask for just SSE builtins, so MMX is also turned
1166 on by -msse. */
1167 if (TARGET_SSE)
1168 target_flags |= MASK_MMX;
c6036a37 1169
47f339cf
BS
1170 /* If it has 3DNow! it also has MMX so MMX is also turned on by -m3dnow */
1171 if (TARGET_3DNOW)
1172 {
1173 target_flags |= MASK_MMX;
1174 /* If we are targetting the Athlon architecture, enable the 3Dnow/MMX
1175 extensions it adds. */
1176 if (x86_3dnow_a & (1 << ix86_arch))
1177 target_flags |= MASK_3DNOW_A;
1178 }
c6036a37 1179 if ((x86_accumulate_outgoing_args & CPUMASK)
0dd0e980 1180 && !(target_flags & MASK_ACCUMULATE_OUTGOING_ARGS_SET)
c6036a37
JH
1181 && !optimize_size)
1182 target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
623fe810
RH
1183
1184 /* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix. */
1185 {
1186 char *p;
1187 ASM_GENERATE_INTERNAL_LABEL (internal_label_prefix, "LX", 0);
1188 p = strchr (internal_label_prefix, 'X');
1189 internal_label_prefix_len = p - internal_label_prefix;
1190 *p = '\0';
1191 }
f5316dfe
MM
1192}
1193\f
32b5b1aa 1194void
c6aded7c 1195optimization_options (level, size)
32b5b1aa 1196 int level;
bb5177ac 1197 int size ATTRIBUTE_UNUSED;
32b5b1aa 1198{
e9a25f70
JL
1199 /* For -O2 and beyond, turn off -fschedule-insns by default. It tends to
1200 make the problem with not enough registers even worse. */
32b5b1aa
SC
1201#ifdef INSN_SCHEDULING
1202 if (level > 1)
1203 flag_schedule_insns = 0;
1204#endif
53c17031
JH
1205 if (TARGET_64BIT && optimize >= 1)
1206 flag_omit_frame_pointer = 1;
1207 if (TARGET_64BIT)
b932f770
JH
1208 {
1209 flag_pcc_struct_return = 0;
1210 flag_asynchronous_unwind_tables = 1;
1211 }
32b5b1aa 1212}
b08de47e 1213\f
91d231cb
JM
1214/* Table of valid machine attributes. */
1215const struct attribute_spec ix86_attribute_table[] =
b08de47e 1216{
91d231cb 1217 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
b08de47e
MM
1218 /* Stdcall attribute says callee is responsible for popping arguments
1219 if they are not variable. */
91d231cb
JM
1220 { "stdcall", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
1221 /* Cdecl attribute says the callee is a normal C declaration */
1222 { "cdecl", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
b08de47e 1223 /* Regparm attribute specifies how many integer arguments are to be
0f290768 1224 passed in registers. */
91d231cb
JM
1225 { "regparm", 1, 1, false, true, true, ix86_handle_regparm_attribute },
1226#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
3da1eb0b
DS
1227 { "dllimport", 0, 0, false, false, false, ix86_handle_dll_attribute },
1228 { "dllexport", 0, 0, false, false, false, ix86_handle_dll_attribute },
1229 { "shared", 0, 0, true, false, false, ix86_handle_shared_attribute },
91d231cb
JM
1230#endif
1231 { NULL, 0, 0, false, false, false, NULL }
1232};
1233
1234/* Handle a "cdecl" or "stdcall" attribute;
1235 arguments as in struct attribute_spec.handler. */
1236static tree
1237ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)
1238 tree *node;
1239 tree name;
1240 tree args ATTRIBUTE_UNUSED;
1241 int flags ATTRIBUTE_UNUSED;
1242 bool *no_add_attrs;
1243{
1244 if (TREE_CODE (*node) != FUNCTION_TYPE
1245 && TREE_CODE (*node) != METHOD_TYPE
1246 && TREE_CODE (*node) != FIELD_DECL
1247 && TREE_CODE (*node) != TYPE_DECL)
b08de47e 1248 {
91d231cb
JM
1249 warning ("`%s' attribute only applies to functions",
1250 IDENTIFIER_POINTER (name));
1251 *no_add_attrs = true;
1252 }
b08de47e 1253
91d231cb
JM
1254 if (TARGET_64BIT)
1255 {
1256 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1257 *no_add_attrs = true;
1258 }
b08de47e 1259
91d231cb
JM
1260 return NULL_TREE;
1261}
b08de47e 1262
91d231cb
JM
1263/* Handle a "regparm" attribute;
1264 arguments as in struct attribute_spec.handler. */
1265static tree
1266ix86_handle_regparm_attribute (node, name, args, flags, no_add_attrs)
1267 tree *node;
1268 tree name;
1269 tree args;
1270 int flags ATTRIBUTE_UNUSED;
1271 bool *no_add_attrs;
1272{
1273 if (TREE_CODE (*node) != FUNCTION_TYPE
1274 && TREE_CODE (*node) != METHOD_TYPE
1275 && TREE_CODE (*node) != FIELD_DECL
1276 && TREE_CODE (*node) != TYPE_DECL)
1277 {
1278 warning ("`%s' attribute only applies to functions",
1279 IDENTIFIER_POINTER (name));
1280 *no_add_attrs = true;
1281 }
1282 else
1283 {
1284 tree cst;
b08de47e 1285
91d231cb
JM
1286 cst = TREE_VALUE (args);
1287 if (TREE_CODE (cst) != INTEGER_CST)
1288 {
1289 warning ("`%s' attribute requires an integer constant argument",
1290 IDENTIFIER_POINTER (name));
1291 *no_add_attrs = true;
1292 }
1293 else if (compare_tree_int (cst, REGPARM_MAX) > 0)
1294 {
1295 warning ("argument to `%s' attribute larger than %d",
1296 IDENTIFIER_POINTER (name), REGPARM_MAX);
1297 *no_add_attrs = true;
1298 }
b08de47e
MM
1299 }
1300
91d231cb 1301 return NULL_TREE;
b08de47e
MM
1302}
1303
08c148a8
NB
1304#if defined (OSF_OS) || defined (TARGET_OSF1ELF)
1305
1306/* Generate the assembly code for function entry. FILE is a stdio
1307 stream to output the code to. SIZE is an int: how many units of
1308 temporary storage to allocate.
1309
1310 Refer to the array `regs_ever_live' to determine which registers to
1311 save; `regs_ever_live[I]' is nonzero if register number I is ever
1312 used in the function. This function is responsible for knowing
1313 which registers should not be saved even if used.
1314
1315 We override it here to allow for the new profiling code to go before
1316 the prologue and the old mcount code to go after the prologue (and
1317 after %ebx has been set up for ELF shared library support). */
1318
1319static void
1320ix86_osf_output_function_prologue (file, size)
1321 FILE *file;
1322 HOST_WIDE_INT size;
1323{
5f37d07c
KG
1324 const char *prefix = "";
1325 const char *const lprefix = LPREFIX;
08c148a8
NB
1326 int labelno = profile_label_no;
1327
1328#ifdef OSF_OS
1329
1330 if (TARGET_UNDERSCORES)
1331 prefix = "_";
1332
1333 if (profile_flag && OSF_PROFILE_BEFORE_PROLOGUE)
1334 {
1335 if (!flag_pic && !HALF_PIC_P ())
1336 {
1337 fprintf (file, "\tmovl $%sP%d,%%edx\n", lprefix, labelno);
1338 fprintf (file, "\tcall *%s_mcount_ptr\n", prefix);
1339 }
1340
1341 else if (HALF_PIC_P ())
1342 {
1343 rtx symref;
1344
1345 HALF_PIC_EXTERNAL ("_mcount_ptr");
1346 symref = HALF_PIC_PTR (gen_rtx_SYMBOL_REF (Pmode,
1347 "_mcount_ptr"));
1348
1349 fprintf (file, "\tmovl $%sP%d,%%edx\n", lprefix, labelno);
1350 fprintf (file, "\tmovl %s%s,%%eax\n", prefix,
1351 XSTR (symref, 0));
1352 fprintf (file, "\tcall *(%%eax)\n");
1353 }
1354
1355 else
1356 {
1357 static int call_no = 0;
1358
1359 fprintf (file, "\tcall %sPc%d\n", lprefix, call_no);
1360 fprintf (file, "%sPc%d:\tpopl %%eax\n", lprefix, call_no);
1361 fprintf (file, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-%sPc%d],%%eax\n",
1362 lprefix, call_no++);
1363 fprintf (file, "\tleal %sP%d@GOTOFF(%%eax),%%edx\n",
1364 lprefix, labelno);
1365 fprintf (file, "\tmovl %s_mcount_ptr@GOT(%%eax),%%eax\n",
1366 prefix);
1367 fprintf (file, "\tcall *(%%eax)\n");
1368 }
1369 }
1370
1371#else /* !OSF_OS */
1372
1373 if (profile_flag && OSF_PROFILE_BEFORE_PROLOGUE)
1374 {
1375 if (!flag_pic)
1376 {
1377 fprintf (file, "\tmovl $%sP%d,%%edx\n", lprefix, labelno);
1378 fprintf (file, "\tcall *%s_mcount_ptr\n", prefix);
1379 }
1380
1381 else
1382 {
1383 static int call_no = 0;
1384
1385 fprintf (file, "\tcall %sPc%d\n", lprefix, call_no);
1386 fprintf (file, "%sPc%d:\tpopl %%eax\n", lprefix, call_no);
1387 fprintf (file, "\taddl $_GLOBAL_OFFSET_TABLE_+[.-%sPc%d],%%eax\n",
1388 lprefix, call_no++);
1389 fprintf (file, "\tleal %sP%d@GOTOFF(%%eax),%%edx\n",
1390 lprefix, labelno);
1391 fprintf (file, "\tmovl %s_mcount_ptr@GOT(%%eax),%%eax\n",
1392 prefix);
1393 fprintf (file, "\tcall *(%%eax)\n");
1394 }
1395 }
1396#endif /* !OSF_OS */
1397
1398 function_prologue (file, size);
1399}
1400
1401#endif /* OSF_OS || TARGET_OSF1ELF */
1402
b08de47e
MM
1403/* Return 0 if the attributes for two types are incompatible, 1 if they
1404 are compatible, and 2 if they are nearly compatible (which causes a
1405 warning to be generated). */
1406
8d8e52be 1407static int
e075ae69 1408ix86_comp_type_attributes (type1, type2)
afcfe58c
MM
1409 tree type1;
1410 tree type2;
b08de47e 1411{
0f290768 1412 /* Check for mismatch of non-default calling convention. */
27c38fbe 1413 const char *const rtdstr = TARGET_RTD ? "cdecl" : "stdcall";
afcfe58c
MM
1414
1415 if (TREE_CODE (type1) != FUNCTION_TYPE)
1416 return 1;
1417
1418 /* Check for mismatched return types (cdecl vs stdcall). */
6093f019
RH
1419 if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
1420 != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
afcfe58c 1421 return 0;
b08de47e
MM
1422 return 1;
1423}
b08de47e
MM
1424\f
1425/* Value is the number of bytes of arguments automatically
1426 popped when returning from a subroutine call.
1427 FUNDECL is the declaration node of the function (as a tree),
1428 FUNTYPE is the data type of the function (as a tree),
1429 or for a library call it is an identifier node for the subroutine name.
1430 SIZE is the number of bytes of arguments passed on the stack.
1431
1432 On the 80386, the RTD insn may be used to pop them if the number
1433 of args is fixed, but if the number is variable then the caller
1434 must pop them all. RTD can't be used for library calls now
1435 because the library is compiled with the Unix compiler.
1436 Use of RTD is a selectable option, since it is incompatible with
1437 standard Unix calling sequences. If the option is not selected,
1438 the caller must always pop the args.
1439
1440 The attribute stdcall is equivalent to RTD on a per module basis. */
1441
1442int
e075ae69 1443ix86_return_pops_args (fundecl, funtype, size)
b08de47e
MM
1444 tree fundecl;
1445 tree funtype;
1446 int size;
79325812 1447{
3345ee7d 1448 int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
b08de47e 1449
0f290768 1450 /* Cdecl functions override -mrtd, and never pop the stack. */
e9a25f70 1451 if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
79325812 1452
0f290768 1453 /* Stdcall functions will pop the stack if not variable args. */
698cdd84
SC
1454 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
1455 rtd = 1;
79325812 1456
698cdd84
SC
1457 if (rtd
1458 && (TYPE_ARG_TYPES (funtype) == NULL_TREE
e9a25f70
JL
1459 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype)))
1460 == void_type_node)))
698cdd84
SC
1461 return size;
1462 }
79325812 1463
e9a25f70 1464 /* Lose any fake structure return argument. */
0d7d98ee
JH
1465 if (aggregate_value_p (TREE_TYPE (funtype))
1466 && !TARGET_64BIT)
698cdd84 1467 return GET_MODE_SIZE (Pmode);
79325812 1468
2614aac6 1469 return 0;
b08de47e 1470}
b08de47e
MM
1471\f
1472/* Argument support functions. */
1473
53c17031
JH
1474/* Return true when register may be used to pass function parameters. */
1475bool
1476ix86_function_arg_regno_p (regno)
1477 int regno;
1478{
1479 int i;
1480 if (!TARGET_64BIT)
1481 return regno < REGPARM_MAX || (TARGET_SSE && SSE_REGNO_P (regno));
1482 if (SSE_REGNO_P (regno) && TARGET_SSE)
1483 return true;
1484 /* RAX is used as hidden argument to va_arg functions. */
1485 if (!regno)
1486 return true;
1487 for (i = 0; i < REGPARM_MAX; i++)
1488 if (regno == x86_64_int_parameter_registers[i])
1489 return true;
1490 return false;
1491}
1492
b08de47e
MM
1493/* Initialize a variable CUM of type CUMULATIVE_ARGS
1494 for a call to a function whose data type is FNTYPE.
1495 For a library call, FNTYPE is 0. */
1496
1497void
1498init_cumulative_args (cum, fntype, libname)
e9a25f70 1499 CUMULATIVE_ARGS *cum; /* Argument info to initialize */
b08de47e
MM
1500 tree fntype; /* tree ptr for function decl */
1501 rtx libname; /* SYMBOL_REF of library name or 0 */
1502{
1503 static CUMULATIVE_ARGS zero_cum;
1504 tree param, next_param;
1505
1506 if (TARGET_DEBUG_ARG)
1507 {
1508 fprintf (stderr, "\ninit_cumulative_args (");
1509 if (fntype)
e9a25f70
JL
1510 fprintf (stderr, "fntype code = %s, ret code = %s",
1511 tree_code_name[(int) TREE_CODE (fntype)],
1512 tree_code_name[(int) TREE_CODE (TREE_TYPE (fntype))]);
b08de47e
MM
1513 else
1514 fprintf (stderr, "no fntype");
1515
1516 if (libname)
1517 fprintf (stderr, ", libname = %s", XSTR (libname, 0));
1518 }
1519
1520 *cum = zero_cum;
1521
1522 /* Set up the number of registers to use for passing arguments. */
e075ae69 1523 cum->nregs = ix86_regparm;
53c17031
JH
1524 cum->sse_nregs = SSE_REGPARM_MAX;
1525 if (fntype && !TARGET_64BIT)
b08de47e
MM
1526 {
1527 tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
e9a25f70 1528
b08de47e
MM
1529 if (attr)
1530 cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
1531 }
53c17031 1532 cum->maybe_vaarg = false;
b08de47e
MM
1533
1534 /* Determine if this function has variable arguments. This is
1535 indicated by the last argument being 'void_type_mode' if there
1536 are no variable arguments. If there are variable arguments, then
1537 we won't pass anything in registers */
1538
1539 if (cum->nregs)
1540 {
1541 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
e9a25f70 1542 param != 0; param = next_param)
b08de47e
MM
1543 {
1544 next_param = TREE_CHAIN (param);
e9a25f70 1545 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
53c17031
JH
1546 {
1547 if (!TARGET_64BIT)
1548 cum->nregs = 0;
1549 cum->maybe_vaarg = true;
1550 }
b08de47e
MM
1551 }
1552 }
53c17031
JH
1553 if ((!fntype && !libname)
1554 || (fntype && !TYPE_ARG_TYPES (fntype)))
1555 cum->maybe_vaarg = 1;
b08de47e
MM
1556
1557 if (TARGET_DEBUG_ARG)
1558 fprintf (stderr, ", nregs=%d )\n", cum->nregs);
1559
1560 return;
1561}
1562
53c17031 1563/* x86-64 register passing impleemntation. See x86-64 ABI for details. Goal
f710504c 1564 of this code is to classify each 8bytes of incoming argument by the register
53c17031
JH
1565 class and assign registers accordingly. */
1566
1567/* Return the union class of CLASS1 and CLASS2.
1568 See the x86-64 PS ABI for details. */
1569
1570static enum x86_64_reg_class
1571merge_classes (class1, class2)
1572 enum x86_64_reg_class class1, class2;
1573{
1574 /* Rule #1: If both classes are equal, this is the resulting class. */
1575 if (class1 == class2)
1576 return class1;
1577
1578 /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
1579 the other class. */
1580 if (class1 == X86_64_NO_CLASS)
1581 return class2;
1582 if (class2 == X86_64_NO_CLASS)
1583 return class1;
1584
1585 /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
1586 if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
1587 return X86_64_MEMORY_CLASS;
1588
1589 /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
1590 if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
1591 || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
1592 return X86_64_INTEGERSI_CLASS;
1593 if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
1594 || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
1595 return X86_64_INTEGER_CLASS;
1596
1597 /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
1598 if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
1599 || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
1600 return X86_64_MEMORY_CLASS;
1601
1602 /* Rule #6: Otherwise class SSE is used. */
1603 return X86_64_SSE_CLASS;
1604}
1605
1606/* Classify the argument of type TYPE and mode MODE.
1607 CLASSES will be filled by the register class used to pass each word
1608 of the operand. The number of words is returned. In case the parameter
1609 should be passed in memory, 0 is returned. As a special case for zero
1610 sized containers, classes[0] will be NO_CLASS and 1 is returned.
1611
1612 BIT_OFFSET is used internally for handling records and specifies offset
1613 of the offset in bits modulo 256 to avoid overflow cases.
1614
1615 See the x86-64 PS ABI for details.
1616*/
1617
1618static int
1619classify_argument (mode, type, classes, bit_offset)
1620 enum machine_mode mode;
1621 tree type;
1622 enum x86_64_reg_class classes[MAX_CLASSES];
1623 int bit_offset;
1624{
1625 int bytes =
1626 (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
1627 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1628
1629 if (type && AGGREGATE_TYPE_P (type))
1630 {
1631 int i;
1632 tree field;
1633 enum x86_64_reg_class subclasses[MAX_CLASSES];
1634
1635 /* On x86-64 we pass structures larger than 16 bytes on the stack. */
1636 if (bytes > 16)
1637 return 0;
1638
1639 for (i = 0; i < words; i++)
1640 classes[i] = X86_64_NO_CLASS;
1641
1642 /* Zero sized arrays or structures are NO_CLASS. We return 0 to
1643 signalize memory class, so handle it as special case. */
1644 if (!words)
1645 {
1646 classes[0] = X86_64_NO_CLASS;
1647 return 1;
1648 }
1649
1650 /* Classify each field of record and merge classes. */
1651 if (TREE_CODE (type) == RECORD_TYPE)
1652 {
1653 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1654 {
1655 if (TREE_CODE (field) == FIELD_DECL)
1656 {
1657 int num;
1658
1659 /* Bitfields are always classified as integer. Handle them
1660 early, since later code would consider them to be
1661 misaligned integers. */
1662 if (DECL_BIT_FIELD (field))
1663 {
1664 for (i = int_bit_position (field) / 8 / 8;
1665 i < (int_bit_position (field)
1666 + tree_low_cst (DECL_SIZE (field), 0)
1667 + 63) / 8 / 8; i++)
1668 classes[i] =
1669 merge_classes (X86_64_INTEGER_CLASS,
1670 classes[i]);
1671 }
1672 else
1673 {
1674 num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
1675 TREE_TYPE (field), subclasses,
1676 (int_bit_position (field)
1677 + bit_offset) % 256);
1678 if (!num)
1679 return 0;
1680 for (i = 0; i < num; i++)
1681 {
1682 int pos =
1683 (int_bit_position (field) + bit_offset) / 8 / 8;
1684 classes[i + pos] =
1685 merge_classes (subclasses[i], classes[i + pos]);
1686 }
1687 }
1688 }
1689 }
1690 }
1691 /* Arrays are handled as small records. */
1692 else if (TREE_CODE (type) == ARRAY_TYPE)
1693 {
1694 int num;
1695 num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
1696 TREE_TYPE (type), subclasses, bit_offset);
1697 if (!num)
1698 return 0;
1699
1700 /* The partial classes are now full classes. */
1701 if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
1702 subclasses[0] = X86_64_SSE_CLASS;
1703 if (subclasses[0] == X86_64_INTEGERSI_CLASS && bytes != 4)
1704 subclasses[0] = X86_64_INTEGER_CLASS;
1705
1706 for (i = 0; i < words; i++)
1707 classes[i] = subclasses[i % num];
1708 }
1709 /* Unions are similar to RECORD_TYPE but offset is always 0. */
1710 else if (TREE_CODE (type) == UNION_TYPE)
1711 {
1712 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1713 {
1714 if (TREE_CODE (field) == FIELD_DECL)
1715 {
1716 int num;
1717 num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
1718 TREE_TYPE (field), subclasses,
1719 bit_offset);
1720 if (!num)
1721 return 0;
1722 for (i = 0; i < num; i++)
1723 classes[i] = merge_classes (subclasses[i], classes[i]);
1724 }
1725 }
1726 }
1727 else
1728 abort ();
1729
1730 /* Final merger cleanup. */
1731 for (i = 0; i < words; i++)
1732 {
1733 /* If one class is MEMORY, everything should be passed in
1734 memory. */
1735 if (classes[i] == X86_64_MEMORY_CLASS)
1736 return 0;
1737
d6a7951f 1738 /* The X86_64_SSEUP_CLASS should be always preceded by
53c17031
JH
1739 X86_64_SSE_CLASS. */
1740 if (classes[i] == X86_64_SSEUP_CLASS
1741 && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
1742 classes[i] = X86_64_SSE_CLASS;
1743
d6a7951f 1744 /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
53c17031
JH
1745 if (classes[i] == X86_64_X87UP_CLASS
1746 && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
1747 classes[i] = X86_64_SSE_CLASS;
1748 }
1749 return words;
1750 }
1751
1752 /* Compute alignment needed. We align all types to natural boundaries with
1753 exception of XFmode that is aligned to 64bits. */
1754 if (mode != VOIDmode && mode != BLKmode)
1755 {
1756 int mode_alignment = GET_MODE_BITSIZE (mode);
1757
1758 if (mode == XFmode)
1759 mode_alignment = 128;
1760 else if (mode == XCmode)
1761 mode_alignment = 256;
f5143c46 1762 /* Misaligned fields are always returned in memory. */
53c17031
JH
1763 if (bit_offset % mode_alignment)
1764 return 0;
1765 }
1766
1767 /* Classification of atomic types. */
1768 switch (mode)
1769 {
1770 case DImode:
1771 case SImode:
1772 case HImode:
1773 case QImode:
1774 case CSImode:
1775 case CHImode:
1776 case CQImode:
1777 if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
1778 classes[0] = X86_64_INTEGERSI_CLASS;
1779 else
1780 classes[0] = X86_64_INTEGER_CLASS;
1781 return 1;
1782 case CDImode:
1783 case TImode:
1784 classes[0] = classes[1] = X86_64_INTEGER_CLASS;
1785 return 2;
1786 case CTImode:
1787 classes[0] = classes[1] = X86_64_INTEGER_CLASS;
1788 classes[2] = classes[3] = X86_64_INTEGER_CLASS;
1789 return 4;
1790 case SFmode:
1791 if (!(bit_offset % 64))
1792 classes[0] = X86_64_SSESF_CLASS;
1793 else
1794 classes[0] = X86_64_SSE_CLASS;
1795 return 1;
1796 case DFmode:
1797 classes[0] = X86_64_SSEDF_CLASS;
1798 return 1;
1799 case TFmode:
1800 classes[0] = X86_64_X87_CLASS;
1801 classes[1] = X86_64_X87UP_CLASS;
1802 return 2;
1803 case TCmode:
1804 classes[0] = X86_64_X87_CLASS;
1805 classes[1] = X86_64_X87UP_CLASS;
1806 classes[2] = X86_64_X87_CLASS;
1807 classes[3] = X86_64_X87UP_CLASS;
1808 return 4;
1809 case DCmode:
1810 classes[0] = X86_64_SSEDF_CLASS;
1811 classes[1] = X86_64_SSEDF_CLASS;
1812 return 2;
1813 case SCmode:
1814 classes[0] = X86_64_SSE_CLASS;
1815 return 1;
1816 case BLKmode:
1817 return 0;
1818 default:
1819 abort ();
1820 }
1821}
1822
1823/* Examine the argument and return set number of register required in each
f5143c46 1824 class. Return 0 iff parameter should be passed in memory. */
53c17031
JH
1825static int
1826examine_argument (mode, type, in_return, int_nregs, sse_nregs)
1827 enum machine_mode mode;
1828 tree type;
1829 int *int_nregs, *sse_nregs;
1830 int in_return;
1831{
1832 enum x86_64_reg_class class[MAX_CLASSES];
1833 int n = classify_argument (mode, type, class, 0);
1834
1835 *int_nregs = 0;
1836 *sse_nregs = 0;
1837 if (!n)
1838 return 0;
1839 for (n--; n >= 0; n--)
1840 switch (class[n])
1841 {
1842 case X86_64_INTEGER_CLASS:
1843 case X86_64_INTEGERSI_CLASS:
1844 (*int_nregs)++;
1845 break;
1846 case X86_64_SSE_CLASS:
1847 case X86_64_SSESF_CLASS:
1848 case X86_64_SSEDF_CLASS:
1849 (*sse_nregs)++;
1850 break;
1851 case X86_64_NO_CLASS:
1852 case X86_64_SSEUP_CLASS:
1853 break;
1854 case X86_64_X87_CLASS:
1855 case X86_64_X87UP_CLASS:
1856 if (!in_return)
1857 return 0;
1858 break;
1859 case X86_64_MEMORY_CLASS:
1860 abort ();
1861 }
1862 return 1;
1863}
1864/* Construct container for the argument used by GCC interface. See
1865 FUNCTION_ARG for the detailed description. */
1866static rtx
1867construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regno)
1868 enum machine_mode mode;
1869 tree type;
1870 int in_return;
1871 int nintregs, nsseregs;
1872 int *intreg, sse_regno;
1873{
1874 enum machine_mode tmpmode;
1875 int bytes =
1876 (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
1877 enum x86_64_reg_class class[MAX_CLASSES];
1878 int n;
1879 int i;
1880 int nexps = 0;
1881 int needed_sseregs, needed_intregs;
1882 rtx exp[MAX_CLASSES];
1883 rtx ret;
1884
1885 n = classify_argument (mode, type, class, 0);
1886 if (TARGET_DEBUG_ARG)
1887 {
1888 if (!n)
1889 fprintf (stderr, "Memory class\n");
1890 else
1891 {
1892 fprintf (stderr, "Classes:");
1893 for (i = 0; i < n; i++)
1894 {
1895 fprintf (stderr, " %s", x86_64_reg_class_name[class[i]]);
1896 }
1897 fprintf (stderr, "\n");
1898 }
1899 }
1900 if (!n)
1901 return NULL;
1902 if (!examine_argument (mode, type, in_return, &needed_intregs, &needed_sseregs))
1903 return NULL;
1904 if (needed_intregs > nintregs || needed_sseregs > nsseregs)
1905 return NULL;
1906
1907 /* First construct simple cases. Avoid SCmode, since we want to use
1908 single register to pass this type. */
1909 if (n == 1 && mode != SCmode)
1910 switch (class[0])
1911 {
1912 case X86_64_INTEGER_CLASS:
1913 case X86_64_INTEGERSI_CLASS:
1914 return gen_rtx_REG (mode, intreg[0]);
1915 case X86_64_SSE_CLASS:
1916 case X86_64_SSESF_CLASS:
1917 case X86_64_SSEDF_CLASS:
1918 return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
1919 case X86_64_X87_CLASS:
1920 return gen_rtx_REG (mode, FIRST_STACK_REG);
1921 case X86_64_NO_CLASS:
1922 /* Zero sized array, struct or class. */
1923 return NULL;
1924 default:
1925 abort ();
1926 }
1927 if (n == 2 && class[0] == X86_64_SSE_CLASS && class[1] == X86_64_SSEUP_CLASS)
1928 return gen_rtx_REG (TImode, SSE_REGNO (sse_regno));
1929 if (n == 2
1930 && class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS)
1931 return gen_rtx_REG (TFmode, FIRST_STACK_REG);
1932 if (n == 2 && class[0] == X86_64_INTEGER_CLASS
1933 && class[1] == X86_64_INTEGER_CLASS
1934 && (mode == CDImode || mode == TImode)
1935 && intreg[0] + 1 == intreg[1])
1936 return gen_rtx_REG (mode, intreg[0]);
1937 if (n == 4
1938 && class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS
1939 && class[2] == X86_64_X87_CLASS && class[3] == X86_64_X87UP_CLASS)
1940 return gen_rtx_REG (TCmode, FIRST_STACK_REG);
1941
1942 /* Otherwise figure out the entries of the PARALLEL. */
1943 for (i = 0; i < n; i++)
1944 {
1945 switch (class[i])
1946 {
1947 case X86_64_NO_CLASS:
1948 break;
1949 case X86_64_INTEGER_CLASS:
1950 case X86_64_INTEGERSI_CLASS:
1951 /* Merge TImodes on aligned occassions here too. */
1952 if (i * 8 + 8 > bytes)
1953 tmpmode = mode_for_size ((bytes - i * 8) * BITS_PER_UNIT, MODE_INT, 0);
1954 else if (class[i] == X86_64_INTEGERSI_CLASS)
1955 tmpmode = SImode;
1956 else
1957 tmpmode = DImode;
1958 /* We've requested 24 bytes we don't have mode for. Use DImode. */
1959 if (tmpmode == BLKmode)
1960 tmpmode = DImode;
1961 exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
1962 gen_rtx_REG (tmpmode, *intreg),
1963 GEN_INT (i*8));
1964 intreg++;
1965 break;
1966 case X86_64_SSESF_CLASS:
1967 exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
1968 gen_rtx_REG (SFmode,
1969 SSE_REGNO (sse_regno)),
1970 GEN_INT (i*8));
1971 sse_regno++;
1972 break;
1973 case X86_64_SSEDF_CLASS:
1974 exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
1975 gen_rtx_REG (DFmode,
1976 SSE_REGNO (sse_regno)),
1977 GEN_INT (i*8));
1978 sse_regno++;
1979 break;
1980 case X86_64_SSE_CLASS:
1981 if (i < n && class[i + 1] == X86_64_SSEUP_CLASS)
1982 tmpmode = TImode, i++;
1983 else
1984 tmpmode = DImode;
1985 exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
1986 gen_rtx_REG (tmpmode,
1987 SSE_REGNO (sse_regno)),
1988 GEN_INT (i*8));
1989 sse_regno++;
1990 break;
1991 default:
1992 abort ();
1993 }
1994 }
1995 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
1996 for (i = 0; i < nexps; i++)
1997 XVECEXP (ret, 0, i) = exp [i];
1998 return ret;
1999}
2000
b08de47e
MM
2001/* Update the data in CUM to advance over an argument
2002 of mode MODE and data type TYPE.
2003 (TYPE is null for libcalls where that information may not be available.) */
2004
2005void
2006function_arg_advance (cum, mode, type, named)
2007 CUMULATIVE_ARGS *cum; /* current arg information */
2008 enum machine_mode mode; /* current arg mode */
2009 tree type; /* type of the argument or 0 if lib support */
2010 int named; /* whether or not the argument was named */
2011{
5ac9118e
KG
2012 int bytes =
2013 (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
b08de47e
MM
2014 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2015
2016 if (TARGET_DEBUG_ARG)
2017 fprintf (stderr,
e9a25f70 2018 "function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
b08de47e 2019 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
53c17031 2020 if (TARGET_64BIT)
b08de47e 2021 {
53c17031
JH
2022 int int_nregs, sse_nregs;
2023 if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs))
2024 cum->words += words;
2025 else if (sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
82a127a9 2026 {
53c17031
JH
2027 cum->nregs -= int_nregs;
2028 cum->sse_nregs -= sse_nregs;
2029 cum->regno += int_nregs;
2030 cum->sse_regno += sse_nregs;
82a127a9 2031 }
53c17031
JH
2032 else
2033 cum->words += words;
b08de47e 2034 }
a4f31c00 2035 else
82a127a9 2036 {
53c17031
JH
2037 if (TARGET_SSE && mode == TImode)
2038 {
2039 cum->sse_words += words;
2040 cum->sse_nregs -= 1;
2041 cum->sse_regno += 1;
2042 if (cum->sse_nregs <= 0)
2043 {
2044 cum->sse_nregs = 0;
2045 cum->sse_regno = 0;
2046 }
2047 }
2048 else
82a127a9 2049 {
53c17031
JH
2050 cum->words += words;
2051 cum->nregs -= words;
2052 cum->regno += words;
2053
2054 if (cum->nregs <= 0)
2055 {
2056 cum->nregs = 0;
2057 cum->regno = 0;
2058 }
82a127a9
CM
2059 }
2060 }
b08de47e
MM
2061 return;
2062}
2063
2064/* Define where to put the arguments to a function.
2065 Value is zero to push the argument on the stack,
2066 or a hard register in which to store the argument.
2067
2068 MODE is the argument's machine mode.
2069 TYPE is the data type of the argument (as a tree).
2070 This is null for libcalls where that information may
2071 not be available.
2072 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2073 the preceding args and about the function being called.
2074 NAMED is nonzero if this argument is a named parameter
2075 (otherwise it is an extra parameter matching an ellipsis). */
2076
2077struct rtx_def *
2078function_arg (cum, mode, type, named)
2079 CUMULATIVE_ARGS *cum; /* current arg information */
2080 enum machine_mode mode; /* current arg mode */
2081 tree type; /* type of the argument or 0 if lib support */
2082 int named; /* != 0 for normal args, == 0 for ... args */
2083{
2084 rtx ret = NULL_RTX;
5ac9118e
KG
2085 int bytes =
2086 (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
b08de47e
MM
2087 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2088
53c17031
JH
2089 /* Handle an hidden AL argument containing number of registers for varargs
2090 x86-64 functions. For i386 ABI just return constm1_rtx to avoid
2091 any AL settings. */
32ee7d1d 2092 if (mode == VOIDmode)
b08de47e 2093 {
53c17031
JH
2094 if (TARGET_64BIT)
2095 return GEN_INT (cum->maybe_vaarg
2096 ? (cum->sse_nregs < 0
2097 ? SSE_REGPARM_MAX
2098 : cum->sse_regno)
2099 : -1);
2100 else
2101 return constm1_rtx;
b08de47e 2102 }
53c17031
JH
2103 if (TARGET_64BIT)
2104 ret = construct_container (mode, type, 0, cum->nregs, cum->sse_nregs,
2105 &x86_64_int_parameter_registers [cum->regno],
2106 cum->sse_regno);
2107 else
2108 switch (mode)
2109 {
2110 /* For now, pass fp/complex values on the stack. */
2111 default:
2112 break;
2113
2114 case BLKmode:
2115 case DImode:
2116 case SImode:
2117 case HImode:
2118 case QImode:
2119 if (words <= cum->nregs)
2120 ret = gen_rtx_REG (mode, cum->regno);
2121 break;
2122 case TImode:
2123 if (cum->sse_nregs)
2124 ret = gen_rtx_REG (mode, cum->sse_regno);
2125 break;
2126 }
b08de47e
MM
2127
2128 if (TARGET_DEBUG_ARG)
2129 {
2130 fprintf (stderr,
e9a25f70 2131 "function_arg (size=%d, wds=%2d, nregs=%d, mode=%4s, named=%d",
b08de47e
MM
2132 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
2133
2134 if (ret)
2135 fprintf (stderr, ", reg=%%e%s", reg_names[ REGNO(ret) ]);
2136 else
2137 fprintf (stderr, ", stack");
2138
2139 fprintf (stderr, " )\n");
2140 }
2141
2142 return ret;
2143}
53c17031
JH
2144
2145/* Gives the alignment boundary, in bits, of an argument with the specified mode
2146 and type. */
2147
2148int
2149ix86_function_arg_boundary (mode, type)
2150 enum machine_mode mode;
2151 tree type;
2152{
2153 int align;
2154 if (!TARGET_64BIT)
2155 return PARM_BOUNDARY;
2156 if (type)
2157 align = TYPE_ALIGN (type);
2158 else
2159 align = GET_MODE_ALIGNMENT (mode);
2160 if (align < PARM_BOUNDARY)
2161 align = PARM_BOUNDARY;
2162 if (align > 128)
2163 align = 128;
2164 return align;
2165}
2166
2167/* Return true if N is a possible register number of function value. */
2168bool
2169ix86_function_value_regno_p (regno)
2170 int regno;
2171{
2172 if (!TARGET_64BIT)
2173 {
2174 return ((regno) == 0
2175 || ((regno) == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)
2176 || ((regno) == FIRST_SSE_REG && TARGET_SSE));
2177 }
2178 return ((regno) == 0 || (regno) == FIRST_FLOAT_REG
2179 || ((regno) == FIRST_SSE_REG && TARGET_SSE)
2180 || ((regno) == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387));
2181}
2182
2183/* Define how to find the value returned by a function.
2184 VALTYPE is the data type of the value (as a tree).
2185 If the precise function being called is known, FUNC is its FUNCTION_DECL;
2186 otherwise, FUNC is 0. */
2187rtx
2188ix86_function_value (valtype)
2189 tree valtype;
2190{
2191 if (TARGET_64BIT)
2192 {
2193 rtx ret = construct_container (TYPE_MODE (valtype), valtype, 1,
2194 REGPARM_MAX, SSE_REGPARM_MAX,
2195 x86_64_int_return_registers, 0);
2196 /* For zero sized structures, construct_continer return NULL, but we need
2197 to keep rest of compiler happy by returning meaningfull value. */
2198 if (!ret)
2199 ret = gen_rtx_REG (TYPE_MODE (valtype), 0);
2200 return ret;
2201 }
2202 else
2203 return gen_rtx_REG (TYPE_MODE (valtype), VALUE_REGNO (TYPE_MODE (valtype)));
2204}
2205
f5143c46 2206/* Return false iff type is returned in memory. */
53c17031
JH
2207int
2208ix86_return_in_memory (type)
2209 tree type;
2210{
2211 int needed_intregs, needed_sseregs;
2212 if (TARGET_64BIT)
2213 {
2214 return !examine_argument (TYPE_MODE (type), type, 1,
2215 &needed_intregs, &needed_sseregs);
2216 }
2217 else
2218 {
2219 if (TYPE_MODE (type) == BLKmode
2220 || (VECTOR_MODE_P (TYPE_MODE (type))
2221 && int_size_in_bytes (type) == 8)
2222 || (int_size_in_bytes (type) > 12 && TYPE_MODE (type) != TImode
2223 && TYPE_MODE (type) != TFmode
2224 && !VECTOR_MODE_P (TYPE_MODE (type))))
2225 return 1;
2226 return 0;
2227 }
2228}
2229
2230/* Define how to find the value returned by a library function
2231 assuming the value has mode MODE. */
2232rtx
2233ix86_libcall_value (mode)
2234 enum machine_mode mode;
2235{
2236 if (TARGET_64BIT)
2237 {
2238 switch (mode)
2239 {
2240 case SFmode:
2241 case SCmode:
2242 case DFmode:
2243 case DCmode:
2244 return gen_rtx_REG (mode, FIRST_SSE_REG);
2245 case TFmode:
2246 case TCmode:
2247 return gen_rtx_REG (mode, FIRST_FLOAT_REG);
2248 default:
2249 return gen_rtx_REG (mode, 0);
2250 }
2251 }
2252 else
2253 return gen_rtx_REG (mode, VALUE_REGNO (mode));
2254}
ad919812
JH
2255\f
2256/* Create the va_list data type. */
53c17031 2257
ad919812
JH
2258tree
2259ix86_build_va_list ()
2260{
2261 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
53c17031 2262
ad919812
JH
2263 /* For i386 we use plain pointer to argument area. */
2264 if (!TARGET_64BIT)
2265 return build_pointer_type (char_type_node);
2266
2267 record = make_lang_type (RECORD_TYPE);
2268 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
2269
2270 f_gpr = build_decl (FIELD_DECL, get_identifier ("gp_offset"),
2271 unsigned_type_node);
2272 f_fpr = build_decl (FIELD_DECL, get_identifier ("fp_offset"),
2273 unsigned_type_node);
2274 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
2275 ptr_type_node);
2276 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
2277 ptr_type_node);
2278
2279 DECL_FIELD_CONTEXT (f_gpr) = record;
2280 DECL_FIELD_CONTEXT (f_fpr) = record;
2281 DECL_FIELD_CONTEXT (f_ovf) = record;
2282 DECL_FIELD_CONTEXT (f_sav) = record;
2283
2284 TREE_CHAIN (record) = type_decl;
2285 TYPE_NAME (record) = type_decl;
2286 TYPE_FIELDS (record) = f_gpr;
2287 TREE_CHAIN (f_gpr) = f_fpr;
2288 TREE_CHAIN (f_fpr) = f_ovf;
2289 TREE_CHAIN (f_ovf) = f_sav;
2290
2291 layout_type (record);
2292
2293 /* The correct type is an array type of one element. */
2294 return build_array_type (record, build_index_type (size_zero_node));
2295}
2296
2297/* Perform any needed actions needed for a function that is receiving a
2298 variable number of arguments.
2299
2300 CUM is as above.
2301
2302 MODE and TYPE are the mode and type of the current parameter.
2303
2304 PRETEND_SIZE is a variable that should be set to the amount of stack
2305 that must be pushed by the prolog to pretend that our caller pushed
2306 it.
2307
2308 Normally, this macro will push all remaining incoming registers on the
2309 stack and set PRETEND_SIZE to the length of the registers pushed. */
2310
2311void
2312ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
2313 CUMULATIVE_ARGS *cum;
2314 enum machine_mode mode;
2315 tree type;
2316 int *pretend_size ATTRIBUTE_UNUSED;
2317 int no_rtl;
2318
2319{
2320 CUMULATIVE_ARGS next_cum;
2321 rtx save_area = NULL_RTX, mem;
2322 rtx label;
2323 rtx label_ref;
2324 rtx tmp_reg;
2325 rtx nsse_reg;
2326 int set;
2327 tree fntype;
2328 int stdarg_p;
2329 int i;
2330
2331 if (!TARGET_64BIT)
2332 return;
2333
2334 /* Indicate to allocate space on the stack for varargs save area. */
2335 ix86_save_varrargs_registers = 1;
2336
2337 fntype = TREE_TYPE (current_function_decl);
2338 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
2339 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2340 != void_type_node));
2341
2342 /* For varargs, we do not want to skip the dummy va_dcl argument.
2343 For stdargs, we do want to skip the last named argument. */
2344 next_cum = *cum;
2345 if (stdarg_p)
2346 function_arg_advance (&next_cum, mode, type, 1);
2347
2348 if (!no_rtl)
2349 save_area = frame_pointer_rtx;
2350
2351 set = get_varargs_alias_set ();
2352
2353 for (i = next_cum.regno; i < ix86_regparm; i++)
2354 {
2355 mem = gen_rtx_MEM (Pmode,
2356 plus_constant (save_area, i * UNITS_PER_WORD));
0692acba 2357 set_mem_alias_set (mem, set);
ad919812
JH
2358 emit_move_insn (mem, gen_rtx_REG (Pmode,
2359 x86_64_int_parameter_registers[i]));
2360 }
2361
2362 if (next_cum.sse_nregs)
2363 {
2364 /* Now emit code to save SSE registers. The AX parameter contains number
2365 of SSE parameter regsiters used to call this function. We use
2366 sse_prologue_save insn template that produces computed jump across
2367 SSE saves. We need some preparation work to get this working. */
2368
2369 label = gen_label_rtx ();
2370 label_ref = gen_rtx_LABEL_REF (Pmode, label);
2371
2372 /* Compute address to jump to :
2373 label - 5*eax + nnamed_sse_arguments*5 */
2374 tmp_reg = gen_reg_rtx (Pmode);
2375 nsse_reg = gen_reg_rtx (Pmode);
2376 emit_insn (gen_zero_extendqidi2 (nsse_reg, gen_rtx_REG (QImode, 0)));
2377 emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
44cf5b6a 2378 gen_rtx_MULT (Pmode, nsse_reg,
ad919812
JH
2379 GEN_INT (4))));
2380 if (next_cum.sse_regno)
2381 emit_move_insn
2382 (nsse_reg,
2383 gen_rtx_CONST (DImode,
2384 gen_rtx_PLUS (DImode,
2385 label_ref,
2386 GEN_INT (next_cum.sse_regno * 4))));
2387 else
2388 emit_move_insn (nsse_reg, label_ref);
2389 emit_insn (gen_subdi3 (nsse_reg, nsse_reg, tmp_reg));
2390
2391 /* Compute address of memory block we save into. We always use pointer
2392 pointing 127 bytes after first byte to store - this is needed to keep
2393 instruction size limited by 4 bytes. */
2394 tmp_reg = gen_reg_rtx (Pmode);
8ac61af7
RK
2395 emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
2396 plus_constant (save_area,
2397 8 * REGPARM_MAX + 127)));
ad919812 2398 mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127));
14f73b5a 2399 set_mem_alias_set (mem, set);
8ac61af7 2400 set_mem_align (mem, BITS_PER_WORD);
ad919812
JH
2401
2402 /* And finally do the dirty job! */
8ac61af7
RK
2403 emit_insn (gen_sse_prologue_save (mem, nsse_reg,
2404 GEN_INT (next_cum.sse_regno), label));
ad919812
JH
2405 }
2406
2407}
2408
2409/* Implement va_start. */
2410
2411void
2412ix86_va_start (stdarg_p, valist, nextarg)
2413 int stdarg_p;
2414 tree valist;
2415 rtx nextarg;
2416{
2417 HOST_WIDE_INT words, n_gpr, n_fpr;
2418 tree f_gpr, f_fpr, f_ovf, f_sav;
2419 tree gpr, fpr, ovf, sav, t;
2420
2421 /* Only 64bit target needs something special. */
2422 if (!TARGET_64BIT)
2423 {
2424 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2425 return;
2426 }
2427
2428 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
2429 f_fpr = TREE_CHAIN (f_gpr);
2430 f_ovf = TREE_CHAIN (f_fpr);
2431 f_sav = TREE_CHAIN (f_ovf);
2432
2433 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
2434 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
2435 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
2436 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
2437 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
2438
2439 /* Count number of gp and fp argument registers used. */
2440 words = current_function_args_info.words;
2441 n_gpr = current_function_args_info.regno;
2442 n_fpr = current_function_args_info.sse_regno;
2443
2444 if (TARGET_DEBUG_ARG)
2445 fprintf (stderr, "va_start: words = %d, n_gpr = %d, n_fpr = %d\n",
14f73b5a 2446 (int)words, (int)n_gpr, (int)n_fpr);
ad919812
JH
2447
2448 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
2449 build_int_2 (n_gpr * 8, 0));
2450 TREE_SIDE_EFFECTS (t) = 1;
2451 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2452
2453 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
2454 build_int_2 (n_fpr * 16 + 8*REGPARM_MAX, 0));
2455 TREE_SIDE_EFFECTS (t) = 1;
2456 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2457
2458 /* Find the overflow area. */
2459 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
2460 if (words != 0)
2461 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
2462 build_int_2 (words * UNITS_PER_WORD, 0));
2463 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
2464 TREE_SIDE_EFFECTS (t) = 1;
2465 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2466
2467 /* Find the register save area.
2468 Prologue of the function save it right above stack frame. */
2469 t = make_tree (TREE_TYPE (sav), frame_pointer_rtx);
2470 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
2471 TREE_SIDE_EFFECTS (t) = 1;
2472 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2473}
2474
2475/* Implement va_arg. */
2476rtx
2477ix86_va_arg (valist, type)
2478 tree valist, type;
2479{
2480 static int intreg[6] = { 0, 1, 2, 3, 4, 5 };
2481 tree f_gpr, f_fpr, f_ovf, f_sav;
2482 tree gpr, fpr, ovf, sav, t;
b932f770 2483 int size, rsize;
ad919812
JH
2484 rtx lab_false, lab_over = NULL_RTX;
2485 rtx addr_rtx, r;
2486 rtx container;
2487
2488 /* Only 64bit target needs something special. */
2489 if (!TARGET_64BIT)
2490 {
2491 return std_expand_builtin_va_arg (valist, type);
2492 }
2493
2494 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
2495 f_fpr = TREE_CHAIN (f_gpr);
2496 f_ovf = TREE_CHAIN (f_fpr);
2497 f_sav = TREE_CHAIN (f_ovf);
2498
2499 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
2500 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
2501 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
2502 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
2503 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
2504
2505 size = int_size_in_bytes (type);
2506 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2507
2508 container = construct_container (TYPE_MODE (type), type, 0,
2509 REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0);
2510 /*
2511 * Pull the value out of the saved registers ...
2512 */
2513
2514 addr_rtx = gen_reg_rtx (Pmode);
2515
2516 if (container)
2517 {
2518 rtx int_addr_rtx, sse_addr_rtx;
2519 int needed_intregs, needed_sseregs;
2520 int need_temp;
2521
2522 lab_over = gen_label_rtx ();
2523 lab_false = gen_label_rtx ();
8bad7136 2524
ad919812
JH
2525 examine_argument (TYPE_MODE (type), type, 0,
2526 &needed_intregs, &needed_sseregs);
2527
2528
2529 need_temp = ((needed_intregs && TYPE_ALIGN (type) > 64)
2530 || TYPE_ALIGN (type) > 128);
2531
2532 /* In case we are passing structure, verify that it is consetuctive block
2533 on the register save area. If not we need to do moves. */
2534 if (!need_temp && !REG_P (container))
2535 {
2536 /* Verify that all registers are strictly consetuctive */
2537 if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
2538 {
2539 int i;
2540
2541 for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
2542 {
2543 rtx slot = XVECEXP (container, 0, i);
2544 if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int)i
2545 || INTVAL (XEXP (slot, 1)) != i * 16)
2546 need_temp = 1;
2547 }
2548 }
2549 else
2550 {
2551 int i;
2552
2553 for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
2554 {
2555 rtx slot = XVECEXP (container, 0, i);
2556 if (REGNO (XEXP (slot, 0)) != (unsigned int)i
2557 || INTVAL (XEXP (slot, 1)) != i * 8)
2558 need_temp = 1;
2559 }
2560 }
2561 }
2562 if (!need_temp)
2563 {
2564 int_addr_rtx = addr_rtx;
2565 sse_addr_rtx = addr_rtx;
2566 }
2567 else
2568 {
2569 int_addr_rtx = gen_reg_rtx (Pmode);
2570 sse_addr_rtx = gen_reg_rtx (Pmode);
2571 }
2572 /* First ensure that we fit completely in registers. */
2573 if (needed_intregs)
2574 {
2575 emit_cmp_and_jump_insns (expand_expr
2576 (gpr, NULL_RTX, SImode, EXPAND_NORMAL),
2577 GEN_INT ((REGPARM_MAX - needed_intregs +
2578 1) * 8), GE, const1_rtx, SImode,
d43e0b7d 2579 1, lab_false);
ad919812
JH
2580 }
2581 if (needed_sseregs)
2582 {
2583 emit_cmp_and_jump_insns (expand_expr
2584 (fpr, NULL_RTX, SImode, EXPAND_NORMAL),
2585 GEN_INT ((SSE_REGPARM_MAX -
2586 needed_sseregs + 1) * 16 +
2587 REGPARM_MAX * 8), GE, const1_rtx,
d43e0b7d 2588 SImode, 1, lab_false);
ad919812
JH
2589 }
2590
2591 /* Compute index to start of area used for integer regs. */
2592 if (needed_intregs)
2593 {
2594 t = build (PLUS_EXPR, ptr_type_node, sav, gpr);
2595 r = expand_expr (t, int_addr_rtx, Pmode, EXPAND_NORMAL);
2596 if (r != int_addr_rtx)
2597 emit_move_insn (int_addr_rtx, r);
2598 }
2599 if (needed_sseregs)
2600 {
2601 t = build (PLUS_EXPR, ptr_type_node, sav, fpr);
2602 r = expand_expr (t, sse_addr_rtx, Pmode, EXPAND_NORMAL);
2603 if (r != sse_addr_rtx)
2604 emit_move_insn (sse_addr_rtx, r);
2605 }
2606 if (need_temp)
2607 {
2608 int i;
2609 rtx mem;
2610
b932f770
JH
2611 /* Never use the memory itself, as it has the alias set. */
2612 addr_rtx = XEXP (assign_temp (type, 0, 1, 0), 0);
2613 mem = gen_rtx_MEM (BLKmode, addr_rtx);
0692acba 2614 set_mem_alias_set (mem, get_varargs_alias_set ());
8ac61af7 2615 set_mem_align (mem, BITS_PER_UNIT);
b932f770 2616
ad919812
JH
2617 for (i = 0; i < XVECLEN (container, 0); i++)
2618 {
2619 rtx slot = XVECEXP (container, 0, i);
2620 rtx reg = XEXP (slot, 0);
2621 enum machine_mode mode = GET_MODE (reg);
2622 rtx src_addr;
2623 rtx src_mem;
2624 int src_offset;
2625 rtx dest_mem;
2626
2627 if (SSE_REGNO_P (REGNO (reg)))
2628 {
2629 src_addr = sse_addr_rtx;
2630 src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
2631 }
2632 else
2633 {
2634 src_addr = int_addr_rtx;
2635 src_offset = REGNO (reg) * 8;
2636 }
2637 src_mem = gen_rtx_MEM (mode, src_addr);
0692acba 2638 set_mem_alias_set (src_mem, get_varargs_alias_set ());
ad919812
JH
2639 src_mem = adjust_address (src_mem, mode, src_offset);
2640 dest_mem = adjust_address (mem, mode, INTVAL (XEXP (slot, 1)));
ad919812
JH
2641 emit_move_insn (dest_mem, src_mem);
2642 }
2643 }
2644
2645 if (needed_intregs)
2646 {
2647 t =
2648 build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
2649 build_int_2 (needed_intregs * 8, 0));
2650 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
2651 TREE_SIDE_EFFECTS (t) = 1;
2652 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2653 }
2654 if (needed_sseregs)
2655 {
2656 t =
2657 build (PLUS_EXPR, TREE_TYPE (fpr), fpr,
2658 build_int_2 (needed_sseregs * 16, 0));
2659 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, t);
2660 TREE_SIDE_EFFECTS (t) = 1;
2661 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2662 }
2663
2664 emit_jump_insn (gen_jump (lab_over));
2665 emit_barrier ();
2666 emit_label (lab_false);
2667 }
2668
2669 /* ... otherwise out of the overflow area. */
2670
2671 /* Care for on-stack alignment if needed. */
2672 if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64)
2673 t = ovf;
2674 else
2675 {
2676 HOST_WIDE_INT align = FUNCTION_ARG_BOUNDARY (VOIDmode, type) / 8;
2677 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align - 1, 0));
2678 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
2679 }
2680 t = save_expr (t);
2681
2682 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
2683 if (r != addr_rtx)
2684 emit_move_insn (addr_rtx, r);
2685
2686 t =
2687 build (PLUS_EXPR, TREE_TYPE (t), t,
2688 build_int_2 (rsize * UNITS_PER_WORD, 0));
2689 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
2690 TREE_SIDE_EFFECTS (t) = 1;
2691 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2692
2693 if (container)
2694 emit_label (lab_over);
2695
ad919812
JH
2696 return addr_rtx;
2697}
2698\f
7dd4b4a3
JH
2699/* Return nonzero if OP is general operand representable on x86_64. */
2700
2701int
2702x86_64_general_operand (op, mode)
2703 rtx op;
2704 enum machine_mode mode;
2705{
2706 if (!TARGET_64BIT)
2707 return general_operand (op, mode);
2708 if (nonimmediate_operand (op, mode))
2709 return 1;
2710 return x86_64_sign_extended_value (op);
2711}
2712
2713/* Return nonzero if OP is general operand representable on x86_64
d6a7951f 2714 as either sign extended or zero extended constant. */
7dd4b4a3
JH
2715
2716int
2717x86_64_szext_general_operand (op, mode)
2718 rtx op;
2719 enum machine_mode mode;
2720{
2721 if (!TARGET_64BIT)
2722 return general_operand (op, mode);
2723 if (nonimmediate_operand (op, mode))
2724 return 1;
2725 return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
2726}
2727
2728/* Return nonzero if OP is nonmemory operand representable on x86_64. */
2729
2730int
2731x86_64_nonmemory_operand (op, mode)
2732 rtx op;
2733 enum machine_mode mode;
2734{
2735 if (!TARGET_64BIT)
2736 return nonmemory_operand (op, mode);
2737 if (register_operand (op, mode))
2738 return 1;
2739 return x86_64_sign_extended_value (op);
2740}
2741
2742/* Return nonzero if OP is nonmemory operand acceptable by movabs patterns. */
2743
2744int
2745x86_64_movabs_operand (op, mode)
2746 rtx op;
2747 enum machine_mode mode;
2748{
2749 if (!TARGET_64BIT || !flag_pic)
2750 return nonmemory_operand (op, mode);
2751 if (register_operand (op, mode) || x86_64_sign_extended_value (op))
2752 return 1;
2753 if (CONSTANT_P (op) && !symbolic_reference_mentioned_p (op))
2754 return 1;
2755 return 0;
2756}
2757
2758/* Return nonzero if OP is nonmemory operand representable on x86_64. */
2759
2760int
2761x86_64_szext_nonmemory_operand (op, mode)
2762 rtx op;
2763 enum machine_mode mode;
2764{
2765 if (!TARGET_64BIT)
2766 return nonmemory_operand (op, mode);
2767 if (register_operand (op, mode))
2768 return 1;
2769 return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
2770}
2771
2772/* Return nonzero if OP is immediate operand representable on x86_64. */
2773
2774int
2775x86_64_immediate_operand (op, mode)
2776 rtx op;
2777 enum machine_mode mode;
2778{
2779 if (!TARGET_64BIT)
2780 return immediate_operand (op, mode);
2781 return x86_64_sign_extended_value (op);
2782}
2783
2784/* Return nonzero if OP is immediate operand representable on x86_64. */
2785
2786int
2787x86_64_zext_immediate_operand (op, mode)
2788 rtx op;
2789 enum machine_mode mode ATTRIBUTE_UNUSED;
2790{
2791 return x86_64_zero_extended_value (op);
2792}
2793
8bad7136
JL
2794/* Return nonzero if OP is (const_int 1), else return zero. */
2795
2796int
2797const_int_1_operand (op, mode)
2798 rtx op;
2799 enum machine_mode mode ATTRIBUTE_UNUSED;
2800{
2801 return (GET_CODE (op) == CONST_INT && INTVAL (op) == 1);
2802}
2803
e075ae69
RH
2804/* Returns 1 if OP is either a symbol reference or a sum of a symbol
2805 reference and a constant. */
b08de47e
MM
2806
2807int
e075ae69
RH
2808symbolic_operand (op, mode)
2809 register rtx op;
2810 enum machine_mode mode ATTRIBUTE_UNUSED;
2a2ab3f9 2811{
e075ae69 2812 switch (GET_CODE (op))
2a2ab3f9 2813 {
e075ae69
RH
2814 case SYMBOL_REF:
2815 case LABEL_REF:
2816 return 1;
2817
2818 case CONST:
2819 op = XEXP (op, 0);
2820 if (GET_CODE (op) == SYMBOL_REF
2821 || GET_CODE (op) == LABEL_REF
2822 || (GET_CODE (op) == UNSPEC
6eb791fc
JH
2823 && (XINT (op, 1) == 6
2824 || XINT (op, 1) == 7
2825 || XINT (op, 1) == 15)))
e075ae69
RH
2826 return 1;
2827 if (GET_CODE (op) != PLUS
2828 || GET_CODE (XEXP (op, 1)) != CONST_INT)
2829 return 0;
2830
2831 op = XEXP (op, 0);
2832 if (GET_CODE (op) == SYMBOL_REF
2833 || GET_CODE (op) == LABEL_REF)
2834 return 1;
2835 /* Only @GOTOFF gets offsets. */
2836 if (GET_CODE (op) != UNSPEC
2837 || XINT (op, 1) != 7)
2838 return 0;
2839
2840 op = XVECEXP (op, 0, 0);
2841 if (GET_CODE (op) == SYMBOL_REF
2842 || GET_CODE (op) == LABEL_REF)
2843 return 1;
2844 return 0;
2845
2846 default:
2847 return 0;
2a2ab3f9
JVA
2848 }
2849}
2a2ab3f9 2850
e075ae69 2851/* Return true if the operand contains a @GOT or @GOTOFF reference. */
3b3c6a3f 2852
e075ae69
RH
2853int
2854pic_symbolic_operand (op, mode)
2855 register rtx op;
2856 enum machine_mode mode ATTRIBUTE_UNUSED;
2857{
6eb791fc
JH
2858 if (GET_CODE (op) != CONST)
2859 return 0;
2860 op = XEXP (op, 0);
2861 if (TARGET_64BIT)
2862 {
2863 if (GET_CODE (XEXP (op, 0)) == UNSPEC)
2864 return 1;
2865 }
2866 else
2a2ab3f9 2867 {
e075ae69
RH
2868 if (GET_CODE (op) == UNSPEC)
2869 return 1;
2870 if (GET_CODE (op) != PLUS
2871 || GET_CODE (XEXP (op, 1)) != CONST_INT)
2872 return 0;
2873 op = XEXP (op, 0);
2874 if (GET_CODE (op) == UNSPEC)
2875 return 1;
2a2ab3f9 2876 }
e075ae69 2877 return 0;
2a2ab3f9 2878}
2a2ab3f9 2879
623fe810
RH
2880/* Return true if OP is a symbolic operand that resolves locally. */
2881
2882static int
2883local_symbolic_operand (op, mode)
2884 rtx op;
2885 enum machine_mode mode ATTRIBUTE_UNUSED;
2886{
2887 if (GET_CODE (op) == LABEL_REF)
2888 return 1;
2889
2890 if (GET_CODE (op) == CONST
2891 && GET_CODE (XEXP (op, 0)) == PLUS
2892 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
2893 op = XEXP (XEXP (op, 0), 0);
2894
2895 if (GET_CODE (op) != SYMBOL_REF)
2896 return 0;
2897
2898 /* These we've been told are local by varasm and encode_section_info
2899 respectively. */
2900 if (CONSTANT_POOL_ADDRESS_P (op) || SYMBOL_REF_FLAG (op))
2901 return 1;
2902
2903 /* There is, however, a not insubstantial body of code in the rest of
2904 the compiler that assumes it can just stick the results of
2905 ASM_GENERATE_INTERNAL_LABEL in a symbol_ref and have done. */
2906 /* ??? This is a hack. Should update the body of the compiler to
2907 always create a DECL an invoke ENCODE_SECTION_INFO. */
2908 if (strncmp (XSTR (op, 0), internal_label_prefix,
2909 internal_label_prefix_len) == 0)
2910 return 1;
2911
2912 return 0;
2913}
2914
28d52ffb
RH
2915/* Test for a valid operand for a call instruction. Don't allow the
2916 arg pointer register or virtual regs since they may decay into
2917 reg + const, which the patterns can't handle. */
2a2ab3f9 2918
e075ae69
RH
2919int
2920call_insn_operand (op, mode)
2921 rtx op;
2922 enum machine_mode mode ATTRIBUTE_UNUSED;
2923{
e075ae69
RH
2924 /* Disallow indirect through a virtual register. This leads to
2925 compiler aborts when trying to eliminate them. */
2926 if (GET_CODE (op) == REG
2927 && (op == arg_pointer_rtx
564d80f4 2928 || op == frame_pointer_rtx
e075ae69
RH
2929 || (REGNO (op) >= FIRST_PSEUDO_REGISTER
2930 && REGNO (op) <= LAST_VIRTUAL_REGISTER)))
2931 return 0;
2a2ab3f9 2932
28d52ffb
RH
2933 /* Disallow `call 1234'. Due to varying assembler lameness this
2934 gets either rejected or translated to `call .+1234'. */
2935 if (GET_CODE (op) == CONST_INT)
2936 return 0;
2937
cbbf65e0
RH
2938 /* Explicitly allow SYMBOL_REF even if pic. */
2939 if (GET_CODE (op) == SYMBOL_REF)
e075ae69 2940 return 1;
2a2ab3f9 2941
cbbf65e0
RH
2942 /* Half-pic doesn't allow anything but registers and constants.
2943 We've just taken care of the later. */
2944 if (HALF_PIC_P ())
2945 return register_operand (op, Pmode);
2946
2947 /* Otherwise we can allow any general_operand in the address. */
2948 return general_operand (op, Pmode);
e075ae69 2949}
79325812 2950
e075ae69
RH
2951int
2952constant_call_address_operand (op, mode)
2953 rtx op;
2954 enum machine_mode mode ATTRIBUTE_UNUSED;
2955{
eaf19aba
JJ
2956 if (GET_CODE (op) == CONST
2957 && GET_CODE (XEXP (op, 0)) == PLUS
2958 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
2959 op = XEXP (XEXP (op, 0), 0);
e1ff012c 2960 return GET_CODE (op) == SYMBOL_REF;
e075ae69 2961}
2a2ab3f9 2962
e075ae69 2963/* Match exactly zero and one. */
e9a25f70 2964
0f290768 2965int
e075ae69
RH
2966const0_operand (op, mode)
2967 register rtx op;
2968 enum machine_mode mode;
2969{
2970 return op == CONST0_RTX (mode);
2971}
e9a25f70 2972
0f290768 2973int
e075ae69
RH
2974const1_operand (op, mode)
2975 register rtx op;
2976 enum machine_mode mode ATTRIBUTE_UNUSED;
2977{
2978 return op == const1_rtx;
2979}
2a2ab3f9 2980
e075ae69 2981/* Match 2, 4, or 8. Used for leal multiplicands. */
e9a25f70 2982
e075ae69
RH
2983int
2984const248_operand (op, mode)
2985 register rtx op;
2986 enum machine_mode mode ATTRIBUTE_UNUSED;
2987{
2988 return (GET_CODE (op) == CONST_INT
2989 && (INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8));
2990}
e9a25f70 2991
e075ae69 2992/* True if this is a constant appropriate for an increment or decremenmt. */
81fd0956 2993
e075ae69
RH
2994int
2995incdec_operand (op, mode)
2996 register rtx op;
0631e0bf 2997 enum machine_mode mode ATTRIBUTE_UNUSED;
e075ae69 2998{
f5143c46 2999 /* On Pentium4, the inc and dec operations causes extra dependency on flag
b4e89e2d
JH
3000 registers, since carry flag is not set. */
3001 if (TARGET_PENTIUM4 && !optimize_size)
3002 return 0;
2b1c08f5 3003 return op == const1_rtx || op == constm1_rtx;
e075ae69 3004}
2a2ab3f9 3005
371bc54b
JH
3006/* Return nonzero if OP is acceptable as operand of DImode shift
3007 expander. */
3008
3009int
3010shiftdi_operand (op, mode)
3011 rtx op;
3012 enum machine_mode mode ATTRIBUTE_UNUSED;
3013{
3014 if (TARGET_64BIT)
3015 return nonimmediate_operand (op, mode);
3016 else
3017 return register_operand (op, mode);
3018}
3019
0f290768 3020/* Return false if this is the stack pointer, or any other fake
e075ae69
RH
3021 register eliminable to the stack pointer. Otherwise, this is
3022 a register operand.
2a2ab3f9 3023
e075ae69
RH
3024 This is used to prevent esp from being used as an index reg.
3025 Which would only happen in pathological cases. */
5f1ec3e6 3026
e075ae69
RH
3027int
3028reg_no_sp_operand (op, mode)
3029 register rtx op;
3030 enum machine_mode mode;
3031{
3032 rtx t = op;
3033 if (GET_CODE (t) == SUBREG)
3034 t = SUBREG_REG (t);
564d80f4 3035 if (t == stack_pointer_rtx || t == arg_pointer_rtx || t == frame_pointer_rtx)
e075ae69 3036 return 0;
2a2ab3f9 3037
e075ae69 3038 return register_operand (op, mode);
2a2ab3f9 3039}
b840bfb0 3040
915119a5
BS
3041int
3042mmx_reg_operand (op, mode)
3043 register rtx op;
bd793c65 3044 enum machine_mode mode ATTRIBUTE_UNUSED;
915119a5
BS
3045{
3046 return MMX_REG_P (op);
3047}
3048
2c5a510c
RH
3049/* Return false if this is any eliminable register. Otherwise
3050 general_operand. */
3051
3052int
3053general_no_elim_operand (op, mode)
3054 register rtx op;
3055 enum machine_mode mode;
3056{
3057 rtx t = op;
3058 if (GET_CODE (t) == SUBREG)
3059 t = SUBREG_REG (t);
3060 if (t == arg_pointer_rtx || t == frame_pointer_rtx
3061 || t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
3062 || t == virtual_stack_dynamic_rtx)
3063 return 0;
1020a5ab
RH
3064 if (REG_P (t)
3065 && REGNO (t) >= FIRST_VIRTUAL_REGISTER
3066 && REGNO (t) <= LAST_VIRTUAL_REGISTER)
3067 return 0;
2c5a510c
RH
3068
3069 return general_operand (op, mode);
3070}
3071
3072/* Return false if this is any eliminable register. Otherwise
3073 register_operand or const_int. */
3074
3075int
3076nonmemory_no_elim_operand (op, mode)
3077 register rtx op;
3078 enum machine_mode mode;
3079{
3080 rtx t = op;
3081 if (GET_CODE (t) == SUBREG)
3082 t = SUBREG_REG (t);
3083 if (t == arg_pointer_rtx || t == frame_pointer_rtx
3084 || t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
3085 || t == virtual_stack_dynamic_rtx)
3086 return 0;
3087
3088 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
3089}
3090
e075ae69 3091/* Return true if op is a Q_REGS class register. */
b840bfb0 3092
e075ae69
RH
3093int
3094q_regs_operand (op, mode)
3095 register rtx op;
3096 enum machine_mode mode;
b840bfb0 3097{
e075ae69
RH
3098 if (mode != VOIDmode && GET_MODE (op) != mode)
3099 return 0;
3100 if (GET_CODE (op) == SUBREG)
3101 op = SUBREG_REG (op);
3102 return QI_REG_P (op);
0f290768 3103}
b840bfb0 3104
e075ae69 3105/* Return true if op is a NON_Q_REGS class register. */
b840bfb0 3106
e075ae69
RH
3107int
3108non_q_regs_operand (op, mode)
3109 register rtx op;
3110 enum machine_mode mode;
3111{
3112 if (mode != VOIDmode && GET_MODE (op) != mode)
3113 return 0;
3114 if (GET_CODE (op) == SUBREG)
3115 op = SUBREG_REG (op);
3116 return NON_QI_REG_P (op);
0f290768 3117}
b840bfb0 3118
915119a5
BS
3119/* Return 1 if OP is a comparison that can be used in the CMPSS/CMPPS
3120 insns. */
3121int
3122sse_comparison_operator (op, mode)
3123 rtx op;
3124 enum machine_mode mode ATTRIBUTE_UNUSED;
3125{
3126 enum rtx_code code = GET_CODE (op);
a46d1d38
JH
3127 switch (code)
3128 {
3129 /* Operations supported directly. */
3130 case EQ:
3131 case LT:
3132 case LE:
3133 case UNORDERED:
3134 case NE:
3135 case UNGE:
3136 case UNGT:
3137 case ORDERED:
3138 return 1;
3139 /* These are equivalent to ones above in non-IEEE comparisons. */
3140 case UNEQ:
3141 case UNLT:
3142 case UNLE:
3143 case LTGT:
3144 case GE:
3145 case GT:
3146 return !TARGET_IEEE_FP;
3147 default:
3148 return 0;
3149 }
915119a5 3150}
9076b9c1 3151/* Return 1 if OP is a valid comparison operator in valid mode. */
e075ae69 3152int
9076b9c1
JH
3153ix86_comparison_operator (op, mode)
3154 register rtx op;
3155 enum machine_mode mode;
e075ae69 3156{
9076b9c1 3157 enum machine_mode inmode;
9a915772 3158 enum rtx_code code = GET_CODE (op);
3a3677ff
RH
3159 if (mode != VOIDmode && GET_MODE (op) != mode)
3160 return 0;
9a915772
JH
3161 if (GET_RTX_CLASS (code) != '<')
3162 return 0;
3163 inmode = GET_MODE (XEXP (op, 0));
3164
3165 if (inmode == CCFPmode || inmode == CCFPUmode)
3166 {
3167 enum rtx_code second_code, bypass_code;
3168 ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
3169 return (bypass_code == NIL && second_code == NIL);
3170 }
3171 switch (code)
3a3677ff
RH
3172 {
3173 case EQ: case NE:
3a3677ff 3174 return 1;
9076b9c1 3175 case LT: case GE:
7e08e190 3176 if (inmode == CCmode || inmode == CCGCmode
9076b9c1
JH
3177 || inmode == CCGOCmode || inmode == CCNOmode)
3178 return 1;
3179 return 0;
7e08e190 3180 case LTU: case GTU: case LEU: case ORDERED: case UNORDERED: case GEU:
7e08e190 3181 if (inmode == CCmode)
9076b9c1
JH
3182 return 1;
3183 return 0;
3184 case GT: case LE:
7e08e190 3185 if (inmode == CCmode || inmode == CCGCmode || inmode == CCNOmode)
9076b9c1
JH
3186 return 1;
3187 return 0;
3a3677ff
RH
3188 default:
3189 return 0;
3190 }
3191}
3192
9076b9c1 3193/* Return 1 if OP is a comparison operator that can be issued by fcmov. */
3a3677ff 3194
9076b9c1
JH
3195int
3196fcmov_comparison_operator (op, mode)
3a3677ff
RH
3197 register rtx op;
3198 enum machine_mode mode;
3199{
b62d22a2 3200 enum machine_mode inmode;
9a915772 3201 enum rtx_code code = GET_CODE (op);
3a3677ff
RH
3202 if (mode != VOIDmode && GET_MODE (op) != mode)
3203 return 0;
9a915772
JH
3204 if (GET_RTX_CLASS (code) != '<')
3205 return 0;
3206 inmode = GET_MODE (XEXP (op, 0));
3207 if (inmode == CCFPmode || inmode == CCFPUmode)
3a3677ff 3208 {
9a915772
JH
3209 enum rtx_code second_code, bypass_code;
3210 ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
3211 if (bypass_code != NIL || second_code != NIL)
3212 return 0;
3213 code = ix86_fp_compare_code_to_integer (code);
3214 }
3215 /* i387 supports just limited amount of conditional codes. */
3216 switch (code)
3217 {
3218 case LTU: case GTU: case LEU: case GEU:
3219 if (inmode == CCmode || inmode == CCFPmode || inmode == CCFPUmode)
9076b9c1
JH
3220 return 1;
3221 return 0;
9a915772
JH
3222 case ORDERED: case UNORDERED:
3223 case EQ: case NE:
3224 return 1;
3a3677ff
RH
3225 default:
3226 return 0;
3227 }
e075ae69 3228}
b840bfb0 3229
e9e80858
JH
3230/* Return 1 if OP is a binary operator that can be promoted to wider mode. */
3231
3232int
3233promotable_binary_operator (op, mode)
3234 register rtx op;
3235 enum machine_mode mode ATTRIBUTE_UNUSED;
3236{
3237 switch (GET_CODE (op))
3238 {
3239 case MULT:
3240 /* Modern CPUs have same latency for HImode and SImode multiply,
3241 but 386 and 486 do HImode multiply faster. */
3242 return ix86_cpu > PROCESSOR_I486;
3243 case PLUS:
3244 case AND:
3245 case IOR:
3246 case XOR:
3247 case ASHIFT:
3248 return 1;
3249 default:
3250 return 0;
3251 }
3252}
3253
e075ae69
RH
3254/* Nearly general operand, but accept any const_double, since we wish
3255 to be able to drop them into memory rather than have them get pulled
3256 into registers. */
b840bfb0 3257
2a2ab3f9 3258int
e075ae69
RH
3259cmp_fp_expander_operand (op, mode)
3260 register rtx op;
3261 enum machine_mode mode;
2a2ab3f9 3262{
e075ae69 3263 if (mode != VOIDmode && mode != GET_MODE (op))
0b6b2900 3264 return 0;
e075ae69 3265 if (GET_CODE (op) == CONST_DOUBLE)
2a2ab3f9 3266 return 1;
e075ae69 3267 return general_operand (op, mode);
2a2ab3f9
JVA
3268}
3269
e075ae69 3270/* Match an SI or HImode register for a zero_extract. */
2a2ab3f9
JVA
3271
3272int
e075ae69 3273ext_register_operand (op, mode)
2a2ab3f9 3274 register rtx op;
bb5177ac 3275 enum machine_mode mode ATTRIBUTE_UNUSED;
2a2ab3f9 3276{
3522082b 3277 int regno;
0d7d98ee
JH
3278 if ((!TARGET_64BIT || GET_MODE (op) != DImode)
3279 && GET_MODE (op) != SImode && GET_MODE (op) != HImode)
e075ae69 3280 return 0;
3522082b
JH
3281
3282 if (!register_operand (op, VOIDmode))
3283 return 0;
3284
3285 /* Be curefull to accept only registers having upper parts. */
3286 regno = REG_P (op) ? REGNO (op) : REGNO (SUBREG_REG (op));
3287 return (regno > LAST_VIRTUAL_REGISTER || regno < 4);
e075ae69
RH
3288}
3289
3290/* Return 1 if this is a valid binary floating-point operation.
0f290768 3291 OP is the expression matched, and MODE is its mode. */
e075ae69
RH
3292
3293int
3294binary_fp_operator (op, mode)
3295 register rtx op;
3296 enum machine_mode mode;
3297{
3298 if (mode != VOIDmode && mode != GET_MODE (op))
3299 return 0;
3300
2a2ab3f9
JVA
3301 switch (GET_CODE (op))
3302 {
e075ae69
RH
3303 case PLUS:
3304 case MINUS:
3305 case MULT:
3306 case DIV:
3307 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
e9a25f70 3308
2a2ab3f9
JVA
3309 default:
3310 return 0;
3311 }
3312}
fee2770d 3313
e075ae69
RH
3314int
3315mult_operator(op, mode)
3316 register rtx op;
3317 enum machine_mode mode ATTRIBUTE_UNUSED;
3318{
3319 return GET_CODE (op) == MULT;
3320}
3321
3322int
3323div_operator(op, mode)
3324 register rtx op;
3325 enum machine_mode mode ATTRIBUTE_UNUSED;
3326{
3327 return GET_CODE (op) == DIV;
3328}
0a726ef1
JL
3329
3330int
e075ae69
RH
3331arith_or_logical_operator (op, mode)
3332 rtx op;
3333 enum machine_mode mode;
0a726ef1 3334{
e075ae69
RH
3335 return ((mode == VOIDmode || GET_MODE (op) == mode)
3336 && (GET_RTX_CLASS (GET_CODE (op)) == 'c'
3337 || GET_RTX_CLASS (GET_CODE (op)) == '2'));
0a726ef1
JL
3338}
3339
e075ae69 3340/* Returns 1 if OP is memory operand with a displacement. */
fee2770d
RS
3341
3342int
e075ae69
RH
3343memory_displacement_operand (op, mode)
3344 register rtx op;
3345 enum machine_mode mode;
4f2c8ebb 3346{
e075ae69 3347 struct ix86_address parts;
e9a25f70 3348
e075ae69
RH
3349 if (! memory_operand (op, mode))
3350 return 0;
3351
3352 if (! ix86_decompose_address (XEXP (op, 0), &parts))
3353 abort ();
3354
3355 return parts.disp != NULL_RTX;
4f2c8ebb
RS
3356}
3357
16189740 3358/* To avoid problems when jump re-emits comparisons like testqi_ext_ccno_0,
e075ae69
RH
3359 re-recognize the operand to avoid a copy_to_mode_reg that will fail.
3360
3361 ??? It seems likely that this will only work because cmpsi is an
3362 expander, and no actual insns use this. */
4f2c8ebb
RS
3363
3364int
e075ae69
RH
3365cmpsi_operand (op, mode)
3366 rtx op;
3367 enum machine_mode mode;
fee2770d 3368{
b9b2c339 3369 if (nonimmediate_operand (op, mode))
e075ae69
RH
3370 return 1;
3371
3372 if (GET_CODE (op) == AND
3373 && GET_MODE (op) == SImode
3374 && GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT
3375 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
3376 && GET_CODE (XEXP (XEXP (op, 0), 2)) == CONST_INT
3377 && INTVAL (XEXP (XEXP (op, 0), 1)) == 8
3378 && INTVAL (XEXP (XEXP (op, 0), 2)) == 8
3379 && GET_CODE (XEXP (op, 1)) == CONST_INT)
fee2770d 3380 return 1;
e9a25f70 3381
fee2770d
RS
3382 return 0;
3383}
d784886d 3384
e075ae69
RH
3385/* Returns 1 if OP is memory operand that can not be represented by the
3386 modRM array. */
d784886d
RK
3387
3388int
e075ae69 3389long_memory_operand (op, mode)
d784886d
RK
3390 register rtx op;
3391 enum machine_mode mode;
3392{
e075ae69 3393 if (! memory_operand (op, mode))
d784886d
RK
3394 return 0;
3395
e075ae69 3396 return memory_address_length (op) != 0;
d784886d 3397}
2247f6ed
JH
3398
3399/* Return nonzero if the rtx is known aligned. */
3400
3401int
3402aligned_operand (op, mode)
3403 rtx op;
3404 enum machine_mode mode;
3405{
3406 struct ix86_address parts;
3407
3408 if (!general_operand (op, mode))
3409 return 0;
3410
0f290768 3411 /* Registers and immediate operands are always "aligned". */
2247f6ed
JH
3412 if (GET_CODE (op) != MEM)
3413 return 1;
3414
0f290768 3415 /* Don't even try to do any aligned optimizations with volatiles. */
2247f6ed
JH
3416 if (MEM_VOLATILE_P (op))
3417 return 0;
3418
3419 op = XEXP (op, 0);
3420
3421 /* Pushes and pops are only valid on the stack pointer. */
3422 if (GET_CODE (op) == PRE_DEC
3423 || GET_CODE (op) == POST_INC)
3424 return 1;
3425
3426 /* Decode the address. */
3427 if (! ix86_decompose_address (op, &parts))
3428 abort ();
3429
3430 /* Look for some component that isn't known to be aligned. */
3431 if (parts.index)
3432 {
3433 if (parts.scale < 4
bdb429a5 3434 && REGNO_POINTER_ALIGN (REGNO (parts.index)) < 32)
2247f6ed
JH
3435 return 0;
3436 }
3437 if (parts.base)
3438 {
bdb429a5 3439 if (REGNO_POINTER_ALIGN (REGNO (parts.base)) < 32)
2247f6ed
JH
3440 return 0;
3441 }
3442 if (parts.disp)
3443 {
3444 if (GET_CODE (parts.disp) != CONST_INT
3445 || (INTVAL (parts.disp) & 3) != 0)
3446 return 0;
3447 }
3448
3449 /* Didn't find one -- this must be an aligned address. */
3450 return 1;
3451}
e075ae69
RH
3452\f
3453/* Return true if the constant is something that can be loaded with
3454 a special instruction. Only handle 0.0 and 1.0; others are less
3455 worthwhile. */
57dbca5e
BS
3456
3457int
e075ae69
RH
3458standard_80387_constant_p (x)
3459 rtx x;
57dbca5e 3460{
2b04e52b 3461 if (GET_CODE (x) != CONST_DOUBLE || !FLOAT_MODE_P (GET_MODE (x)))
e075ae69 3462 return -1;
2b04e52b
JH
3463 /* Note that on the 80387, other constants, such as pi, that we should support
3464 too. On some machines, these are much slower to load as standard constant,
3465 than to load from doubles in memory. */
3466 if (x == CONST0_RTX (GET_MODE (x)))
3467 return 1;
3468 if (x == CONST1_RTX (GET_MODE (x)))
3469 return 2;
e075ae69 3470 return 0;
57dbca5e
BS
3471}
3472
2b04e52b
JH
3473/* Return 1 if X is FP constant we can load to SSE register w/o using memory.
3474 */
3475int
3476standard_sse_constant_p (x)
3477 rtx x;
3478{
3479 if (GET_CODE (x) != CONST_DOUBLE)
3480 return -1;
3481 return (x == CONST0_RTX (GET_MODE (x)));
3482}
3483
2a2ab3f9
JVA
3484/* Returns 1 if OP contains a symbol reference */
3485
3486int
3487symbolic_reference_mentioned_p (op)
3488 rtx op;
3489{
6f7d635c 3490 register const char *fmt;
2a2ab3f9
JVA
3491 register int i;
3492
3493 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
3494 return 1;
3495
3496 fmt = GET_RTX_FORMAT (GET_CODE (op));
3497 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
3498 {
3499 if (fmt[i] == 'E')
3500 {
3501 register int j;
3502
3503 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
3504 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
3505 return 1;
3506 }
e9a25f70 3507
2a2ab3f9
JVA
3508 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
3509 return 1;
3510 }
3511
3512 return 0;
3513}
e075ae69
RH
3514
3515/* Return 1 if it is appropriate to emit `ret' instructions in the
3516 body of a function. Do this only if the epilogue is simple, needing a
3517 couple of insns. Prior to reloading, we can't tell how many registers
3518 must be saved, so return 0 then. Return 0 if there is no frame
3519 marker to de-allocate.
3520
3521 If NON_SAVING_SETJMP is defined and true, then it is not possible
3522 for the epilogue to be simple, so return 0. This is a special case
3523 since NON_SAVING_SETJMP will not cause regs_ever_live to change
3524 until final, but jump_optimize may need to know sooner if a
3525 `return' is OK. */
32b5b1aa
SC
3526
3527int
e075ae69 3528ix86_can_use_return_insn_p ()
32b5b1aa 3529{
4dd2ac2c 3530 struct ix86_frame frame;
9a7372d6 3531
e075ae69
RH
3532#ifdef NON_SAVING_SETJMP
3533 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
3534 return 0;
3535#endif
9a7372d6
RH
3536
3537 if (! reload_completed || frame_pointer_needed)
3538 return 0;
32b5b1aa 3539
9a7372d6
RH
3540 /* Don't allow more than 32 pop, since that's all we can do
3541 with one instruction. */
3542 if (current_function_pops_args
3543 && current_function_args_size >= 32768)
e075ae69 3544 return 0;
32b5b1aa 3545
4dd2ac2c
JH
3546 ix86_compute_frame_layout (&frame);
3547 return frame.to_allocate == 0 && frame.nregs == 0;
e075ae69 3548}
6189a572
JH
3549\f
3550/* Return 1 if VALUE can be stored in the sign extended immediate field. */
3551int
3552x86_64_sign_extended_value (value)
3553 rtx value;
3554{
3555 switch (GET_CODE (value))
3556 {
3557 /* CONST_DOUBLES never match, since HOST_BITS_PER_WIDE_INT is known
3558 to be at least 32 and this all acceptable constants are
3559 represented as CONST_INT. */
3560 case CONST_INT:
3561 if (HOST_BITS_PER_WIDE_INT == 32)
3562 return 1;
3563 else
3564 {
3565 HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (value), DImode);
fa9f36a1 3566 return trunc_int_for_mode (val, SImode) == val;
6189a572
JH
3567 }
3568 break;
3569
3570 /* For certain code models, the symbolic references are known to fit. */
3571 case SYMBOL_REF:
3572 return ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL;
3573
3574 /* For certain code models, the code is near as well. */
3575 case LABEL_REF:
3576 return ix86_cmodel != CM_LARGE && ix86_cmodel != CM_SMALL_PIC;
3577
3578 /* We also may accept the offsetted memory references in certain special
3579 cases. */
3580 case CONST:
3581 if (GET_CODE (XEXP (value, 0)) == UNSPEC
3582 && XVECLEN (XEXP (value, 0), 0) == 1
3583 && XINT (XEXP (value, 0), 1) == 15)
3584 return 1;
3585 else if (GET_CODE (XEXP (value, 0)) == PLUS)
3586 {
3587 rtx op1 = XEXP (XEXP (value, 0), 0);
3588 rtx op2 = XEXP (XEXP (value, 0), 1);
3589 HOST_WIDE_INT offset;
3590
3591 if (ix86_cmodel == CM_LARGE)
3592 return 0;
3593 if (GET_CODE (op2) != CONST_INT)
3594 return 0;
3595 offset = trunc_int_for_mode (INTVAL (op2), DImode);
3596 switch (GET_CODE (op1))
3597 {
3598 case SYMBOL_REF:
3599 /* For CM_SMALL assume that latest object is 1MB before
3600 end of 31bits boundary. We may also accept pretty
3601 large negative constants knowing that all objects are
3602 in the positive half of address space. */
3603 if (ix86_cmodel == CM_SMALL
3604 && offset < 1024*1024*1024
3605 && trunc_int_for_mode (offset, SImode) == offset)
3606 return 1;
3607 /* For CM_KERNEL we know that all object resist in the
3608 negative half of 32bits address space. We may not
3609 accept negative offsets, since they may be just off
d6a7951f 3610 and we may accept pretty large positive ones. */
6189a572
JH
3611 if (ix86_cmodel == CM_KERNEL
3612 && offset > 0
3613 && trunc_int_for_mode (offset, SImode) == offset)
3614 return 1;
3615 break;
3616 case LABEL_REF:
3617 /* These conditions are similar to SYMBOL_REF ones, just the
3618 constraints for code models differ. */
3619 if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM)
3620 && offset < 1024*1024*1024
3621 && trunc_int_for_mode (offset, SImode) == offset)
3622 return 1;
3623 if (ix86_cmodel == CM_KERNEL
3624 && offset > 0
3625 && trunc_int_for_mode (offset, SImode) == offset)
3626 return 1;
3627 break;
3628 default:
3629 return 0;
3630 }
3631 }
3632 return 0;
3633 default:
3634 return 0;
3635 }
3636}
3637
3638/* Return 1 if VALUE can be stored in the zero extended immediate field. */
3639int
3640x86_64_zero_extended_value (value)
3641 rtx value;
3642{
3643 switch (GET_CODE (value))
3644 {
3645 case CONST_DOUBLE:
3646 if (HOST_BITS_PER_WIDE_INT == 32)
3647 return (GET_MODE (value) == VOIDmode
3648 && !CONST_DOUBLE_HIGH (value));
3649 else
3650 return 0;
3651 case CONST_INT:
3652 if (HOST_BITS_PER_WIDE_INT == 32)
3653 return INTVAL (value) >= 0;
3654 else
3655 return !(INTVAL (value) & ~(HOST_WIDE_INT)0xffffffff);
3656 break;
3657
3658 /* For certain code models, the symbolic references are known to fit. */
3659 case SYMBOL_REF:
3660 return ix86_cmodel == CM_SMALL;
3661
3662 /* For certain code models, the code is near as well. */
3663 case LABEL_REF:
3664 return ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM;
3665
3666 /* We also may accept the offsetted memory references in certain special
3667 cases. */
3668 case CONST:
3669 if (GET_CODE (XEXP (value, 0)) == PLUS)
3670 {
3671 rtx op1 = XEXP (XEXP (value, 0), 0);
3672 rtx op2 = XEXP (XEXP (value, 0), 1);
3673
3674 if (ix86_cmodel == CM_LARGE)
3675 return 0;
3676 switch (GET_CODE (op1))
3677 {
3678 case SYMBOL_REF:
3679 return 0;
d6a7951f 3680 /* For small code model we may accept pretty large positive
6189a572
JH
3681 offsets, since one bit is available for free. Negative
3682 offsets are limited by the size of NULL pointer area
3683 specified by the ABI. */
3684 if (ix86_cmodel == CM_SMALL
3685 && GET_CODE (op2) == CONST_INT
3686 && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000
3687 && (trunc_int_for_mode (INTVAL (op2), SImode)
3688 == INTVAL (op2)))
3689 return 1;
3690 /* ??? For the kernel, we may accept adjustment of
3691 -0x10000000, since we know that it will just convert
d6a7951f 3692 negative address space to positive, but perhaps this
6189a572
JH
3693 is not worthwhile. */
3694 break;
3695 case LABEL_REF:
3696 /* These conditions are similar to SYMBOL_REF ones, just the
3697 constraints for code models differ. */
3698 if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM)
3699 && GET_CODE (op2) == CONST_INT
3700 && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000
3701 && (trunc_int_for_mode (INTVAL (op2), SImode)
3702 == INTVAL (op2)))
3703 return 1;
3704 break;
3705 default:
3706 return 0;
3707 }
3708 }
3709 return 0;
3710 default:
3711 return 0;
3712 }
3713}
6fca22eb
RH
3714
3715/* Value should be nonzero if functions must have frame pointers.
3716 Zero means the frame pointer need not be set up (and parms may
3717 be accessed via the stack pointer) in functions that seem suitable. */
3718
3719int
3720ix86_frame_pointer_required ()
3721{
3722 /* If we accessed previous frames, then the generated code expects
3723 to be able to access the saved ebp value in our frame. */
3724 if (cfun->machine->accesses_prev_frame)
3725 return 1;
a4f31c00 3726
6fca22eb
RH
3727 /* Several x86 os'es need a frame pointer for other reasons,
3728 usually pertaining to setjmp. */
3729 if (SUBTARGET_FRAME_POINTER_REQUIRED)
3730 return 1;
3731
3732 /* In override_options, TARGET_OMIT_LEAF_FRAME_POINTER turns off
3733 the frame pointer by default. Turn it back on now if we've not
3734 got a leaf function. */
3735 if (TARGET_OMIT_LEAF_FRAME_POINTER && ! leaf_function_p ())
3736 return 1;
3737
3738 return 0;
3739}
3740
3741/* Record that the current function accesses previous call frames. */
3742
3743void
3744ix86_setup_frame_addresses ()
3745{
3746 cfun->machine->accesses_prev_frame = 1;
3747}
e075ae69 3748\f
4cf12e7e 3749static char pic_label_name[32];
e9a25f70 3750
e075ae69
RH
3751/* This function generates code for -fpic that loads %ebx with
3752 the return address of the caller and then returns. */
3753
3754void
4cf12e7e 3755ix86_asm_file_end (file)
e075ae69 3756 FILE *file;
e075ae69
RH
3757{
3758 rtx xops[2];
32b5b1aa 3759
4cf12e7e
RH
3760 if (! TARGET_DEEP_BRANCH_PREDICTION || pic_label_name[0] == 0)
3761 return;
32b5b1aa 3762
c7f0da1d
RH
3763 /* ??? Binutils 2.10 and earlier has a linkonce elimination bug related
3764 to updating relocations to a section being discarded such that this
3765 doesn't work. Ought to detect this at configure time. */
7c262518 3766#if 0
4cf12e7e
RH
3767 /* The trick here is to create a linkonce section containing the
3768 pic label thunk, but to refer to it with an internal label.
3769 Because the label is internal, we don't have inter-dso name
3770 binding issues on hosts that don't support ".hidden".
e9a25f70 3771
4cf12e7e
RH
3772 In order to use these macros, however, we must create a fake
3773 function decl. */
7c262518
RH
3774 if (targetm.have_named_sections)
3775 {
3776 tree decl = build_decl (FUNCTION_DECL,
3777 get_identifier ("i686.get_pc_thunk"),
3778 error_mark_node);
3779 DECL_ONE_ONLY (decl) = 1;
3780 UNIQUE_SECTION (decl, 0);
715bdd29 3781 named_section (decl, NULL);
7c262518
RH
3782 }
3783 else
4cf12e7e 3784#else
7c262518 3785 text_section ();
4cf12e7e 3786#endif
0afeb08a 3787
4cf12e7e
RH
3788 /* This used to call ASM_DECLARE_FUNCTION_NAME() but since it's an
3789 internal (non-global) label that's being emitted, it didn't make
3790 sense to have .type information for local labels. This caused
3791 the SCO OpenServer 5.0.4 ELF assembler grief (why are you giving
3792 me debug info for a label that you're declaring non-global?) this
3793 was changed to call ASM_OUTPUT_LABEL() instead. */
3794
3795 ASM_OUTPUT_LABEL (file, pic_label_name);
3796
3797 xops[0] = pic_offset_table_rtx;
3798 xops[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
3799 output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
3800 output_asm_insn ("ret", xops);
32b5b1aa 3801}
32b5b1aa 3802
e075ae69
RH
3803void
3804load_pic_register ()
32b5b1aa 3805{
e075ae69 3806 rtx gotsym, pclab;
32b5b1aa 3807
0d7d98ee
JH
3808 if (TARGET_64BIT)
3809 abort();
3810
a8a05998 3811 gotsym = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
32b5b1aa 3812
e075ae69 3813 if (TARGET_DEEP_BRANCH_PREDICTION)
32b5b1aa 3814 {
4cf12e7e
RH
3815 if (! pic_label_name[0])
3816 ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
e075ae69 3817 pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name));
32b5b1aa 3818 }
e075ae69 3819 else
e5cb57e8 3820 {
e075ae69 3821 pclab = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
e5cb57e8 3822 }
e5cb57e8 3823
e075ae69 3824 emit_insn (gen_prologue_get_pc (pic_offset_table_rtx, pclab));
2a2ab3f9 3825
e075ae69
RH
3826 if (! TARGET_DEEP_BRANCH_PREDICTION)
3827 emit_insn (gen_popsi1 (pic_offset_table_rtx));
79325812 3828
e075ae69 3829 emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab));
e9a25f70 3830}
8dfe5673 3831
0d7d98ee 3832/* Generate an "push" pattern for input ARG. */
e9a25f70 3833
e075ae69
RH
3834static rtx
3835gen_push (arg)
3836 rtx arg;
e9a25f70 3837{
c5c76735 3838 return gen_rtx_SET (VOIDmode,
0d7d98ee
JH
3839 gen_rtx_MEM (Pmode,
3840 gen_rtx_PRE_DEC (Pmode,
c5c76735
JL
3841 stack_pointer_rtx)),
3842 arg);
e9a25f70
JL
3843}
3844
4dd2ac2c
JH
3845/* Return 1 if we need to save REGNO. */
3846static int
1020a5ab
RH
3847ix86_save_reg (regno, maybe_eh_return)
3848 int regno;
37a58036 3849 int maybe_eh_return;
1020a5ab
RH
3850{
3851 if (flag_pic
3852 && ! TARGET_64BIT
3853 && regno == PIC_OFFSET_TABLE_REGNUM
3854 && (current_function_uses_pic_offset_table
3855 || current_function_uses_const_pool
3856 || current_function_calls_eh_return))
3857 return 1;
3858
3859 if (current_function_calls_eh_return && maybe_eh_return)
3860 {
3861 unsigned i;
3862 for (i = 0; ; i++)
3863 {
3864 unsigned test = EH_RETURN_DATA_REGNO(i);
3865 if (test == INVALID_REGNUM)
3866 break;
3867 if (test == (unsigned) regno)
3868 return 1;
3869 }
3870 }
4dd2ac2c 3871
1020a5ab
RH
3872 return (regs_ever_live[regno]
3873 && !call_used_regs[regno]
3874 && !fixed_regs[regno]
3875 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
4dd2ac2c
JH
3876}
3877
0903fcab
JH
3878/* Return number of registers to be saved on the stack. */
3879
3880static int
3881ix86_nsaved_regs ()
3882{
3883 int nregs = 0;
0903fcab
JH
3884 int regno;
3885
4dd2ac2c 3886 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
1020a5ab 3887 if (ix86_save_reg (regno, true))
4dd2ac2c 3888 nregs++;
0903fcab
JH
3889 return nregs;
3890}
3891
3892/* Return the offset between two registers, one to be eliminated, and the other
3893 its replacement, at the start of a routine. */
3894
3895HOST_WIDE_INT
3896ix86_initial_elimination_offset (from, to)
3897 int from;
3898 int to;
3899{
4dd2ac2c
JH
3900 struct ix86_frame frame;
3901 ix86_compute_frame_layout (&frame);
564d80f4
JH
3902
3903 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
4dd2ac2c 3904 return frame.hard_frame_pointer_offset;
564d80f4
JH
3905 else if (from == FRAME_POINTER_REGNUM
3906 && to == HARD_FRAME_POINTER_REGNUM)
4dd2ac2c 3907 return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
0903fcab
JH
3908 else
3909 {
564d80f4
JH
3910 if (to != STACK_POINTER_REGNUM)
3911 abort ();
3912 else if (from == ARG_POINTER_REGNUM)
4dd2ac2c 3913 return frame.stack_pointer_offset;
564d80f4
JH
3914 else if (from != FRAME_POINTER_REGNUM)
3915 abort ();
0903fcab 3916 else
4dd2ac2c 3917 return frame.stack_pointer_offset - frame.frame_pointer_offset;
0903fcab
JH
3918 }
3919}
3920
4dd2ac2c 3921/* Fill structure ix86_frame about frame of currently computed function. */
0f290768 3922
4dd2ac2c
JH
3923static void
3924ix86_compute_frame_layout (frame)
3925 struct ix86_frame *frame;
65954bd8 3926{
65954bd8 3927 HOST_WIDE_INT total_size;
564d80f4 3928 int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT;
44affdae
JH
3929 int offset;
3930 int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT;
4dd2ac2c 3931 HOST_WIDE_INT size = get_frame_size ();
65954bd8 3932
4dd2ac2c 3933 frame->nregs = ix86_nsaved_regs ();
564d80f4 3934 total_size = size;
65954bd8 3935
4dd2ac2c
JH
3936 /* Skip return value and save base pointer. */
3937 offset = frame_pointer_needed ? UNITS_PER_WORD * 2 : UNITS_PER_WORD;
3938
3939 frame->hard_frame_pointer_offset = offset;
564d80f4 3940
fcbfaa65
RK
3941 /* Do some sanity checking of stack_alignment_needed and
3942 preferred_alignment, since i386 port is the only using those features
f710504c 3943 that may break easily. */
564d80f4 3944
44affdae
JH
3945 if (size && !stack_alignment_needed)
3946 abort ();
44affdae
JH
3947 if (preferred_alignment < STACK_BOUNDARY / BITS_PER_UNIT)
3948 abort ();
3949 if (preferred_alignment > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
3950 abort ();
3951 if (stack_alignment_needed > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
3952 abort ();
564d80f4 3953
4dd2ac2c
JH
3954 if (stack_alignment_needed < STACK_BOUNDARY / BITS_PER_UNIT)
3955 stack_alignment_needed = STACK_BOUNDARY / BITS_PER_UNIT;
564d80f4 3956
4dd2ac2c
JH
3957 /* Register save area */
3958 offset += frame->nregs * UNITS_PER_WORD;
65954bd8 3959
8362f420
JH
3960 /* Va-arg area */
3961 if (ix86_save_varrargs_registers)
3962 {
3963 offset += X86_64_VARARGS_SIZE;
3964 frame->va_arg_size = X86_64_VARARGS_SIZE;
3965 }
3966 else
3967 frame->va_arg_size = 0;
3968
4dd2ac2c
JH
3969 /* Align start of frame for local function. */
3970 frame->padding1 = ((offset + stack_alignment_needed - 1)
3971 & -stack_alignment_needed) - offset;
f73ad30e 3972
4dd2ac2c 3973 offset += frame->padding1;
65954bd8 3974
4dd2ac2c
JH
3975 /* Frame pointer points here. */
3976 frame->frame_pointer_offset = offset;
54ff41b7 3977
4dd2ac2c 3978 offset += size;
65954bd8 3979
4dd2ac2c 3980 /* Add outgoing arguments area. */
f73ad30e 3981 if (ACCUMULATE_OUTGOING_ARGS)
4dd2ac2c
JH
3982 {
3983 offset += current_function_outgoing_args_size;
3984 frame->outgoing_arguments_size = current_function_outgoing_args_size;
3985 }
3986 else
3987 frame->outgoing_arguments_size = 0;
564d80f4 3988
4dd2ac2c
JH
3989 /* Align stack boundary. */
3990 frame->padding2 = ((offset + preferred_alignment - 1)
3991 & -preferred_alignment) - offset;
3992
3993 offset += frame->padding2;
3994
3995 /* We've reached end of stack frame. */
3996 frame->stack_pointer_offset = offset;
3997
3998 /* Size prologue needs to allocate. */
3999 frame->to_allocate =
4000 (size + frame->padding1 + frame->padding2
8362f420 4001 + frame->outgoing_arguments_size + frame->va_arg_size);
4dd2ac2c 4002
8362f420
JH
4003 if (TARGET_64BIT && TARGET_RED_ZONE && current_function_sp_is_unchanging
4004 && current_function_is_leaf)
4005 {
4006 frame->red_zone_size = frame->to_allocate;
4007 if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
4008 frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
4009 }
4010 else
4011 frame->red_zone_size = 0;
4012 frame->to_allocate -= frame->red_zone_size;
4013 frame->stack_pointer_offset -= frame->red_zone_size;
4dd2ac2c
JH
4014#if 0
4015 fprintf (stderr, "nregs: %i\n", frame->nregs);
4016 fprintf (stderr, "size: %i\n", size);
4017 fprintf (stderr, "alignment1: %i\n", stack_alignment_needed);
4018 fprintf (stderr, "padding1: %i\n", frame->padding1);
8362f420 4019 fprintf (stderr, "va_arg: %i\n", frame->va_arg_size);
4dd2ac2c
JH
4020 fprintf (stderr, "padding2: %i\n", frame->padding2);
4021 fprintf (stderr, "to_allocate: %i\n", frame->to_allocate);
8362f420 4022 fprintf (stderr, "red_zone_size: %i\n", frame->red_zone_size);
4dd2ac2c
JH
4023 fprintf (stderr, "frame_pointer_offset: %i\n", frame->frame_pointer_offset);
4024 fprintf (stderr, "hard_frame_pointer_offset: %i\n",
4025 frame->hard_frame_pointer_offset);
4026 fprintf (stderr, "stack_pointer_offset: %i\n", frame->stack_pointer_offset);
4027#endif
65954bd8
JL
4028}
4029
0903fcab
JH
4030/* Emit code to save registers in the prologue. */
4031
4032static void
4033ix86_emit_save_regs ()
4034{
4035 register int regno;
0903fcab 4036 rtx insn;
0903fcab 4037
4dd2ac2c 4038 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
1020a5ab 4039 if (ix86_save_reg (regno, true))
0903fcab 4040 {
0d7d98ee 4041 insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
0903fcab
JH
4042 RTX_FRAME_RELATED_P (insn) = 1;
4043 }
4044}
4045
c6036a37
JH
4046/* Emit code to save registers using MOV insns. First register
4047 is restored from POINTER + OFFSET. */
4048static void
4049ix86_emit_save_regs_using_mov (pointer, offset)
b72f00af
RK
4050 rtx pointer;
4051 HOST_WIDE_INT offset;
c6036a37
JH
4052{
4053 int regno;
4054 rtx insn;
4055
4056 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
4057 if (ix86_save_reg (regno, true))
4058 {
b72f00af
RK
4059 insn = emit_move_insn (adjust_address (gen_rtx_MEM (Pmode, pointer),
4060 Pmode, offset),
c6036a37
JH
4061 gen_rtx_REG (Pmode, regno));
4062 RTX_FRAME_RELATED_P (insn) = 1;
4063 offset += UNITS_PER_WORD;
4064 }
4065}
4066
0f290768 4067/* Expand the prologue into a bunch of separate insns. */
e075ae69
RH
4068
4069void
4070ix86_expand_prologue ()
2a2ab3f9 4071{
564d80f4 4072 rtx insn;
0d7d98ee
JH
4073 int pic_reg_used = (flag_pic && (current_function_uses_pic_offset_table
4074 || current_function_uses_const_pool)
4075 && !TARGET_64BIT);
4dd2ac2c 4076 struct ix86_frame frame;
6ab16dd9 4077 int use_mov = 0;
c6036a37 4078 HOST_WIDE_INT allocate;
4dd2ac2c 4079
2ab0437e 4080 if (!optimize_size)
6ab16dd9
JH
4081 {
4082 use_fast_prologue_epilogue
4083 = !expensive_function_p (FAST_PROLOGUE_INSN_COUNT);
2ab0437e
JH
4084 if (TARGET_PROLOGUE_USING_MOVE)
4085 use_mov = use_fast_prologue_epilogue;
6ab16dd9 4086 }
4dd2ac2c 4087 ix86_compute_frame_layout (&frame);
79325812 4088
e075ae69
RH
4089 /* Note: AT&T enter does NOT have reversed args. Enter is probably
4090 slower on all targets. Also sdb doesn't like it. */
e9a25f70 4091
2a2ab3f9
JVA
4092 if (frame_pointer_needed)
4093 {
564d80f4 4094 insn = emit_insn (gen_push (hard_frame_pointer_rtx));
e075ae69 4095 RTX_FRAME_RELATED_P (insn) = 1;
e9a25f70 4096
564d80f4 4097 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
e075ae69 4098 RTX_FRAME_RELATED_P (insn) = 1;
2a2ab3f9
JVA
4099 }
4100
c6036a37
JH
4101 allocate = frame.to_allocate;
4102 /* In case we are dealing only with single register and empty frame,
4103 push is equivalent of the mov+add sequence. */
4104 if (allocate == 0 && frame.nregs <= 1)
4105 use_mov = 0;
4106
4107 if (!use_mov)
4108 ix86_emit_save_regs ();
4109 else
4110 allocate += frame.nregs * UNITS_PER_WORD;
564d80f4 4111
c6036a37 4112 if (allocate == 0)
8dfe5673 4113 ;
e323735c 4114 else if (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)
469ac993 4115 {
f2042df3
RH
4116 insn = emit_insn (gen_pro_epilogue_adjust_stack
4117 (stack_pointer_rtx, stack_pointer_rtx,
e323735c 4118 GEN_INT (-allocate)));
e075ae69 4119 RTX_FRAME_RELATED_P (insn) = 1;
469ac993 4120 }
79325812 4121 else
8dfe5673 4122 {
e075ae69 4123 /* ??? Is this only valid for Win32? */
e9a25f70 4124
e075ae69 4125 rtx arg0, sym;
e9a25f70 4126
8362f420
JH
4127 if (TARGET_64BIT)
4128 abort();
4129
e075ae69 4130 arg0 = gen_rtx_REG (SImode, 0);
c6036a37 4131 emit_move_insn (arg0, GEN_INT (allocate));
77a989d1 4132
e075ae69
RH
4133 sym = gen_rtx_MEM (FUNCTION_MODE,
4134 gen_rtx_SYMBOL_REF (Pmode, "_alloca"));
32ee7d1d 4135 insn = emit_call_insn (gen_call (sym, const0_rtx, constm1_rtx));
e075ae69
RH
4136
4137 CALL_INSN_FUNCTION_USAGE (insn)
276ab4a4
RH
4138 = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0),
4139 CALL_INSN_FUNCTION_USAGE (insn));
e075ae69 4140 }
c6036a37
JH
4141 if (use_mov)
4142 {
4143 if (!frame_pointer_needed || !frame.to_allocate)
4144 ix86_emit_save_regs_using_mov (stack_pointer_rtx, frame.to_allocate);
4145 else
4146 ix86_emit_save_regs_using_mov (hard_frame_pointer_rtx,
4147 -frame.nregs * UNITS_PER_WORD);
4148 }
e9a25f70 4149
84530511
SC
4150#ifdef SUBTARGET_PROLOGUE
4151 SUBTARGET_PROLOGUE;
0f290768 4152#endif
84530511 4153
e9a25f70 4154 if (pic_reg_used)
e075ae69 4155 load_pic_register ();
77a989d1 4156
e9a25f70
JL
4157 /* If we are profiling, make sure no instructions are scheduled before
4158 the call to mcount. However, if -fpic, the above call will have
4159 done that. */
8456b95a 4160 if (profile_flag && ! pic_reg_used)
e9a25f70 4161 emit_insn (gen_blockage ());
77a989d1
SC
4162}
4163
da2d1d3a
JH
4164/* Emit code to restore saved registers using MOV insns. First register
4165 is restored from POINTER + OFFSET. */
4166static void
1020a5ab
RH
4167ix86_emit_restore_regs_using_mov (pointer, offset, maybe_eh_return)
4168 rtx pointer;
4169 int offset;
37a58036 4170 int maybe_eh_return;
da2d1d3a
JH
4171{
4172 int regno;
da2d1d3a 4173
4dd2ac2c 4174 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1020a5ab 4175 if (ix86_save_reg (regno, maybe_eh_return))
da2d1d3a 4176 {
4dd2ac2c 4177 emit_move_insn (gen_rtx_REG (Pmode, regno),
b72f00af
RK
4178 adjust_address (gen_rtx_MEM (Pmode, pointer),
4179 Pmode, offset));
4dd2ac2c 4180 offset += UNITS_PER_WORD;
da2d1d3a
JH
4181 }
4182}
4183
0f290768 4184/* Restore function stack, frame, and registers. */
e9a25f70 4185
2a2ab3f9 4186void
1020a5ab
RH
4187ix86_expand_epilogue (style)
4188 int style;
2a2ab3f9 4189{
1c71e60e 4190 int regno;
fdb8a883 4191 int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
4dd2ac2c 4192 struct ix86_frame frame;
65954bd8 4193 HOST_WIDE_INT offset;
4dd2ac2c
JH
4194
4195 ix86_compute_frame_layout (&frame);
2a2ab3f9 4196
a4f31c00 4197 /* Calculate start of saved registers relative to ebp. Special care
84e306b4
RH
4198 must be taken for the normal return case of a function using
4199 eh_return: the eax and edx registers are marked as saved, but not
4200 restored along this path. */
4201 offset = frame.nregs;
4202 if (current_function_calls_eh_return && style != 2)
4203 offset -= 2;
4204 offset *= -UNITS_PER_WORD;
2a2ab3f9 4205
fdb8a883
JW
4206 /* If we're only restoring one register and sp is not valid then
4207 using a move instruction to restore the register since it's
0f290768 4208 less work than reloading sp and popping the register.
da2d1d3a
JH
4209
4210 The default code result in stack adjustment using add/lea instruction,
4211 while this code results in LEAVE instruction (or discrete equivalent),
4212 so it is profitable in some other cases as well. Especially when there
4213 are no registers to restore. We also use this code when TARGET_USE_LEAVE
4214 and there is exactly one register to pop. This heruistic may need some
4215 tuning in future. */
4dd2ac2c 4216 if ((!sp_valid && frame.nregs <= 1)
2ab0437e 4217 || (TARGET_EPILOGUE_USING_MOVE
6ab16dd9 4218 && use_fast_prologue_epilogue
c6036a37 4219 && (frame.nregs > 1 || frame.to_allocate))
4dd2ac2c 4220 || (frame_pointer_needed && !frame.nregs && frame.to_allocate)
2ab0437e 4221 || (frame_pointer_needed && TARGET_USE_LEAVE
6ab16dd9 4222 && use_fast_prologue_epilogue && frame.nregs == 1)
2ab0437e 4223 || current_function_calls_eh_return)
2a2ab3f9 4224 {
da2d1d3a
JH
4225 /* Restore registers. We can use ebp or esp to address the memory
4226 locations. If both are available, default to ebp, since offsets
4227 are known to be small. Only exception is esp pointing directly to the
4228 end of block of saved registers, where we may simplify addressing
4229 mode. */
4230
4dd2ac2c 4231 if (!frame_pointer_needed || (sp_valid && !frame.to_allocate))
1020a5ab
RH
4232 ix86_emit_restore_regs_using_mov (stack_pointer_rtx,
4233 frame.to_allocate, style == 2);
da2d1d3a 4234 else
1020a5ab
RH
4235 ix86_emit_restore_regs_using_mov (hard_frame_pointer_rtx,
4236 offset, style == 2);
4237
4238 /* eh_return epilogues need %ecx added to the stack pointer. */
4239 if (style == 2)
4240 {
4241 rtx tmp, sa = EH_RETURN_STACKADJ_RTX;
2a2ab3f9 4242
1020a5ab
RH
4243 if (frame_pointer_needed)
4244 {
4245 tmp = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
4246 tmp = plus_constant (tmp, UNITS_PER_WORD);
4247 emit_insn (gen_rtx_SET (VOIDmode, sa, tmp));
4248
4249 tmp = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
4250 emit_move_insn (hard_frame_pointer_rtx, tmp);
4251
4252 emit_insn (gen_pro_epilogue_adjust_stack
f2042df3 4253 (stack_pointer_rtx, sa, const0_rtx));
1020a5ab
RH
4254 }
4255 else
4256 {
4257 tmp = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
4258 tmp = plus_constant (tmp, (frame.to_allocate
4259 + frame.nregs * UNITS_PER_WORD));
4260 emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, tmp));
4261 }
4262 }
4263 else if (!frame_pointer_needed)
f2042df3
RH
4264 emit_insn (gen_pro_epilogue_adjust_stack
4265 (stack_pointer_rtx, stack_pointer_rtx,
4266 GEN_INT (frame.to_allocate
4267 + frame.nregs * UNITS_PER_WORD)));
0f290768 4268 /* If not an i386, mov & pop is faster than "leave". */
6ab16dd9 4269 else if (TARGET_USE_LEAVE || optimize_size || !use_fast_prologue_epilogue)
8362f420 4270 emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
c8c5cb99 4271 else
2a2ab3f9 4272 {
1c71e60e
JH
4273 emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
4274 hard_frame_pointer_rtx,
f2042df3 4275 const0_rtx));
8362f420
JH
4276 if (TARGET_64BIT)
4277 emit_insn (gen_popdi1 (hard_frame_pointer_rtx));
4278 else
4279 emit_insn (gen_popsi1 (hard_frame_pointer_rtx));
e9a25f70
JL
4280 }
4281 }
1c71e60e 4282 else
68f654ec 4283 {
1c71e60e
JH
4284 /* First step is to deallocate the stack frame so that we can
4285 pop the registers. */
4286 if (!sp_valid)
4287 {
4288 if (!frame_pointer_needed)
4289 abort ();
4290 emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
4291 hard_frame_pointer_rtx,
f2042df3 4292 GEN_INT (offset)));
1c71e60e 4293 }
4dd2ac2c 4294 else if (frame.to_allocate)
f2042df3
RH
4295 emit_insn (gen_pro_epilogue_adjust_stack
4296 (stack_pointer_rtx, stack_pointer_rtx,
4297 GEN_INT (frame.to_allocate)));
1c71e60e 4298
4dd2ac2c 4299 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1020a5ab 4300 if (ix86_save_reg (regno, false))
8362f420
JH
4301 {
4302 if (TARGET_64BIT)
4303 emit_insn (gen_popdi1 (gen_rtx_REG (Pmode, regno)));
4304 else
4305 emit_insn (gen_popsi1 (gen_rtx_REG (Pmode, regno)));
4306 }
4dd2ac2c 4307 if (frame_pointer_needed)
8362f420 4308 {
f5143c46 4309 /* Leave results in shorter dependency chains on CPUs that are
2ab0437e
JH
4310 able to grok it fast. */
4311 if (TARGET_USE_LEAVE)
4312 emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
4313 else if (TARGET_64BIT)
8362f420
JH
4314 emit_insn (gen_popdi1 (hard_frame_pointer_rtx));
4315 else
4316 emit_insn (gen_popsi1 (hard_frame_pointer_rtx));
4317 }
68f654ec 4318 }
68f654ec 4319
cbbf65e0 4320 /* Sibcall epilogues don't want a return instruction. */
1020a5ab 4321 if (style == 0)
cbbf65e0
RH
4322 return;
4323
2a2ab3f9
JVA
4324 if (current_function_pops_args && current_function_args_size)
4325 {
e075ae69 4326 rtx popc = GEN_INT (current_function_pops_args);
2a2ab3f9 4327
b8c752c8
UD
4328 /* i386 can only pop 64K bytes. If asked to pop more, pop
4329 return address, do explicit add, and jump indirectly to the
0f290768 4330 caller. */
2a2ab3f9 4331
b8c752c8 4332 if (current_function_pops_args >= 65536)
2a2ab3f9 4333 {
e075ae69 4334 rtx ecx = gen_rtx_REG (SImode, 2);
e9a25f70 4335
8362f420
JH
4336 /* There are is no "pascal" calling convention in 64bit ABI. */
4337 if (TARGET_64BIT)
4338 abort();
4339
e075ae69
RH
4340 emit_insn (gen_popsi1 (ecx));
4341 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, popc));
11837777 4342 emit_jump_insn (gen_return_indirect_internal (ecx));
e9a25f70 4343 }
79325812 4344 else
e075ae69
RH
4345 emit_jump_insn (gen_return_pop_internal (popc));
4346 }
4347 else
4348 emit_jump_insn (gen_return_internal ());
4349}
4350\f
4351/* Extract the parts of an RTL expression that is a valid memory address
4352 for an instruction. Return false if the structure of the address is
4353 grossly off. */
4354
4355static int
4356ix86_decompose_address (addr, out)
4357 register rtx addr;
4358 struct ix86_address *out;
4359{
4360 rtx base = NULL_RTX;
4361 rtx index = NULL_RTX;
4362 rtx disp = NULL_RTX;
4363 HOST_WIDE_INT scale = 1;
4364 rtx scale_rtx = NULL_RTX;
4365
4366 if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
4367 base = addr;
4368 else if (GET_CODE (addr) == PLUS)
4369 {
4370 rtx op0 = XEXP (addr, 0);
4371 rtx op1 = XEXP (addr, 1);
4372 enum rtx_code code0 = GET_CODE (op0);
4373 enum rtx_code code1 = GET_CODE (op1);
4374
4375 if (code0 == REG || code0 == SUBREG)
4376 {
4377 if (code1 == REG || code1 == SUBREG)
4378 index = op0, base = op1; /* index + base */
4379 else
4380 base = op0, disp = op1; /* base + displacement */
4381 }
4382 else if (code0 == MULT)
e9a25f70 4383 {
e075ae69
RH
4384 index = XEXP (op0, 0);
4385 scale_rtx = XEXP (op0, 1);
4386 if (code1 == REG || code1 == SUBREG)
4387 base = op1; /* index*scale + base */
e9a25f70 4388 else
e075ae69
RH
4389 disp = op1; /* index*scale + disp */
4390 }
4391 else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
4392 {
4393 index = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
4394 scale_rtx = XEXP (XEXP (op0, 0), 1);
4395 base = XEXP (op0, 1);
4396 disp = op1;
2a2ab3f9 4397 }
e075ae69
RH
4398 else if (code0 == PLUS)
4399 {
4400 index = XEXP (op0, 0); /* index + base + disp */
4401 base = XEXP (op0, 1);
4402 disp = op1;
4403 }
4404 else
4405 return FALSE;
4406 }
4407 else if (GET_CODE (addr) == MULT)
4408 {
4409 index = XEXP (addr, 0); /* index*scale */
4410 scale_rtx = XEXP (addr, 1);
4411 }
4412 else if (GET_CODE (addr) == ASHIFT)
4413 {
4414 rtx tmp;
4415
4416 /* We're called for lea too, which implements ashift on occasion. */
4417 index = XEXP (addr, 0);
4418 tmp = XEXP (addr, 1);
4419 if (GET_CODE (tmp) != CONST_INT)
4420 return FALSE;
4421 scale = INTVAL (tmp);
4422 if ((unsigned HOST_WIDE_INT) scale > 3)
4423 return FALSE;
4424 scale = 1 << scale;
2a2ab3f9 4425 }
2a2ab3f9 4426 else
e075ae69
RH
4427 disp = addr; /* displacement */
4428
4429 /* Extract the integral value of scale. */
4430 if (scale_rtx)
e9a25f70 4431 {
e075ae69
RH
4432 if (GET_CODE (scale_rtx) != CONST_INT)
4433 return FALSE;
4434 scale = INTVAL (scale_rtx);
e9a25f70 4435 }
3b3c6a3f 4436
e075ae69
RH
4437 /* Allow arg pointer and stack pointer as index if there is not scaling */
4438 if (base && index && scale == 1
564d80f4
JH
4439 && (index == arg_pointer_rtx || index == frame_pointer_rtx
4440 || index == stack_pointer_rtx))
e075ae69
RH
4441 {
4442 rtx tmp = base;
4443 base = index;
4444 index = tmp;
4445 }
4446
4447 /* Special case: %ebp cannot be encoded as a base without a displacement. */
564d80f4
JH
4448 if ((base == hard_frame_pointer_rtx
4449 || base == frame_pointer_rtx
4450 || base == arg_pointer_rtx) && !disp)
e075ae69
RH
4451 disp = const0_rtx;
4452
4453 /* Special case: on K6, [%esi] makes the instruction vector decoded.
4454 Avoid this by transforming to [%esi+0]. */
4455 if (ix86_cpu == PROCESSOR_K6 && !optimize_size
4456 && base && !index && !disp
329e1d01 4457 && REG_P (base)
e075ae69
RH
4458 && REGNO_REG_CLASS (REGNO (base)) == SIREG)
4459 disp = const0_rtx;
4460
4461 /* Special case: encode reg+reg instead of reg*2. */
4462 if (!base && index && scale && scale == 2)
4463 base = index, scale = 1;
0f290768 4464
e075ae69
RH
4465 /* Special case: scaling cannot be encoded without base or displacement. */
4466 if (!base && !disp && index && scale != 1)
4467 disp = const0_rtx;
4468
4469 out->base = base;
4470 out->index = index;
4471 out->disp = disp;
4472 out->scale = scale;
3b3c6a3f 4473
e075ae69
RH
4474 return TRUE;
4475}
01329426
JH
4476\f
4477/* Return cost of the memory address x.
4478 For i386, it is better to use a complex address than let gcc copy
4479 the address into a reg and make a new pseudo. But not if the address
4480 requires to two regs - that would mean more pseudos with longer
4481 lifetimes. */
4482int
4483ix86_address_cost (x)
4484 rtx x;
4485{
4486 struct ix86_address parts;
4487 int cost = 1;
3b3c6a3f 4488
01329426
JH
4489 if (!ix86_decompose_address (x, &parts))
4490 abort ();
4491
4492 /* More complex memory references are better. */
4493 if (parts.disp && parts.disp != const0_rtx)
4494 cost--;
4495
4496 /* Attempt to minimize number of registers in the address. */
4497 if ((parts.base
4498 && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER))
4499 || (parts.index
4500 && (!REG_P (parts.index)
4501 || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)))
4502 cost++;
4503
4504 if (parts.base
4505 && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
4506 && parts.index
4507 && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
4508 && parts.base != parts.index)
4509 cost++;
4510
4511 /* AMD-K6 don't like addresses with ModR/M set to 00_xxx_100b,
4512 since it's predecode logic can't detect the length of instructions
4513 and it degenerates to vector decoded. Increase cost of such
4514 addresses here. The penalty is minimally 2 cycles. It may be worthwhile
0f290768 4515 to split such addresses or even refuse such addresses at all.
01329426
JH
4516
4517 Following addressing modes are affected:
4518 [base+scale*index]
4519 [scale*index+disp]
4520 [base+index]
0f290768 4521
01329426
JH
4522 The first and last case may be avoidable by explicitly coding the zero in
4523 memory address, but I don't have AMD-K6 machine handy to check this
4524 theory. */
4525
4526 if (TARGET_K6
4527 && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
4528 || (parts.disp && !parts.base && parts.index && parts.scale != 1)
4529 || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
4530 cost += 10;
0f290768 4531
01329426
JH
4532 return cost;
4533}
4534\f
b949ea8b
JW
4535/* If X is a machine specific address (i.e. a symbol or label being
4536 referenced as a displacement from the GOT implemented using an
4537 UNSPEC), then return the base term. Otherwise return X. */
4538
4539rtx
4540ix86_find_base_term (x)
4541 rtx x;
4542{
4543 rtx term;
4544
6eb791fc
JH
4545 if (TARGET_64BIT)
4546 {
4547 if (GET_CODE (x) != CONST)
4548 return x;
4549 term = XEXP (x, 0);
4550 if (GET_CODE (term) == PLUS
4551 && (GET_CODE (XEXP (term, 1)) == CONST_INT
4552 || GET_CODE (XEXP (term, 1)) == CONST_DOUBLE))
4553 term = XEXP (term, 0);
4554 if (GET_CODE (term) != UNSPEC
4555 || XVECLEN (term, 0) != 1
4556 || XINT (term, 1) != 15)
4557 return x;
4558
4559 term = XVECEXP (term, 0, 0);
4560
4561 if (GET_CODE (term) != SYMBOL_REF
4562 && GET_CODE (term) != LABEL_REF)
4563 return x;
4564
4565 return term;
4566 }
4567
b949ea8b
JW
4568 if (GET_CODE (x) != PLUS
4569 || XEXP (x, 0) != pic_offset_table_rtx
4570 || GET_CODE (XEXP (x, 1)) != CONST)
4571 return x;
4572
4573 term = XEXP (XEXP (x, 1), 0);
4574
4575 if (GET_CODE (term) == PLUS && GET_CODE (XEXP (term, 1)) == CONST_INT)
4576 term = XEXP (term, 0);
4577
4578 if (GET_CODE (term) != UNSPEC
4579 || XVECLEN (term, 0) != 1
4580 || XINT (term, 1) != 7)
4581 return x;
4582
4583 term = XVECEXP (term, 0, 0);
4584
4585 if (GET_CODE (term) != SYMBOL_REF
4586 && GET_CODE (term) != LABEL_REF)
4587 return x;
4588
4589 return term;
4590}
4591\f
e075ae69
RH
4592/* Determine if a given CONST RTX is a valid memory displacement
4593 in PIC mode. */
0f290768 4594
59be65f6 4595int
91bb873f
RH
4596legitimate_pic_address_disp_p (disp)
4597 register rtx disp;
4598{
6eb791fc
JH
4599 /* In 64bit mode we can allow direct addresses of symbols and labels
4600 when they are not dynamic symbols. */
4601 if (TARGET_64BIT)
4602 {
4603 rtx x = disp;
4604 if (GET_CODE (disp) == CONST)
4605 x = XEXP (disp, 0);
4606 /* ??? Handle PIC code models */
4607 if (GET_CODE (x) == PLUS
4608 && (GET_CODE (XEXP (x, 1)) == CONST_INT
4609 && ix86_cmodel == CM_SMALL_PIC
4610 && INTVAL (XEXP (x, 1)) < 1024*1024*1024
4611 && INTVAL (XEXP (x, 1)) > -1024*1024*1024))
4612 x = XEXP (x, 0);
4613 if (local_symbolic_operand (x, Pmode))
4614 return 1;
4615 }
91bb873f
RH
4616 if (GET_CODE (disp) != CONST)
4617 return 0;
4618 disp = XEXP (disp, 0);
4619
6eb791fc
JH
4620 if (TARGET_64BIT)
4621 {
4622 /* We are unsafe to allow PLUS expressions. This limit allowed distance
4623 of GOT tables. We should not need these anyway. */
4624 if (GET_CODE (disp) != UNSPEC
4625 || XVECLEN (disp, 0) != 1
4626 || XINT (disp, 1) != 15)
4627 return 0;
4628
4629 if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
4630 && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
4631 return 0;
4632 return 1;
4633 }
4634
91bb873f
RH
4635 if (GET_CODE (disp) == PLUS)
4636 {
4637 if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
4638 return 0;
4639 disp = XEXP (disp, 0);
4640 }
4641
4642 if (GET_CODE (disp) != UNSPEC
4643 || XVECLEN (disp, 0) != 1)
4644 return 0;
4645
4646 /* Must be @GOT or @GOTOFF. */
623fe810
RH
4647 switch (XINT (disp, 1))
4648 {
4649 case 6: /* @GOT */
4650 return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
91bb873f 4651
623fe810
RH
4652 case 7: /* @GOTOFF */
4653 return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
4654 }
4655
4656 return 0;
91bb873f
RH
4657}
4658
e075ae69
RH
4659/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a valid
4660 memory address for an instruction. The MODE argument is the machine mode
4661 for the MEM expression that wants to use this address.
4662
4663 It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
4664 convert common non-canonical forms to canonical form so that they will
4665 be recognized. */
4666
3b3c6a3f
MM
4667int
4668legitimate_address_p (mode, addr, strict)
4669 enum machine_mode mode;
4670 register rtx addr;
4671 int strict;
4672{
e075ae69
RH
4673 struct ix86_address parts;
4674 rtx base, index, disp;
4675 HOST_WIDE_INT scale;
4676 const char *reason = NULL;
4677 rtx reason_rtx = NULL_RTX;
3b3c6a3f
MM
4678
4679 if (TARGET_DEBUG_ADDR)
4680 {
4681 fprintf (stderr,
e9a25f70 4682 "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
3b3c6a3f 4683 GET_MODE_NAME (mode), strict);
3b3c6a3f
MM
4684 debug_rtx (addr);
4685 }
4686
e075ae69 4687 if (! ix86_decompose_address (addr, &parts))
3b3c6a3f 4688 {
e075ae69 4689 reason = "decomposition failed";
50e60bc3 4690 goto report_error;
3b3c6a3f
MM
4691 }
4692
e075ae69
RH
4693 base = parts.base;
4694 index = parts.index;
4695 disp = parts.disp;
4696 scale = parts.scale;
91f0226f 4697
e075ae69 4698 /* Validate base register.
e9a25f70
JL
4699
4700 Don't allow SUBREG's here, it can lead to spill failures when the base
3d771dfd
MM
4701 is one word out of a two word structure, which is represented internally
4702 as a DImode int. */
e9a25f70 4703
3b3c6a3f
MM
4704 if (base)
4705 {
e075ae69
RH
4706 reason_rtx = base;
4707
3d771dfd 4708 if (GET_CODE (base) != REG)
3b3c6a3f 4709 {
e075ae69 4710 reason = "base is not a register";
50e60bc3 4711 goto report_error;
3b3c6a3f
MM
4712 }
4713
c954bd01
RH
4714 if (GET_MODE (base) != Pmode)
4715 {
e075ae69 4716 reason = "base is not in Pmode";
50e60bc3 4717 goto report_error;
c954bd01
RH
4718 }
4719
e9a25f70
JL
4720 if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
4721 || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
3b3c6a3f 4722 {
e075ae69 4723 reason = "base is not valid";
50e60bc3 4724 goto report_error;
3b3c6a3f
MM
4725 }
4726 }
4727
e075ae69 4728 /* Validate index register.
e9a25f70
JL
4729
4730 Don't allow SUBREG's here, it can lead to spill failures when the index
3d771dfd
MM
4731 is one word out of a two word structure, which is represented internally
4732 as a DImode int. */
e075ae69
RH
4733
4734 if (index)
3b3c6a3f 4735 {
e075ae69
RH
4736 reason_rtx = index;
4737
4738 if (GET_CODE (index) != REG)
3b3c6a3f 4739 {
e075ae69 4740 reason = "index is not a register";
50e60bc3 4741 goto report_error;
3b3c6a3f
MM
4742 }
4743
e075ae69 4744 if (GET_MODE (index) != Pmode)
c954bd01 4745 {
e075ae69 4746 reason = "index is not in Pmode";
50e60bc3 4747 goto report_error;
c954bd01
RH
4748 }
4749
e075ae69
RH
4750 if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (index))
4751 || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (index)))
3b3c6a3f 4752 {
e075ae69 4753 reason = "index is not valid";
50e60bc3 4754 goto report_error;
3b3c6a3f
MM
4755 }
4756 }
3b3c6a3f 4757
e075ae69
RH
4758 /* Validate scale factor. */
4759 if (scale != 1)
3b3c6a3f 4760 {
e075ae69
RH
4761 reason_rtx = GEN_INT (scale);
4762 if (!index)
3b3c6a3f 4763 {
e075ae69 4764 reason = "scale without index";
50e60bc3 4765 goto report_error;
3b3c6a3f
MM
4766 }
4767
e075ae69 4768 if (scale != 2 && scale != 4 && scale != 8)
3b3c6a3f 4769 {
e075ae69 4770 reason = "scale is not a valid multiplier";
50e60bc3 4771 goto report_error;
3b3c6a3f
MM
4772 }
4773 }
4774
91bb873f 4775 /* Validate displacement. */
3b3c6a3f
MM
4776 if (disp)
4777 {
e075ae69
RH
4778 reason_rtx = disp;
4779
91bb873f 4780 if (!CONSTANT_ADDRESS_P (disp))
3b3c6a3f 4781 {
e075ae69 4782 reason = "displacement is not constant";
50e60bc3 4783 goto report_error;
3b3c6a3f
MM
4784 }
4785
0d7d98ee 4786 if (TARGET_64BIT)
3b3c6a3f 4787 {
0d7d98ee
JH
4788 if (!x86_64_sign_extended_value (disp))
4789 {
4790 reason = "displacement is out of range";
4791 goto report_error;
4792 }
4793 }
4794 else
4795 {
4796 if (GET_CODE (disp) == CONST_DOUBLE)
4797 {
4798 reason = "displacement is a const_double";
4799 goto report_error;
4800 }
3b3c6a3f
MM
4801 }
4802
91bb873f 4803 if (flag_pic && SYMBOLIC_CONST (disp))
3b3c6a3f 4804 {
0d7d98ee
JH
4805 if (TARGET_64BIT && (index || base))
4806 {
4807 reason = "non-constant pic memory reference";
4808 goto report_error;
4809 }
91bb873f
RH
4810 if (! legitimate_pic_address_disp_p (disp))
4811 {
e075ae69 4812 reason = "displacement is an invalid pic construct";
50e60bc3 4813 goto report_error;
91bb873f
RH
4814 }
4815
4e9efe54 4816 /* This code used to verify that a symbolic pic displacement
0f290768
KH
4817 includes the pic_offset_table_rtx register.
4818
4e9efe54
JH
4819 While this is good idea, unfortunately these constructs may
4820 be created by "adds using lea" optimization for incorrect
4821 code like:
4822
4823 int a;
4824 int foo(int i)
4825 {
4826 return *(&a+i);
4827 }
4828
50e60bc3 4829 This code is nonsensical, but results in addressing
4e9efe54 4830 GOT table with pic_offset_table_rtx base. We can't
f710504c 4831 just refuse it easily, since it gets matched by
4e9efe54
JH
4832 "addsi3" pattern, that later gets split to lea in the
4833 case output register differs from input. While this
4834 can be handled by separate addsi pattern for this case
4835 that never results in lea, this seems to be easier and
4836 correct fix for crash to disable this test. */
3b3c6a3f 4837 }
91bb873f 4838 else if (HALF_PIC_P ())
3b3c6a3f 4839 {
91bb873f 4840 if (! HALF_PIC_ADDRESS_P (disp)
e075ae69 4841 || (base != NULL_RTX || index != NULL_RTX))
91bb873f 4842 {
e075ae69 4843 reason = "displacement is an invalid half-pic reference";
50e60bc3 4844 goto report_error;
91bb873f 4845 }
3b3c6a3f
MM
4846 }
4847 }
4848
e075ae69 4849 /* Everything looks valid. */
3b3c6a3f 4850 if (TARGET_DEBUG_ADDR)
e075ae69 4851 fprintf (stderr, "Success.\n");
3b3c6a3f 4852 return TRUE;
e075ae69 4853
50e60bc3 4854report_error:
e075ae69
RH
4855 if (TARGET_DEBUG_ADDR)
4856 {
4857 fprintf (stderr, "Error: %s\n", reason);
4858 debug_rtx (reason_rtx);
4859 }
4860 return FALSE;
3b3c6a3f 4861}
3b3c6a3f 4862\f
55efb413
JW
4863/* Return an unique alias set for the GOT. */
4864
0f290768 4865static HOST_WIDE_INT
55efb413
JW
4866ix86_GOT_alias_set ()
4867{
4868 static HOST_WIDE_INT set = -1;
4869 if (set == -1)
4870 set = new_alias_set ();
4871 return set;
0f290768 4872}
55efb413 4873
3b3c6a3f
MM
4874/* Return a legitimate reference for ORIG (an address) using the
4875 register REG. If REG is 0, a new pseudo is generated.
4876
91bb873f 4877 There are two types of references that must be handled:
3b3c6a3f
MM
4878
4879 1. Global data references must load the address from the GOT, via
4880 the PIC reg. An insn is emitted to do this load, and the reg is
4881 returned.
4882
91bb873f
RH
4883 2. Static data references, constant pool addresses, and code labels
4884 compute the address as an offset from the GOT, whose base is in
4885 the PIC reg. Static data objects have SYMBOL_REF_FLAG set to
4886 differentiate them from global data objects. The returned
4887 address is the PIC reg + an unspec constant.
3b3c6a3f
MM
4888
4889 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
91bb873f 4890 reg also appears in the address. */
3b3c6a3f
MM
4891
4892rtx
4893legitimize_pic_address (orig, reg)
4894 rtx orig;
4895 rtx reg;
4896{
4897 rtx addr = orig;
4898 rtx new = orig;
91bb873f 4899 rtx base;
3b3c6a3f 4900
623fe810 4901 if (local_symbolic_operand (addr, Pmode))
3b3c6a3f 4902 {
14f73b5a
JH
4903 /* In 64bit mode we can address such objects directly. */
4904 if (TARGET_64BIT)
4905 new = addr;
4906 else
4907 {
4908 /* This symbol may be referenced via a displacement from the PIC
4909 base address (@GOTOFF). */
3b3c6a3f 4910
14f73b5a
JH
4911 current_function_uses_pic_offset_table = 1;
4912 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 7);
4913 new = gen_rtx_CONST (Pmode, new);
4914 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
3b3c6a3f 4915
14f73b5a
JH
4916 if (reg != 0)
4917 {
4918 emit_move_insn (reg, new);
4919 new = reg;
4920 }
4921 }
3b3c6a3f 4922 }
91bb873f 4923 else if (GET_CODE (addr) == SYMBOL_REF)
3b3c6a3f 4924 {
14f73b5a
JH
4925 if (TARGET_64BIT)
4926 {
4927 current_function_uses_pic_offset_table = 1;
4928 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 15);
4929 new = gen_rtx_CONST (Pmode, new);
4930 new = gen_rtx_MEM (Pmode, new);
4931 RTX_UNCHANGING_P (new) = 1;
4932 set_mem_alias_set (new, ix86_GOT_alias_set ());
4933
4934 if (reg == 0)
4935 reg = gen_reg_rtx (Pmode);
4936 /* Use directly gen_movsi, otherwise the address is loaded
4937 into register for CSE. We don't want to CSE this addresses,
4938 instead we CSE addresses from the GOT table, so skip this. */
4939 emit_insn (gen_movsi (reg, new));
4940 new = reg;
4941 }
4942 else
4943 {
4944 /* This symbol must be referenced via a load from the
4945 Global Offset Table (@GOT). */
3b3c6a3f 4946
14f73b5a
JH
4947 current_function_uses_pic_offset_table = 1;
4948 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 6);
4949 new = gen_rtx_CONST (Pmode, new);
4950 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
4951 new = gen_rtx_MEM (Pmode, new);
4952 RTX_UNCHANGING_P (new) = 1;
4953 set_mem_alias_set (new, ix86_GOT_alias_set ());
3b3c6a3f 4954
14f73b5a
JH
4955 if (reg == 0)
4956 reg = gen_reg_rtx (Pmode);
4957 emit_move_insn (reg, new);
4958 new = reg;
4959 }
0f290768 4960 }
91bb873f
RH
4961 else
4962 {
4963 if (GET_CODE (addr) == CONST)
3b3c6a3f 4964 {
91bb873f
RH
4965 addr = XEXP (addr, 0);
4966 if (GET_CODE (addr) == UNSPEC)
4967 {
4968 /* Check that the unspec is one of the ones we generate? */
4969 }
4970 else if (GET_CODE (addr) != PLUS)
564d80f4 4971 abort ();
3b3c6a3f 4972 }
91bb873f
RH
4973 if (GET_CODE (addr) == PLUS)
4974 {
4975 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
e9a25f70 4976
91bb873f
RH
4977 /* Check first to see if this is a constant offset from a @GOTOFF
4978 symbol reference. */
623fe810 4979 if (local_symbolic_operand (op0, Pmode)
91bb873f
RH
4980 && GET_CODE (op1) == CONST_INT)
4981 {
6eb791fc
JH
4982 if (!TARGET_64BIT)
4983 {
4984 current_function_uses_pic_offset_table = 1;
4985 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 7);
4986 new = gen_rtx_PLUS (Pmode, new, op1);
4987 new = gen_rtx_CONST (Pmode, new);
4988 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
91bb873f 4989
6eb791fc
JH
4990 if (reg != 0)
4991 {
4992 emit_move_insn (reg, new);
4993 new = reg;
4994 }
4995 }
4996 else
91bb873f 4997 {
6eb791fc 4998 /* ??? We need to limit offsets here. */
91bb873f
RH
4999 }
5000 }
5001 else
5002 {
5003 base = legitimize_pic_address (XEXP (addr, 0), reg);
5004 new = legitimize_pic_address (XEXP (addr, 1),
5005 base == reg ? NULL_RTX : reg);
5006
5007 if (GET_CODE (new) == CONST_INT)
5008 new = plus_constant (base, INTVAL (new));
5009 else
5010 {
5011 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
5012 {
5013 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
5014 new = XEXP (new, 1);
5015 }
5016 new = gen_rtx_PLUS (Pmode, base, new);
5017 }
5018 }
5019 }
3b3c6a3f
MM
5020 }
5021 return new;
5022}
5023\f
3b3c6a3f
MM
5024/* Try machine-dependent ways of modifying an illegitimate address
5025 to be legitimate. If we find one, return the new, valid address.
5026 This macro is used in only one place: `memory_address' in explow.c.
5027
5028 OLDX is the address as it was before break_out_memory_refs was called.
5029 In some cases it is useful to look at this to decide what needs to be done.
5030
5031 MODE and WIN are passed so that this macro can use
5032 GO_IF_LEGITIMATE_ADDRESS.
5033
5034 It is always safe for this macro to do nothing. It exists to recognize
5035 opportunities to optimize the output.
5036
5037 For the 80386, we handle X+REG by loading X into a register R and
5038 using R+REG. R will go in a general reg and indexing will be used.
5039 However, if REG is a broken-out memory address or multiplication,
5040 nothing needs to be done because REG can certainly go in a general reg.
5041
5042 When -fpic is used, special handling is needed for symbolic references.
5043 See comments by legitimize_pic_address in i386.c for details. */
5044
5045rtx
5046legitimize_address (x, oldx, mode)
5047 register rtx x;
bb5177ac 5048 register rtx oldx ATTRIBUTE_UNUSED;
3b3c6a3f
MM
5049 enum machine_mode mode;
5050{
5051 int changed = 0;
5052 unsigned log;
5053
5054 if (TARGET_DEBUG_ADDR)
5055 {
e9a25f70
JL
5056 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n",
5057 GET_MODE_NAME (mode));
3b3c6a3f
MM
5058 debug_rtx (x);
5059 }
5060
5061 if (flag_pic && SYMBOLIC_CONST (x))
5062 return legitimize_pic_address (x, 0);
5063
5064 /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
5065 if (GET_CODE (x) == ASHIFT
5066 && GET_CODE (XEXP (x, 1)) == CONST_INT
5067 && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
5068 {
5069 changed = 1;
a269a03c
JC
5070 x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
5071 GEN_INT (1 << log));
3b3c6a3f
MM
5072 }
5073
5074 if (GET_CODE (x) == PLUS)
5075 {
0f290768 5076 /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
e9a25f70 5077
3b3c6a3f
MM
5078 if (GET_CODE (XEXP (x, 0)) == ASHIFT
5079 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5080 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
5081 {
5082 changed = 1;
c5c76735
JL
5083 XEXP (x, 0) = gen_rtx_MULT (Pmode,
5084 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
5085 GEN_INT (1 << log));
3b3c6a3f
MM
5086 }
5087
5088 if (GET_CODE (XEXP (x, 1)) == ASHIFT
5089 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
5090 && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
5091 {
5092 changed = 1;
c5c76735
JL
5093 XEXP (x, 1) = gen_rtx_MULT (Pmode,
5094 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
5095 GEN_INT (1 << log));
3b3c6a3f
MM
5096 }
5097
0f290768 5098 /* Put multiply first if it isn't already. */
3b3c6a3f
MM
5099 if (GET_CODE (XEXP (x, 1)) == MULT)
5100 {
5101 rtx tmp = XEXP (x, 0);
5102 XEXP (x, 0) = XEXP (x, 1);
5103 XEXP (x, 1) = tmp;
5104 changed = 1;
5105 }
5106
5107 /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
5108 into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
5109 created by virtual register instantiation, register elimination, and
5110 similar optimizations. */
5111 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
5112 {
5113 changed = 1;
c5c76735
JL
5114 x = gen_rtx_PLUS (Pmode,
5115 gen_rtx_PLUS (Pmode, XEXP (x, 0),
5116 XEXP (XEXP (x, 1), 0)),
5117 XEXP (XEXP (x, 1), 1));
3b3c6a3f
MM
5118 }
5119
e9a25f70
JL
5120 /* Canonicalize
5121 (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
3b3c6a3f
MM
5122 into (plus (plus (mult (reg) (const)) (reg)) (const)). */
5123 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
5124 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
5125 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
5126 && CONSTANT_P (XEXP (x, 1)))
5127 {
00c79232
ML
5128 rtx constant;
5129 rtx other = NULL_RTX;
3b3c6a3f
MM
5130
5131 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
5132 {
5133 constant = XEXP (x, 1);
5134 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
5135 }
5136 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
5137 {
5138 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
5139 other = XEXP (x, 1);
5140 }
5141 else
5142 constant = 0;
5143
5144 if (constant)
5145 {
5146 changed = 1;
c5c76735
JL
5147 x = gen_rtx_PLUS (Pmode,
5148 gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
5149 XEXP (XEXP (XEXP (x, 0), 1), 0)),
5150 plus_constant (other, INTVAL (constant)));
3b3c6a3f
MM
5151 }
5152 }
5153
5154 if (changed && legitimate_address_p (mode, x, FALSE))
5155 return x;
5156
5157 if (GET_CODE (XEXP (x, 0)) == MULT)
5158 {
5159 changed = 1;
5160 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
5161 }
5162
5163 if (GET_CODE (XEXP (x, 1)) == MULT)
5164 {
5165 changed = 1;
5166 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
5167 }
5168
5169 if (changed
5170 && GET_CODE (XEXP (x, 1)) == REG
5171 && GET_CODE (XEXP (x, 0)) == REG)
5172 return x;
5173
5174 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
5175 {
5176 changed = 1;
5177 x = legitimize_pic_address (x, 0);
5178 }
5179
5180 if (changed && legitimate_address_p (mode, x, FALSE))
5181 return x;
5182
5183 if (GET_CODE (XEXP (x, 0)) == REG)
5184 {
5185 register rtx temp = gen_reg_rtx (Pmode);
5186 register rtx val = force_operand (XEXP (x, 1), temp);
5187 if (val != temp)
5188 emit_move_insn (temp, val);
5189
5190 XEXP (x, 1) = temp;
5191 return x;
5192 }
5193
5194 else if (GET_CODE (XEXP (x, 1)) == REG)
5195 {
5196 register rtx temp = gen_reg_rtx (Pmode);
5197 register rtx val = force_operand (XEXP (x, 0), temp);
5198 if (val != temp)
5199 emit_move_insn (temp, val);
5200
5201 XEXP (x, 0) = temp;
5202 return x;
5203 }
5204 }
5205
5206 return x;
5207}
2a2ab3f9
JVA
5208\f
5209/* Print an integer constant expression in assembler syntax. Addition
5210 and subtraction are the only arithmetic that may appear in these
5211 expressions. FILE is the stdio stream to write to, X is the rtx, and
5212 CODE is the operand print code from the output string. */
5213
5214static void
5215output_pic_addr_const (file, x, code)
5216 FILE *file;
5217 rtx x;
5218 int code;
5219{
5220 char buf[256];
5221
5222 switch (GET_CODE (x))
5223 {
5224 case PC:
5225 if (flag_pic)
5226 putc ('.', file);
5227 else
5228 abort ();
5229 break;
5230
5231 case SYMBOL_REF:
91bb873f
RH
5232 assemble_name (file, XSTR (x, 0));
5233 if (code == 'P' && ! SYMBOL_REF_FLAG (x))
5234 fputs ("@PLT", file);
2a2ab3f9
JVA
5235 break;
5236
91bb873f
RH
5237 case LABEL_REF:
5238 x = XEXP (x, 0);
5239 /* FALLTHRU */
2a2ab3f9
JVA
5240 case CODE_LABEL:
5241 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
5242 assemble_name (asm_out_file, buf);
5243 break;
5244
5245 case CONST_INT:
f64cecad 5246 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2a2ab3f9
JVA
5247 break;
5248
5249 case CONST:
5250 /* This used to output parentheses around the expression,
5251 but that does not work on the 386 (either ATT or BSD assembler). */
5252 output_pic_addr_const (file, XEXP (x, 0), code);
5253 break;
5254
5255 case CONST_DOUBLE:
5256 if (GET_MODE (x) == VOIDmode)
5257 {
5258 /* We can use %d if the number is <32 bits and positive. */
5259 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
f64cecad
JC
5260 fprintf (file, "0x%lx%08lx",
5261 (unsigned long) CONST_DOUBLE_HIGH (x),
5262 (unsigned long) CONST_DOUBLE_LOW (x));
2a2ab3f9 5263 else
f64cecad 5264 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
2a2ab3f9
JVA
5265 }
5266 else
5267 /* We can't handle floating point constants;
5268 PRINT_OPERAND must handle them. */
5269 output_operand_lossage ("floating constant misused");
5270 break;
5271
5272 case PLUS:
e9a25f70 5273 /* Some assemblers need integer constants to appear first. */
2a2ab3f9
JVA
5274 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
5275 {
2a2ab3f9 5276 output_pic_addr_const (file, XEXP (x, 0), code);
e075ae69 5277 putc ('+', file);
e9a25f70 5278 output_pic_addr_const (file, XEXP (x, 1), code);
2a2ab3f9 5279 }
91bb873f 5280 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2a2ab3f9 5281 {
2a2ab3f9 5282 output_pic_addr_const (file, XEXP (x, 1), code);
e075ae69 5283 putc ('+', file);
e9a25f70 5284 output_pic_addr_const (file, XEXP (x, 0), code);
2a2ab3f9 5285 }
91bb873f
RH
5286 else
5287 abort ();
2a2ab3f9
JVA
5288 break;
5289
5290 case MINUS:
e075ae69 5291 putc (ASSEMBLER_DIALECT ? '(' : '[', file);
2a2ab3f9 5292 output_pic_addr_const (file, XEXP (x, 0), code);
e075ae69 5293 putc ('-', file);
2a2ab3f9 5294 output_pic_addr_const (file, XEXP (x, 1), code);
e075ae69 5295 putc (ASSEMBLER_DIALECT ? ')' : ']', file);
2a2ab3f9
JVA
5296 break;
5297
91bb873f
RH
5298 case UNSPEC:
5299 if (XVECLEN (x, 0) != 1)
77ebd435 5300 abort ();
91bb873f
RH
5301 output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
5302 switch (XINT (x, 1))
77ebd435
AJ
5303 {
5304 case 6:
5305 fputs ("@GOT", file);
5306 break;
5307 case 7:
5308 fputs ("@GOTOFF", file);
5309 break;
5310 case 8:
5311 fputs ("@PLT", file);
5312 break;
6eb791fc
JH
5313 case 15:
5314 fputs ("@GOTPCREL(%RIP)", file);
5315 break;
77ebd435
AJ
5316 default:
5317 output_operand_lossage ("invalid UNSPEC as operand");
5318 break;
5319 }
91bb873f
RH
5320 break;
5321
2a2ab3f9
JVA
5322 default:
5323 output_operand_lossage ("invalid expression as operand");
5324 }
5325}
1865dbb5 5326
0f290768 5327/* This is called from dwarfout.c via ASM_OUTPUT_DWARF_ADDR_CONST.
1865dbb5
JM
5328 We need to handle our special PIC relocations. */
5329
0f290768 5330void
1865dbb5
JM
5331i386_dwarf_output_addr_const (file, x)
5332 FILE *file;
5333 rtx x;
5334{
14f73b5a 5335#ifdef ASM_QUAD
18b5b8d6 5336 fprintf (file, "%s", TARGET_64BIT ? ASM_QUAD : ASM_LONG);
14f73b5a
JH
5337#else
5338 if (TARGET_64BIT)
5339 abort ();
18b5b8d6 5340 fprintf (file, "%s", ASM_LONG);
14f73b5a 5341#endif
1865dbb5
JM
5342 if (flag_pic)
5343 output_pic_addr_const (file, x, '\0');
5344 else
5345 output_addr_const (file, x);
5346 fputc ('\n', file);
5347}
5348
5349/* In the name of slightly smaller debug output, and to cater to
5350 general assembler losage, recognize PIC+GOTOFF and turn it back
5351 into a direct symbol reference. */
5352
5353rtx
5354i386_simplify_dwarf_addr (orig_x)
5355 rtx orig_x;
5356{
5357 rtx x = orig_x;
5358
6eb791fc
JH
5359 if (TARGET_64BIT)
5360 {
5361 if (GET_CODE (x) != CONST
5362 || GET_CODE (XEXP (x, 0)) != UNSPEC
5363 || XINT (XEXP (x, 0), 1) != 15)
5364 return orig_x;
5365 return XVECEXP (XEXP (x, 0), 0, 0);
5366 }
5367
1865dbb5
JM
5368 if (GET_CODE (x) != PLUS
5369 || GET_CODE (XEXP (x, 0)) != REG
5370 || GET_CODE (XEXP (x, 1)) != CONST)
5371 return orig_x;
5372
5373 x = XEXP (XEXP (x, 1), 0);
5374 if (GET_CODE (x) == UNSPEC
3adbce3d
RH
5375 && (XINT (x, 1) == 6
5376 || XINT (x, 1) == 7))
1865dbb5
JM
5377 return XVECEXP (x, 0, 0);
5378
5379 if (GET_CODE (x) == PLUS
5380 && GET_CODE (XEXP (x, 0)) == UNSPEC
5381 && GET_CODE (XEXP (x, 1)) == CONST_INT
3adbce3d
RH
5382 && (XINT (XEXP (x, 0), 1) == 6
5383 || XINT (XEXP (x, 0), 1) == 7))
1865dbb5
JM
5384 return gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
5385
5386 return orig_x;
5387}
2a2ab3f9 5388\f
a269a03c 5389static void
e075ae69 5390put_condition_code (code, mode, reverse, fp, file)
a269a03c 5391 enum rtx_code code;
e075ae69
RH
5392 enum machine_mode mode;
5393 int reverse, fp;
a269a03c
JC
5394 FILE *file;
5395{
a269a03c
JC
5396 const char *suffix;
5397
9a915772
JH
5398 if (mode == CCFPmode || mode == CCFPUmode)
5399 {
5400 enum rtx_code second_code, bypass_code;
5401 ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
5402 if (bypass_code != NIL || second_code != NIL)
5403 abort();
5404 code = ix86_fp_compare_code_to_integer (code);
5405 mode = CCmode;
5406 }
a269a03c
JC
5407 if (reverse)
5408 code = reverse_condition (code);
e075ae69 5409
a269a03c
JC
5410 switch (code)
5411 {
5412 case EQ:
5413 suffix = "e";
5414 break;
a269a03c
JC
5415 case NE:
5416 suffix = "ne";
5417 break;
a269a03c 5418 case GT:
7e08e190 5419 if (mode != CCmode && mode != CCNOmode && mode != CCGCmode)
e075ae69
RH
5420 abort ();
5421 suffix = "g";
a269a03c 5422 break;
a269a03c 5423 case GTU:
e075ae69
RH
5424 /* ??? Use "nbe" instead of "a" for fcmov losage on some assemblers.
5425 Those same assemblers have the same but opposite losage on cmov. */
7e08e190 5426 if (mode != CCmode)
0f290768 5427 abort ();
e075ae69 5428 suffix = fp ? "nbe" : "a";
a269a03c 5429 break;
a269a03c 5430 case LT:
9076b9c1 5431 if (mode == CCNOmode || mode == CCGOCmode)
a269a03c 5432 suffix = "s";
7e08e190 5433 else if (mode == CCmode || mode == CCGCmode)
e075ae69 5434 suffix = "l";
9076b9c1 5435 else
0f290768 5436 abort ();
a269a03c 5437 break;
a269a03c 5438 case LTU:
9076b9c1 5439 if (mode != CCmode)
0f290768 5440 abort ();
a269a03c
JC
5441 suffix = "b";
5442 break;
a269a03c 5443 case GE:
9076b9c1 5444 if (mode == CCNOmode || mode == CCGOCmode)
a269a03c 5445 suffix = "ns";
7e08e190 5446 else if (mode == CCmode || mode == CCGCmode)
e075ae69 5447 suffix = "ge";
9076b9c1 5448 else
0f290768 5449 abort ();
a269a03c 5450 break;
a269a03c 5451 case GEU:
e075ae69 5452 /* ??? As above. */
7e08e190 5453 if (mode != CCmode)
0f290768 5454 abort ();
7e08e190 5455 suffix = fp ? "nb" : "ae";
a269a03c 5456 break;
a269a03c 5457 case LE:
7e08e190 5458 if (mode != CCmode && mode != CCGCmode && mode != CCNOmode)
e075ae69
RH
5459 abort ();
5460 suffix = "le";
a269a03c 5461 break;
a269a03c 5462 case LEU:
9076b9c1
JH
5463 if (mode != CCmode)
5464 abort ();
7e08e190 5465 suffix = "be";
a269a03c 5466 break;
3a3677ff 5467 case UNORDERED:
9e7adcb3 5468 suffix = fp ? "u" : "p";
3a3677ff
RH
5469 break;
5470 case ORDERED:
9e7adcb3 5471 suffix = fp ? "nu" : "np";
3a3677ff 5472 break;
a269a03c
JC
5473 default:
5474 abort ();
5475 }
5476 fputs (suffix, file);
5477}
5478
e075ae69
RH
5479void
5480print_reg (x, code, file)
5481 rtx x;
5482 int code;
5483 FILE *file;
e5cb57e8 5484{
e075ae69 5485 if (REGNO (x) == ARG_POINTER_REGNUM
564d80f4 5486 || REGNO (x) == FRAME_POINTER_REGNUM
e075ae69
RH
5487 || REGNO (x) == FLAGS_REG
5488 || REGNO (x) == FPSR_REG)
5489 abort ();
e9a25f70 5490
e075ae69
RH
5491 if (ASSEMBLER_DIALECT == 0 || USER_LABEL_PREFIX[0] == 0)
5492 putc ('%', file);
5493
ef6257cd 5494 if (code == 'w' || MMX_REG_P (x))
e075ae69
RH
5495 code = 2;
5496 else if (code == 'b')
5497 code = 1;
5498 else if (code == 'k')
5499 code = 4;
3f3f2124
JH
5500 else if (code == 'q')
5501 code = 8;
e075ae69
RH
5502 else if (code == 'y')
5503 code = 3;
5504 else if (code == 'h')
5505 code = 0;
5506 else
5507 code = GET_MODE_SIZE (GET_MODE (x));
e9a25f70 5508
3f3f2124
JH
5509 /* Irritatingly, AMD extended registers use different naming convention
5510 from the normal registers. */
5511 if (REX_INT_REG_P (x))
5512 {
885a70fd
JH
5513 if (!TARGET_64BIT)
5514 abort ();
3f3f2124
JH
5515 switch (code)
5516 {
ef6257cd 5517 case 0:
c725bd79 5518 error ("extended registers have no high halves");
3f3f2124
JH
5519 break;
5520 case 1:
5521 fprintf (file, "r%ib", REGNO (x) - FIRST_REX_INT_REG + 8);
5522 break;
5523 case 2:
5524 fprintf (file, "r%iw", REGNO (x) - FIRST_REX_INT_REG + 8);
5525 break;
5526 case 4:
5527 fprintf (file, "r%id", REGNO (x) - FIRST_REX_INT_REG + 8);
5528 break;
5529 case 8:
5530 fprintf (file, "r%i", REGNO (x) - FIRST_REX_INT_REG + 8);
5531 break;
5532 default:
c725bd79 5533 error ("unsupported operand size for extended register");
3f3f2124
JH
5534 break;
5535 }
5536 return;
5537 }
e075ae69
RH
5538 switch (code)
5539 {
5540 case 3:
5541 if (STACK_TOP_P (x))
5542 {
5543 fputs ("st(0)", file);
5544 break;
5545 }
5546 /* FALLTHRU */
e075ae69 5547 case 8:
3f3f2124 5548 case 4:
e075ae69 5549 case 12:
446988df 5550 if (! ANY_FP_REG_P (x))
885a70fd 5551 putc (code == 8 && TARGET_64BIT ? 'r' : 'e', file);
e075ae69 5552 /* FALLTHRU */
a7180f70 5553 case 16:
e075ae69
RH
5554 case 2:
5555 fputs (hi_reg_name[REGNO (x)], file);
5556 break;
5557 case 1:
5558 fputs (qi_reg_name[REGNO (x)], file);
5559 break;
5560 case 0:
5561 fputs (qi_high_reg_name[REGNO (x)], file);
5562 break;
5563 default:
5564 abort ();
fe25fea3 5565 }
e5cb57e8
SC
5566}
5567
2a2ab3f9 5568/* Meaning of CODE:
fe25fea3 5569 L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
e5cb57e8 5570 C -- print opcode suffix for set/cmov insn.
fe25fea3 5571 c -- like C, but print reversed condition
ef6257cd 5572 F,f -- likewise, but for floating-point.
2a2ab3f9
JVA
5573 R -- print the prefix for register names.
5574 z -- print the opcode suffix for the size of the current operand.
5575 * -- print a star (in certain assembler syntax)
fb204271 5576 A -- print an absolute memory reference.
2a2ab3f9 5577 w -- print the operand as if it's a "word" (HImode) even if it isn't.
2d49677f
SC
5578 s -- print a shift double count, followed by the assemblers argument
5579 delimiter.
fe25fea3
SC
5580 b -- print the QImode name of the register for the indicated operand.
5581 %b0 would print %al if operands[0] is reg 0.
5582 w -- likewise, print the HImode name of the register.
5583 k -- likewise, print the SImode name of the register.
3f3f2124 5584 q -- likewise, print the DImode name of the register.
ef6257cd
JH
5585 h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
5586 y -- print "st(0)" instead of "st" as a register.
a46d1d38 5587 D -- print condition for SSE cmp instruction.
ef6257cd
JH
5588 P -- if PIC, print an @PLT suffix.
5589 X -- don't print any sort of PIC '@' suffix for a symbol.
a46d1d38 5590 */
2a2ab3f9
JVA
5591
5592void
5593print_operand (file, x, code)
5594 FILE *file;
5595 rtx x;
5596 int code;
5597{
5598 if (code)
5599 {
5600 switch (code)
5601 {
5602 case '*':
e075ae69 5603 if (ASSEMBLER_DIALECT == 0)
2a2ab3f9
JVA
5604 putc ('*', file);
5605 return;
5606
fb204271
DN
5607 case 'A':
5608 if (ASSEMBLER_DIALECT == 0)
5609 putc ('*', file);
5610 else if (ASSEMBLER_DIALECT == 1)
5611 {
5612 /* Intel syntax. For absolute addresses, registers should not
5613 be surrounded by braces. */
5614 if (GET_CODE (x) != REG)
5615 {
5616 putc ('[', file);
5617 PRINT_OPERAND (file, x, 0);
5618 putc (']', file);
5619 return;
5620 }
5621 }
5622
5623 PRINT_OPERAND (file, x, 0);
5624 return;
5625
5626
2a2ab3f9 5627 case 'L':
e075ae69
RH
5628 if (ASSEMBLER_DIALECT == 0)
5629 putc ('l', file);
2a2ab3f9
JVA
5630 return;
5631
5632 case 'W':
e075ae69
RH
5633 if (ASSEMBLER_DIALECT == 0)
5634 putc ('w', file);
2a2ab3f9
JVA
5635 return;
5636
5637 case 'B':
e075ae69
RH
5638 if (ASSEMBLER_DIALECT == 0)
5639 putc ('b', file);
2a2ab3f9
JVA
5640 return;
5641
5642 case 'Q':
e075ae69
RH
5643 if (ASSEMBLER_DIALECT == 0)
5644 putc ('l', file);
2a2ab3f9
JVA
5645 return;
5646
5647 case 'S':
e075ae69
RH
5648 if (ASSEMBLER_DIALECT == 0)
5649 putc ('s', file);
2a2ab3f9
JVA
5650 return;
5651
5f1ec3e6 5652 case 'T':
e075ae69
RH
5653 if (ASSEMBLER_DIALECT == 0)
5654 putc ('t', file);
5f1ec3e6
JVA
5655 return;
5656
2a2ab3f9
JVA
5657 case 'z':
5658 /* 387 opcodes don't get size suffixes if the operands are
0f290768 5659 registers. */
2a2ab3f9
JVA
5660
5661 if (STACK_REG_P (x))
5662 return;
5663
5664 /* this is the size of op from size of operand */
5665 switch (GET_MODE_SIZE (GET_MODE (x)))
5666 {
2a2ab3f9 5667 case 2:
155d8a47
JW
5668#ifdef HAVE_GAS_FILDS_FISTS
5669 putc ('s', file);
5670#endif
2a2ab3f9
JVA
5671 return;
5672
5673 case 4:
5674 if (GET_MODE (x) == SFmode)
5675 {
e075ae69 5676 putc ('s', file);
2a2ab3f9
JVA
5677 return;
5678 }
5679 else
e075ae69 5680 putc ('l', file);
2a2ab3f9
JVA
5681 return;
5682
5f1ec3e6 5683 case 12:
2b589241 5684 case 16:
e075ae69
RH
5685 putc ('t', file);
5686 return;
5f1ec3e6 5687
2a2ab3f9
JVA
5688 case 8:
5689 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
56c0e8fa
JVA
5690 {
5691#ifdef GAS_MNEMONICS
e075ae69 5692 putc ('q', file);
56c0e8fa 5693#else
e075ae69
RH
5694 putc ('l', file);
5695 putc ('l', file);
56c0e8fa
JVA
5696#endif
5697 }
e075ae69
RH
5698 else
5699 putc ('l', file);
2a2ab3f9 5700 return;
155d8a47
JW
5701
5702 default:
5703 abort ();
2a2ab3f9 5704 }
4af3895e
JVA
5705
5706 case 'b':
5707 case 'w':
5708 case 'k':
3f3f2124 5709 case 'q':
4af3895e
JVA
5710 case 'h':
5711 case 'y':
5cb6195d 5712 case 'X':
e075ae69 5713 case 'P':
4af3895e
JVA
5714 break;
5715
2d49677f
SC
5716 case 's':
5717 if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
5718 {
5719 PRINT_OPERAND (file, x, 0);
e075ae69 5720 putc (',', file);
2d49677f 5721 }
a269a03c
JC
5722 return;
5723
a46d1d38
JH
5724 case 'D':
5725 /* Little bit of braindamage here. The SSE compare instructions
5726 does use completely different names for the comparisons that the
5727 fp conditional moves. */
5728 switch (GET_CODE (x))
5729 {
5730 case EQ:
5731 case UNEQ:
5732 fputs ("eq", file);
5733 break;
5734 case LT:
5735 case UNLT:
5736 fputs ("lt", file);
5737 break;
5738 case LE:
5739 case UNLE:
5740 fputs ("le", file);
5741 break;
5742 case UNORDERED:
5743 fputs ("unord", file);
5744 break;
5745 case NE:
5746 case LTGT:
5747 fputs ("neq", file);
5748 break;
5749 case UNGE:
5750 case GE:
5751 fputs ("nlt", file);
5752 break;
5753 case UNGT:
5754 case GT:
5755 fputs ("nle", file);
5756 break;
5757 case ORDERED:
5758 fputs ("ord", file);
5759 break;
5760 default:
5761 abort ();
5762 break;
5763 }
5764 return;
1853aadd 5765 case 'C':
e075ae69 5766 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file);
1853aadd 5767 return;
fe25fea3 5768 case 'F':
e075ae69 5769 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 1, file);
fe25fea3
SC
5770 return;
5771
e9a25f70 5772 /* Like above, but reverse condition */
e075ae69 5773 case 'c':
c1d5afc4
CR
5774 /* Check to see if argument to %c is really a constant
5775 and not a condition code which needs to be reversed. */
5776 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
5777 {
5778 output_operand_lossage ("operand is neither a constant nor a condition code, invalid operand code 'c'");
5779 return;
5780 }
e075ae69
RH
5781 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 0, file);
5782 return;
fe25fea3 5783 case 'f':
e075ae69 5784 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 1, file);
1853aadd 5785 return;
ef6257cd
JH
5786 case '+':
5787 {
5788 rtx x;
e5cb57e8 5789
ef6257cd
JH
5790 if (!optimize || optimize_size || !TARGET_BRANCH_PREDICTION_HINTS)
5791 return;
a4f31c00 5792
ef6257cd
JH
5793 x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
5794 if (x)
5795 {
5796 int pred_val = INTVAL (XEXP (x, 0));
5797
5798 if (pred_val < REG_BR_PROB_BASE * 45 / 100
5799 || pred_val > REG_BR_PROB_BASE * 55 / 100)
5800 {
5801 int taken = pred_val > REG_BR_PROB_BASE / 2;
5802 int cputaken = final_forward_branch_p (current_output_insn) == 0;
5803
5804 /* Emit hints only in the case default branch prediction
5805 heruistics would fail. */
5806 if (taken != cputaken)
5807 {
5808 /* We use 3e (DS) prefix for taken branches and
5809 2e (CS) prefix for not taken branches. */
5810 if (taken)
5811 fputs ("ds ; ", file);
5812 else
5813 fputs ("cs ; ", file);
5814 }
5815 }
5816 }
5817 return;
5818 }
4af3895e 5819 default:
68daafd4
JVA
5820 {
5821 char str[50];
68daafd4
JVA
5822 sprintf (str, "invalid operand code `%c'", code);
5823 output_operand_lossage (str);
5824 }
2a2ab3f9
JVA
5825 }
5826 }
e9a25f70 5827
2a2ab3f9
JVA
5828 if (GET_CODE (x) == REG)
5829 {
5830 PRINT_REG (x, code, file);
5831 }
e9a25f70 5832
2a2ab3f9
JVA
5833 else if (GET_CODE (x) == MEM)
5834 {
e075ae69
RH
5835 /* No `byte ptr' prefix for call instructions. */
5836 if (ASSEMBLER_DIALECT != 0 && code != 'X' && code != 'P')
2a2ab3f9 5837 {
69ddee61 5838 const char * size;
e075ae69
RH
5839 switch (GET_MODE_SIZE (GET_MODE (x)))
5840 {
5841 case 1: size = "BYTE"; break;
5842 case 2: size = "WORD"; break;
5843 case 4: size = "DWORD"; break;
5844 case 8: size = "QWORD"; break;
5845 case 12: size = "XWORD"; break;
a7180f70 5846 case 16: size = "XMMWORD"; break;
e075ae69 5847 default:
564d80f4 5848 abort ();
e075ae69 5849 }
fb204271
DN
5850
5851 /* Check for explicit size override (codes 'b', 'w' and 'k') */
5852 if (code == 'b')
5853 size = "BYTE";
5854 else if (code == 'w')
5855 size = "WORD";
5856 else if (code == 'k')
5857 size = "DWORD";
5858
e075ae69
RH
5859 fputs (size, file);
5860 fputs (" PTR ", file);
2a2ab3f9 5861 }
e075ae69
RH
5862
5863 x = XEXP (x, 0);
5864 if (flag_pic && CONSTANT_ADDRESS_P (x))
5865 output_pic_addr_const (file, x, code);
0d7d98ee
JH
5866 /* Avoid (%rip) for call operands. */
5867 else if (CONSTANT_ADDRESS_P (x) && code =='P'
5868 && GET_CODE (x) != CONST_INT)
5869 output_addr_const (file, x);
2a2ab3f9 5870 else
e075ae69 5871 output_address (x);
2a2ab3f9 5872 }
e9a25f70 5873
2a2ab3f9
JVA
5874 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
5875 {
e9a25f70
JL
5876 REAL_VALUE_TYPE r;
5877 long l;
5878
5f1ec3e6
JVA
5879 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
5880 REAL_VALUE_TO_TARGET_SINGLE (r, l);
e075ae69
RH
5881
5882 if (ASSEMBLER_DIALECT == 0)
5883 putc ('$', file);
52267fcb 5884 fprintf (file, "0x%lx", l);
5f1ec3e6 5885 }
e9a25f70 5886
0f290768 5887 /* These float cases don't actually occur as immediate operands. */
5f1ec3e6
JVA
5888 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
5889 {
e9a25f70
JL
5890 REAL_VALUE_TYPE r;
5891 char dstr[30];
5892
5f1ec3e6
JVA
5893 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
5894 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
5895 fprintf (file, "%s", dstr);
2a2ab3f9 5896 }
e9a25f70 5897
2b589241
JH
5898 else if (GET_CODE (x) == CONST_DOUBLE
5899 && (GET_MODE (x) == XFmode || GET_MODE (x) == TFmode))
2a2ab3f9 5900 {
e9a25f70
JL
5901 REAL_VALUE_TYPE r;
5902 char dstr[30];
5903
5f1ec3e6
JVA
5904 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
5905 REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
5906 fprintf (file, "%s", dstr);
2a2ab3f9 5907 }
79325812 5908 else
2a2ab3f9 5909 {
4af3895e 5910 if (code != 'P')
2a2ab3f9 5911 {
695dac07 5912 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
e075ae69
RH
5913 {
5914 if (ASSEMBLER_DIALECT == 0)
5915 putc ('$', file);
5916 }
2a2ab3f9
JVA
5917 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
5918 || GET_CODE (x) == LABEL_REF)
e075ae69
RH
5919 {
5920 if (ASSEMBLER_DIALECT == 0)
5921 putc ('$', file);
5922 else
5923 fputs ("OFFSET FLAT:", file);
5924 }
2a2ab3f9 5925 }
e075ae69
RH
5926 if (GET_CODE (x) == CONST_INT)
5927 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
5928 else if (flag_pic)
2a2ab3f9
JVA
5929 output_pic_addr_const (file, x, code);
5930 else
5931 output_addr_const (file, x);
5932 }
5933}
5934\f
5935/* Print a memory operand whose address is ADDR. */
5936
5937void
5938print_operand_address (file, addr)
5939 FILE *file;
5940 register rtx addr;
5941{
e075ae69
RH
5942 struct ix86_address parts;
5943 rtx base, index, disp;
5944 int scale;
e9a25f70 5945
e075ae69
RH
5946 if (! ix86_decompose_address (addr, &parts))
5947 abort ();
e9a25f70 5948
e075ae69
RH
5949 base = parts.base;
5950 index = parts.index;
5951 disp = parts.disp;
5952 scale = parts.scale;
e9a25f70 5953
e075ae69
RH
5954 if (!base && !index)
5955 {
5956 /* Displacement only requires special attention. */
e9a25f70 5957
e075ae69 5958 if (GET_CODE (disp) == CONST_INT)
2a2ab3f9 5959 {
e075ae69 5960 if (ASSEMBLER_DIALECT != 0)
fb204271
DN
5961 {
5962 if (USER_LABEL_PREFIX[0] == 0)
5963 putc ('%', file);
5964 fputs ("ds:", file);
5965 }
e075ae69 5966 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
2a2ab3f9 5967 }
e075ae69
RH
5968 else if (flag_pic)
5969 output_pic_addr_const (file, addr, 0);
5970 else
5971 output_addr_const (file, addr);
0d7d98ee
JH
5972
5973 /* Use one byte shorter RIP relative addressing for 64bit mode. */
5974 if (GET_CODE (disp) != CONST_INT && TARGET_64BIT)
5975 fputs ("(%rip)", file);
e075ae69
RH
5976 }
5977 else
5978 {
5979 if (ASSEMBLER_DIALECT == 0)
2a2ab3f9 5980 {
e075ae69 5981 if (disp)
2a2ab3f9 5982 {
c399861d 5983 if (flag_pic)
e075ae69
RH
5984 output_pic_addr_const (file, disp, 0);
5985 else if (GET_CODE (disp) == LABEL_REF)
5986 output_asm_label (disp);
2a2ab3f9 5987 else
e075ae69 5988 output_addr_const (file, disp);
2a2ab3f9
JVA
5989 }
5990
e075ae69
RH
5991 putc ('(', file);
5992 if (base)
5993 PRINT_REG (base, 0, file);
5994 if (index)
2a2ab3f9 5995 {
e075ae69
RH
5996 putc (',', file);
5997 PRINT_REG (index, 0, file);
5998 if (scale != 1)
5999 fprintf (file, ",%d", scale);
2a2ab3f9 6000 }
e075ae69 6001 putc (')', file);
2a2ab3f9 6002 }
2a2ab3f9
JVA
6003 else
6004 {
e075ae69 6005 rtx offset = NULL_RTX;
e9a25f70 6006
e075ae69
RH
6007 if (disp)
6008 {
6009 /* Pull out the offset of a symbol; print any symbol itself. */
6010 if (GET_CODE (disp) == CONST
6011 && GET_CODE (XEXP (disp, 0)) == PLUS
6012 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
6013 {
6014 offset = XEXP (XEXP (disp, 0), 1);
6015 disp = gen_rtx_CONST (VOIDmode,
6016 XEXP (XEXP (disp, 0), 0));
6017 }
ce193852 6018
e075ae69
RH
6019 if (flag_pic)
6020 output_pic_addr_const (file, disp, 0);
6021 else if (GET_CODE (disp) == LABEL_REF)
6022 output_asm_label (disp);
6023 else if (GET_CODE (disp) == CONST_INT)
6024 offset = disp;
6025 else
6026 output_addr_const (file, disp);
6027 }
e9a25f70 6028
e075ae69
RH
6029 putc ('[', file);
6030 if (base)
a8620236 6031 {
e075ae69
RH
6032 PRINT_REG (base, 0, file);
6033 if (offset)
6034 {
6035 if (INTVAL (offset) >= 0)
6036 putc ('+', file);
6037 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
6038 }
a8620236 6039 }
e075ae69
RH
6040 else if (offset)
6041 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
2247a58c 6042 else
e075ae69 6043 putc ('0', file);
e9a25f70 6044
e075ae69
RH
6045 if (index)
6046 {
6047 putc ('+', file);
6048 PRINT_REG (index, 0, file);
6049 if (scale != 1)
6050 fprintf (file, "*%d", scale);
6051 }
6052 putc (']', file);
6053 }
2a2ab3f9
JVA
6054 }
6055}
6056\f
6057/* Split one or more DImode RTL references into pairs of SImode
6058 references. The RTL can be REG, offsettable MEM, integer constant, or
6059 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
6060 split and "num" is its length. lo_half and hi_half are output arrays
0f290768 6061 that parallel "operands". */
2a2ab3f9
JVA
6062
6063void
6064split_di (operands, num, lo_half, hi_half)
6065 rtx operands[];
6066 int num;
6067 rtx lo_half[], hi_half[];
6068{
6069 while (num--)
6070 {
57dbca5e 6071 rtx op = operands[num];
b932f770
JH
6072
6073 /* simplify_subreg refuse to split volatile memory addresses,
6074 but we still have to handle it. */
6075 if (GET_CODE (op) == MEM)
2a2ab3f9 6076 {
f4ef873c 6077 lo_half[num] = adjust_address (op, SImode, 0);
b72f00af 6078 hi_half[num] = adjust_address (op, SImode, 4);
2a2ab3f9
JVA
6079 }
6080 else
b932f770 6081 {
38ca929b
JH
6082 lo_half[num] = simplify_gen_subreg (SImode, op,
6083 GET_MODE (op) == VOIDmode
6084 ? DImode : GET_MODE (op), 0);
6085 hi_half[num] = simplify_gen_subreg (SImode, op,
6086 GET_MODE (op) == VOIDmode
6087 ? DImode : GET_MODE (op), 4);
b932f770 6088 }
2a2ab3f9
JVA
6089 }
6090}
44cf5b6a
JH
6091/* Split one or more TImode RTL references into pairs of SImode
6092 references. The RTL can be REG, offsettable MEM, integer constant, or
6093 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
6094 split and "num" is its length. lo_half and hi_half are output arrays
6095 that parallel "operands". */
6096
6097void
6098split_ti (operands, num, lo_half, hi_half)
6099 rtx operands[];
6100 int num;
6101 rtx lo_half[], hi_half[];
6102{
6103 while (num--)
6104 {
6105 rtx op = operands[num];
b932f770
JH
6106
6107 /* simplify_subreg refuse to split volatile memory addresses, but we
6108 still have to handle it. */
6109 if (GET_CODE (op) == MEM)
44cf5b6a
JH
6110 {
6111 lo_half[num] = adjust_address (op, DImode, 0);
6112 hi_half[num] = adjust_address (op, DImode, 8);
6113 }
6114 else
b932f770
JH
6115 {
6116 lo_half[num] = simplify_gen_subreg (DImode, op, TImode, 0);
6117 hi_half[num] = simplify_gen_subreg (DImode, op, TImode, 8);
6118 }
44cf5b6a
JH
6119 }
6120}
2a2ab3f9 6121\f
2a2ab3f9
JVA
6122/* Output code to perform a 387 binary operation in INSN, one of PLUS,
6123 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
6124 is the expression of the binary operation. The output may either be
6125 emitted here, or returned to the caller, like all output_* functions.
6126
6127 There is no guarantee that the operands are the same mode, as they
0f290768 6128 might be within FLOAT or FLOAT_EXTEND expressions. */
2a2ab3f9 6129
e3c2afab
AM
6130#ifndef SYSV386_COMPAT
6131/* Set to 1 for compatibility with brain-damaged assemblers. No-one
6132 wants to fix the assemblers because that causes incompatibility
6133 with gcc. No-one wants to fix gcc because that causes
6134 incompatibility with assemblers... You can use the option of
6135 -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way. */
6136#define SYSV386_COMPAT 1
6137#endif
6138
69ddee61 6139const char *
2a2ab3f9
JVA
6140output_387_binary_op (insn, operands)
6141 rtx insn;
6142 rtx *operands;
6143{
e3c2afab 6144 static char buf[30];
69ddee61 6145 const char *p;
1deaa899
JH
6146 const char *ssep;
6147 int is_sse = SSE_REG_P (operands[0]) | SSE_REG_P (operands[1]) | SSE_REG_P (operands[2]);
2a2ab3f9 6148
e3c2afab
AM
6149#ifdef ENABLE_CHECKING
6150 /* Even if we do not want to check the inputs, this documents input
6151 constraints. Which helps in understanding the following code. */
6152 if (STACK_REG_P (operands[0])
6153 && ((REG_P (operands[1])
6154 && REGNO (operands[0]) == REGNO (operands[1])
6155 && (STACK_REG_P (operands[2]) || GET_CODE (operands[2]) == MEM))
6156 || (REG_P (operands[2])
6157 && REGNO (operands[0]) == REGNO (operands[2])
6158 && (STACK_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)))
6159 && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
6160 ; /* ok */
1deaa899 6161 else if (!is_sse)
e3c2afab
AM
6162 abort ();
6163#endif
6164
2a2ab3f9
JVA
6165 switch (GET_CODE (operands[3]))
6166 {
6167 case PLUS:
e075ae69
RH
6168 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
6169 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
6170 p = "fiadd";
6171 else
6172 p = "fadd";
1deaa899 6173 ssep = "add";
2a2ab3f9
JVA
6174 break;
6175
6176 case MINUS:
e075ae69
RH
6177 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
6178 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
6179 p = "fisub";
6180 else
6181 p = "fsub";
1deaa899 6182 ssep = "sub";
2a2ab3f9
JVA
6183 break;
6184
6185 case MULT:
e075ae69
RH
6186 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
6187 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
6188 p = "fimul";
6189 else
6190 p = "fmul";
1deaa899 6191 ssep = "mul";
2a2ab3f9
JVA
6192 break;
6193
6194 case DIV:
e075ae69
RH
6195 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
6196 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
6197 p = "fidiv";
6198 else
6199 p = "fdiv";
1deaa899 6200 ssep = "div";
2a2ab3f9
JVA
6201 break;
6202
6203 default:
6204 abort ();
6205 }
6206
1deaa899
JH
6207 if (is_sse)
6208 {
6209 strcpy (buf, ssep);
6210 if (GET_MODE (operands[0]) == SFmode)
6211 strcat (buf, "ss\t{%2, %0|%0, %2}");
6212 else
6213 strcat (buf, "sd\t{%2, %0|%0, %2}");
6214 return buf;
6215 }
e075ae69 6216 strcpy (buf, p);
2a2ab3f9
JVA
6217
6218 switch (GET_CODE (operands[3]))
6219 {
6220 case MULT:
6221 case PLUS:
6222 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
6223 {
e3c2afab 6224 rtx temp = operands[2];
2a2ab3f9
JVA
6225 operands[2] = operands[1];
6226 operands[1] = temp;
6227 }
6228
e3c2afab
AM
6229 /* know operands[0] == operands[1]. */
6230
2a2ab3f9 6231 if (GET_CODE (operands[2]) == MEM)
e075ae69
RH
6232 {
6233 p = "%z2\t%2";
6234 break;
6235 }
2a2ab3f9
JVA
6236
6237 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63
JL
6238 {
6239 if (STACK_TOP_P (operands[0]))
e3c2afab
AM
6240 /* How is it that we are storing to a dead operand[2]?
6241 Well, presumably operands[1] is dead too. We can't
6242 store the result to st(0) as st(0) gets popped on this
6243 instruction. Instead store to operands[2] (which I
6244 think has to be st(1)). st(1) will be popped later.
6245 gcc <= 2.8.1 didn't have this check and generated
6246 assembly code that the Unixware assembler rejected. */
6247 p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
6b28fd63 6248 else
e3c2afab 6249 p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
e075ae69 6250 break;
6b28fd63 6251 }
2a2ab3f9
JVA
6252
6253 if (STACK_TOP_P (operands[0]))
e3c2afab 6254 p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
2a2ab3f9 6255 else
e3c2afab 6256 p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
e075ae69 6257 break;
2a2ab3f9
JVA
6258
6259 case MINUS:
6260 case DIV:
6261 if (GET_CODE (operands[1]) == MEM)
e075ae69
RH
6262 {
6263 p = "r%z1\t%1";
6264 break;
6265 }
2a2ab3f9
JVA
6266
6267 if (GET_CODE (operands[2]) == MEM)
e075ae69
RH
6268 {
6269 p = "%z2\t%2";
6270 break;
6271 }
2a2ab3f9 6272
2a2ab3f9 6273 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
6b28fd63 6274 {
e3c2afab
AM
6275#if SYSV386_COMPAT
6276 /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
6277 derived assemblers, confusingly reverse the direction of
6278 the operation for fsub{r} and fdiv{r} when the
6279 destination register is not st(0). The Intel assembler
6280 doesn't have this brain damage. Read !SYSV386_COMPAT to
6281 figure out what the hardware really does. */
6282 if (STACK_TOP_P (operands[0]))
6283 p = "{p\t%0, %2|rp\t%2, %0}";
6284 else
6285 p = "{rp\t%2, %0|p\t%0, %2}";
6286#else
6b28fd63 6287 if (STACK_TOP_P (operands[0]))
e3c2afab
AM
6288 /* As above for fmul/fadd, we can't store to st(0). */
6289 p = "rp\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
6b28fd63 6290 else
e3c2afab
AM
6291 p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
6292#endif
e075ae69 6293 break;
6b28fd63 6294 }
2a2ab3f9
JVA
6295
6296 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
6b28fd63 6297 {
e3c2afab 6298#if SYSV386_COMPAT
6b28fd63 6299 if (STACK_TOP_P (operands[0]))
e3c2afab 6300 p = "{rp\t%0, %1|p\t%1, %0}";
6b28fd63 6301 else
e3c2afab
AM
6302 p = "{p\t%1, %0|rp\t%0, %1}";
6303#else
6304 if (STACK_TOP_P (operands[0]))
6305 p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
6306 else
6307 p = "rp\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2); pop */
6308#endif
e075ae69 6309 break;
6b28fd63 6310 }
2a2ab3f9
JVA
6311
6312 if (STACK_TOP_P (operands[0]))
6313 {
6314 if (STACK_TOP_P (operands[1]))
e3c2afab 6315 p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
2a2ab3f9 6316 else
e3c2afab 6317 p = "r\t{%y1, %0|%0, %y1}"; /* st(0) = st(r1) op st(0) */
e075ae69 6318 break;
2a2ab3f9
JVA
6319 }
6320 else if (STACK_TOP_P (operands[1]))
e3c2afab
AM
6321 {
6322#if SYSV386_COMPAT
6323 p = "{\t%1, %0|r\t%0, %1}";
6324#else
6325 p = "r\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2) */
6326#endif
6327 }
2a2ab3f9 6328 else
e3c2afab
AM
6329 {
6330#if SYSV386_COMPAT
6331 p = "{r\t%2, %0|\t%0, %2}";
6332#else
6333 p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
6334#endif
6335 }
e075ae69 6336 break;
2a2ab3f9
JVA
6337
6338 default:
6339 abort ();
6340 }
e075ae69
RH
6341
6342 strcat (buf, p);
6343 return buf;
2a2ab3f9 6344}
e075ae69 6345
a4f31c00 6346/* Output code to initialize control word copies used by
7a2e09f4
JH
6347 trunc?f?i patterns. NORMAL is set to current control word, while ROUND_DOWN
6348 is set to control word rounding downwards. */
6349void
6350emit_i387_cw_initialization (normal, round_down)
6351 rtx normal, round_down;
6352{
6353 rtx reg = gen_reg_rtx (HImode);
6354
6355 emit_insn (gen_x86_fnstcw_1 (normal));
6356 emit_move_insn (reg, normal);
6357 if (!TARGET_PARTIAL_REG_STALL && !optimize_size
6358 && !TARGET_64BIT)
6359 emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0xc)));
6360 else
6361 emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0xc00)));
6362 emit_move_insn (round_down, reg);
6363}
6364
2a2ab3f9 6365/* Output code for INSN to convert a float to a signed int. OPERANDS
46d21d2c 6366 are the insn operands. The output may be [HSD]Imode and the input
e075ae69 6367 operand may be [SDX]Fmode. */
2a2ab3f9 6368
69ddee61 6369const char *
2a2ab3f9
JVA
6370output_fix_trunc (insn, operands)
6371 rtx insn;
6372 rtx *operands;
6373{
6374 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
e075ae69 6375 int dimode_p = GET_MODE (operands[0]) == DImode;
2a2ab3f9 6376
e075ae69
RH
6377 /* Jump through a hoop or two for DImode, since the hardware has no
6378 non-popping instruction. We used to do this a different way, but
6379 that was somewhat fragile and broke with post-reload splitters. */
a05924f9
JH
6380 if (dimode_p && !stack_top_dies)
6381 output_asm_insn ("fld\t%y1", operands);
e075ae69 6382
7a2e09f4 6383 if (!STACK_TOP_P (operands[1]))
10195bd8
JW
6384 abort ();
6385
e075ae69 6386 if (GET_CODE (operands[0]) != MEM)
7a2e09f4 6387 abort ();
e9a25f70 6388
7a2e09f4 6389 output_asm_insn ("fldcw\t%3", operands);
e075ae69 6390 if (stack_top_dies || dimode_p)
7a2e09f4 6391 output_asm_insn ("fistp%z0\t%0", operands);
10195bd8 6392 else
7a2e09f4 6393 output_asm_insn ("fist%z0\t%0", operands);
e075ae69 6394 output_asm_insn ("fldcw\t%2", operands);
10195bd8 6395
e075ae69 6396 return "";
2a2ab3f9 6397}
cda749b1 6398
e075ae69
RH
6399/* Output code for INSN to compare OPERANDS. EFLAGS_P is 1 when fcomi
6400 should be used and 2 when fnstsw should be used. UNORDERED_P is true
6401 when fucom should be used. */
6402
69ddee61 6403const char *
e075ae69 6404output_fp_compare (insn, operands, eflags_p, unordered_p)
cda749b1
JW
6405 rtx insn;
6406 rtx *operands;
e075ae69 6407 int eflags_p, unordered_p;
cda749b1 6408{
e075ae69
RH
6409 int stack_top_dies;
6410 rtx cmp_op0 = operands[0];
6411 rtx cmp_op1 = operands[1];
0644b628 6412 int is_sse = SSE_REG_P (operands[0]) | SSE_REG_P (operands[1]);
e075ae69
RH
6413
6414 if (eflags_p == 2)
6415 {
6416 cmp_op0 = cmp_op1;
6417 cmp_op1 = operands[2];
6418 }
0644b628
JH
6419 if (is_sse)
6420 {
6421 if (GET_MODE (operands[0]) == SFmode)
6422 if (unordered_p)
6423 return "ucomiss\t{%1, %0|%0, %1}";
6424 else
6425 return "comiss\t{%1, %0|%0, %y}";
6426 else
6427 if (unordered_p)
6428 return "ucomisd\t{%1, %0|%0, %1}";
6429 else
6430 return "comisd\t{%1, %0|%0, %y}";
6431 }
cda749b1 6432
e075ae69 6433 if (! STACK_TOP_P (cmp_op0))
cda749b1
JW
6434 abort ();
6435
e075ae69 6436 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
cda749b1 6437
e075ae69
RH
6438 if (STACK_REG_P (cmp_op1)
6439 && stack_top_dies
6440 && find_regno_note (insn, REG_DEAD, REGNO (cmp_op1))
6441 && REGNO (cmp_op1) != FIRST_STACK_REG)
cda749b1 6442 {
e075ae69
RH
6443 /* If both the top of the 387 stack dies, and the other operand
6444 is also a stack register that dies, then this must be a
6445 `fcompp' float compare */
6446
6447 if (eflags_p == 1)
6448 {
6449 /* There is no double popping fcomi variant. Fortunately,
6450 eflags is immune from the fstp's cc clobbering. */
6451 if (unordered_p)
6452 output_asm_insn ("fucomip\t{%y1, %0|%0, %y1}", operands);
6453 else
6454 output_asm_insn ("fcomip\t{%y1, %0|%0, %y1}", operands);
6455 return "fstp\t%y0";
6456 }
6457 else
cda749b1 6458 {
e075ae69
RH
6459 if (eflags_p == 2)
6460 {
6461 if (unordered_p)
6462 return "fucompp\n\tfnstsw\t%0";
6463 else
6464 return "fcompp\n\tfnstsw\t%0";
6465 }
cda749b1
JW
6466 else
6467 {
e075ae69
RH
6468 if (unordered_p)
6469 return "fucompp";
6470 else
6471 return "fcompp";
cda749b1
JW
6472 }
6473 }
cda749b1
JW
6474 }
6475 else
6476 {
e075ae69 6477 /* Encoded here as eflags_p | intmode | unordered_p | stack_top_dies. */
cda749b1 6478
0f290768 6479 static const char * const alt[24] =
e075ae69
RH
6480 {
6481 "fcom%z1\t%y1",
6482 "fcomp%z1\t%y1",
6483 "fucom%z1\t%y1",
6484 "fucomp%z1\t%y1",
0f290768 6485
e075ae69
RH
6486 "ficom%z1\t%y1",
6487 "ficomp%z1\t%y1",
6488 NULL,
6489 NULL,
6490
6491 "fcomi\t{%y1, %0|%0, %y1}",
6492 "fcomip\t{%y1, %0|%0, %y1}",
6493 "fucomi\t{%y1, %0|%0, %y1}",
6494 "fucomip\t{%y1, %0|%0, %y1}",
6495
6496 NULL,
6497 NULL,
6498 NULL,
6499 NULL,
6500
6501 "fcom%z2\t%y2\n\tfnstsw\t%0",
6502 "fcomp%z2\t%y2\n\tfnstsw\t%0",
6503 "fucom%z2\t%y2\n\tfnstsw\t%0",
6504 "fucomp%z2\t%y2\n\tfnstsw\t%0",
0f290768 6505
e075ae69
RH
6506 "ficom%z2\t%y2\n\tfnstsw\t%0",
6507 "ficomp%z2\t%y2\n\tfnstsw\t%0",
6508 NULL,
6509 NULL
6510 };
6511
6512 int mask;
69ddee61 6513 const char *ret;
e075ae69
RH
6514
6515 mask = eflags_p << 3;
6516 mask |= (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT) << 2;
6517 mask |= unordered_p << 1;
6518 mask |= stack_top_dies;
6519
6520 if (mask >= 24)
6521 abort ();
6522 ret = alt[mask];
6523 if (ret == NULL)
6524 abort ();
cda749b1 6525
e075ae69 6526 return ret;
cda749b1
JW
6527 }
6528}
2a2ab3f9 6529
f88c65f7
RH
6530void
6531ix86_output_addr_vec_elt (file, value)
6532 FILE *file;
6533 int value;
6534{
6535 const char *directive = ASM_LONG;
6536
6537 if (TARGET_64BIT)
6538 {
6539#ifdef ASM_QUAD
6540 directive = ASM_QUAD;
6541#else
6542 abort ();
6543#endif
6544 }
6545
6546 fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
6547}
6548
6549void
6550ix86_output_addr_diff_elt (file, value, rel)
6551 FILE *file;
6552 int value, rel;
6553{
6554 if (TARGET_64BIT)
6555 fprintf (file, "%s%s%d-.+4+(.-%s%d)\n",
6556 ASM_LONG, LPREFIX, value, LPREFIX, rel);
6557 else if (HAVE_AS_GOTOFF_IN_DATA)
6558 fprintf (file, "%s%s%d@GOTOFF\n", ASM_LONG, LPREFIX, value);
6559 else
6560 asm_fprintf (file, "%s%U_GLOBAL_OFFSET_TABLE_+[.-%s%d]\n",
6561 ASM_LONG, LPREFIX, value);
6562}
32b5b1aa 6563\f
a8bac9ab
RH
6564/* Generate either "mov $0, reg" or "xor reg, reg", as appropriate
6565 for the target. */
6566
6567void
6568ix86_expand_clear (dest)
6569 rtx dest;
6570{
6571 rtx tmp;
6572
6573 /* We play register width games, which are only valid after reload. */
6574 if (!reload_completed)
6575 abort ();
6576
6577 /* Avoid HImode and its attendant prefix byte. */
6578 if (GET_MODE_SIZE (GET_MODE (dest)) < 4)
6579 dest = gen_rtx_REG (SImode, REGNO (dest));
6580
6581 tmp = gen_rtx_SET (VOIDmode, dest, const0_rtx);
6582
6583 /* This predicate should match that for movsi_xor and movdi_xor_rex64. */
6584 if (reload_completed && (!TARGET_USE_MOV0 || optimize_size))
6585 {
6586 rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, 17));
6587 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
6588 }
6589
6590 emit_insn (tmp);
6591}
6592
79325812 6593void
e075ae69
RH
6594ix86_expand_move (mode, operands)
6595 enum machine_mode mode;
6596 rtx operands[];
32b5b1aa 6597{
e075ae69 6598 int strict = (reload_in_progress || reload_completed);
e075ae69 6599 rtx insn;
e9a25f70 6600
e075ae69 6601 if (flag_pic && mode == Pmode && symbolic_operand (operands[1], Pmode))
32b5b1aa 6602 {
e075ae69 6603 /* Emit insns to move operands[1] into operands[0]. */
e9a25f70 6604
e075ae69
RH
6605 if (GET_CODE (operands[0]) == MEM)
6606 operands[1] = force_reg (Pmode, operands[1]);
6607 else
32b5b1aa 6608 {
e075ae69
RH
6609 rtx temp = operands[0];
6610 if (GET_CODE (temp) != REG)
6611 temp = gen_reg_rtx (Pmode);
6612 temp = legitimize_pic_address (operands[1], temp);
6613 if (temp == operands[0])
6614 return;
6615 operands[1] = temp;
32b5b1aa 6616 }
e075ae69
RH
6617 }
6618 else
6619 {
d7a29404 6620 if (GET_CODE (operands[0]) == MEM
44cf5b6a 6621 && (PUSH_ROUNDING (GET_MODE_SIZE (mode)) != GET_MODE_SIZE (mode)
d7a29404
JH
6622 || !push_operand (operands[0], mode))
6623 && GET_CODE (operands[1]) == MEM)
e075ae69 6624 operands[1] = force_reg (mode, operands[1]);
e9a25f70 6625
2c5a510c
RH
6626 if (push_operand (operands[0], mode)
6627 && ! general_no_elim_operand (operands[1], mode))
6628 operands[1] = copy_to_mode_reg (mode, operands[1]);
6629
44cf5b6a
JH
6630 /* Force large constants in 64bit compilation into register
6631 to get them CSEed. */
6632 if (TARGET_64BIT && mode == DImode
6633 && immediate_operand (operands[1], mode)
6634 && !x86_64_zero_extended_value (operands[1])
6635 && !register_operand (operands[0], mode)
6636 && optimize && !reload_completed && !reload_in_progress)
6637 operands[1] = copy_to_mode_reg (mode, operands[1]);
6638
e075ae69 6639 if (FLOAT_MODE_P (mode))
32b5b1aa 6640 {
d7a29404
JH
6641 /* If we are loading a floating point constant to a register,
6642 force the value to memory now, since we'll get better code
6643 out the back end. */
e075ae69
RH
6644
6645 if (strict)
6646 ;
e075ae69 6647 else if (GET_CODE (operands[1]) == CONST_DOUBLE
d7a29404 6648 && register_operand (operands[0], mode))
e075ae69 6649 operands[1] = validize_mem (force_const_mem (mode, operands[1]));
32b5b1aa 6650 }
32b5b1aa 6651 }
e9a25f70 6652
e075ae69 6653 insn = gen_rtx_SET (VOIDmode, operands[0], operands[1]);
e9a25f70 6654
e075ae69
RH
6655 emit_insn (insn);
6656}
e9a25f70 6657
e075ae69
RH
6658/* Attempt to expand a binary operator. Make the expansion closer to the
6659 actual machine, then just general_operand, which will allow 3 separate
9d81fc27 6660 memory references (one output, two input) in a single insn. */
e9a25f70 6661
e075ae69
RH
6662void
6663ix86_expand_binary_operator (code, mode, operands)
6664 enum rtx_code code;
6665 enum machine_mode mode;
6666 rtx operands[];
6667{
6668 int matching_memory;
6669 rtx src1, src2, dst, op, clob;
6670
6671 dst = operands[0];
6672 src1 = operands[1];
6673 src2 = operands[2];
6674
6675 /* Recognize <var1> = <value> <op> <var1> for commutative operators */
6676 if (GET_RTX_CLASS (code) == 'c'
6677 && (rtx_equal_p (dst, src2)
6678 || immediate_operand (src1, mode)))
6679 {
6680 rtx temp = src1;
6681 src1 = src2;
6682 src2 = temp;
32b5b1aa 6683 }
e9a25f70 6684
e075ae69
RH
6685 /* If the destination is memory, and we do not have matching source
6686 operands, do things in registers. */
6687 matching_memory = 0;
6688 if (GET_CODE (dst) == MEM)
32b5b1aa 6689 {
e075ae69
RH
6690 if (rtx_equal_p (dst, src1))
6691 matching_memory = 1;
6692 else if (GET_RTX_CLASS (code) == 'c'
6693 && rtx_equal_p (dst, src2))
6694 matching_memory = 2;
6695 else
6696 dst = gen_reg_rtx (mode);
6697 }
0f290768 6698
e075ae69
RH
6699 /* Both source operands cannot be in memory. */
6700 if (GET_CODE (src1) == MEM && GET_CODE (src2) == MEM)
6701 {
6702 if (matching_memory != 2)
6703 src2 = force_reg (mode, src2);
6704 else
6705 src1 = force_reg (mode, src1);
32b5b1aa 6706 }
e9a25f70 6707
06a964de
JH
6708 /* If the operation is not commutable, source 1 cannot be a constant
6709 or non-matching memory. */
0f290768 6710 if ((CONSTANT_P (src1)
06a964de
JH
6711 || (!matching_memory && GET_CODE (src1) == MEM))
6712 && GET_RTX_CLASS (code) != 'c')
e075ae69 6713 src1 = force_reg (mode, src1);
0f290768 6714
e075ae69 6715 /* If optimizing, copy to regs to improve CSE */
fe577e58 6716 if (optimize && ! no_new_pseudos)
32b5b1aa 6717 {
e075ae69
RH
6718 if (GET_CODE (dst) == MEM)
6719 dst = gen_reg_rtx (mode);
6720 if (GET_CODE (src1) == MEM)
6721 src1 = force_reg (mode, src1);
6722 if (GET_CODE (src2) == MEM)
6723 src2 = force_reg (mode, src2);
32b5b1aa 6724 }
e9a25f70 6725
e075ae69
RH
6726 /* Emit the instruction. */
6727
6728 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, mode, src1, src2));
6729 if (reload_in_progress)
6730 {
6731 /* Reload doesn't know about the flags register, and doesn't know that
6732 it doesn't want to clobber it. We can only do this with PLUS. */
6733 if (code != PLUS)
6734 abort ();
6735 emit_insn (op);
6736 }
6737 else
32b5b1aa 6738 {
e075ae69
RH
6739 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
6740 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
32b5b1aa 6741 }
e9a25f70 6742
e075ae69
RH
6743 /* Fix up the destination if needed. */
6744 if (dst != operands[0])
6745 emit_move_insn (operands[0], dst);
6746}
6747
6748/* Return TRUE or FALSE depending on whether the binary operator meets the
6749 appropriate constraints. */
6750
6751int
6752ix86_binary_operator_ok (code, mode, operands)
6753 enum rtx_code code;
6754 enum machine_mode mode ATTRIBUTE_UNUSED;
6755 rtx operands[3];
6756{
6757 /* Both source operands cannot be in memory. */
6758 if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[2]) == MEM)
6759 return 0;
6760 /* If the operation is not commutable, source 1 cannot be a constant. */
6761 if (CONSTANT_P (operands[1]) && GET_RTX_CLASS (code) != 'c')
6762 return 0;
6763 /* If the destination is memory, we must have a matching source operand. */
6764 if (GET_CODE (operands[0]) == MEM
6765 && ! (rtx_equal_p (operands[0], operands[1])
6766 || (GET_RTX_CLASS (code) == 'c'
6767 && rtx_equal_p (operands[0], operands[2]))))
6768 return 0;
06a964de 6769 /* If the operation is not commutable and the source 1 is memory, we must
d6a7951f 6770 have a matching destination. */
06a964de
JH
6771 if (GET_CODE (operands[1]) == MEM
6772 && GET_RTX_CLASS (code) != 'c'
6773 && ! rtx_equal_p (operands[0], operands[1]))
6774 return 0;
e075ae69
RH
6775 return 1;
6776}
6777
6778/* Attempt to expand a unary operator. Make the expansion closer to the
6779 actual machine, then just general_operand, which will allow 2 separate
9d81fc27 6780 memory references (one output, one input) in a single insn. */
e075ae69 6781
9d81fc27 6782void
e075ae69
RH
6783ix86_expand_unary_operator (code, mode, operands)
6784 enum rtx_code code;
6785 enum machine_mode mode;
6786 rtx operands[];
6787{
06a964de
JH
6788 int matching_memory;
6789 rtx src, dst, op, clob;
6790
6791 dst = operands[0];
6792 src = operands[1];
e075ae69 6793
06a964de
JH
6794 /* If the destination is memory, and we do not have matching source
6795 operands, do things in registers. */
6796 matching_memory = 0;
6797 if (GET_CODE (dst) == MEM)
32b5b1aa 6798 {
06a964de
JH
6799 if (rtx_equal_p (dst, src))
6800 matching_memory = 1;
e075ae69 6801 else
06a964de 6802 dst = gen_reg_rtx (mode);
32b5b1aa 6803 }
e9a25f70 6804
06a964de
JH
6805 /* When source operand is memory, destination must match. */
6806 if (!matching_memory && GET_CODE (src) == MEM)
6807 src = force_reg (mode, src);
0f290768 6808
06a964de 6809 /* If optimizing, copy to regs to improve CSE */
fe577e58 6810 if (optimize && ! no_new_pseudos)
06a964de
JH
6811 {
6812 if (GET_CODE (dst) == MEM)
6813 dst = gen_reg_rtx (mode);
6814 if (GET_CODE (src) == MEM)
6815 src = force_reg (mode, src);
6816 }
6817
6818 /* Emit the instruction. */
6819
6820 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_e (code, mode, src));
6821 if (reload_in_progress || code == NOT)
6822 {
6823 /* Reload doesn't know about the flags register, and doesn't know that
6824 it doesn't want to clobber it. */
6825 if (code != NOT)
6826 abort ();
6827 emit_insn (op);
6828 }
6829 else
6830 {
6831 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
6832 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
6833 }
6834
6835 /* Fix up the destination if needed. */
6836 if (dst != operands[0])
6837 emit_move_insn (operands[0], dst);
e075ae69
RH
6838}
6839
6840/* Return TRUE or FALSE depending on whether the unary operator meets the
6841 appropriate constraints. */
6842
6843int
6844ix86_unary_operator_ok (code, mode, operands)
6845 enum rtx_code code ATTRIBUTE_UNUSED;
6846 enum machine_mode mode ATTRIBUTE_UNUSED;
6847 rtx operands[2] ATTRIBUTE_UNUSED;
6848{
06a964de
JH
6849 /* If one of operands is memory, source and destination must match. */
6850 if ((GET_CODE (operands[0]) == MEM
6851 || GET_CODE (operands[1]) == MEM)
6852 && ! rtx_equal_p (operands[0], operands[1]))
6853 return FALSE;
e075ae69
RH
6854 return TRUE;
6855}
6856
16189740
RH
6857/* Return TRUE or FALSE depending on whether the first SET in INSN
6858 has source and destination with matching CC modes, and that the
6859 CC mode is at least as constrained as REQ_MODE. */
6860
6861int
6862ix86_match_ccmode (insn, req_mode)
6863 rtx insn;
6864 enum machine_mode req_mode;
6865{
6866 rtx set;
6867 enum machine_mode set_mode;
6868
6869 set = PATTERN (insn);
6870 if (GET_CODE (set) == PARALLEL)
6871 set = XVECEXP (set, 0, 0);
6872 if (GET_CODE (set) != SET)
6873 abort ();
9076b9c1
JH
6874 if (GET_CODE (SET_SRC (set)) != COMPARE)
6875 abort ();
16189740
RH
6876
6877 set_mode = GET_MODE (SET_DEST (set));
6878 switch (set_mode)
6879 {
9076b9c1
JH
6880 case CCNOmode:
6881 if (req_mode != CCNOmode
6882 && (req_mode != CCmode
6883 || XEXP (SET_SRC (set), 1) != const0_rtx))
6884 return 0;
6885 break;
16189740 6886 case CCmode:
9076b9c1 6887 if (req_mode == CCGCmode)
16189740
RH
6888 return 0;
6889 /* FALLTHRU */
9076b9c1
JH
6890 case CCGCmode:
6891 if (req_mode == CCGOCmode || req_mode == CCNOmode)
6892 return 0;
6893 /* FALLTHRU */
6894 case CCGOCmode:
16189740
RH
6895 if (req_mode == CCZmode)
6896 return 0;
6897 /* FALLTHRU */
6898 case CCZmode:
6899 break;
6900
6901 default:
6902 abort ();
6903 }
6904
6905 return (GET_MODE (SET_SRC (set)) == set_mode);
6906}
6907
e075ae69
RH
6908/* Generate insn patterns to do an integer compare of OPERANDS. */
6909
6910static rtx
6911ix86_expand_int_compare (code, op0, op1)
6912 enum rtx_code code;
6913 rtx op0, op1;
6914{
6915 enum machine_mode cmpmode;
6916 rtx tmp, flags;
6917
6918 cmpmode = SELECT_CC_MODE (code, op0, op1);
6919 flags = gen_rtx_REG (cmpmode, FLAGS_REG);
6920
6921 /* This is very simple, but making the interface the same as in the
6922 FP case makes the rest of the code easier. */
6923 tmp = gen_rtx_COMPARE (cmpmode, op0, op1);
6924 emit_insn (gen_rtx_SET (VOIDmode, flags, tmp));
6925
6926 /* Return the test that should be put into the flags user, i.e.
6927 the bcc, scc, or cmov instruction. */
6928 return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
6929}
6930
3a3677ff
RH
6931/* Figure out whether to use ordered or unordered fp comparisons.
6932 Return the appropriate mode to use. */
e075ae69 6933
b1cdafbb 6934enum machine_mode
3a3677ff 6935ix86_fp_compare_mode (code)
8752c357 6936 enum rtx_code code ATTRIBUTE_UNUSED;
e075ae69 6937{
9e7adcb3
JH
6938 /* ??? In order to make all comparisons reversible, we do all comparisons
6939 non-trapping when compiling for IEEE. Once gcc is able to distinguish
6940 all forms trapping and nontrapping comparisons, we can make inequality
6941 comparisons trapping again, since it results in better code when using
6942 FCOM based compares. */
6943 return TARGET_IEEE_FP ? CCFPUmode : CCFPmode;
3a3677ff
RH
6944}
6945
9076b9c1
JH
6946enum machine_mode
6947ix86_cc_mode (code, op0, op1)
6948 enum rtx_code code;
6949 rtx op0, op1;
6950{
6951 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
6952 return ix86_fp_compare_mode (code);
6953 switch (code)
6954 {
6955 /* Only zero flag is needed. */
6956 case EQ: /* ZF=0 */
6957 case NE: /* ZF!=0 */
6958 return CCZmode;
6959 /* Codes needing carry flag. */
265dab10
JH
6960 case GEU: /* CF=0 */
6961 case GTU: /* CF=0 & ZF=0 */
7e08e190
JH
6962 case LTU: /* CF=1 */
6963 case LEU: /* CF=1 | ZF=1 */
265dab10 6964 return CCmode;
9076b9c1
JH
6965 /* Codes possibly doable only with sign flag when
6966 comparing against zero. */
6967 case GE: /* SF=OF or SF=0 */
7e08e190 6968 case LT: /* SF<>OF or SF=1 */
9076b9c1
JH
6969 if (op1 == const0_rtx)
6970 return CCGOCmode;
6971 else
6972 /* For other cases Carry flag is not required. */
6973 return CCGCmode;
6974 /* Codes doable only with sign flag when comparing
6975 against zero, but we miss jump instruction for it
6976 so we need to use relational tests agains overflow
6977 that thus needs to be zero. */
6978 case GT: /* ZF=0 & SF=OF */
6979 case LE: /* ZF=1 | SF<>OF */
6980 if (op1 == const0_rtx)
6981 return CCNOmode;
6982 else
6983 return CCGCmode;
7fcd7218
JH
6984 /* strcmp pattern do (use flags) and combine may ask us for proper
6985 mode. */
6986 case USE:
6987 return CCmode;
9076b9c1 6988 default:
0f290768 6989 abort ();
9076b9c1
JH
6990 }
6991}
6992
3a3677ff
RH
6993/* Return true if we should use an FCOMI instruction for this fp comparison. */
6994
a940d8bd 6995int
3a3677ff 6996ix86_use_fcomi_compare (code)
9e7adcb3 6997 enum rtx_code code ATTRIBUTE_UNUSED;
3a3677ff 6998{
9e7adcb3
JH
6999 enum rtx_code swapped_code = swap_condition (code);
7000 return ((ix86_fp_comparison_cost (code) == ix86_fp_comparison_fcomi_cost (code))
7001 || (ix86_fp_comparison_cost (swapped_code)
7002 == ix86_fp_comparison_fcomi_cost (swapped_code)));
3a3677ff
RH
7003}
7004
0f290768 7005/* Swap, force into registers, or otherwise massage the two operands
3a3677ff
RH
7006 to a fp comparison. The operands are updated in place; the new
7007 comparsion code is returned. */
7008
7009static enum rtx_code
7010ix86_prepare_fp_compare_args (code, pop0, pop1)
7011 enum rtx_code code;
7012 rtx *pop0, *pop1;
7013{
7014 enum machine_mode fpcmp_mode = ix86_fp_compare_mode (code);
7015 rtx op0 = *pop0, op1 = *pop1;
7016 enum machine_mode op_mode = GET_MODE (op0);
0644b628 7017 int is_sse = SSE_REG_P (op0) | SSE_REG_P (op1);
3a3677ff 7018
e075ae69 7019 /* All of the unordered compare instructions only work on registers.
3a3677ff
RH
7020 The same is true of the XFmode compare instructions. The same is
7021 true of the fcomi compare instructions. */
7022
0644b628
JH
7023 if (!is_sse
7024 && (fpcmp_mode == CCFPUmode
7025 || op_mode == XFmode
7026 || op_mode == TFmode
7027 || ix86_use_fcomi_compare (code)))
e075ae69 7028 {
3a3677ff
RH
7029 op0 = force_reg (op_mode, op0);
7030 op1 = force_reg (op_mode, op1);
e075ae69
RH
7031 }
7032 else
7033 {
7034 /* %%% We only allow op1 in memory; op0 must be st(0). So swap
7035 things around if they appear profitable, otherwise force op0
7036 into a register. */
7037
7038 if (standard_80387_constant_p (op0) == 0
7039 || (GET_CODE (op0) == MEM
7040 && ! (standard_80387_constant_p (op1) == 0
7041 || GET_CODE (op1) == MEM)))
32b5b1aa 7042 {
e075ae69
RH
7043 rtx tmp;
7044 tmp = op0, op0 = op1, op1 = tmp;
7045 code = swap_condition (code);
7046 }
7047
7048 if (GET_CODE (op0) != REG)
3a3677ff 7049 op0 = force_reg (op_mode, op0);
e075ae69
RH
7050
7051 if (CONSTANT_P (op1))
7052 {
7053 if (standard_80387_constant_p (op1))
3a3677ff 7054 op1 = force_reg (op_mode, op1);
e075ae69 7055 else
3a3677ff 7056 op1 = validize_mem (force_const_mem (op_mode, op1));
32b5b1aa
SC
7057 }
7058 }
e9a25f70 7059
9e7adcb3
JH
7060 /* Try to rearrange the comparison to make it cheaper. */
7061 if (ix86_fp_comparison_cost (code)
7062 > ix86_fp_comparison_cost (swap_condition (code))
7063 && (GET_CODE (op0) == REG || !reload_completed))
7064 {
7065 rtx tmp;
7066 tmp = op0, op0 = op1, op1 = tmp;
7067 code = swap_condition (code);
7068 if (GET_CODE (op0) != REG)
7069 op0 = force_reg (op_mode, op0);
7070 }
7071
3a3677ff
RH
7072 *pop0 = op0;
7073 *pop1 = op1;
7074 return code;
7075}
7076
c0c102a9
JH
7077/* Convert comparison codes we use to represent FP comparison to integer
7078 code that will result in proper branch. Return UNKNOWN if no such code
7079 is available. */
7080static enum rtx_code
7081ix86_fp_compare_code_to_integer (code)
7082 enum rtx_code code;
7083{
7084 switch (code)
7085 {
7086 case GT:
7087 return GTU;
7088 case GE:
7089 return GEU;
7090 case ORDERED:
7091 case UNORDERED:
7092 return code;
7093 break;
7094 case UNEQ:
7095 return EQ;
7096 break;
7097 case UNLT:
7098 return LTU;
7099 break;
7100 case UNLE:
7101 return LEU;
7102 break;
7103 case LTGT:
7104 return NE;
7105 break;
7106 default:
7107 return UNKNOWN;
7108 }
7109}
7110
7111/* Split comparison code CODE into comparisons we can do using branch
7112 instructions. BYPASS_CODE is comparison code for branch that will
7113 branch around FIRST_CODE and SECOND_CODE. If some of branches
7114 is not required, set value to NIL.
7115 We never require more than two branches. */
7116static void
7117ix86_fp_comparison_codes (code, bypass_code, first_code, second_code)
7118 enum rtx_code code, *bypass_code, *first_code, *second_code;
7119{
7120 *first_code = code;
7121 *bypass_code = NIL;
7122 *second_code = NIL;
7123
7124 /* The fcomi comparison sets flags as follows:
7125
7126 cmp ZF PF CF
7127 > 0 0 0
7128 < 0 0 1
7129 = 1 0 0
7130 un 1 1 1 */
7131
7132 switch (code)
7133 {
7134 case GT: /* GTU - CF=0 & ZF=0 */
7135 case GE: /* GEU - CF=0 */
7136 case ORDERED: /* PF=0 */
7137 case UNORDERED: /* PF=1 */
7138 case UNEQ: /* EQ - ZF=1 */
7139 case UNLT: /* LTU - CF=1 */
7140 case UNLE: /* LEU - CF=1 | ZF=1 */
7141 case LTGT: /* EQ - ZF=0 */
7142 break;
7143 case LT: /* LTU - CF=1 - fails on unordered */
7144 *first_code = UNLT;
7145 *bypass_code = UNORDERED;
7146 break;
7147 case LE: /* LEU - CF=1 | ZF=1 - fails on unordered */
7148 *first_code = UNLE;
7149 *bypass_code = UNORDERED;
7150 break;
7151 case EQ: /* EQ - ZF=1 - fails on unordered */
7152 *first_code = UNEQ;
7153 *bypass_code = UNORDERED;
7154 break;
7155 case NE: /* NE - ZF=0 - fails on unordered */
7156 *first_code = LTGT;
7157 *second_code = UNORDERED;
7158 break;
7159 case UNGE: /* GEU - CF=0 - fails on unordered */
7160 *first_code = GE;
7161 *second_code = UNORDERED;
7162 break;
7163 case UNGT: /* GTU - CF=0 & ZF=0 - fails on unordered */
7164 *first_code = GT;
7165 *second_code = UNORDERED;
7166 break;
7167 default:
7168 abort ();
7169 }
7170 if (!TARGET_IEEE_FP)
7171 {
7172 *second_code = NIL;
7173 *bypass_code = NIL;
7174 }
7175}
7176
9e7adcb3
JH
7177/* Return cost of comparison done fcom + arithmetics operations on AX.
7178 All following functions do use number of instructions as an cost metrics.
7179 In future this should be tweaked to compute bytes for optimize_size and
7180 take into account performance of various instructions on various CPUs. */
7181static int
7182ix86_fp_comparison_arithmetics_cost (code)
7183 enum rtx_code code;
7184{
7185 if (!TARGET_IEEE_FP)
7186 return 4;
7187 /* The cost of code output by ix86_expand_fp_compare. */
7188 switch (code)
7189 {
7190 case UNLE:
7191 case UNLT:
7192 case LTGT:
7193 case GT:
7194 case GE:
7195 case UNORDERED:
7196 case ORDERED:
7197 case UNEQ:
7198 return 4;
7199 break;
7200 case LT:
7201 case NE:
7202 case EQ:
7203 case UNGE:
7204 return 5;
7205 break;
7206 case LE:
7207 case UNGT:
7208 return 6;
7209 break;
7210 default:
7211 abort ();
7212 }
7213}
7214
7215/* Return cost of comparison done using fcomi operation.
7216 See ix86_fp_comparison_arithmetics_cost for the metrics. */
7217static int
7218ix86_fp_comparison_fcomi_cost (code)
7219 enum rtx_code code;
7220{
7221 enum rtx_code bypass_code, first_code, second_code;
7222 /* Return arbitarily high cost when instruction is not supported - this
7223 prevents gcc from using it. */
7224 if (!TARGET_CMOVE)
7225 return 1024;
7226 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
7227 return (bypass_code != NIL || second_code != NIL) + 2;
7228}
7229
7230/* Return cost of comparison done using sahf operation.
7231 See ix86_fp_comparison_arithmetics_cost for the metrics. */
7232static int
7233ix86_fp_comparison_sahf_cost (code)
7234 enum rtx_code code;
7235{
7236 enum rtx_code bypass_code, first_code, second_code;
7237 /* Return arbitarily high cost when instruction is not preferred - this
7238 avoids gcc from using it. */
7239 if (!TARGET_USE_SAHF && !optimize_size)
7240 return 1024;
7241 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
7242 return (bypass_code != NIL || second_code != NIL) + 3;
7243}
7244
7245/* Compute cost of the comparison done using any method.
7246 See ix86_fp_comparison_arithmetics_cost for the metrics. */
7247static int
7248ix86_fp_comparison_cost (code)
7249 enum rtx_code code;
7250{
7251 int fcomi_cost, sahf_cost, arithmetics_cost = 1024;
7252 int min;
7253
7254 fcomi_cost = ix86_fp_comparison_fcomi_cost (code);
7255 sahf_cost = ix86_fp_comparison_sahf_cost (code);
7256
7257 min = arithmetics_cost = ix86_fp_comparison_arithmetics_cost (code);
7258 if (min > sahf_cost)
7259 min = sahf_cost;
7260 if (min > fcomi_cost)
7261 min = fcomi_cost;
7262 return min;
7263}
c0c102a9 7264
3a3677ff
RH
7265/* Generate insn patterns to do a floating point compare of OPERANDS. */
7266
9e7adcb3
JH
7267static rtx
7268ix86_expand_fp_compare (code, op0, op1, scratch, second_test, bypass_test)
3a3677ff
RH
7269 enum rtx_code code;
7270 rtx op0, op1, scratch;
9e7adcb3
JH
7271 rtx *second_test;
7272 rtx *bypass_test;
3a3677ff
RH
7273{
7274 enum machine_mode fpcmp_mode, intcmp_mode;
c0c102a9 7275 rtx tmp, tmp2;
9e7adcb3 7276 int cost = ix86_fp_comparison_cost (code);
c0c102a9 7277 enum rtx_code bypass_code, first_code, second_code;
3a3677ff
RH
7278
7279 fpcmp_mode = ix86_fp_compare_mode (code);
7280 code = ix86_prepare_fp_compare_args (code, &op0, &op1);
7281
9e7adcb3
JH
7282 if (second_test)
7283 *second_test = NULL_RTX;
7284 if (bypass_test)
7285 *bypass_test = NULL_RTX;
7286
c0c102a9
JH
7287 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
7288
9e7adcb3
JH
7289 /* Do fcomi/sahf based test when profitable. */
7290 if ((bypass_code == NIL || bypass_test)
7291 && (second_code == NIL || second_test)
7292 && ix86_fp_comparison_arithmetics_cost (code) > cost)
32b5b1aa 7293 {
c0c102a9
JH
7294 if (TARGET_CMOVE)
7295 {
7296 tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
7297 tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
7298 tmp);
7299 emit_insn (tmp);
7300 }
7301 else
7302 {
7303 tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
7304 tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), 9);
bf71a4f8
JH
7305 if (!scratch)
7306 scratch = gen_reg_rtx (HImode);
c0c102a9
JH
7307 emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp2));
7308 emit_insn (gen_x86_sahf_1 (scratch));
7309 }
e075ae69
RH
7310
7311 /* The FP codes work out to act like unsigned. */
9a915772 7312 intcmp_mode = fpcmp_mode;
9e7adcb3
JH
7313 code = first_code;
7314 if (bypass_code != NIL)
7315 *bypass_test = gen_rtx_fmt_ee (bypass_code, VOIDmode,
7316 gen_rtx_REG (intcmp_mode, FLAGS_REG),
7317 const0_rtx);
7318 if (second_code != NIL)
7319 *second_test = gen_rtx_fmt_ee (second_code, VOIDmode,
7320 gen_rtx_REG (intcmp_mode, FLAGS_REG),
7321 const0_rtx);
e075ae69
RH
7322 }
7323 else
7324 {
7325 /* Sadness wrt reg-stack pops killing fpsr -- gotta get fnstsw first. */
e075ae69
RH
7326 tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
7327 tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), 9);
bf71a4f8
JH
7328 if (!scratch)
7329 scratch = gen_reg_rtx (HImode);
3a3677ff 7330 emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp2));
e075ae69 7331
9a915772
JH
7332 /* In the unordered case, we have to check C2 for NaN's, which
7333 doesn't happen to work out to anything nice combination-wise.
7334 So do some bit twiddling on the value we've got in AH to come
7335 up with an appropriate set of condition codes. */
e075ae69 7336
9a915772
JH
7337 intcmp_mode = CCNOmode;
7338 switch (code)
32b5b1aa 7339 {
9a915772
JH
7340 case GT:
7341 case UNGT:
7342 if (code == GT || !TARGET_IEEE_FP)
32b5b1aa 7343 {
3a3677ff 7344 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x45)));
e075ae69 7345 code = EQ;
9a915772
JH
7346 }
7347 else
7348 {
7349 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
7350 emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
7351 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x44)));
7352 intcmp_mode = CCmode;
7353 code = GEU;
7354 }
7355 break;
7356 case LT:
7357 case UNLT:
7358 if (code == LT && TARGET_IEEE_FP)
7359 {
3a3677ff
RH
7360 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
7361 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x01)));
e075ae69
RH
7362 intcmp_mode = CCmode;
7363 code = EQ;
9a915772
JH
7364 }
7365 else
7366 {
7367 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x01)));
7368 code = NE;
7369 }
7370 break;
7371 case GE:
7372 case UNGE:
7373 if (code == GE || !TARGET_IEEE_FP)
7374 {
3a3677ff 7375 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x05)));
e075ae69 7376 code = EQ;
9a915772
JH
7377 }
7378 else
7379 {
7380 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
7381 emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch,
7382 GEN_INT (0x01)));
7383 code = NE;
7384 }
7385 break;
7386 case LE:
7387 case UNLE:
7388 if (code == LE && TARGET_IEEE_FP)
7389 {
3a3677ff
RH
7390 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
7391 emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
7392 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
e075ae69
RH
7393 intcmp_mode = CCmode;
7394 code = LTU;
9a915772
JH
7395 }
7396 else
7397 {
7398 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x45)));
7399 code = NE;
7400 }
7401 break;
7402 case EQ:
7403 case UNEQ:
7404 if (code == EQ && TARGET_IEEE_FP)
7405 {
3a3677ff
RH
7406 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
7407 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
e075ae69
RH
7408 intcmp_mode = CCmode;
7409 code = EQ;
9a915772
JH
7410 }
7411 else
7412 {
3a3677ff
RH
7413 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40)));
7414 code = NE;
7415 break;
9a915772
JH
7416 }
7417 break;
7418 case NE:
7419 case LTGT:
7420 if (code == NE && TARGET_IEEE_FP)
7421 {
3a3677ff 7422 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
9a915772
JH
7423 emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch,
7424 GEN_INT (0x40)));
3a3677ff 7425 code = NE;
9a915772
JH
7426 }
7427 else
7428 {
3a3677ff
RH
7429 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40)));
7430 code = EQ;
32b5b1aa 7431 }
9a915772
JH
7432 break;
7433
7434 case UNORDERED:
7435 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x04)));
7436 code = NE;
7437 break;
7438 case ORDERED:
7439 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x04)));
7440 code = EQ;
7441 break;
7442
7443 default:
7444 abort ();
32b5b1aa 7445 }
32b5b1aa 7446 }
e075ae69
RH
7447
7448 /* Return the test that should be put into the flags user, i.e.
7449 the bcc, scc, or cmov instruction. */
7450 return gen_rtx_fmt_ee (code, VOIDmode,
7451 gen_rtx_REG (intcmp_mode, FLAGS_REG),
7452 const0_rtx);
7453}
7454
9e3e266c 7455rtx
a1b8572c 7456ix86_expand_compare (code, second_test, bypass_test)
e075ae69 7457 enum rtx_code code;
a1b8572c 7458 rtx *second_test, *bypass_test;
e075ae69
RH
7459{
7460 rtx op0, op1, ret;
7461 op0 = ix86_compare_op0;
7462 op1 = ix86_compare_op1;
7463
a1b8572c
JH
7464 if (second_test)
7465 *second_test = NULL_RTX;
7466 if (bypass_test)
7467 *bypass_test = NULL_RTX;
7468
e075ae69 7469 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
bf71a4f8 7470 ret = ix86_expand_fp_compare (code, op0, op1, NULL_RTX,
77ebd435 7471 second_test, bypass_test);
32b5b1aa 7472 else
e075ae69
RH
7473 ret = ix86_expand_int_compare (code, op0, op1);
7474
7475 return ret;
7476}
7477
03598dea
JH
7478/* Return true if the CODE will result in nontrivial jump sequence. */
7479bool
7480ix86_fp_jump_nontrivial_p (code)
7481 enum rtx_code code;
7482{
7483 enum rtx_code bypass_code, first_code, second_code;
7484 if (!TARGET_CMOVE)
7485 return true;
7486 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
7487 return bypass_code != NIL || second_code != NIL;
7488}
7489
e075ae69 7490void
3a3677ff 7491ix86_expand_branch (code, label)
e075ae69 7492 enum rtx_code code;
e075ae69
RH
7493 rtx label;
7494{
3a3677ff 7495 rtx tmp;
e075ae69 7496
3a3677ff 7497 switch (GET_MODE (ix86_compare_op0))
32b5b1aa 7498 {
3a3677ff
RH
7499 case QImode:
7500 case HImode:
7501 case SImode:
0d7d98ee 7502 simple:
a1b8572c 7503 tmp = ix86_expand_compare (code, NULL, NULL);
e075ae69
RH
7504 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
7505 gen_rtx_LABEL_REF (VOIDmode, label),
7506 pc_rtx);
7507 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
32b5b1aa 7508 return;
e075ae69 7509
3a3677ff
RH
7510 case SFmode:
7511 case DFmode:
0f290768 7512 case XFmode:
2b589241 7513 case TFmode:
3a3677ff
RH
7514 {
7515 rtvec vec;
7516 int use_fcomi;
03598dea 7517 enum rtx_code bypass_code, first_code, second_code;
3a3677ff
RH
7518
7519 code = ix86_prepare_fp_compare_args (code, &ix86_compare_op0,
7520 &ix86_compare_op1);
03598dea
JH
7521
7522 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
7523
7524 /* Check whether we will use the natural sequence with one jump. If
7525 so, we can expand jump early. Otherwise delay expansion by
7526 creating compound insn to not confuse optimizers. */
7527 if (bypass_code == NIL && second_code == NIL
7528 && TARGET_CMOVE)
7529 {
7530 ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1,
7531 gen_rtx_LABEL_REF (VOIDmode, label),
7532 pc_rtx, NULL_RTX);
7533 }
7534 else
7535 {
7536 tmp = gen_rtx_fmt_ee (code, VOIDmode,
7537 ix86_compare_op0, ix86_compare_op1);
7538 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
7539 gen_rtx_LABEL_REF (VOIDmode, label),
7540 pc_rtx);
7541 tmp = gen_rtx_SET (VOIDmode, pc_rtx, tmp);
7542
7543 use_fcomi = ix86_use_fcomi_compare (code);
7544 vec = rtvec_alloc (3 + !use_fcomi);
7545 RTVEC_ELT (vec, 0) = tmp;
7546 RTVEC_ELT (vec, 1)
7547 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 18));
7548 RTVEC_ELT (vec, 2)
7549 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 17));
7550 if (! use_fcomi)
7551 RTVEC_ELT (vec, 3)
7552 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (HImode));
7553
7554 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7555 }
3a3677ff
RH
7556 return;
7557 }
32b5b1aa 7558
3a3677ff 7559 case DImode:
0d7d98ee
JH
7560 if (TARGET_64BIT)
7561 goto simple;
3a3677ff
RH
7562 /* Expand DImode branch into multiple compare+branch. */
7563 {
7564 rtx lo[2], hi[2], label2;
7565 enum rtx_code code1, code2, code3;
32b5b1aa 7566
3a3677ff
RH
7567 if (CONSTANT_P (ix86_compare_op0) && ! CONSTANT_P (ix86_compare_op1))
7568 {
7569 tmp = ix86_compare_op0;
7570 ix86_compare_op0 = ix86_compare_op1;
7571 ix86_compare_op1 = tmp;
7572 code = swap_condition (code);
7573 }
7574 split_di (&ix86_compare_op0, 1, lo+0, hi+0);
7575 split_di (&ix86_compare_op1, 1, lo+1, hi+1);
32b5b1aa 7576
3a3677ff
RH
7577 /* When comparing for equality, we can use (hi0^hi1)|(lo0^lo1) to
7578 avoid two branches. This costs one extra insn, so disable when
7579 optimizing for size. */
32b5b1aa 7580
3a3677ff
RH
7581 if ((code == EQ || code == NE)
7582 && (!optimize_size
7583 || hi[1] == const0_rtx || lo[1] == const0_rtx))
7584 {
7585 rtx xor0, xor1;
32b5b1aa 7586
3a3677ff
RH
7587 xor1 = hi[0];
7588 if (hi[1] != const0_rtx)
7589 xor1 = expand_binop (SImode, xor_optab, xor1, hi[1],
7590 NULL_RTX, 0, OPTAB_WIDEN);
32b5b1aa 7591
3a3677ff
RH
7592 xor0 = lo[0];
7593 if (lo[1] != const0_rtx)
7594 xor0 = expand_binop (SImode, xor_optab, xor0, lo[1],
7595 NULL_RTX, 0, OPTAB_WIDEN);
e075ae69 7596
3a3677ff
RH
7597 tmp = expand_binop (SImode, ior_optab, xor1, xor0,
7598 NULL_RTX, 0, OPTAB_WIDEN);
32b5b1aa 7599
3a3677ff
RH
7600 ix86_compare_op0 = tmp;
7601 ix86_compare_op1 = const0_rtx;
7602 ix86_expand_branch (code, label);
7603 return;
7604 }
e075ae69 7605
1f9124e4
JJ
7606 /* Otherwise, if we are doing less-than or greater-or-equal-than,
7607 op1 is a constant and the low word is zero, then we can just
7608 examine the high word. */
32b5b1aa 7609
1f9124e4
JJ
7610 if (GET_CODE (hi[1]) == CONST_INT && lo[1] == const0_rtx)
7611 switch (code)
7612 {
7613 case LT: case LTU: case GE: case GEU:
7614 ix86_compare_op0 = hi[0];
7615 ix86_compare_op1 = hi[1];
7616 ix86_expand_branch (code, label);
7617 return;
7618 default:
7619 break;
7620 }
e075ae69 7621
3a3677ff 7622 /* Otherwise, we need two or three jumps. */
e075ae69 7623
3a3677ff 7624 label2 = gen_label_rtx ();
e075ae69 7625
3a3677ff
RH
7626 code1 = code;
7627 code2 = swap_condition (code);
7628 code3 = unsigned_condition (code);
e075ae69 7629
3a3677ff
RH
7630 switch (code)
7631 {
7632 case LT: case GT: case LTU: case GTU:
7633 break;
e075ae69 7634
3a3677ff
RH
7635 case LE: code1 = LT; code2 = GT; break;
7636 case GE: code1 = GT; code2 = LT; break;
7637 case LEU: code1 = LTU; code2 = GTU; break;
7638 case GEU: code1 = GTU; code2 = LTU; break;
e075ae69 7639
3a3677ff
RH
7640 case EQ: code1 = NIL; code2 = NE; break;
7641 case NE: code2 = NIL; break;
e075ae69 7642
3a3677ff
RH
7643 default:
7644 abort ();
7645 }
e075ae69 7646
3a3677ff
RH
7647 /*
7648 * a < b =>
7649 * if (hi(a) < hi(b)) goto true;
7650 * if (hi(a) > hi(b)) goto false;
7651 * if (lo(a) < lo(b)) goto true;
7652 * false:
7653 */
7654
7655 ix86_compare_op0 = hi[0];
7656 ix86_compare_op1 = hi[1];
7657
7658 if (code1 != NIL)
7659 ix86_expand_branch (code1, label);
7660 if (code2 != NIL)
7661 ix86_expand_branch (code2, label2);
7662
7663 ix86_compare_op0 = lo[0];
7664 ix86_compare_op1 = lo[1];
7665 ix86_expand_branch (code3, label);
7666
7667 if (code2 != NIL)
7668 emit_label (label2);
7669 return;
7670 }
e075ae69 7671
3a3677ff
RH
7672 default:
7673 abort ();
7674 }
32b5b1aa 7675}
e075ae69 7676
9e7adcb3
JH
7677/* Split branch based on floating point condition. */
7678void
03598dea
JH
7679ix86_split_fp_branch (code, op1, op2, target1, target2, tmp)
7680 enum rtx_code code;
7681 rtx op1, op2, target1, target2, tmp;
9e7adcb3
JH
7682{
7683 rtx second, bypass;
7684 rtx label = NULL_RTX;
03598dea 7685 rtx condition;
6b24c259
JH
7686 int bypass_probability = -1, second_probability = -1, probability = -1;
7687 rtx i;
9e7adcb3
JH
7688
7689 if (target2 != pc_rtx)
7690 {
7691 rtx tmp = target2;
7692 code = reverse_condition_maybe_unordered (code);
7693 target2 = target1;
7694 target1 = tmp;
7695 }
7696
7697 condition = ix86_expand_fp_compare (code, op1, op2,
7698 tmp, &second, &bypass);
6b24c259
JH
7699
7700 if (split_branch_probability >= 0)
7701 {
7702 /* Distribute the probabilities across the jumps.
7703 Assume the BYPASS and SECOND to be always test
7704 for UNORDERED. */
7705 probability = split_branch_probability;
7706
d6a7951f 7707 /* Value of 1 is low enough to make no need for probability
6b24c259
JH
7708 to be updated. Later we may run some experiments and see
7709 if unordered values are more frequent in practice. */
7710 if (bypass)
7711 bypass_probability = 1;
7712 if (second)
7713 second_probability = 1;
7714 }
9e7adcb3
JH
7715 if (bypass != NULL_RTX)
7716 {
7717 label = gen_label_rtx ();
6b24c259
JH
7718 i = emit_jump_insn (gen_rtx_SET
7719 (VOIDmode, pc_rtx,
7720 gen_rtx_IF_THEN_ELSE (VOIDmode,
7721 bypass,
7722 gen_rtx_LABEL_REF (VOIDmode,
7723 label),
7724 pc_rtx)));
7725 if (bypass_probability >= 0)
7726 REG_NOTES (i)
7727 = gen_rtx_EXPR_LIST (REG_BR_PROB,
7728 GEN_INT (bypass_probability),
7729 REG_NOTES (i));
7730 }
7731 i = emit_jump_insn (gen_rtx_SET
9e7adcb3
JH
7732 (VOIDmode, pc_rtx,
7733 gen_rtx_IF_THEN_ELSE (VOIDmode,
6b24c259
JH
7734 condition, target1, target2)));
7735 if (probability >= 0)
7736 REG_NOTES (i)
7737 = gen_rtx_EXPR_LIST (REG_BR_PROB,
7738 GEN_INT (probability),
7739 REG_NOTES (i));
7740 if (second != NULL_RTX)
9e7adcb3 7741 {
6b24c259
JH
7742 i = emit_jump_insn (gen_rtx_SET
7743 (VOIDmode, pc_rtx,
7744 gen_rtx_IF_THEN_ELSE (VOIDmode, second, target1,
7745 target2)));
7746 if (second_probability >= 0)
7747 REG_NOTES (i)
7748 = gen_rtx_EXPR_LIST (REG_BR_PROB,
7749 GEN_INT (second_probability),
7750 REG_NOTES (i));
9e7adcb3 7751 }
9e7adcb3
JH
7752 if (label != NULL_RTX)
7753 emit_label (label);
7754}
7755
32b5b1aa 7756int
3a3677ff 7757ix86_expand_setcc (code, dest)
e075ae69 7758 enum rtx_code code;
e075ae69 7759 rtx dest;
32b5b1aa 7760{
a1b8572c
JH
7761 rtx ret, tmp, tmpreg;
7762 rtx second_test, bypass_test;
e075ae69 7763
885a70fd
JH
7764 if (GET_MODE (ix86_compare_op0) == DImode
7765 && !TARGET_64BIT)
e075ae69
RH
7766 return 0; /* FAIL */
7767
b932f770
JH
7768 if (GET_MODE (dest) != QImode)
7769 abort ();
e075ae69 7770
a1b8572c 7771 ret = ix86_expand_compare (code, &second_test, &bypass_test);
e075ae69
RH
7772 PUT_MODE (ret, QImode);
7773
7774 tmp = dest;
a1b8572c 7775 tmpreg = dest;
32b5b1aa 7776
e075ae69 7777 emit_insn (gen_rtx_SET (VOIDmode, tmp, ret));
a1b8572c
JH
7778 if (bypass_test || second_test)
7779 {
7780 rtx test = second_test;
7781 int bypass = 0;
7782 rtx tmp2 = gen_reg_rtx (QImode);
7783 if (bypass_test)
7784 {
7785 if (second_test)
7786 abort();
7787 test = bypass_test;
7788 bypass = 1;
7789 PUT_CODE (test, reverse_condition_maybe_unordered (GET_CODE (test)));
7790 }
7791 PUT_MODE (test, QImode);
7792 emit_insn (gen_rtx_SET (VOIDmode, tmp2, test));
7793
7794 if (bypass)
7795 emit_insn (gen_andqi3 (tmp, tmpreg, tmp2));
7796 else
7797 emit_insn (gen_iorqi3 (tmp, tmpreg, tmp2));
7798 }
e075ae69 7799
e075ae69 7800 return 1; /* DONE */
32b5b1aa 7801}
e075ae69 7802
32b5b1aa 7803int
e075ae69
RH
7804ix86_expand_int_movcc (operands)
7805 rtx operands[];
32b5b1aa 7806{
e075ae69
RH
7807 enum rtx_code code = GET_CODE (operands[1]), compare_code;
7808 rtx compare_seq, compare_op;
a1b8572c 7809 rtx second_test, bypass_test;
635559ab 7810 enum machine_mode mode = GET_MODE (operands[0]);
32b5b1aa 7811
36583fea
JH
7812 /* When the compare code is not LTU or GEU, we can not use sbbl case.
7813 In case comparsion is done with immediate, we can convert it to LTU or
7814 GEU by altering the integer. */
7815
7816 if ((code == LEU || code == GTU)
7817 && GET_CODE (ix86_compare_op1) == CONST_INT
635559ab 7818 && mode != HImode
36583fea 7819 && (unsigned int)INTVAL (ix86_compare_op1) != 0xffffffff
0f290768 7820 && GET_CODE (operands[2]) == CONST_INT
36583fea
JH
7821 && GET_CODE (operands[3]) == CONST_INT)
7822 {
7823 if (code == LEU)
7824 code = LTU;
7825 else
7826 code = GEU;
7827 ix86_compare_op1 = GEN_INT (INTVAL (ix86_compare_op1) + 1);
7828 }
3a3677ff 7829
e075ae69 7830 start_sequence ();
a1b8572c 7831 compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
e075ae69
RH
7832 compare_seq = gen_sequence ();
7833 end_sequence ();
7834
7835 compare_code = GET_CODE (compare_op);
7836
7837 /* Don't attempt mode expansion here -- if we had to expand 5 or 6
7838 HImode insns, we'd be swallowed in word prefix ops. */
7839
635559ab
JH
7840 if (mode != HImode
7841 && (mode != DImode || TARGET_64BIT)
0f290768 7842 && GET_CODE (operands[2]) == CONST_INT
e075ae69
RH
7843 && GET_CODE (operands[3]) == CONST_INT)
7844 {
7845 rtx out = operands[0];
7846 HOST_WIDE_INT ct = INTVAL (operands[2]);
7847 HOST_WIDE_INT cf = INTVAL (operands[3]);
7848 HOST_WIDE_INT diff;
7849
a1b8572c
JH
7850 if ((compare_code == LTU || compare_code == GEU)
7851 && !second_test && !bypass_test)
e075ae69 7852 {
e075ae69
RH
7853
7854 /* Detect overlap between destination and compare sources. */
7855 rtx tmp = out;
7856
0f290768 7857 /* To simplify rest of code, restrict to the GEU case. */
36583fea
JH
7858 if (compare_code == LTU)
7859 {
7860 int tmp = ct;
7861 ct = cf;
7862 cf = tmp;
7863 compare_code = reverse_condition (compare_code);
7864 code = reverse_condition (code);
7865 }
7866 diff = ct - cf;
7867
e075ae69 7868 if (reg_overlap_mentioned_p (out, ix86_compare_op0)
a500c31b 7869 || reg_overlap_mentioned_p (out, ix86_compare_op1))
635559ab 7870 tmp = gen_reg_rtx (mode);
e075ae69
RH
7871
7872 emit_insn (compare_seq);
635559ab 7873 if (mode == DImode)
14f73b5a
JH
7874 emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp));
7875 else
7876 emit_insn (gen_x86_movsicc_0_m1 (tmp));
e075ae69 7877
36583fea
JH
7878 if (diff == 1)
7879 {
7880 /*
7881 * cmpl op0,op1
7882 * sbbl dest,dest
7883 * [addl dest, ct]
7884 *
7885 * Size 5 - 8.
7886 */
7887 if (ct)
635559ab
JH
7888 tmp = expand_simple_binop (mode, PLUS,
7889 tmp, GEN_INT (ct),
7890 tmp, 1, OPTAB_DIRECT);
36583fea
JH
7891 }
7892 else if (cf == -1)
7893 {
7894 /*
7895 * cmpl op0,op1
7896 * sbbl dest,dest
7897 * orl $ct, dest
7898 *
7899 * Size 8.
7900 */
635559ab
JH
7901 tmp = expand_simple_binop (mode, IOR,
7902 tmp, GEN_INT (ct),
7903 tmp, 1, OPTAB_DIRECT);
36583fea
JH
7904 }
7905 else if (diff == -1 && ct)
7906 {
7907 /*
7908 * cmpl op0,op1
7909 * sbbl dest,dest
7910 * xorl $-1, dest
7911 * [addl dest, cf]
7912 *
7913 * Size 8 - 11.
7914 */
635559ab
JH
7915 tmp = expand_simple_unop (mode, NOT, tmp, tmp, 1);
7916 if (cf)
7917 tmp = expand_simple_binop (mode, PLUS,
7918 tmp, GEN_INT (cf),
7919 tmp, 1, OPTAB_DIRECT);
36583fea
JH
7920 }
7921 else
7922 {
7923 /*
7924 * cmpl op0,op1
7925 * sbbl dest,dest
7926 * andl cf - ct, dest
7927 * [addl dest, ct]
7928 *
7929 * Size 8 - 11.
7930 */
635559ab
JH
7931 tmp = expand_simple_binop (mode, AND,
7932 tmp,
7933 GEN_INT (trunc_int_for_mode
7934 (cf - ct, mode)),
7935 tmp, 1, OPTAB_DIRECT);
7936 if (ct)
7937 tmp = expand_simple_binop (mode, PLUS,
7938 tmp, GEN_INT (ct),
7939 tmp, 1, OPTAB_DIRECT);
36583fea 7940 }
e075ae69
RH
7941
7942 if (tmp != out)
7943 emit_move_insn (out, tmp);
7944
7945 return 1; /* DONE */
7946 }
7947
7948 diff = ct - cf;
7949 if (diff < 0)
7950 {
7951 HOST_WIDE_INT tmp;
7952 tmp = ct, ct = cf, cf = tmp;
7953 diff = -diff;
734dba19
JH
7954 if (FLOAT_MODE_P (GET_MODE (ix86_compare_op0)))
7955 {
7956 /* We may be reversing unordered compare to normal compare, that
7957 is not valid in general (we may convert non-trapping condition
7958 to trapping one), however on i386 we currently emit all
7959 comparisons unordered. */
7960 compare_code = reverse_condition_maybe_unordered (compare_code);
7961 code = reverse_condition_maybe_unordered (code);
7962 }
7963 else
7964 {
7965 compare_code = reverse_condition (compare_code);
7966 code = reverse_condition (code);
7967 }
e075ae69 7968 }
635559ab
JH
7969 if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
7970 || diff == 3 || diff == 5 || diff == 9)
7971 && (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf))))
e075ae69
RH
7972 {
7973 /*
7974 * xorl dest,dest
7975 * cmpl op1,op2
7976 * setcc dest
7977 * lea cf(dest*(ct-cf)),dest
7978 *
7979 * Size 14.
7980 *
7981 * This also catches the degenerate setcc-only case.
7982 */
7983
7984 rtx tmp;
7985 int nops;
7986
7987 out = emit_store_flag (out, code, ix86_compare_op0,
7988 ix86_compare_op1, VOIDmode, 0, 1);
7989
7990 nops = 0;
885a70fd
JH
7991 /* On x86_64 the lea instruction operates on Pmode, so we need to get arithmetics
7992 done in proper mode to match. */
e075ae69 7993 if (diff == 1)
14f73b5a 7994 tmp = out;
e075ae69
RH
7995 else
7996 {
885a70fd 7997 rtx out1;
14f73b5a 7998 out1 = out;
635559ab 7999 tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1));
e075ae69
RH
8000 nops++;
8001 if (diff & 1)
8002 {
635559ab 8003 tmp = gen_rtx_PLUS (mode, tmp, out1);
e075ae69
RH
8004 nops++;
8005 }
8006 }
8007 if (cf != 0)
8008 {
635559ab 8009 tmp = gen_rtx_PLUS (mode, tmp, GEN_INT (cf));
e075ae69
RH
8010 nops++;
8011 }
885a70fd
JH
8012 if (tmp != out
8013 && (GET_CODE (tmp) != SUBREG || SUBREG_REG (tmp) != out))
e075ae69 8014 {
14f73b5a 8015 if (nops == 1)
e075ae69
RH
8016 {
8017 rtx clob;
8018
8019 clob = gen_rtx_REG (CCmode, FLAGS_REG);
8020 clob = gen_rtx_CLOBBER (VOIDmode, clob);
8021
8022 tmp = gen_rtx_SET (VOIDmode, out, tmp);
8023 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
8024 emit_insn (tmp);
8025 }
8026 else
8027 emit_insn (gen_rtx_SET (VOIDmode, out, tmp));
8028 }
8029 if (out != operands[0])
8030 emit_move_insn (operands[0], out);
8031
8032 return 1; /* DONE */
8033 }
8034
8035 /*
8036 * General case: Jumpful:
8037 * xorl dest,dest cmpl op1, op2
8038 * cmpl op1, op2 movl ct, dest
8039 * setcc dest jcc 1f
8040 * decl dest movl cf, dest
8041 * andl (cf-ct),dest 1:
8042 * addl ct,dest
0f290768 8043 *
e075ae69
RH
8044 * Size 20. Size 14.
8045 *
8046 * This is reasonably steep, but branch mispredict costs are
8047 * high on modern cpus, so consider failing only if optimizing
8048 * for space.
8049 *
8050 * %%% Parameterize branch_cost on the tuning architecture, then
8051 * use that. The 80386 couldn't care less about mispredicts.
8052 */
8053
8054 if (!optimize_size && !TARGET_CMOVE)
8055 {
8056 if (ct == 0)
8057 {
8058 ct = cf;
8059 cf = 0;
734dba19
JH
8060 if (FLOAT_MODE_P (GET_MODE (ix86_compare_op0)))
8061 {
8062 /* We may be reversing unordered compare to normal compare,
8063 that is not valid in general (we may convert non-trapping
8064 condition to trapping one), however on i386 we currently
8065 emit all comparisons unordered. */
8066 compare_code = reverse_condition_maybe_unordered (compare_code);
8067 code = reverse_condition_maybe_unordered (code);
8068 }
8069 else
8070 {
8071 compare_code = reverse_condition (compare_code);
8072 code = reverse_condition (code);
8073 }
e075ae69
RH
8074 }
8075
8076 out = emit_store_flag (out, code, ix86_compare_op0,
8077 ix86_compare_op1, VOIDmode, 0, 1);
8078
635559ab
JH
8079 out = expand_simple_binop (mode, PLUS,
8080 out, constm1_rtx,
8081 out, 1, OPTAB_DIRECT);
8082 out = expand_simple_binop (mode, AND,
8083 out,
8084 GEN_INT (trunc_int_for_mode
8085 (cf - ct, mode)),
8086 out, 1, OPTAB_DIRECT);
8087 out = expand_simple_binop (mode, PLUS,
8088 out, GEN_INT (ct),
8089 out, 1, OPTAB_DIRECT);
e075ae69
RH
8090 if (out != operands[0])
8091 emit_move_insn (operands[0], out);
8092
8093 return 1; /* DONE */
8094 }
8095 }
8096
8097 if (!TARGET_CMOVE)
8098 {
8099 /* Try a few things more with specific constants and a variable. */
8100
78a0d70c 8101 optab op;
e075ae69
RH
8102 rtx var, orig_out, out, tmp;
8103
8104 if (optimize_size)
8105 return 0; /* FAIL */
8106
0f290768 8107 /* If one of the two operands is an interesting constant, load a
e075ae69 8108 constant with the above and mask it in with a logical operation. */
0f290768 8109
e075ae69
RH
8110 if (GET_CODE (operands[2]) == CONST_INT)
8111 {
8112 var = operands[3];
8113 if (INTVAL (operands[2]) == 0)
8114 operands[3] = constm1_rtx, op = and_optab;
8115 else if (INTVAL (operands[2]) == -1)
8116 operands[3] = const0_rtx, op = ior_optab;
78a0d70c
ZW
8117 else
8118 return 0; /* FAIL */
e075ae69
RH
8119 }
8120 else if (GET_CODE (operands[3]) == CONST_INT)
8121 {
8122 var = operands[2];
8123 if (INTVAL (operands[3]) == 0)
8124 operands[2] = constm1_rtx, op = and_optab;
8125 else if (INTVAL (operands[3]) == -1)
8126 operands[2] = const0_rtx, op = ior_optab;
78a0d70c
ZW
8127 else
8128 return 0; /* FAIL */
e075ae69 8129 }
78a0d70c 8130 else
e075ae69
RH
8131 return 0; /* FAIL */
8132
8133 orig_out = operands[0];
635559ab 8134 tmp = gen_reg_rtx (mode);
e075ae69
RH
8135 operands[0] = tmp;
8136
8137 /* Recurse to get the constant loaded. */
8138 if (ix86_expand_int_movcc (operands) == 0)
8139 return 0; /* FAIL */
8140
8141 /* Mask in the interesting variable. */
635559ab 8142 out = expand_binop (mode, op, var, tmp, orig_out, 0,
e075ae69
RH
8143 OPTAB_WIDEN);
8144 if (out != orig_out)
8145 emit_move_insn (orig_out, out);
8146
8147 return 1; /* DONE */
8148 }
8149
8150 /*
8151 * For comparison with above,
8152 *
8153 * movl cf,dest
8154 * movl ct,tmp
8155 * cmpl op1,op2
8156 * cmovcc tmp,dest
8157 *
8158 * Size 15.
8159 */
8160
635559ab
JH
8161 if (! nonimmediate_operand (operands[2], mode))
8162 operands[2] = force_reg (mode, operands[2]);
8163 if (! nonimmediate_operand (operands[3], mode))
8164 operands[3] = force_reg (mode, operands[3]);
e075ae69 8165
a1b8572c
JH
8166 if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
8167 {
635559ab 8168 rtx tmp = gen_reg_rtx (mode);
a1b8572c
JH
8169 emit_move_insn (tmp, operands[3]);
8170 operands[3] = tmp;
8171 }
8172 if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
8173 {
635559ab 8174 rtx tmp = gen_reg_rtx (mode);
a1b8572c
JH
8175 emit_move_insn (tmp, operands[2]);
8176 operands[2] = tmp;
8177 }
c9682caf
JH
8178 if (! register_operand (operands[2], VOIDmode)
8179 && ! register_operand (operands[3], VOIDmode))
635559ab 8180 operands[2] = force_reg (mode, operands[2]);
a1b8572c 8181
e075ae69
RH
8182 emit_insn (compare_seq);
8183 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
635559ab 8184 gen_rtx_IF_THEN_ELSE (mode,
e075ae69
RH
8185 compare_op, operands[2],
8186 operands[3])));
a1b8572c
JH
8187 if (bypass_test)
8188 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
635559ab 8189 gen_rtx_IF_THEN_ELSE (mode,
a1b8572c
JH
8190 bypass_test,
8191 operands[3],
8192 operands[0])));
8193 if (second_test)
8194 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
635559ab 8195 gen_rtx_IF_THEN_ELSE (mode,
a1b8572c
JH
8196 second_test,
8197 operands[2],
8198 operands[0])));
e075ae69
RH
8199
8200 return 1; /* DONE */
e9a25f70 8201}
e075ae69 8202
32b5b1aa 8203int
e075ae69
RH
8204ix86_expand_fp_movcc (operands)
8205 rtx operands[];
32b5b1aa 8206{
e075ae69 8207 enum rtx_code code;
e075ae69 8208 rtx tmp;
a1b8572c 8209 rtx compare_op, second_test, bypass_test;
32b5b1aa 8210
0073023d
JH
8211 /* For SF/DFmode conditional moves based on comparisons
8212 in same mode, we may want to use SSE min/max instructions. */
965f5423
JH
8213 if (((TARGET_SSE_MATH && GET_MODE (operands[0]) == SFmode)
8214 || (TARGET_SSE2 && TARGET_SSE_MATH && GET_MODE (operands[0]) == DFmode))
0073023d 8215 && GET_MODE (ix86_compare_op0) == GET_MODE (operands[0])
fa9f36a1
JH
8216 /* The SSE comparisons does not support the LTGT/UNEQ pair. */
8217 && (!TARGET_IEEE_FP
8218 || (GET_CODE (operands[1]) != LTGT && GET_CODE (operands[1]) != UNEQ))
0073023d
JH
8219 /* We may be called from the post-reload splitter. */
8220 && (!REG_P (operands[0])
8221 || SSE_REG_P (operands[0])
52a661a6 8222 || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
0073023d
JH
8223 {
8224 rtx op0 = ix86_compare_op0, op1 = ix86_compare_op1;
8225 code = GET_CODE (operands[1]);
8226
8227 /* See if we have (cross) match between comparison operands and
8228 conditional move operands. */
8229 if (rtx_equal_p (operands[2], op1))
8230 {
8231 rtx tmp = op0;
8232 op0 = op1;
8233 op1 = tmp;
8234 code = reverse_condition_maybe_unordered (code);
8235 }
8236 if (rtx_equal_p (operands[2], op0) && rtx_equal_p (operands[3], op1))
8237 {
8238 /* Check for min operation. */
8239 if (code == LT)
8240 {
8241 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
8242 if (memory_operand (op0, VOIDmode))
8243 op0 = force_reg (GET_MODE (operands[0]), op0);
8244 if (GET_MODE (operands[0]) == SFmode)
8245 emit_insn (gen_minsf3 (operands[0], op0, op1));
8246 else
8247 emit_insn (gen_mindf3 (operands[0], op0, op1));
8248 return 1;
8249 }
8250 /* Check for max operation. */
8251 if (code == GT)
8252 {
8253 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
8254 if (memory_operand (op0, VOIDmode))
8255 op0 = force_reg (GET_MODE (operands[0]), op0);
8256 if (GET_MODE (operands[0]) == SFmode)
8257 emit_insn (gen_maxsf3 (operands[0], op0, op1));
8258 else
8259 emit_insn (gen_maxdf3 (operands[0], op0, op1));
8260 return 1;
8261 }
8262 }
8263 /* Manage condition to be sse_comparison_operator. In case we are
8264 in non-ieee mode, try to canonicalize the destination operand
8265 to be first in the comparison - this helps reload to avoid extra
8266 moves. */
8267 if (!sse_comparison_operator (operands[1], VOIDmode)
8268 || (rtx_equal_p (operands[0], ix86_compare_op1) && !TARGET_IEEE_FP))
8269 {
8270 rtx tmp = ix86_compare_op0;
8271 ix86_compare_op0 = ix86_compare_op1;
8272 ix86_compare_op1 = tmp;
8273 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
8274 VOIDmode, ix86_compare_op0,
8275 ix86_compare_op1);
8276 }
8277 /* Similary try to manage result to be first operand of conditional
fa9f36a1
JH
8278 move. We also don't support the NE comparison on SSE, so try to
8279 avoid it. */
037f20f1
JH
8280 if ((rtx_equal_p (operands[0], operands[3])
8281 && (!TARGET_IEEE_FP || GET_CODE (operands[1]) != EQ))
8282 || (GET_CODE (operands[1]) == NE && TARGET_IEEE_FP))
0073023d
JH
8283 {
8284 rtx tmp = operands[2];
8285 operands[2] = operands[3];
92d0fb09 8286 operands[3] = tmp;
0073023d
JH
8287 operands[1] = gen_rtx_fmt_ee (reverse_condition_maybe_unordered
8288 (GET_CODE (operands[1])),
8289 VOIDmode, ix86_compare_op0,
8290 ix86_compare_op1);
8291 }
8292 if (GET_MODE (operands[0]) == SFmode)
8293 emit_insn (gen_sse_movsfcc (operands[0], operands[1],
8294 operands[2], operands[3],
8295 ix86_compare_op0, ix86_compare_op1));
8296 else
8297 emit_insn (gen_sse_movdfcc (operands[0], operands[1],
8298 operands[2], operands[3],
8299 ix86_compare_op0, ix86_compare_op1));
8300 return 1;
8301 }
8302
e075ae69 8303 /* The floating point conditional move instructions don't directly
0f290768 8304 support conditions resulting from a signed integer comparison. */
32b5b1aa 8305
e075ae69 8306 code = GET_CODE (operands[1]);
a1b8572c 8307 compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
9e7adcb3
JH
8308
8309 /* The floating point conditional move instructions don't directly
8310 support signed integer comparisons. */
8311
a1b8572c 8312 if (!fcmov_comparison_operator (compare_op, VOIDmode))
e075ae69 8313 {
a1b8572c
JH
8314 if (second_test != NULL || bypass_test != NULL)
8315 abort();
e075ae69 8316 tmp = gen_reg_rtx (QImode);
3a3677ff 8317 ix86_expand_setcc (code, tmp);
e075ae69
RH
8318 code = NE;
8319 ix86_compare_op0 = tmp;
8320 ix86_compare_op1 = const0_rtx;
a1b8572c
JH
8321 compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
8322 }
8323 if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
8324 {
8325 tmp = gen_reg_rtx (GET_MODE (operands[0]));
8326 emit_move_insn (tmp, operands[3]);
8327 operands[3] = tmp;
8328 }
8329 if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
8330 {
8331 tmp = gen_reg_rtx (GET_MODE (operands[0]));
8332 emit_move_insn (tmp, operands[2]);
8333 operands[2] = tmp;
e075ae69 8334 }
e9a25f70 8335
e075ae69
RH
8336 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
8337 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
9e7adcb3 8338 compare_op,
e075ae69
RH
8339 operands[2],
8340 operands[3])));
a1b8572c
JH
8341 if (bypass_test)
8342 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
8343 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
8344 bypass_test,
8345 operands[3],
8346 operands[0])));
8347 if (second_test)
8348 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
8349 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
8350 second_test,
8351 operands[2],
8352 operands[0])));
32b5b1aa 8353
e075ae69 8354 return 1;
32b5b1aa
SC
8355}
8356
2450a057
JH
8357/* Split operands 0 and 1 into SImode parts. Similar to split_di, but
8358 works for floating pointer parameters and nonoffsetable memories.
8359 For pushes, it returns just stack offsets; the values will be saved
8360 in the right order. Maximally three parts are generated. */
8361
2b589241 8362static int
2450a057
JH
8363ix86_split_to_parts (operand, parts, mode)
8364 rtx operand;
8365 rtx *parts;
8366 enum machine_mode mode;
32b5b1aa 8367{
26e5b205
JH
8368 int size;
8369
8370 if (!TARGET_64BIT)
8371 size = mode == TFmode ? 3 : (GET_MODE_SIZE (mode) / 4);
8372 else
8373 size = (GET_MODE_SIZE (mode) + 4) / 8;
2450a057 8374
a7180f70
BS
8375 if (GET_CODE (operand) == REG && MMX_REGNO_P (REGNO (operand)))
8376 abort ();
2450a057
JH
8377 if (size < 2 || size > 3)
8378 abort ();
8379
d7a29404
JH
8380 /* Optimize constant pool reference to immediates. This is used by fp moves,
8381 that force all constants to memory to allow combining. */
8382
8383 if (GET_CODE (operand) == MEM
8384 && GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
8385 && CONSTANT_POOL_ADDRESS_P (XEXP (operand, 0)))
8386 operand = get_pool_constant (XEXP (operand, 0));
8387
2450a057 8388 if (GET_CODE (operand) == MEM && !offsettable_memref_p (operand))
e075ae69 8389 {
2450a057
JH
8390 /* The only non-offsetable memories we handle are pushes. */
8391 if (! push_operand (operand, VOIDmode))
8392 abort ();
8393
26e5b205
JH
8394 operand = copy_rtx (operand);
8395 PUT_MODE (operand, Pmode);
2450a057
JH
8396 parts[0] = parts[1] = parts[2] = operand;
8397 }
26e5b205 8398 else if (!TARGET_64BIT)
2450a057
JH
8399 {
8400 if (mode == DImode)
8401 split_di (&operand, 1, &parts[0], &parts[1]);
8402 else
e075ae69 8403 {
2450a057
JH
8404 if (REG_P (operand))
8405 {
8406 if (!reload_completed)
8407 abort ();
8408 parts[0] = gen_rtx_REG (SImode, REGNO (operand) + 0);
8409 parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
8410 if (size == 3)
8411 parts[2] = gen_rtx_REG (SImode, REGNO (operand) + 2);
8412 }
8413 else if (offsettable_memref_p (operand))
8414 {
f4ef873c 8415 operand = adjust_address (operand, SImode, 0);
2450a057 8416 parts[0] = operand;
b72f00af 8417 parts[1] = adjust_address (operand, SImode, 4);
2450a057 8418 if (size == 3)
b72f00af 8419 parts[2] = adjust_address (operand, SImode, 8);
2450a057
JH
8420 }
8421 else if (GET_CODE (operand) == CONST_DOUBLE)
8422 {
8423 REAL_VALUE_TYPE r;
2b589241 8424 long l[4];
2450a057
JH
8425
8426 REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
8427 switch (mode)
8428 {
8429 case XFmode:
2b589241 8430 case TFmode:
2450a057 8431 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
523fbd9d 8432 parts[2] = GEN_INT (trunc_int_for_mode (l[2], SImode));
2450a057
JH
8433 break;
8434 case DFmode:
8435 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
8436 break;
8437 default:
8438 abort ();
8439 }
523fbd9d
RK
8440 parts[1] = GEN_INT (trunc_int_for_mode (l[1], SImode));
8441 parts[0] = GEN_INT (trunc_int_for_mode (l[0], SImode));
2450a057
JH
8442 }
8443 else
8444 abort ();
e075ae69 8445 }
2450a057 8446 }
26e5b205
JH
8447 else
8448 {
44cf5b6a
JH
8449 if (mode == TImode)
8450 split_ti (&operand, 1, &parts[0], &parts[1]);
26e5b205
JH
8451 if (mode == XFmode || mode == TFmode)
8452 {
8453 if (REG_P (operand))
8454 {
8455 if (!reload_completed)
8456 abort ();
8457 parts[0] = gen_rtx_REG (DImode, REGNO (operand) + 0);
8458 parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
8459 }
8460 else if (offsettable_memref_p (operand))
8461 {
b72f00af 8462 operand = adjust_address (operand, DImode, 0);
26e5b205 8463 parts[0] = operand;
b72f00af 8464 parts[1] = adjust_address (operand, SImode, 8);
26e5b205
JH
8465 }
8466 else if (GET_CODE (operand) == CONST_DOUBLE)
8467 {
8468 REAL_VALUE_TYPE r;
8469 long l[3];
8470
8471 REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
8472 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
8473 /* Do not use shift by 32 to avoid warning on 32bit systems. */
8474 if (HOST_BITS_PER_WIDE_INT >= 64)
523fbd9d 8475 parts[0]
44cf5b6a
JH
8476 = GEN_INT (trunc_int_for_mode
8477 ((l[0] & (((HOST_WIDE_INT) 2 << 31) - 1))
8478 + ((((HOST_WIDE_INT)l[1]) << 31) << 1),
8479 DImode));
26e5b205
JH
8480 else
8481 parts[0] = immed_double_const (l[0], l[1], DImode);
523fbd9d 8482 parts[1] = GEN_INT (trunc_int_for_mode (l[2], SImode));
26e5b205
JH
8483 }
8484 else
8485 abort ();
8486 }
8487 }
2450a057 8488
2b589241 8489 return size;
2450a057
JH
8490}
8491
8492/* Emit insns to perform a move or push of DI, DF, and XF values.
8493 Return false when normal moves are needed; true when all required
8494 insns have been emitted. Operands 2-4 contain the input values
8495 int the correct order; operands 5-7 contain the output values. */
8496
26e5b205
JH
8497void
8498ix86_split_long_move (operands)
8499 rtx operands[];
2450a057
JH
8500{
8501 rtx part[2][3];
26e5b205 8502 int nparts;
2450a057
JH
8503 int push = 0;
8504 int collisions = 0;
26e5b205
JH
8505 enum machine_mode mode = GET_MODE (operands[0]);
8506
8507 /* The DFmode expanders may ask us to move double.
8508 For 64bit target this is single move. By hiding the fact
8509 here we simplify i386.md splitters. */
8510 if (GET_MODE_SIZE (GET_MODE (operands[0])) == 8 && TARGET_64BIT)
8511 {
8cdfa312
RH
8512 /* Optimize constant pool reference to immediates. This is used by
8513 fp moves, that force all constants to memory to allow combining. */
26e5b205
JH
8514
8515 if (GET_CODE (operands[1]) == MEM
8516 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8517 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
8518 operands[1] = get_pool_constant (XEXP (operands[1], 0));
8519 if (push_operand (operands[0], VOIDmode))
b47b4f21
JH
8520 {
8521 operands[0] = copy_rtx (operands[0]);
8522 PUT_MODE (operands[0], Pmode);
8523 }
26e5b205
JH
8524 else
8525 operands[0] = gen_lowpart (DImode, operands[0]);
8526 operands[1] = gen_lowpart (DImode, operands[1]);
8527 emit_move_insn (operands[0], operands[1]);
8528 return;
8529 }
2450a057 8530
2450a057
JH
8531 /* The only non-offsettable memory we handle is push. */
8532 if (push_operand (operands[0], VOIDmode))
8533 push = 1;
8534 else if (GET_CODE (operands[0]) == MEM
8535 && ! offsettable_memref_p (operands[0]))
8536 abort ();
8537
26e5b205
JH
8538 nparts = ix86_split_to_parts (operands[1], part[1], GET_MODE (operands[0]));
8539 ix86_split_to_parts (operands[0], part[0], GET_MODE (operands[0]));
2450a057
JH
8540
8541 /* When emitting push, take care for source operands on the stack. */
8542 if (push && GET_CODE (operands[1]) == MEM
8543 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
8544 {
26e5b205 8545 if (nparts == 3)
886cbb88
JH
8546 part[1][1] = change_address (part[1][1], GET_MODE (part[1][1]),
8547 XEXP (part[1][2], 0));
8548 part[1][0] = change_address (part[1][0], GET_MODE (part[1][0]),
8549 XEXP (part[1][1], 0));
2450a057
JH
8550 }
8551
0f290768 8552 /* We need to do copy in the right order in case an address register
2450a057
JH
8553 of the source overlaps the destination. */
8554 if (REG_P (part[0][0]) && GET_CODE (part[1][0]) == MEM)
8555 {
8556 if (reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0)))
8557 collisions++;
8558 if (reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
8559 collisions++;
26e5b205 8560 if (nparts == 3
2450a057
JH
8561 && reg_overlap_mentioned_p (part[0][2], XEXP (part[1][0], 0)))
8562 collisions++;
8563
8564 /* Collision in the middle part can be handled by reordering. */
26e5b205 8565 if (collisions == 1 && nparts == 3
2450a057 8566 && reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
e075ae69 8567 {
2450a057
JH
8568 rtx tmp;
8569 tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
8570 tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
8571 }
e075ae69 8572
2450a057
JH
8573 /* If there are more collisions, we can't handle it by reordering.
8574 Do an lea to the last part and use only one colliding move. */
8575 else if (collisions > 1)
8576 {
8577 collisions = 1;
26e5b205 8578 emit_insn (gen_rtx_SET (VOIDmode, part[0][nparts - 1],
2450a057 8579 XEXP (part[1][0], 0)));
26e5b205
JH
8580 part[1][0] = change_address (part[1][0],
8581 TARGET_64BIT ? DImode : SImode,
8582 part[0][nparts - 1]);
b72f00af 8583 part[1][1] = adjust_address (part[1][0], VOIDmode, UNITS_PER_WORD);
26e5b205 8584 if (nparts == 3)
b72f00af 8585 part[1][2] = adjust_address (part[1][0], VOIDmode, 8);
2450a057
JH
8586 }
8587 }
8588
8589 if (push)
8590 {
26e5b205 8591 if (!TARGET_64BIT)
2b589241 8592 {
26e5b205
JH
8593 if (nparts == 3)
8594 {
8595 /* We use only first 12 bytes of TFmode value, but for pushing we
8596 are required to adjust stack as if we were pushing real 16byte
8597 value. */
8598 if (mode == TFmode && !TARGET_64BIT)
8599 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
8600 GEN_INT (-4)));
8601 emit_move_insn (part[0][2], part[1][2]);
8602 }
2b589241 8603 }
26e5b205
JH
8604 else
8605 {
8606 /* In 64bit mode we don't have 32bit push available. In case this is
8607 register, it is OK - we will just use larger counterpart. We also
8608 retype memory - these comes from attempt to avoid REX prefix on
8609 moving of second half of TFmode value. */
8610 if (GET_MODE (part[1][1]) == SImode)
8611 {
8612 if (GET_CODE (part[1][1]) == MEM)
f4ef873c 8613 part[1][1] = adjust_address (part[1][1], DImode, 0);
26e5b205
JH
8614 else if (REG_P (part[1][1]))
8615 part[1][1] = gen_rtx_REG (DImode, REGNO (part[1][1]));
8616 else
8617 abort();
886cbb88
JH
8618 if (GET_MODE (part[1][0]) == SImode)
8619 part[1][0] = part[1][1];
26e5b205
JH
8620 }
8621 }
8622 emit_move_insn (part[0][1], part[1][1]);
8623 emit_move_insn (part[0][0], part[1][0]);
8624 return;
2450a057
JH
8625 }
8626
8627 /* Choose correct order to not overwrite the source before it is copied. */
8628 if ((REG_P (part[0][0])
8629 && REG_P (part[1][1])
8630 && (REGNO (part[0][0]) == REGNO (part[1][1])
26e5b205 8631 || (nparts == 3
2450a057
JH
8632 && REGNO (part[0][0]) == REGNO (part[1][2]))))
8633 || (collisions > 0
8634 && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))))
8635 {
26e5b205 8636 if (nparts == 3)
2450a057 8637 {
26e5b205
JH
8638 operands[2] = part[0][2];
8639 operands[3] = part[0][1];
8640 operands[4] = part[0][0];
8641 operands[5] = part[1][2];
8642 operands[6] = part[1][1];
8643 operands[7] = part[1][0];
2450a057
JH
8644 }
8645 else
8646 {
26e5b205
JH
8647 operands[2] = part[0][1];
8648 operands[3] = part[0][0];
8649 operands[5] = part[1][1];
8650 operands[6] = part[1][0];
2450a057
JH
8651 }
8652 }
8653 else
8654 {
26e5b205 8655 if (nparts == 3)
2450a057 8656 {
26e5b205
JH
8657 operands[2] = part[0][0];
8658 operands[3] = part[0][1];
8659 operands[4] = part[0][2];
8660 operands[5] = part[1][0];
8661 operands[6] = part[1][1];
8662 operands[7] = part[1][2];
2450a057
JH
8663 }
8664 else
8665 {
26e5b205
JH
8666 operands[2] = part[0][0];
8667 operands[3] = part[0][1];
8668 operands[5] = part[1][0];
8669 operands[6] = part[1][1];
e075ae69
RH
8670 }
8671 }
26e5b205
JH
8672 emit_move_insn (operands[2], operands[5]);
8673 emit_move_insn (operands[3], operands[6]);
8674 if (nparts == 3)
8675 emit_move_insn (operands[4], operands[7]);
32b5b1aa 8676
26e5b205 8677 return;
32b5b1aa 8678}
32b5b1aa 8679
e075ae69
RH
8680void
8681ix86_split_ashldi (operands, scratch)
8682 rtx *operands, scratch;
32b5b1aa 8683{
e075ae69
RH
8684 rtx low[2], high[2];
8685 int count;
b985a30f 8686
e075ae69
RH
8687 if (GET_CODE (operands[2]) == CONST_INT)
8688 {
8689 split_di (operands, 2, low, high);
8690 count = INTVAL (operands[2]) & 63;
32b5b1aa 8691
e075ae69
RH
8692 if (count >= 32)
8693 {
8694 emit_move_insn (high[0], low[1]);
8695 emit_move_insn (low[0], const0_rtx);
b985a30f 8696
e075ae69
RH
8697 if (count > 32)
8698 emit_insn (gen_ashlsi3 (high[0], high[0], GEN_INT (count - 32)));
8699 }
8700 else
8701 {
8702 if (!rtx_equal_p (operands[0], operands[1]))
8703 emit_move_insn (operands[0], operands[1]);
8704 emit_insn (gen_x86_shld_1 (high[0], low[0], GEN_INT (count)));
8705 emit_insn (gen_ashlsi3 (low[0], low[0], GEN_INT (count)));
8706 }
8707 }
8708 else
8709 {
8710 if (!rtx_equal_p (operands[0], operands[1]))
8711 emit_move_insn (operands[0], operands[1]);
b985a30f 8712
e075ae69 8713 split_di (operands, 1, low, high);
b985a30f 8714
e075ae69
RH
8715 emit_insn (gen_x86_shld_1 (high[0], low[0], operands[2]));
8716 emit_insn (gen_ashlsi3 (low[0], low[0], operands[2]));
32b5b1aa 8717
fe577e58 8718 if (TARGET_CMOVE && (! no_new_pseudos || scratch))
e075ae69 8719 {
fe577e58 8720 if (! no_new_pseudos)
e075ae69
RH
8721 scratch = force_reg (SImode, const0_rtx);
8722 else
8723 emit_move_insn (scratch, const0_rtx);
8724
8725 emit_insn (gen_x86_shift_adj_1 (high[0], low[0], operands[2],
8726 scratch));
8727 }
8728 else
8729 emit_insn (gen_x86_shift_adj_2 (high[0], low[0], operands[2]));
8730 }
e9a25f70 8731}
32b5b1aa 8732
e075ae69
RH
8733void
8734ix86_split_ashrdi (operands, scratch)
8735 rtx *operands, scratch;
32b5b1aa 8736{
e075ae69
RH
8737 rtx low[2], high[2];
8738 int count;
32b5b1aa 8739
e075ae69
RH
8740 if (GET_CODE (operands[2]) == CONST_INT)
8741 {
8742 split_di (operands, 2, low, high);
8743 count = INTVAL (operands[2]) & 63;
32b5b1aa 8744
e075ae69
RH
8745 if (count >= 32)
8746 {
8747 emit_move_insn (low[0], high[1]);
32b5b1aa 8748
e075ae69
RH
8749 if (! reload_completed)
8750 emit_insn (gen_ashrsi3 (high[0], low[0], GEN_INT (31)));
8751 else
8752 {
8753 emit_move_insn (high[0], low[0]);
8754 emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (31)));
8755 }
8756
8757 if (count > 32)
8758 emit_insn (gen_ashrsi3 (low[0], low[0], GEN_INT (count - 32)));
8759 }
8760 else
8761 {
8762 if (!rtx_equal_p (operands[0], operands[1]))
8763 emit_move_insn (operands[0], operands[1]);
8764 emit_insn (gen_x86_shrd_1 (low[0], high[0], GEN_INT (count)));
8765 emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (count)));
8766 }
8767 }
8768 else
32b5b1aa 8769 {
e075ae69
RH
8770 if (!rtx_equal_p (operands[0], operands[1]))
8771 emit_move_insn (operands[0], operands[1]);
8772
8773 split_di (operands, 1, low, high);
8774
8775 emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2]));
8776 emit_insn (gen_ashrsi3 (high[0], high[0], operands[2]));
8777
fe577e58 8778 if (TARGET_CMOVE && (! no_new_pseudos || scratch))
e075ae69 8779 {
fe577e58 8780 if (! no_new_pseudos)
e075ae69
RH
8781 scratch = gen_reg_rtx (SImode);
8782 emit_move_insn (scratch, high[0]);
8783 emit_insn (gen_ashrsi3 (scratch, scratch, GEN_INT (31)));
8784 emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
8785 scratch));
8786 }
8787 else
8788 emit_insn (gen_x86_shift_adj_3 (low[0], high[0], operands[2]));
32b5b1aa 8789 }
e075ae69 8790}
32b5b1aa 8791
e075ae69
RH
8792void
8793ix86_split_lshrdi (operands, scratch)
8794 rtx *operands, scratch;
8795{
8796 rtx low[2], high[2];
8797 int count;
32b5b1aa 8798
e075ae69 8799 if (GET_CODE (operands[2]) == CONST_INT)
32b5b1aa 8800 {
e075ae69
RH
8801 split_di (operands, 2, low, high);
8802 count = INTVAL (operands[2]) & 63;
8803
8804 if (count >= 32)
c7271385 8805 {
e075ae69
RH
8806 emit_move_insn (low[0], high[1]);
8807 emit_move_insn (high[0], const0_rtx);
32b5b1aa 8808
e075ae69
RH
8809 if (count > 32)
8810 emit_insn (gen_lshrsi3 (low[0], low[0], GEN_INT (count - 32)));
8811 }
8812 else
8813 {
8814 if (!rtx_equal_p (operands[0], operands[1]))
8815 emit_move_insn (operands[0], operands[1]);
8816 emit_insn (gen_x86_shrd_1 (low[0], high[0], GEN_INT (count)));
8817 emit_insn (gen_lshrsi3 (high[0], high[0], GEN_INT (count)));
8818 }
32b5b1aa 8819 }
e075ae69
RH
8820 else
8821 {
8822 if (!rtx_equal_p (operands[0], operands[1]))
8823 emit_move_insn (operands[0], operands[1]);
32b5b1aa 8824
e075ae69
RH
8825 split_di (operands, 1, low, high);
8826
8827 emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2]));
8828 emit_insn (gen_lshrsi3 (high[0], high[0], operands[2]));
8829
8830 /* Heh. By reversing the arguments, we can reuse this pattern. */
fe577e58 8831 if (TARGET_CMOVE && (! no_new_pseudos || scratch))
e075ae69 8832 {
fe577e58 8833 if (! no_new_pseudos)
e075ae69
RH
8834 scratch = force_reg (SImode, const0_rtx);
8835 else
8836 emit_move_insn (scratch, const0_rtx);
8837
8838 emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
8839 scratch));
8840 }
8841 else
8842 emit_insn (gen_x86_shift_adj_2 (low[0], high[0], operands[2]));
8843 }
32b5b1aa 8844}
3f803cd9 8845
0407c02b 8846/* Helper function for the string operations below. Dest VARIABLE whether
0945b39d
JH
8847 it is aligned to VALUE bytes. If true, jump to the label. */
8848static rtx
8849ix86_expand_aligntest (variable, value)
8850 rtx variable;
8851 int value;
8852{
8853 rtx label = gen_label_rtx ();
8854 rtx tmpcount = gen_reg_rtx (GET_MODE (variable));
8855 if (GET_MODE (variable) == DImode)
8856 emit_insn (gen_anddi3 (tmpcount, variable, GEN_INT (value)));
8857 else
8858 emit_insn (gen_andsi3 (tmpcount, variable, GEN_INT (value)));
8859 emit_cmp_and_jump_insns (tmpcount, const0_rtx, EQ, 0, GET_MODE (variable),
d43e0b7d 8860 1, label);
0945b39d
JH
8861 return label;
8862}
8863
8864/* Adjust COUNTER by the VALUE. */
8865static void
8866ix86_adjust_counter (countreg, value)
8867 rtx countreg;
8868 HOST_WIDE_INT value;
8869{
8870 if (GET_MODE (countreg) == DImode)
8871 emit_insn (gen_adddi3 (countreg, countreg, GEN_INT (-value)));
8872 else
8873 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-value)));
8874}
8875
8876/* Zero extend possibly SImode EXP to Pmode register. */
d24b3457 8877rtx
0945b39d
JH
8878ix86_zero_extend_to_Pmode (exp)
8879 rtx exp;
8880{
8881 rtx r;
8882 if (GET_MODE (exp) == VOIDmode)
8883 return force_reg (Pmode, exp);
8884 if (GET_MODE (exp) == Pmode)
8885 return copy_to_mode_reg (Pmode, exp);
8886 r = gen_reg_rtx (Pmode);
8887 emit_insn (gen_zero_extendsidi2 (r, exp));
8888 return r;
8889}
8890
8891/* Expand string move (memcpy) operation. Use i386 string operations when
8892 profitable. expand_clrstr contains similar code. */
8893int
8894ix86_expand_movstr (dst, src, count_exp, align_exp)
8895 rtx dst, src, count_exp, align_exp;
8896{
8897 rtx srcreg, destreg, countreg;
8898 enum machine_mode counter_mode;
8899 HOST_WIDE_INT align = 0;
8900 unsigned HOST_WIDE_INT count = 0;
8901 rtx insns;
8902
8903 start_sequence ();
8904
8905 if (GET_CODE (align_exp) == CONST_INT)
8906 align = INTVAL (align_exp);
8907
5519a4f9 8908 /* This simple hack avoids all inlining code and simplifies code below. */
0945b39d
JH
8909 if (!TARGET_ALIGN_STRINGOPS)
8910 align = 64;
8911
8912 if (GET_CODE (count_exp) == CONST_INT)
8913 count = INTVAL (count_exp);
8914
8915 /* Figure out proper mode for counter. For 32bits it is always SImode,
8916 for 64bits use SImode when possible, otherwise DImode.
8917 Set count to number of bytes copied when known at compile time. */
8918 if (!TARGET_64BIT || GET_MODE (count_exp) == SImode
8919 || x86_64_zero_extended_value (count_exp))
8920 counter_mode = SImode;
8921 else
8922 counter_mode = DImode;
8923
8924 if (counter_mode != SImode && counter_mode != DImode)
8925 abort ();
8926
8927 destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
8928 srcreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
8929
8930 emit_insn (gen_cld ());
8931
8932 /* When optimizing for size emit simple rep ; movsb instruction for
8933 counts not divisible by 4. */
8934
8935 if ((!optimize || optimize_size) && (count == 0 || (count & 0x03)))
8936 {
8937 countreg = ix86_zero_extend_to_Pmode (count_exp);
8938 if (TARGET_64BIT)
8939 emit_insn (gen_rep_movqi_rex64 (destreg, srcreg, countreg,
8940 destreg, srcreg, countreg));
8941 else
8942 emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
8943 destreg, srcreg, countreg));
8944 }
8945
8946 /* For constant aligned (or small unaligned) copies use rep movsl
8947 followed by code copying the rest. For PentiumPro ensure 8 byte
8948 alignment to allow rep movsl acceleration. */
8949
8950 else if (count != 0
8951 && (align >= 8
8952 || (!TARGET_PENTIUMPRO && !TARGET_64BIT && align >= 4)
8953 || optimize_size || count < (unsigned int)64))
8954 {
8955 int size = TARGET_64BIT && !optimize_size ? 8 : 4;
8956 if (count & ~(size - 1))
8957 {
8958 countreg = copy_to_mode_reg (counter_mode,
8959 GEN_INT ((count >> (size == 4 ? 2 : 3))
8960 & (TARGET_64BIT ? -1 : 0x3fffffff)));
8961 countreg = ix86_zero_extend_to_Pmode (countreg);
8962 if (size == 4)
8963 {
8964 if (TARGET_64BIT)
8965 emit_insn (gen_rep_movsi_rex64 (destreg, srcreg, countreg,
8966 destreg, srcreg, countreg));
8967 else
8968 emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
8969 destreg, srcreg, countreg));
8970 }
8971 else
8972 emit_insn (gen_rep_movdi_rex64 (destreg, srcreg, countreg,
8973 destreg, srcreg, countreg));
8974 }
8975 if (size == 8 && (count & 0x04))
8976 emit_insn (gen_strmovsi (destreg, srcreg));
8977 if (count & 0x02)
8978 emit_insn (gen_strmovhi (destreg, srcreg));
8979 if (count & 0x01)
8980 emit_insn (gen_strmovqi (destreg, srcreg));
8981 }
8982 /* The generic code based on the glibc implementation:
8983 - align destination to 4 bytes (8 byte alignment is used for PentiumPro
8984 allowing accelerated copying there)
8985 - copy the data using rep movsl
8986 - copy the rest. */
8987 else
8988 {
8989 rtx countreg2;
8990 rtx label = NULL;
8991
8992 /* In case we don't know anything about the alignment, default to
8993 library version, since it is usually equally fast and result in
8994 shorter code. */
8995 if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD)
8996 {
8997 end_sequence ();
8998 return 0;
8999 }
9000
9001 if (TARGET_SINGLE_STRINGOP)
9002 emit_insn (gen_cld ());
9003
9004 countreg2 = gen_reg_rtx (Pmode);
9005 countreg = copy_to_mode_reg (counter_mode, count_exp);
9006
9007 /* We don't use loops to align destination and to copy parts smaller
9008 than 4 bytes, because gcc is able to optimize such code better (in
9009 the case the destination or the count really is aligned, gcc is often
9010 able to predict the branches) and also it is friendlier to the
a4f31c00 9011 hardware branch prediction.
0945b39d
JH
9012
9013 Using loops is benefical for generic case, because we can
9014 handle small counts using the loops. Many CPUs (such as Athlon)
9015 have large REP prefix setup costs.
9016
9017 This is quite costy. Maybe we can revisit this decision later or
9018 add some customizability to this code. */
9019
9020 if (count == 0
9021 && align < (TARGET_PENTIUMPRO && (count == 0
9022 || count >= (unsigned int)260)
9023 ? 8 : UNITS_PER_WORD))
9024 {
9025 label = gen_label_rtx ();
9026 emit_cmp_and_jump_insns (countreg, GEN_INT (UNITS_PER_WORD - 1),
d43e0b7d 9027 LEU, 0, counter_mode, 1, label);
0945b39d
JH
9028 }
9029 if (align <= 1)
9030 {
9031 rtx label = ix86_expand_aligntest (destreg, 1);
9032 emit_insn (gen_strmovqi (destreg, srcreg));
9033 ix86_adjust_counter (countreg, 1);
9034 emit_label (label);
9035 LABEL_NUSES (label) = 1;
9036 }
9037 if (align <= 2)
9038 {
9039 rtx label = ix86_expand_aligntest (destreg, 2);
9040 emit_insn (gen_strmovhi (destreg, srcreg));
9041 ix86_adjust_counter (countreg, 2);
9042 emit_label (label);
9043 LABEL_NUSES (label) = 1;
9044 }
9045 if (align <= 4
9046 && ((TARGET_PENTIUMPRO && (count == 0
9047 || count >= (unsigned int)260))
9048 || TARGET_64BIT))
9049 {
9050 rtx label = ix86_expand_aligntest (destreg, 4);
9051 emit_insn (gen_strmovsi (destreg, srcreg));
9052 ix86_adjust_counter (countreg, 4);
9053 emit_label (label);
9054 LABEL_NUSES (label) = 1;
9055 }
9056
9057 if (!TARGET_SINGLE_STRINGOP)
9058 emit_insn (gen_cld ());
9059 if (TARGET_64BIT)
9060 {
9061 emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg),
9062 GEN_INT (3)));
9063 emit_insn (gen_rep_movdi_rex64 (destreg, srcreg, countreg2,
9064 destreg, srcreg, countreg2));
9065 }
9066 else
9067 {
9068 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
9069 emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
9070 destreg, srcreg, countreg2));
9071 }
9072
9073 if (label)
9074 {
9075 emit_label (label);
9076 LABEL_NUSES (label) = 1;
9077 }
9078 if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
9079 emit_insn (gen_strmovsi (destreg, srcreg));
9080 if ((align <= 4 || count == 0) && TARGET_64BIT)
9081 {
9082 rtx label = ix86_expand_aligntest (countreg, 4);
9083 emit_insn (gen_strmovsi (destreg, srcreg));
9084 emit_label (label);
9085 LABEL_NUSES (label) = 1;
9086 }
9087 if (align > 2 && count != 0 && (count & 2))
9088 emit_insn (gen_strmovhi (destreg, srcreg));
9089 if (align <= 2 || count == 0)
9090 {
9091 rtx label = ix86_expand_aligntest (countreg, 2);
9092 emit_insn (gen_strmovhi (destreg, srcreg));
9093 emit_label (label);
9094 LABEL_NUSES (label) = 1;
9095 }
9096 if (align > 1 && count != 0 && (count & 1))
9097 emit_insn (gen_strmovqi (destreg, srcreg));
9098 if (align <= 1 || count == 0)
9099 {
9100 rtx label = ix86_expand_aligntest (countreg, 1);
9101 emit_insn (gen_strmovqi (destreg, srcreg));
9102 emit_label (label);
9103 LABEL_NUSES (label) = 1;
9104 }
9105 }
9106
9107 insns = get_insns ();
9108 end_sequence ();
9109
9110 ix86_set_move_mem_attrs (insns, dst, src, destreg, srcreg);
9111 emit_insns (insns);
9112 return 1;
9113}
9114
9115/* Expand string clear operation (bzero). Use i386 string operations when
9116 profitable. expand_movstr contains similar code. */
9117int
9118ix86_expand_clrstr (src, count_exp, align_exp)
9119 rtx src, count_exp, align_exp;
9120{
9121 rtx destreg, zeroreg, countreg;
9122 enum machine_mode counter_mode;
9123 HOST_WIDE_INT align = 0;
9124 unsigned HOST_WIDE_INT count = 0;
9125
9126 if (GET_CODE (align_exp) == CONST_INT)
9127 align = INTVAL (align_exp);
9128
5519a4f9 9129 /* This simple hack avoids all inlining code and simplifies code below. */
0945b39d
JH
9130 if (!TARGET_ALIGN_STRINGOPS)
9131 align = 32;
9132
9133 if (GET_CODE (count_exp) == CONST_INT)
9134 count = INTVAL (count_exp);
9135 /* Figure out proper mode for counter. For 32bits it is always SImode,
9136 for 64bits use SImode when possible, otherwise DImode.
9137 Set count to number of bytes copied when known at compile time. */
9138 if (!TARGET_64BIT || GET_MODE (count_exp) == SImode
9139 || x86_64_zero_extended_value (count_exp))
9140 counter_mode = SImode;
9141 else
9142 counter_mode = DImode;
9143
9144 destreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
9145
9146 emit_insn (gen_cld ());
9147
9148 /* When optimizing for size emit simple rep ; movsb instruction for
9149 counts not divisible by 4. */
9150
9151 if ((!optimize || optimize_size) && (count == 0 || (count & 0x03)))
9152 {
9153 countreg = ix86_zero_extend_to_Pmode (count_exp);
9154 zeroreg = copy_to_mode_reg (QImode, const0_rtx);
9155 if (TARGET_64BIT)
9156 emit_insn (gen_rep_stosqi_rex64 (destreg, countreg, zeroreg,
9157 destreg, countreg));
9158 else
9159 emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
9160 destreg, countreg));
9161 }
9162 else if (count != 0
9163 && (align >= 8
9164 || (!TARGET_PENTIUMPRO && !TARGET_64BIT && align >= 4)
9165 || optimize_size || count < (unsigned int)64))
9166 {
9167 int size = TARGET_64BIT && !optimize_size ? 8 : 4;
9168 zeroreg = copy_to_mode_reg (size == 4 ? SImode : DImode, const0_rtx);
9169 if (count & ~(size - 1))
9170 {
9171 countreg = copy_to_mode_reg (counter_mode,
9172 GEN_INT ((count >> (size == 4 ? 2 : 3))
9173 & (TARGET_64BIT ? -1 : 0x3fffffff)));
9174 countreg = ix86_zero_extend_to_Pmode (countreg);
9175 if (size == 4)
9176 {
9177 if (TARGET_64BIT)
9178 emit_insn (gen_rep_stossi_rex64 (destreg, countreg, zeroreg,
9179 destreg, countreg));
9180 else
9181 emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
9182 destreg, countreg));
9183 }
9184 else
9185 emit_insn (gen_rep_stosdi_rex64 (destreg, countreg, zeroreg,
9186 destreg, countreg));
9187 }
9188 if (size == 8 && (count & 0x04))
9189 emit_insn (gen_strsetsi (destreg,
9190 gen_rtx_SUBREG (SImode, zeroreg, 0)));
9191 if (count & 0x02)
9192 emit_insn (gen_strsethi (destreg,
9193 gen_rtx_SUBREG (HImode, zeroreg, 0)));
9194 if (count & 0x01)
9195 emit_insn (gen_strsetqi (destreg,
9196 gen_rtx_SUBREG (QImode, zeroreg, 0)));
9197 }
9198 else
9199 {
9200 rtx countreg2;
9201 rtx label = NULL;
9202
9203 /* In case we don't know anything about the alignment, default to
9204 library version, since it is usually equally fast and result in
9205 shorter code. */
9206 if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD)
9207 return 0;
9208
9209 if (TARGET_SINGLE_STRINGOP)
9210 emit_insn (gen_cld ());
9211
9212 countreg2 = gen_reg_rtx (Pmode);
9213 countreg = copy_to_mode_reg (counter_mode, count_exp);
9214 zeroreg = copy_to_mode_reg (Pmode, const0_rtx);
9215
9216 if (count == 0
9217 && align < (TARGET_PENTIUMPRO && (count == 0
9218 || count >= (unsigned int)260)
9219 ? 8 : UNITS_PER_WORD))
9220 {
9221 label = gen_label_rtx ();
9222 emit_cmp_and_jump_insns (countreg, GEN_INT (UNITS_PER_WORD - 1),
d43e0b7d 9223 LEU, 0, counter_mode, 1, label);
0945b39d
JH
9224 }
9225 if (align <= 1)
9226 {
9227 rtx label = ix86_expand_aligntest (destreg, 1);
9228 emit_insn (gen_strsetqi (destreg,
9229 gen_rtx_SUBREG (QImode, zeroreg, 0)));
9230 ix86_adjust_counter (countreg, 1);
9231 emit_label (label);
9232 LABEL_NUSES (label) = 1;
9233 }
9234 if (align <= 2)
9235 {
9236 rtx label = ix86_expand_aligntest (destreg, 2);
9237 emit_insn (gen_strsethi (destreg,
9238 gen_rtx_SUBREG (HImode, zeroreg, 0)));
9239 ix86_adjust_counter (countreg, 2);
9240 emit_label (label);
9241 LABEL_NUSES (label) = 1;
9242 }
9243 if (align <= 4 && TARGET_PENTIUMPRO && (count == 0
9244 || count >= (unsigned int)260))
9245 {
9246 rtx label = ix86_expand_aligntest (destreg, 4);
9247 emit_insn (gen_strsetsi (destreg, (TARGET_64BIT
9248 ? gen_rtx_SUBREG (SImode, zeroreg, 0)
9249 : zeroreg)));
9250 ix86_adjust_counter (countreg, 4);
9251 emit_label (label);
9252 LABEL_NUSES (label) = 1;
9253 }
9254
9255 if (!TARGET_SINGLE_STRINGOP)
9256 emit_insn (gen_cld ());
9257 if (TARGET_64BIT)
9258 {
9259 emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg),
9260 GEN_INT (3)));
9261 emit_insn (gen_rep_stosdi_rex64 (destreg, countreg2, zeroreg,
9262 destreg, countreg2));
9263 }
9264 else
9265 {
9266 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
9267 emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
9268 destreg, countreg2));
9269 }
9270
9271 if (label)
9272 {
9273 emit_label (label);
9274 LABEL_NUSES (label) = 1;
9275 }
9276 if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
9277 emit_insn (gen_strsetsi (destreg,
9278 gen_rtx_SUBREG (SImode, zeroreg, 0)));
9279 if (TARGET_64BIT && (align <= 4 || count == 0))
9280 {
9281 rtx label = ix86_expand_aligntest (destreg, 2);
9282 emit_insn (gen_strsetsi (destreg,
9283 gen_rtx_SUBREG (SImode, zeroreg, 0)));
9284 emit_label (label);
9285 LABEL_NUSES (label) = 1;
9286 }
9287 if (align > 2 && count != 0 && (count & 2))
9288 emit_insn (gen_strsethi (destreg,
9289 gen_rtx_SUBREG (HImode, zeroreg, 0)));
9290 if (align <= 2 || count == 0)
9291 {
9292 rtx label = ix86_expand_aligntest (destreg, 2);
9293 emit_insn (gen_strsethi (destreg,
9294 gen_rtx_SUBREG (HImode, zeroreg, 0)));
9295 emit_label (label);
9296 LABEL_NUSES (label) = 1;
9297 }
9298 if (align > 1 && count != 0 && (count & 1))
9299 emit_insn (gen_strsetqi (destreg,
9300 gen_rtx_SUBREG (QImode, zeroreg, 0)));
9301 if (align <= 1 || count == 0)
9302 {
9303 rtx label = ix86_expand_aligntest (destreg, 1);
9304 emit_insn (gen_strsetqi (destreg,
9305 gen_rtx_SUBREG (QImode, zeroreg, 0)));
9306 emit_label (label);
9307 LABEL_NUSES (label) = 1;
9308 }
9309 }
9310 return 1;
9311}
9312/* Expand strlen. */
9313int
9314ix86_expand_strlen (out, src, eoschar, align)
9315 rtx out, src, eoschar, align;
9316{
9317 rtx addr, scratch1, scratch2, scratch3, scratch4;
9318
9319 /* The generic case of strlen expander is long. Avoid it's
9320 expanding unless TARGET_INLINE_ALL_STRINGOPS. */
9321
9322 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
9323 && !TARGET_INLINE_ALL_STRINGOPS
9324 && !optimize_size
9325 && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
9326 return 0;
9327
9328 addr = force_reg (Pmode, XEXP (src, 0));
9329 scratch1 = gen_reg_rtx (Pmode);
9330
9331 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
9332 && !optimize_size)
9333 {
9334 /* Well it seems that some optimizer does not combine a call like
9335 foo(strlen(bar), strlen(bar));
9336 when the move and the subtraction is done here. It does calculate
9337 the length just once when these instructions are done inside of
9338 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
9339 often used and I use one fewer register for the lifetime of
9340 output_strlen_unroll() this is better. */
9341
9342 emit_move_insn (out, addr);
9343
9344 ix86_expand_strlensi_unroll_1 (out, align);
9345
9346 /* strlensi_unroll_1 returns the address of the zero at the end of
9347 the string, like memchr(), so compute the length by subtracting
9348 the start address. */
9349 if (TARGET_64BIT)
9350 emit_insn (gen_subdi3 (out, out, addr));
9351 else
9352 emit_insn (gen_subsi3 (out, out, addr));
9353 }
9354 else
9355 {
9356 scratch2 = gen_reg_rtx (Pmode);
9357 scratch3 = gen_reg_rtx (Pmode);
9358 scratch4 = force_reg (Pmode, constm1_rtx);
9359
9360 emit_move_insn (scratch3, addr);
9361 eoschar = force_reg (QImode, eoschar);
9362
9363 emit_insn (gen_cld ());
9364 if (TARGET_64BIT)
9365 {
9366 emit_insn (gen_strlenqi_rex_1 (scratch1, scratch3, eoschar,
9367 align, scratch4, scratch3));
9368 emit_insn (gen_one_cmpldi2 (scratch2, scratch1));
9369 emit_insn (gen_adddi3 (out, scratch2, constm1_rtx));
9370 }
9371 else
9372 {
9373 emit_insn (gen_strlenqi_1 (scratch1, scratch3, eoschar,
9374 align, scratch4, scratch3));
9375 emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
9376 emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
9377 }
9378 }
9379 return 1;
9380}
9381
e075ae69
RH
9382/* Expand the appropriate insns for doing strlen if not just doing
9383 repnz; scasb
9384
9385 out = result, initialized with the start address
9386 align_rtx = alignment of the address.
9387 scratch = scratch register, initialized with the startaddress when
77ebd435 9388 not aligned, otherwise undefined
3f803cd9
SC
9389
9390 This is just the body. It needs the initialisations mentioned above and
9391 some address computing at the end. These things are done in i386.md. */
9392
0945b39d
JH
9393static void
9394ix86_expand_strlensi_unroll_1 (out, align_rtx)
9395 rtx out, align_rtx;
3f803cd9 9396{
e075ae69
RH
9397 int align;
9398 rtx tmp;
9399 rtx align_2_label = NULL_RTX;
9400 rtx align_3_label = NULL_RTX;
9401 rtx align_4_label = gen_label_rtx ();
9402 rtx end_0_label = gen_label_rtx ();
e075ae69 9403 rtx mem;
e2e52e1b 9404 rtx tmpreg = gen_reg_rtx (SImode);
0945b39d 9405 rtx scratch = gen_reg_rtx (SImode);
e075ae69
RH
9406
9407 align = 0;
9408 if (GET_CODE (align_rtx) == CONST_INT)
9409 align = INTVAL (align_rtx);
3f803cd9 9410
e9a25f70 9411 /* Loop to check 1..3 bytes for null to get an aligned pointer. */
3f803cd9 9412
e9a25f70 9413 /* Is there a known alignment and is it less than 4? */
e075ae69 9414 if (align < 4)
3f803cd9 9415 {
0945b39d
JH
9416 rtx scratch1 = gen_reg_rtx (Pmode);
9417 emit_move_insn (scratch1, out);
e9a25f70 9418 /* Is there a known alignment and is it not 2? */
e075ae69 9419 if (align != 2)
3f803cd9 9420 {
e075ae69
RH
9421 align_3_label = gen_label_rtx (); /* Label when aligned to 3-byte */
9422 align_2_label = gen_label_rtx (); /* Label when aligned to 2-byte */
9423
9424 /* Leave just the 3 lower bits. */
0945b39d 9425 align_rtx = expand_binop (Pmode, and_optab, scratch1, GEN_INT (3),
e075ae69
RH
9426 NULL_RTX, 0, OPTAB_WIDEN);
9427
9076b9c1 9428 emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL,
d43e0b7d 9429 Pmode, 1, align_4_label);
9076b9c1 9430 emit_cmp_and_jump_insns (align_rtx, GEN_INT (2), EQ, NULL,
d43e0b7d 9431 Pmode, 1, align_2_label);
9076b9c1 9432 emit_cmp_and_jump_insns (align_rtx, GEN_INT (2), GTU, NULL,
d43e0b7d 9433 Pmode, 1, align_3_label);
3f803cd9
SC
9434 }
9435 else
9436 {
e9a25f70
JL
9437 /* Since the alignment is 2, we have to check 2 or 0 bytes;
9438 check if is aligned to 4 - byte. */
e9a25f70 9439
0945b39d 9440 align_rtx = expand_binop (Pmode, and_optab, scratch1, GEN_INT (2),
e075ae69
RH
9441 NULL_RTX, 0, OPTAB_WIDEN);
9442
9076b9c1 9443 emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL,
d43e0b7d 9444 Pmode, 1, align_4_label);
3f803cd9
SC
9445 }
9446
e075ae69 9447 mem = gen_rtx_MEM (QImode, out);
e9a25f70 9448
e075ae69 9449 /* Now compare the bytes. */
e9a25f70 9450
0f290768 9451 /* Compare the first n unaligned byte on a byte per byte basis. */
9076b9c1 9452 emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL,
d43e0b7d 9453 QImode, 1, end_0_label);
3f803cd9 9454
0f290768 9455 /* Increment the address. */
0945b39d
JH
9456 if (TARGET_64BIT)
9457 emit_insn (gen_adddi3 (out, out, const1_rtx));
9458 else
9459 emit_insn (gen_addsi3 (out, out, const1_rtx));
e9a25f70 9460
e075ae69
RH
9461 /* Not needed with an alignment of 2 */
9462 if (align != 2)
9463 {
9464 emit_label (align_2_label);
3f803cd9 9465
d43e0b7d
RK
9466 emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, QImode, 1,
9467 end_0_label);
e075ae69 9468
0945b39d
JH
9469 if (TARGET_64BIT)
9470 emit_insn (gen_adddi3 (out, out, const1_rtx));
9471 else
9472 emit_insn (gen_addsi3 (out, out, const1_rtx));
e075ae69
RH
9473
9474 emit_label (align_3_label);
9475 }
9476
d43e0b7d
RK
9477 emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, QImode, 1,
9478 end_0_label);
e075ae69 9479
0945b39d
JH
9480 if (TARGET_64BIT)
9481 emit_insn (gen_adddi3 (out, out, const1_rtx));
9482 else
9483 emit_insn (gen_addsi3 (out, out, const1_rtx));
3f803cd9
SC
9484 }
9485
e075ae69
RH
9486 /* Generate loop to check 4 bytes at a time. It is not a good idea to
9487 align this loop. It gives only huge programs, but does not help to
9488 speed up. */
9489 emit_label (align_4_label);
3f803cd9 9490
e075ae69
RH
9491 mem = gen_rtx_MEM (SImode, out);
9492 emit_move_insn (scratch, mem);
0945b39d
JH
9493 if (TARGET_64BIT)
9494 emit_insn (gen_adddi3 (out, out, GEN_INT (4)));
9495 else
9496 emit_insn (gen_addsi3 (out, out, GEN_INT (4)));
e075ae69 9497
e2e52e1b
JH
9498 /* This formula yields a nonzero result iff one of the bytes is zero.
9499 This saves three branches inside loop and many cycles. */
9500
9501 emit_insn (gen_addsi3 (tmpreg, scratch, GEN_INT (-0x01010101)));
9502 emit_insn (gen_one_cmplsi2 (scratch, scratch));
9503 emit_insn (gen_andsi3 (tmpreg, tmpreg, scratch));
7471a1f0
AO
9504 emit_insn (gen_andsi3 (tmpreg, tmpreg,
9505 GEN_INT (trunc_int_for_mode
9506 (0x80808080, SImode))));
d43e0b7d
RK
9507 emit_cmp_and_jump_insns (tmpreg, const0_rtx, EQ, 0, SImode, 1,
9508 align_4_label);
e2e52e1b
JH
9509
9510 if (TARGET_CMOVE)
9511 {
9512 rtx reg = gen_reg_rtx (SImode);
0945b39d 9513 rtx reg2 = gen_reg_rtx (Pmode);
e2e52e1b
JH
9514 emit_move_insn (reg, tmpreg);
9515 emit_insn (gen_lshrsi3 (reg, reg, GEN_INT (16)));
9516
0f290768 9517 /* If zero is not in the first two bytes, move two bytes forward. */
16189740 9518 emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
e2e52e1b
JH
9519 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
9520 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9521 emit_insn (gen_rtx_SET (VOIDmode, tmpreg,
9522 gen_rtx_IF_THEN_ELSE (SImode, tmp,
77ebd435
AJ
9523 reg,
9524 tmpreg)));
e2e52e1b 9525 /* Emit lea manually to avoid clobbering of flags. */
0945b39d
JH
9526 emit_insn (gen_rtx_SET (SImode, reg2,
9527 gen_rtx_PLUS (Pmode, out, GEN_INT (2))));
e2e52e1b
JH
9528
9529 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
9530 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9531 emit_insn (gen_rtx_SET (VOIDmode, out,
0945b39d 9532 gen_rtx_IF_THEN_ELSE (Pmode, tmp,
a4f31c00
AJ
9533 reg2,
9534 out)));
e2e52e1b
JH
9535
9536 }
9537 else
9538 {
9539 rtx end_2_label = gen_label_rtx ();
9540 /* Is zero in the first two bytes? */
9541
16189740 9542 emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
e2e52e1b
JH
9543 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
9544 tmp = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
9545 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9546 gen_rtx_LABEL_REF (VOIDmode, end_2_label),
9547 pc_rtx);
9548 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9549 JUMP_LABEL (tmp) = end_2_label;
9550
0f290768 9551 /* Not in the first two. Move two bytes forward. */
e2e52e1b 9552 emit_insn (gen_lshrsi3 (tmpreg, tmpreg, GEN_INT (16)));
0945b39d
JH
9553 if (TARGET_64BIT)
9554 emit_insn (gen_adddi3 (out, out, GEN_INT (2)));
9555 else
9556 emit_insn (gen_addsi3 (out, out, GEN_INT (2)));
e2e52e1b
JH
9557
9558 emit_label (end_2_label);
9559
9560 }
9561
0f290768 9562 /* Avoid branch in fixing the byte. */
e2e52e1b 9563 tmpreg = gen_lowpart (QImode, tmpreg);
7e08e190 9564 emit_insn (gen_addqi3_cc (tmpreg, tmpreg, tmpreg));
0945b39d
JH
9565 if (TARGET_64BIT)
9566 emit_insn (gen_subdi3_carry_rex64 (out, out, GEN_INT (3)));
9567 else
9568 emit_insn (gen_subsi3_carry (out, out, GEN_INT (3)));
e075ae69
RH
9569
9570 emit_label (end_0_label);
9571}
9572\f
e075ae69
RH
9573/* Clear stack slot assignments remembered from previous functions.
9574 This is called from INIT_EXPANDERS once before RTL is emitted for each
9575 function. */
9576
36edd3cc
BS
9577static void
9578ix86_init_machine_status (p)
1526a060 9579 struct function *p;
e075ae69 9580{
37b15744
RH
9581 p->machine = (struct machine_function *)
9582 xcalloc (1, sizeof (struct machine_function));
e075ae69
RH
9583}
9584
1526a060
BS
9585/* Mark machine specific bits of P for GC. */
9586static void
9587ix86_mark_machine_status (p)
9588 struct function *p;
9589{
37b15744 9590 struct machine_function *machine = p->machine;
1526a060
BS
9591 enum machine_mode mode;
9592 int n;
9593
37b15744
RH
9594 if (! machine)
9595 return;
9596
1526a060
BS
9597 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
9598 mode = (enum machine_mode) ((int) mode + 1))
9599 for (n = 0; n < MAX_386_STACK_LOCALS; n++)
37b15744
RH
9600 ggc_mark_rtx (machine->stack_locals[(int) mode][n]);
9601}
9602
9603static void
9604ix86_free_machine_status (p)
9605 struct function *p;
9606{
9607 free (p->machine);
9608 p->machine = NULL;
1526a060
BS
9609}
9610
e075ae69
RH
9611/* Return a MEM corresponding to a stack slot with mode MODE.
9612 Allocate a new slot if necessary.
9613
9614 The RTL for a function can have several slots available: N is
9615 which slot to use. */
9616
9617rtx
9618assign_386_stack_local (mode, n)
9619 enum machine_mode mode;
9620 int n;
9621{
9622 if (n < 0 || n >= MAX_386_STACK_LOCALS)
9623 abort ();
9624
9625 if (ix86_stack_locals[(int) mode][n] == NULL_RTX)
9626 ix86_stack_locals[(int) mode][n]
9627 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
9628
9629 return ix86_stack_locals[(int) mode][n];
9630}
9631\f
9632/* Calculate the length of the memory address in the instruction
9633 encoding. Does not include the one-byte modrm, opcode, or prefix. */
9634
9635static int
9636memory_address_length (addr)
9637 rtx addr;
9638{
9639 struct ix86_address parts;
9640 rtx base, index, disp;
9641 int len;
9642
9643 if (GET_CODE (addr) == PRE_DEC
0d7d98ee
JH
9644 || GET_CODE (addr) == POST_INC
9645 || GET_CODE (addr) == PRE_MODIFY
9646 || GET_CODE (addr) == POST_MODIFY)
e075ae69 9647 return 0;
3f803cd9 9648
e075ae69
RH
9649 if (! ix86_decompose_address (addr, &parts))
9650 abort ();
3f803cd9 9651
e075ae69
RH
9652 base = parts.base;
9653 index = parts.index;
9654 disp = parts.disp;
9655 len = 0;
3f803cd9 9656
e075ae69
RH
9657 /* Register Indirect. */
9658 if (base && !index && !disp)
9659 {
9660 /* Special cases: ebp and esp need the two-byte modrm form. */
9661 if (addr == stack_pointer_rtx
9662 || addr == arg_pointer_rtx
564d80f4
JH
9663 || addr == frame_pointer_rtx
9664 || addr == hard_frame_pointer_rtx)
e075ae69 9665 len = 1;
3f803cd9 9666 }
e9a25f70 9667
e075ae69
RH
9668 /* Direct Addressing. */
9669 else if (disp && !base && !index)
9670 len = 4;
9671
3f803cd9
SC
9672 else
9673 {
e075ae69
RH
9674 /* Find the length of the displacement constant. */
9675 if (disp)
9676 {
9677 if (GET_CODE (disp) == CONST_INT
9678 && CONST_OK_FOR_LETTER_P (INTVAL (disp), 'K'))
9679 len = 1;
9680 else
9681 len = 4;
9682 }
3f803cd9 9683
e075ae69
RH
9684 /* An index requires the two-byte modrm form. */
9685 if (index)
9686 len += 1;
3f803cd9
SC
9687 }
9688
e075ae69
RH
9689 return len;
9690}
79325812 9691
6ef67412
JH
9692/* Compute default value for "length_immediate" attribute. When SHORTFORM is set
9693 expect that insn have 8bit immediate alternative. */
e075ae69 9694int
6ef67412 9695ix86_attr_length_immediate_default (insn, shortform)
e075ae69 9696 rtx insn;
6ef67412 9697 int shortform;
e075ae69 9698{
6ef67412
JH
9699 int len = 0;
9700 int i;
6c698a6d 9701 extract_insn_cached (insn);
6ef67412
JH
9702 for (i = recog_data.n_operands - 1; i >= 0; --i)
9703 if (CONSTANT_P (recog_data.operand[i]))
3071fab5 9704 {
6ef67412 9705 if (len)
3071fab5 9706 abort ();
6ef67412
JH
9707 if (shortform
9708 && GET_CODE (recog_data.operand[i]) == CONST_INT
9709 && CONST_OK_FOR_LETTER_P (INTVAL (recog_data.operand[i]), 'K'))
9710 len = 1;
9711 else
9712 {
9713 switch (get_attr_mode (insn))
9714 {
9715 case MODE_QI:
9716 len+=1;
9717 break;
9718 case MODE_HI:
9719 len+=2;
9720 break;
9721 case MODE_SI:
9722 len+=4;
9723 break;
14f73b5a
JH
9724 /* Immediates for DImode instructions are encoded as 32bit sign extended values. */
9725 case MODE_DI:
9726 len+=4;
9727 break;
6ef67412 9728 default:
c725bd79 9729 fatal_insn ("unknown insn mode", insn);
6ef67412
JH
9730 }
9731 }
3071fab5 9732 }
6ef67412
JH
9733 return len;
9734}
9735/* Compute default value for "length_address" attribute. */
9736int
9737ix86_attr_length_address_default (insn)
9738 rtx insn;
9739{
9740 int i;
6c698a6d 9741 extract_insn_cached (insn);
1ccbefce
RH
9742 for (i = recog_data.n_operands - 1; i >= 0; --i)
9743 if (GET_CODE (recog_data.operand[i]) == MEM)
e075ae69 9744 {
6ef67412 9745 return memory_address_length (XEXP (recog_data.operand[i], 0));
e075ae69
RH
9746 break;
9747 }
6ef67412 9748 return 0;
3f803cd9 9749}
e075ae69
RH
9750\f
9751/* Return the maximum number of instructions a cpu can issue. */
b657fc39 9752
c237e94a 9753static int
e075ae69 9754ix86_issue_rate ()
b657fc39 9755{
e075ae69 9756 switch (ix86_cpu)
b657fc39 9757 {
e075ae69
RH
9758 case PROCESSOR_PENTIUM:
9759 case PROCESSOR_K6:
9760 return 2;
79325812 9761
e075ae69 9762 case PROCESSOR_PENTIUMPRO:
b4e89e2d
JH
9763 case PROCESSOR_PENTIUM4:
9764 case PROCESSOR_ATHLON:
e075ae69 9765 return 3;
b657fc39 9766
b657fc39 9767 default:
e075ae69 9768 return 1;
b657fc39 9769 }
b657fc39
L
9770}
9771
e075ae69
RH
9772/* A subroutine of ix86_adjust_cost -- return true iff INSN reads flags set
9773 by DEP_INSN and nothing set by DEP_INSN. */
b657fc39 9774
e075ae69
RH
9775static int
9776ix86_flags_dependant (insn, dep_insn, insn_type)
9777 rtx insn, dep_insn;
9778 enum attr_type insn_type;
9779{
9780 rtx set, set2;
b657fc39 9781
e075ae69
RH
9782 /* Simplify the test for uninteresting insns. */
9783 if (insn_type != TYPE_SETCC
9784 && insn_type != TYPE_ICMOV
9785 && insn_type != TYPE_FCMOV
9786 && insn_type != TYPE_IBR)
9787 return 0;
b657fc39 9788
e075ae69
RH
9789 if ((set = single_set (dep_insn)) != 0)
9790 {
9791 set = SET_DEST (set);
9792 set2 = NULL_RTX;
9793 }
9794 else if (GET_CODE (PATTERN (dep_insn)) == PARALLEL
9795 && XVECLEN (PATTERN (dep_insn), 0) == 2
9796 && GET_CODE (XVECEXP (PATTERN (dep_insn), 0, 0)) == SET
9797 && GET_CODE (XVECEXP (PATTERN (dep_insn), 0, 1)) == SET)
9798 {
9799 set = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
9800 set2 = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
9801 }
78a0d70c
ZW
9802 else
9803 return 0;
b657fc39 9804
78a0d70c
ZW
9805 if (GET_CODE (set) != REG || REGNO (set) != FLAGS_REG)
9806 return 0;
b657fc39 9807
f5143c46 9808 /* This test is true if the dependent insn reads the flags but
78a0d70c
ZW
9809 not any other potentially set register. */
9810 if (!reg_overlap_mentioned_p (set, PATTERN (insn)))
9811 return 0;
9812
9813 if (set2 && reg_overlap_mentioned_p (set2, PATTERN (insn)))
9814 return 0;
9815
9816 return 1;
e075ae69 9817}
b657fc39 9818
e075ae69
RH
9819/* A subroutine of ix86_adjust_cost -- return true iff INSN has a memory
9820 address with operands set by DEP_INSN. */
9821
9822static int
9823ix86_agi_dependant (insn, dep_insn, insn_type)
9824 rtx insn, dep_insn;
9825 enum attr_type insn_type;
9826{
9827 rtx addr;
9828
6ad48e84
JH
9829 if (insn_type == TYPE_LEA
9830 && TARGET_PENTIUM)
5fbdde42
RH
9831 {
9832 addr = PATTERN (insn);
9833 if (GET_CODE (addr) == SET)
9834 ;
9835 else if (GET_CODE (addr) == PARALLEL
9836 && GET_CODE (XVECEXP (addr, 0, 0)) == SET)
9837 addr = XVECEXP (addr, 0, 0);
9838 else
9839 abort ();
9840 addr = SET_SRC (addr);
9841 }
e075ae69
RH
9842 else
9843 {
9844 int i;
6c698a6d 9845 extract_insn_cached (insn);
1ccbefce
RH
9846 for (i = recog_data.n_operands - 1; i >= 0; --i)
9847 if (GET_CODE (recog_data.operand[i]) == MEM)
e075ae69 9848 {
1ccbefce 9849 addr = XEXP (recog_data.operand[i], 0);
e075ae69
RH
9850 goto found;
9851 }
9852 return 0;
9853 found:;
b657fc39
L
9854 }
9855
e075ae69 9856 return modified_in_p (addr, dep_insn);
b657fc39 9857}
a269a03c 9858
c237e94a 9859static int
e075ae69 9860ix86_adjust_cost (insn, link, dep_insn, cost)
a269a03c
JC
9861 rtx insn, link, dep_insn;
9862 int cost;
9863{
e075ae69 9864 enum attr_type insn_type, dep_insn_type;
6ad48e84 9865 enum attr_memory memory, dep_memory;
e075ae69 9866 rtx set, set2;
9b00189f 9867 int dep_insn_code_number;
a269a03c 9868
309ada50 9869 /* Anti and output depenancies have zero cost on all CPUs. */
e075ae69 9870 if (REG_NOTE_KIND (link) != 0)
309ada50 9871 return 0;
a269a03c 9872
9b00189f
JH
9873 dep_insn_code_number = recog_memoized (dep_insn);
9874
e075ae69 9875 /* If we can't recognize the insns, we can't really do anything. */
9b00189f 9876 if (dep_insn_code_number < 0 || recog_memoized (insn) < 0)
e075ae69 9877 return cost;
a269a03c 9878
1c71e60e
JH
9879 insn_type = get_attr_type (insn);
9880 dep_insn_type = get_attr_type (dep_insn);
9b00189f 9881
a269a03c
JC
9882 switch (ix86_cpu)
9883 {
9884 case PROCESSOR_PENTIUM:
e075ae69
RH
9885 /* Address Generation Interlock adds a cycle of latency. */
9886 if (ix86_agi_dependant (insn, dep_insn, insn_type))
9887 cost += 1;
9888
9889 /* ??? Compares pair with jump/setcc. */
9890 if (ix86_flags_dependant (insn, dep_insn, insn_type))
9891 cost = 0;
9892
9893 /* Floating point stores require value to be ready one cycle ealier. */
0f290768 9894 if (insn_type == TYPE_FMOV
e075ae69
RH
9895 && get_attr_memory (insn) == MEMORY_STORE
9896 && !ix86_agi_dependant (insn, dep_insn, insn_type))
9897 cost += 1;
9898 break;
a269a03c 9899
e075ae69 9900 case PROCESSOR_PENTIUMPRO:
6ad48e84
JH
9901 memory = get_attr_memory (insn);
9902 dep_memory = get_attr_memory (dep_insn);
9903
0f290768 9904 /* Since we can't represent delayed latencies of load+operation,
e075ae69
RH
9905 increase the cost here for non-imov insns. */
9906 if (dep_insn_type != TYPE_IMOV
6ad48e84
JH
9907 && dep_insn_type != TYPE_FMOV
9908 && (dep_memory == MEMORY_LOAD || dep_memory == MEMORY_BOTH))
e075ae69
RH
9909 cost += 1;
9910
9911 /* INT->FP conversion is expensive. */
9912 if (get_attr_fp_int_src (dep_insn))
9913 cost += 5;
9914
9915 /* There is one cycle extra latency between an FP op and a store. */
9916 if (insn_type == TYPE_FMOV
9917 && (set = single_set (dep_insn)) != NULL_RTX
9918 && (set2 = single_set (insn)) != NULL_RTX
9919 && rtx_equal_p (SET_DEST (set), SET_SRC (set2))
9920 && GET_CODE (SET_DEST (set2)) == MEM)
9921 cost += 1;
6ad48e84
JH
9922
9923 /* Show ability of reorder buffer to hide latency of load by executing
9924 in parallel with previous instruction in case
9925 previous instruction is not needed to compute the address. */
9926 if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
9927 && !ix86_agi_dependant (insn, dep_insn, insn_type))
9928 {
9929 /* Claim moves to take one cycle, as core can issue one load
9930 at time and the next load can start cycle later. */
9931 if (dep_insn_type == TYPE_IMOV
9932 || dep_insn_type == TYPE_FMOV)
9933 cost = 1;
9934 else if (cost > 1)
9935 cost--;
9936 }
e075ae69 9937 break;
a269a03c 9938
e075ae69 9939 case PROCESSOR_K6:
6ad48e84
JH
9940 memory = get_attr_memory (insn);
9941 dep_memory = get_attr_memory (dep_insn);
e075ae69
RH
9942 /* The esp dependency is resolved before the instruction is really
9943 finished. */
9944 if ((insn_type == TYPE_PUSH || insn_type == TYPE_POP)
9945 && (dep_insn_type == TYPE_PUSH || dep_insn_type == TYPE_POP))
9946 return 1;
a269a03c 9947
0f290768 9948 /* Since we can't represent delayed latencies of load+operation,
e075ae69 9949 increase the cost here for non-imov insns. */
6ad48e84 9950 if (dep_memory == MEMORY_LOAD || dep_memory == MEMORY_BOTH)
e075ae69
RH
9951 cost += (dep_insn_type != TYPE_IMOV) ? 2 : 1;
9952
9953 /* INT->FP conversion is expensive. */
9954 if (get_attr_fp_int_src (dep_insn))
9955 cost += 5;
6ad48e84
JH
9956
9957 /* Show ability of reorder buffer to hide latency of load by executing
9958 in parallel with previous instruction in case
9959 previous instruction is not needed to compute the address. */
9960 if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
9961 && !ix86_agi_dependant (insn, dep_insn, insn_type))
9962 {
9963 /* Claim moves to take one cycle, as core can issue one load
9964 at time and the next load can start cycle later. */
9965 if (dep_insn_type == TYPE_IMOV
9966 || dep_insn_type == TYPE_FMOV)
9967 cost = 1;
9968 else if (cost > 2)
9969 cost -= 2;
9970 else
9971 cost = 1;
9972 }
a14003ee 9973 break;
e075ae69 9974
309ada50 9975 case PROCESSOR_ATHLON:
6ad48e84
JH
9976 memory = get_attr_memory (insn);
9977 dep_memory = get_attr_memory (dep_insn);
9978
9979 if (dep_memory == MEMORY_LOAD || dep_memory == MEMORY_BOTH)
0b5107cf
JH
9980 {
9981 if (dep_insn_type == TYPE_IMOV || dep_insn_type == TYPE_FMOV)
9982 cost += 2;
9983 else
9984 cost += 3;
9985 }
6ad48e84
JH
9986 /* Show ability of reorder buffer to hide latency of load by executing
9987 in parallel with previous instruction in case
9988 previous instruction is not needed to compute the address. */
9989 if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
9990 && !ix86_agi_dependant (insn, dep_insn, insn_type))
9991 {
9992 /* Claim moves to take one cycle, as core can issue one load
9993 at time and the next load can start cycle later. */
9994 if (dep_insn_type == TYPE_IMOV
9995 || dep_insn_type == TYPE_FMOV)
9996 cost = 0;
9997 else if (cost >= 3)
9998 cost -= 3;
9999 else
10000 cost = 0;
10001 }
309ada50 10002
a269a03c 10003 default:
a269a03c
JC
10004 break;
10005 }
10006
10007 return cost;
10008}
0a726ef1 10009
e075ae69
RH
10010static union
10011{
10012 struct ppro_sched_data
10013 {
10014 rtx decode[3];
10015 int issued_this_cycle;
10016 } ppro;
10017} ix86_sched_data;
0a726ef1 10018
e075ae69
RH
10019static int
10020ix86_safe_length (insn)
10021 rtx insn;
10022{
10023 if (recog_memoized (insn) >= 0)
10024 return get_attr_length(insn);
10025 else
10026 return 128;
10027}
0a726ef1 10028
e075ae69
RH
10029static int
10030ix86_safe_length_prefix (insn)
10031 rtx insn;
10032{
10033 if (recog_memoized (insn) >= 0)
10034 return get_attr_length(insn);
10035 else
10036 return 0;
10037}
10038
10039static enum attr_memory
10040ix86_safe_memory (insn)
10041 rtx insn;
10042{
10043 if (recog_memoized (insn) >= 0)
10044 return get_attr_memory(insn);
10045 else
10046 return MEMORY_UNKNOWN;
10047}
0a726ef1 10048
e075ae69
RH
10049static enum attr_pent_pair
10050ix86_safe_pent_pair (insn)
10051 rtx insn;
10052{
10053 if (recog_memoized (insn) >= 0)
10054 return get_attr_pent_pair(insn);
10055 else
10056 return PENT_PAIR_NP;
10057}
0a726ef1 10058
e075ae69
RH
10059static enum attr_ppro_uops
10060ix86_safe_ppro_uops (insn)
10061 rtx insn;
10062{
10063 if (recog_memoized (insn) >= 0)
10064 return get_attr_ppro_uops (insn);
10065 else
10066 return PPRO_UOPS_MANY;
10067}
0a726ef1 10068
e075ae69
RH
10069static void
10070ix86_dump_ppro_packet (dump)
10071 FILE *dump;
0a726ef1 10072{
e075ae69 10073 if (ix86_sched_data.ppro.decode[0])
0a726ef1 10074 {
e075ae69
RH
10075 fprintf (dump, "PPRO packet: %d",
10076 INSN_UID (ix86_sched_data.ppro.decode[0]));
10077 if (ix86_sched_data.ppro.decode[1])
10078 fprintf (dump, " %d", INSN_UID (ix86_sched_data.ppro.decode[1]));
10079 if (ix86_sched_data.ppro.decode[2])
10080 fprintf (dump, " %d", INSN_UID (ix86_sched_data.ppro.decode[2]));
10081 fputc ('\n', dump);
10082 }
10083}
0a726ef1 10084
e075ae69 10085/* We're beginning a new block. Initialize data structures as necessary. */
0a726ef1 10086
c237e94a
ZW
10087static void
10088ix86_sched_init (dump, sched_verbose, veclen)
e075ae69
RH
10089 FILE *dump ATTRIBUTE_UNUSED;
10090 int sched_verbose ATTRIBUTE_UNUSED;
c237e94a 10091 int veclen ATTRIBUTE_UNUSED;
e075ae69
RH
10092{
10093 memset (&ix86_sched_data, 0, sizeof (ix86_sched_data));
10094}
10095
10096/* Shift INSN to SLOT, and shift everything else down. */
10097
10098static void
10099ix86_reorder_insn (insnp, slot)
10100 rtx *insnp, *slot;
10101{
10102 if (insnp != slot)
10103 {
10104 rtx insn = *insnp;
0f290768 10105 do
e075ae69
RH
10106 insnp[0] = insnp[1];
10107 while (++insnp != slot);
10108 *insnp = insn;
0a726ef1 10109 }
e075ae69
RH
10110}
10111
10112/* Find an instruction with given pairability and minimal amount of cycles
10113 lost by the fact that the CPU waits for both pipelines to finish before
10114 reading next instructions. Also take care that both instructions together
10115 can not exceed 7 bytes. */
10116
10117static rtx *
10118ix86_pent_find_pair (e_ready, ready, type, first)
10119 rtx *e_ready;
10120 rtx *ready;
10121 enum attr_pent_pair type;
10122 rtx first;
10123{
10124 int mincycles, cycles;
10125 enum attr_pent_pair tmp;
10126 enum attr_memory memory;
10127 rtx *insnp, *bestinsnp = NULL;
0a726ef1 10128
e075ae69
RH
10129 if (ix86_safe_length (first) > 7 + ix86_safe_length_prefix (first))
10130 return NULL;
0a726ef1 10131
e075ae69
RH
10132 memory = ix86_safe_memory (first);
10133 cycles = result_ready_cost (first);
10134 mincycles = INT_MAX;
10135
10136 for (insnp = e_ready; insnp >= ready && mincycles; --insnp)
10137 if ((tmp = ix86_safe_pent_pair (*insnp)) == type
10138 && ix86_safe_length (*insnp) <= 7 + ix86_safe_length_prefix (*insnp))
6ec6d558 10139 {
e075ae69
RH
10140 enum attr_memory second_memory;
10141 int secondcycles, currentcycles;
10142
10143 second_memory = ix86_safe_memory (*insnp);
10144 secondcycles = result_ready_cost (*insnp);
10145 currentcycles = abs (cycles - secondcycles);
10146
10147 if (secondcycles >= 1 && cycles >= 1)
6ec6d558 10148 {
e075ae69
RH
10149 /* Two read/modify/write instructions together takes two
10150 cycles longer. */
10151 if (memory == MEMORY_BOTH && second_memory == MEMORY_BOTH)
10152 currentcycles += 2;
0f290768 10153
e075ae69
RH
10154 /* Read modify/write instruction followed by read/modify
10155 takes one cycle longer. */
10156 if (memory == MEMORY_BOTH && second_memory == MEMORY_LOAD
10157 && tmp != PENT_PAIR_UV
10158 && ix86_safe_pent_pair (first) != PENT_PAIR_UV)
10159 currentcycles += 1;
6ec6d558 10160 }
e075ae69
RH
10161 if (currentcycles < mincycles)
10162 bestinsnp = insnp, mincycles = currentcycles;
6ec6d558 10163 }
0a726ef1 10164
e075ae69
RH
10165 return bestinsnp;
10166}
10167
78a0d70c 10168/* Subroutines of ix86_sched_reorder. */
e075ae69 10169
c6991660 10170static void
78a0d70c 10171ix86_sched_reorder_pentium (ready, e_ready)
e075ae69 10172 rtx *ready;
78a0d70c 10173 rtx *e_ready;
e075ae69 10174{
78a0d70c 10175 enum attr_pent_pair pair1, pair2;
e075ae69 10176 rtx *insnp;
e075ae69 10177
78a0d70c
ZW
10178 /* This wouldn't be necessary if Haifa knew that static insn ordering
10179 is important to which pipe an insn is issued to. So we have to make
10180 some minor rearrangements. */
e075ae69 10181
78a0d70c
ZW
10182 pair1 = ix86_safe_pent_pair (*e_ready);
10183
10184 /* If the first insn is non-pairable, let it be. */
10185 if (pair1 == PENT_PAIR_NP)
10186 return;
10187
10188 pair2 = PENT_PAIR_NP;
10189 insnp = 0;
10190
10191 /* If the first insn is UV or PV pairable, search for a PU
10192 insn to go with. */
10193 if (pair1 == PENT_PAIR_UV || pair1 == PENT_PAIR_PV)
e075ae69 10194 {
78a0d70c
ZW
10195 insnp = ix86_pent_find_pair (e_ready-1, ready,
10196 PENT_PAIR_PU, *e_ready);
10197 if (insnp)
10198 pair2 = PENT_PAIR_PU;
10199 }
e075ae69 10200
78a0d70c
ZW
10201 /* If the first insn is PU or UV pairable, search for a PV
10202 insn to go with. */
10203 if (pair2 == PENT_PAIR_NP
10204 && (pair1 == PENT_PAIR_PU || pair1 == PENT_PAIR_UV))
10205 {
10206 insnp = ix86_pent_find_pair (e_ready-1, ready,
10207 PENT_PAIR_PV, *e_ready);
10208 if (insnp)
10209 pair2 = PENT_PAIR_PV;
10210 }
e075ae69 10211
78a0d70c
ZW
10212 /* If the first insn is pairable, search for a UV
10213 insn to go with. */
10214 if (pair2 == PENT_PAIR_NP)
10215 {
10216 insnp = ix86_pent_find_pair (e_ready-1, ready,
10217 PENT_PAIR_UV, *e_ready);
10218 if (insnp)
10219 pair2 = PENT_PAIR_UV;
10220 }
e075ae69 10221
78a0d70c
ZW
10222 if (pair2 == PENT_PAIR_NP)
10223 return;
e075ae69 10224
78a0d70c
ZW
10225 /* Found something! Decide if we need to swap the order. */
10226 if (pair1 == PENT_PAIR_PV || pair2 == PENT_PAIR_PU
10227 || (pair1 == PENT_PAIR_UV && pair2 == PENT_PAIR_UV
10228 && ix86_safe_memory (*e_ready) == MEMORY_BOTH
10229 && ix86_safe_memory (*insnp) == MEMORY_LOAD))
10230 ix86_reorder_insn (insnp, e_ready);
10231 else
10232 ix86_reorder_insn (insnp, e_ready - 1);
10233}
e075ae69 10234
c6991660 10235static void
78a0d70c
ZW
10236ix86_sched_reorder_ppro (ready, e_ready)
10237 rtx *ready;
10238 rtx *e_ready;
10239{
10240 rtx decode[3];
10241 enum attr_ppro_uops cur_uops;
10242 int issued_this_cycle;
10243 rtx *insnp;
10244 int i;
e075ae69 10245
0f290768 10246 /* At this point .ppro.decode contains the state of the three
78a0d70c 10247 decoders from last "cycle". That is, those insns that were
0f290768 10248 actually independent. But here we're scheduling for the
78a0d70c
ZW
10249 decoder, and we may find things that are decodable in the
10250 same cycle. */
e075ae69 10251
0f290768 10252 memcpy (decode, ix86_sched_data.ppro.decode, sizeof (decode));
78a0d70c 10253 issued_this_cycle = 0;
e075ae69 10254
78a0d70c
ZW
10255 insnp = e_ready;
10256 cur_uops = ix86_safe_ppro_uops (*insnp);
0a726ef1 10257
78a0d70c
ZW
10258 /* If the decoders are empty, and we've a complex insn at the
10259 head of the priority queue, let it issue without complaint. */
10260 if (decode[0] == NULL)
10261 {
10262 if (cur_uops == PPRO_UOPS_MANY)
10263 {
10264 decode[0] = *insnp;
10265 goto ppro_done;
10266 }
10267
10268 /* Otherwise, search for a 2-4 uop unsn to issue. */
10269 while (cur_uops != PPRO_UOPS_FEW)
10270 {
10271 if (insnp == ready)
10272 break;
10273 cur_uops = ix86_safe_ppro_uops (*--insnp);
10274 }
10275
10276 /* If so, move it to the head of the line. */
10277 if (cur_uops == PPRO_UOPS_FEW)
10278 ix86_reorder_insn (insnp, e_ready);
0a726ef1 10279
78a0d70c
ZW
10280 /* Issue the head of the queue. */
10281 issued_this_cycle = 1;
10282 decode[0] = *e_ready--;
10283 }
fb693d44 10284
78a0d70c
ZW
10285 /* Look for simple insns to fill in the other two slots. */
10286 for (i = 1; i < 3; ++i)
10287 if (decode[i] == NULL)
10288 {
10289 if (ready >= e_ready)
10290 goto ppro_done;
fb693d44 10291
e075ae69
RH
10292 insnp = e_ready;
10293 cur_uops = ix86_safe_ppro_uops (*insnp);
78a0d70c
ZW
10294 while (cur_uops != PPRO_UOPS_ONE)
10295 {
10296 if (insnp == ready)
10297 break;
10298 cur_uops = ix86_safe_ppro_uops (*--insnp);
10299 }
fb693d44 10300
78a0d70c
ZW
10301 /* Found one. Move it to the head of the queue and issue it. */
10302 if (cur_uops == PPRO_UOPS_ONE)
e075ae69 10303 {
78a0d70c
ZW
10304 ix86_reorder_insn (insnp, e_ready);
10305 decode[i] = *e_ready--;
10306 issued_this_cycle++;
10307 continue;
10308 }
fb693d44 10309
78a0d70c
ZW
10310 /* ??? Didn't find one. Ideally, here we would do a lazy split
10311 of 2-uop insns, issue one and queue the other. */
10312 }
fb693d44 10313
78a0d70c
ZW
10314 ppro_done:
10315 if (issued_this_cycle == 0)
10316 issued_this_cycle = 1;
10317 ix86_sched_data.ppro.issued_this_cycle = issued_this_cycle;
10318}
fb693d44 10319
0f290768 10320/* We are about to being issuing insns for this clock cycle.
78a0d70c 10321 Override the default sort algorithm to better slot instructions. */
c237e94a
ZW
10322static int
10323ix86_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
78a0d70c
ZW
10324 FILE *dump ATTRIBUTE_UNUSED;
10325 int sched_verbose ATTRIBUTE_UNUSED;
10326 rtx *ready;
c237e94a 10327 int *n_readyp;
78a0d70c
ZW
10328 int clock_var ATTRIBUTE_UNUSED;
10329{
c237e94a 10330 int n_ready = *n_readyp;
78a0d70c 10331 rtx *e_ready = ready + n_ready - 1;
fb693d44 10332
78a0d70c
ZW
10333 if (n_ready < 2)
10334 goto out;
e075ae69 10335
78a0d70c
ZW
10336 switch (ix86_cpu)
10337 {
10338 default:
10339 break;
e075ae69 10340
78a0d70c
ZW
10341 case PROCESSOR_PENTIUM:
10342 ix86_sched_reorder_pentium (ready, e_ready);
10343 break;
e075ae69 10344
78a0d70c
ZW
10345 case PROCESSOR_PENTIUMPRO:
10346 ix86_sched_reorder_ppro (ready, e_ready);
e075ae69 10347 break;
fb693d44
RH
10348 }
10349
e075ae69
RH
10350out:
10351 return ix86_issue_rate ();
10352}
fb693d44 10353
e075ae69
RH
10354/* We are about to issue INSN. Return the number of insns left on the
10355 ready queue that can be issued this cycle. */
b222082e 10356
c237e94a 10357static int
e075ae69
RH
10358ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
10359 FILE *dump;
10360 int sched_verbose;
10361 rtx insn;
10362 int can_issue_more;
10363{
10364 int i;
10365 switch (ix86_cpu)
fb693d44 10366 {
e075ae69
RH
10367 default:
10368 return can_issue_more - 1;
fb693d44 10369
e075ae69
RH
10370 case PROCESSOR_PENTIUMPRO:
10371 {
10372 enum attr_ppro_uops uops = ix86_safe_ppro_uops (insn);
fb693d44 10373
e075ae69
RH
10374 if (uops == PPRO_UOPS_MANY)
10375 {
10376 if (sched_verbose)
10377 ix86_dump_ppro_packet (dump);
10378 ix86_sched_data.ppro.decode[0] = insn;
10379 ix86_sched_data.ppro.decode[1] = NULL;
10380 ix86_sched_data.ppro.decode[2] = NULL;
10381 if (sched_verbose)
10382 ix86_dump_ppro_packet (dump);
10383 ix86_sched_data.ppro.decode[0] = NULL;
10384 }
10385 else if (uops == PPRO_UOPS_FEW)
10386 {
10387 if (sched_verbose)
10388 ix86_dump_ppro_packet (dump);
10389 ix86_sched_data.ppro.decode[0] = insn;
10390 ix86_sched_data.ppro.decode[1] = NULL;
10391 ix86_sched_data.ppro.decode[2] = NULL;
10392 }
10393 else
10394 {
10395 for (i = 0; i < 3; ++i)
10396 if (ix86_sched_data.ppro.decode[i] == NULL)
10397 {
10398 ix86_sched_data.ppro.decode[i] = insn;
10399 break;
10400 }
10401 if (i == 3)
10402 abort ();
10403 if (i == 2)
10404 {
10405 if (sched_verbose)
10406 ix86_dump_ppro_packet (dump);
10407 ix86_sched_data.ppro.decode[0] = NULL;
10408 ix86_sched_data.ppro.decode[1] = NULL;
10409 ix86_sched_data.ppro.decode[2] = NULL;
10410 }
10411 }
10412 }
10413 return --ix86_sched_data.ppro.issued_this_cycle;
10414 }
fb693d44 10415}
a7180f70 10416\f
0e4970d7
RK
10417/* Walk through INSNS and look for MEM references whose address is DSTREG or
10418 SRCREG and set the memory attribute to those of DSTREF and SRCREF, as
10419 appropriate. */
10420
10421void
10422ix86_set_move_mem_attrs (insns, dstref, srcref, dstreg, srcreg)
10423 rtx insns;
10424 rtx dstref, srcref, dstreg, srcreg;
10425{
10426 rtx insn;
10427
10428 for (insn = insns; insn != 0 ; insn = NEXT_INSN (insn))
10429 if (INSN_P (insn))
10430 ix86_set_move_mem_attrs_1 (PATTERN (insn), dstref, srcref,
10431 dstreg, srcreg);
10432}
10433
10434/* Subroutine of above to actually do the updating by recursively walking
10435 the rtx. */
10436
10437static void
10438ix86_set_move_mem_attrs_1 (x, dstref, srcref, dstreg, srcreg)
10439 rtx x;
10440 rtx dstref, srcref, dstreg, srcreg;
10441{
10442 enum rtx_code code = GET_CODE (x);
10443 const char *format_ptr = GET_RTX_FORMAT (code);
10444 int i, j;
10445
10446 if (code == MEM && XEXP (x, 0) == dstreg)
10447 MEM_COPY_ATTRIBUTES (x, dstref);
10448 else if (code == MEM && XEXP (x, 0) == srcreg)
10449 MEM_COPY_ATTRIBUTES (x, srcref);
10450
10451 for (i = 0; i < GET_RTX_LENGTH (code); i++, format_ptr++)
10452 {
10453 if (*format_ptr == 'e')
10454 ix86_set_move_mem_attrs_1 (XEXP (x, i), dstref, srcref,
10455 dstreg, srcreg);
10456 else if (*format_ptr == 'E')
10457 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
397be6cf 10458 ix86_set_move_mem_attrs_1 (XVECEXP (x, i, j), dstref, srcref,
0e4970d7
RK
10459 dstreg, srcreg);
10460 }
10461}
10462\f
a7180f70
BS
10463/* Compute the alignment given to a constant that is being placed in memory.
10464 EXP is the constant and ALIGN is the alignment that the object would
10465 ordinarily have.
10466 The value of this function is used instead of that alignment to align
10467 the object. */
10468
10469int
10470ix86_constant_alignment (exp, align)
10471 tree exp;
10472 int align;
10473{
10474 if (TREE_CODE (exp) == REAL_CST)
10475 {
10476 if (TYPE_MODE (TREE_TYPE (exp)) == DFmode && align < 64)
10477 return 64;
10478 else if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (exp))) && align < 128)
10479 return 128;
10480 }
10481 else if (TREE_CODE (exp) == STRING_CST && TREE_STRING_LENGTH (exp) >= 31
10482 && align < 256)
10483 return 256;
10484
10485 return align;
10486}
10487
10488/* Compute the alignment for a static variable.
10489 TYPE is the data type, and ALIGN is the alignment that
10490 the object would ordinarily have. The value of this function is used
10491 instead of that alignment to align the object. */
10492
10493int
10494ix86_data_alignment (type, align)
10495 tree type;
10496 int align;
10497{
10498 if (AGGREGATE_TYPE_P (type)
10499 && TYPE_SIZE (type)
10500 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
10501 && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 256
10502 || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 256)
10503 return 256;
10504
0d7d98ee
JH
10505 /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
10506 to 16byte boundary. */
10507 if (TARGET_64BIT)
10508 {
10509 if (AGGREGATE_TYPE_P (type)
10510 && TYPE_SIZE (type)
10511 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
10512 && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128
10513 || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
10514 return 128;
10515 }
10516
a7180f70
BS
10517 if (TREE_CODE (type) == ARRAY_TYPE)
10518 {
10519 if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
10520 return 64;
10521 if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
10522 return 128;
10523 }
10524 else if (TREE_CODE (type) == COMPLEX_TYPE)
10525 {
0f290768 10526
a7180f70
BS
10527 if (TYPE_MODE (type) == DCmode && align < 64)
10528 return 64;
10529 if (TYPE_MODE (type) == XCmode && align < 128)
10530 return 128;
10531 }
10532 else if ((TREE_CODE (type) == RECORD_TYPE
10533 || TREE_CODE (type) == UNION_TYPE
10534 || TREE_CODE (type) == QUAL_UNION_TYPE)
10535 && TYPE_FIELDS (type))
10536 {
10537 if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
10538 return 64;
10539 if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
10540 return 128;
10541 }
10542 else if (TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == VECTOR_TYPE
10543 || TREE_CODE (type) == INTEGER_TYPE)
10544 {
10545 if (TYPE_MODE (type) == DFmode && align < 64)
10546 return 64;
10547 if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
10548 return 128;
10549 }
10550
10551 return align;
10552}
10553
10554/* Compute the alignment for a local variable.
10555 TYPE is the data type, and ALIGN is the alignment that
10556 the object would ordinarily have. The value of this macro is used
10557 instead of that alignment to align the object. */
10558
10559int
10560ix86_local_alignment (type, align)
10561 tree type;
10562 int align;
10563{
0d7d98ee
JH
10564 /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
10565 to 16byte boundary. */
10566 if (TARGET_64BIT)
10567 {
10568 if (AGGREGATE_TYPE_P (type)
10569 && TYPE_SIZE (type)
10570 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
10571 && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 16
10572 || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
10573 return 128;
10574 }
a7180f70
BS
10575 if (TREE_CODE (type) == ARRAY_TYPE)
10576 {
10577 if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
10578 return 64;
10579 if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
10580 return 128;
10581 }
10582 else if (TREE_CODE (type) == COMPLEX_TYPE)
10583 {
10584 if (TYPE_MODE (type) == DCmode && align < 64)
10585 return 64;
10586 if (TYPE_MODE (type) == XCmode && align < 128)
10587 return 128;
10588 }
10589 else if ((TREE_CODE (type) == RECORD_TYPE
10590 || TREE_CODE (type) == UNION_TYPE
10591 || TREE_CODE (type) == QUAL_UNION_TYPE)
10592 && TYPE_FIELDS (type))
10593 {
10594 if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
10595 return 64;
10596 if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
10597 return 128;
10598 }
10599 else if (TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == VECTOR_TYPE
10600 || TREE_CODE (type) == INTEGER_TYPE)
10601 {
0f290768 10602
a7180f70
BS
10603 if (TYPE_MODE (type) == DFmode && align < 64)
10604 return 64;
10605 if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
10606 return 128;
10607 }
10608 return align;
10609}
0ed08620
JH
10610\f
10611/* Emit RTL insns to initialize the variable parts of a trampoline.
10612 FNADDR is an RTX for the address of the function's pure code.
10613 CXT is an RTX for the static chain value for the function. */
10614void
10615x86_initialize_trampoline (tramp, fnaddr, cxt)
10616 rtx tramp, fnaddr, cxt;
10617{
10618 if (!TARGET_64BIT)
10619 {
10620 /* Compute offset from the end of the jmp to the target function. */
10621 rtx disp = expand_binop (SImode, sub_optab, fnaddr,
10622 plus_constant (tramp, 10),
10623 NULL_RTX, 1, OPTAB_DIRECT);
10624 emit_move_insn (gen_rtx_MEM (QImode, tramp),
10625 GEN_INT (trunc_int_for_mode (0xb9, QImode)));
10626 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 1)), cxt);
10627 emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, 5)),
10628 GEN_INT (trunc_int_for_mode (0xe9, QImode)));
10629 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 6)), disp);
10630 }
10631 else
10632 {
10633 int offset = 0;
10634 /* Try to load address using shorter movl instead of movabs.
10635 We may want to support movq for kernel mode, but kernel does not use
10636 trampolines at the moment. */
10637 if (x86_64_zero_extended_value (fnaddr))
10638 {
10639 fnaddr = copy_to_mode_reg (DImode, fnaddr);
10640 emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
10641 GEN_INT (trunc_int_for_mode (0xbb41, HImode)));
10642 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, offset + 2)),
10643 gen_lowpart (SImode, fnaddr));
10644 offset += 6;
10645 }
10646 else
10647 {
10648 emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
10649 GEN_INT (trunc_int_for_mode (0xbb49, HImode)));
10650 emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, offset + 2)),
10651 fnaddr);
10652 offset += 10;
10653 }
10654 /* Load static chain using movabs to r10. */
10655 emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
10656 GEN_INT (trunc_int_for_mode (0xba49, HImode)));
10657 emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, offset + 2)),
10658 cxt);
10659 offset += 10;
10660 /* Jump to the r11 */
10661 emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
10662 GEN_INT (trunc_int_for_mode (0xff49, HImode)));
10663 emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, offset+2)),
44cf5b6a 10664 GEN_INT (trunc_int_for_mode (0xe3, QImode)));
0ed08620
JH
10665 offset += 3;
10666 if (offset > TRAMPOLINE_SIZE)
10667 abort();
10668 }
10669}
eeb06b1b
BS
10670\f
10671#define def_builtin(MASK, NAME, TYPE, CODE) \
10672do { \
10673 if ((MASK) & target_flags) \
10674 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL); \
10675} while (0)
bd793c65 10676
bd793c65
BS
10677struct builtin_description
10678{
8b60264b
KG
10679 const unsigned int mask;
10680 const enum insn_code icode;
10681 const char *const name;
10682 const enum ix86_builtins code;
10683 const enum rtx_code comparison;
10684 const unsigned int flag;
bd793c65
BS
10685};
10686
8b60264b 10687static const struct builtin_description bdesc_comi[] =
bd793c65 10688{
eeb06b1b
BS
10689 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comieq", IX86_BUILTIN_COMIEQSS, EQ, 0 },
10690 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comilt", IX86_BUILTIN_COMILTSS, LT, 0 },
10691 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comile", IX86_BUILTIN_COMILESS, LE, 0 },
10692 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comigt", IX86_BUILTIN_COMIGTSS, LT, 1 },
10693 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comige", IX86_BUILTIN_COMIGESS, LE, 1 },
10694 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comineq", IX86_BUILTIN_COMINEQSS, NE, 0 },
10695 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomieq", IX86_BUILTIN_UCOMIEQSS, EQ, 0 },
10696 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomilt", IX86_BUILTIN_UCOMILTSS, LT, 0 },
10697 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomile", IX86_BUILTIN_UCOMILESS, LE, 0 },
10698 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomigt", IX86_BUILTIN_UCOMIGTSS, LT, 1 },
10699 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomige", IX86_BUILTIN_UCOMIGESS, LE, 1 },
10700 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomineq", IX86_BUILTIN_UCOMINEQSS, NE, 0 }
bd793c65
BS
10701};
10702
8b60264b 10703static const struct builtin_description bdesc_2arg[] =
bd793c65
BS
10704{
10705 /* SSE */
eeb06b1b
BS
10706 { MASK_SSE, CODE_FOR_addv4sf3, "__builtin_ia32_addps", IX86_BUILTIN_ADDPS, 0, 0 },
10707 { MASK_SSE, CODE_FOR_subv4sf3, "__builtin_ia32_subps", IX86_BUILTIN_SUBPS, 0, 0 },
10708 { MASK_SSE, CODE_FOR_mulv4sf3, "__builtin_ia32_mulps", IX86_BUILTIN_MULPS, 0, 0 },
10709 { MASK_SSE, CODE_FOR_divv4sf3, "__builtin_ia32_divps", IX86_BUILTIN_DIVPS, 0, 0 },
10710 { MASK_SSE, CODE_FOR_vmaddv4sf3, "__builtin_ia32_addss", IX86_BUILTIN_ADDSS, 0, 0 },
10711 { MASK_SSE, CODE_FOR_vmsubv4sf3, "__builtin_ia32_subss", IX86_BUILTIN_SUBSS, 0, 0 },
10712 { MASK_SSE, CODE_FOR_vmmulv4sf3, "__builtin_ia32_mulss", IX86_BUILTIN_MULSS, 0, 0 },
10713 { MASK_SSE, CODE_FOR_vmdivv4sf3, "__builtin_ia32_divss", IX86_BUILTIN_DIVSS, 0, 0 },
10714
10715 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpeqps", IX86_BUILTIN_CMPEQPS, EQ, 0 },
10716 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpltps", IX86_BUILTIN_CMPLTPS, LT, 0 },
10717 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpleps", IX86_BUILTIN_CMPLEPS, LE, 0 },
10718 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpgtps", IX86_BUILTIN_CMPGTPS, LT, 1 },
10719 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpgeps", IX86_BUILTIN_CMPGEPS, LE, 1 },
10720 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpunordps", IX86_BUILTIN_CMPUNORDPS, UNORDERED, 0 },
10721 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpneqps", IX86_BUILTIN_CMPNEQPS, EQ, 0 },
10722 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpnltps", IX86_BUILTIN_CMPNLTPS, LT, 0 },
10723 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpnleps", IX86_BUILTIN_CMPNLEPS, LE, 0 },
10724 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpngtps", IX86_BUILTIN_CMPNGTPS, LT, 1 },
10725 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpngeps", IX86_BUILTIN_CMPNGEPS, LE, 1 },
10726 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpordps", IX86_BUILTIN_CMPORDPS, UNORDERED, 0 },
10727 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpeqss", IX86_BUILTIN_CMPEQSS, EQ, 0 },
10728 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpltss", IX86_BUILTIN_CMPLTSS, LT, 0 },
10729 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpless", IX86_BUILTIN_CMPLESS, LE, 0 },
10730 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpgtss", IX86_BUILTIN_CMPGTSS, LT, 1 },
10731 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpgess", IX86_BUILTIN_CMPGESS, LE, 1 },
10732 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpunordss", IX86_BUILTIN_CMPUNORDSS, UNORDERED, 0 },
10733 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpneqss", IX86_BUILTIN_CMPNEQSS, EQ, 0 },
10734 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpnltss", IX86_BUILTIN_CMPNLTSS, LT, 0 },
10735 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpnless", IX86_BUILTIN_CMPNLESS, LE, 0 },
10736 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpngtss", IX86_BUILTIN_CMPNGTSS, LT, 1 },
10737 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpngess", IX86_BUILTIN_CMPNGESS, LE, 1 },
10738 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpordss", IX86_BUILTIN_CMPORDSS, UNORDERED, 0 },
10739
10740 { MASK_SSE, CODE_FOR_sminv4sf3, "__builtin_ia32_minps", IX86_BUILTIN_MINPS, 0, 0 },
10741 { MASK_SSE, CODE_FOR_smaxv4sf3, "__builtin_ia32_maxps", IX86_BUILTIN_MAXPS, 0, 0 },
10742 { MASK_SSE, CODE_FOR_vmsminv4sf3, "__builtin_ia32_minss", IX86_BUILTIN_MINSS, 0, 0 },
10743 { MASK_SSE, CODE_FOR_vmsmaxv4sf3, "__builtin_ia32_maxss", IX86_BUILTIN_MAXSS, 0, 0 },
10744
10745 { MASK_SSE, CODE_FOR_sse_andti3, "__builtin_ia32_andps", IX86_BUILTIN_ANDPS, 0, 0 },
10746 { MASK_SSE, CODE_FOR_sse_nandti3, "__builtin_ia32_andnps", IX86_BUILTIN_ANDNPS, 0, 0 },
10747 { MASK_SSE, CODE_FOR_sse_iorti3, "__builtin_ia32_orps", IX86_BUILTIN_ORPS, 0, 0 },
10748 { MASK_SSE, CODE_FOR_sse_xorti3, "__builtin_ia32_xorps", IX86_BUILTIN_XORPS, 0, 0 },
10749
10750 { MASK_SSE, CODE_FOR_sse_movss, "__builtin_ia32_movss", IX86_BUILTIN_MOVSS, 0, 0 },
10751 { MASK_SSE, CODE_FOR_sse_movhlps, "__builtin_ia32_movhlps", IX86_BUILTIN_MOVHLPS, 0, 0 },
10752 { MASK_SSE, CODE_FOR_sse_movlhps, "__builtin_ia32_movlhps", IX86_BUILTIN_MOVLHPS, 0, 0 },
10753 { MASK_SSE, CODE_FOR_sse_unpckhps, "__builtin_ia32_unpckhps", IX86_BUILTIN_UNPCKHPS, 0, 0 },
10754 { MASK_SSE, CODE_FOR_sse_unpcklps, "__builtin_ia32_unpcklps", IX86_BUILTIN_UNPCKLPS, 0, 0 },
bd793c65
BS
10755
10756 /* MMX */
eeb06b1b
BS
10757 { MASK_MMX, CODE_FOR_addv8qi3, "__builtin_ia32_paddb", IX86_BUILTIN_PADDB, 0, 0 },
10758 { MASK_MMX, CODE_FOR_addv4hi3, "__builtin_ia32_paddw", IX86_BUILTIN_PADDW, 0, 0 },
10759 { MASK_MMX, CODE_FOR_addv2si3, "__builtin_ia32_paddd", IX86_BUILTIN_PADDD, 0, 0 },
10760 { MASK_MMX, CODE_FOR_subv8qi3, "__builtin_ia32_psubb", IX86_BUILTIN_PSUBB, 0, 0 },
10761 { MASK_MMX, CODE_FOR_subv4hi3, "__builtin_ia32_psubw", IX86_BUILTIN_PSUBW, 0, 0 },
10762 { MASK_MMX, CODE_FOR_subv2si3, "__builtin_ia32_psubd", IX86_BUILTIN_PSUBD, 0, 0 },
10763
10764 { MASK_MMX, CODE_FOR_ssaddv8qi3, "__builtin_ia32_paddsb", IX86_BUILTIN_PADDSB, 0, 0 },
10765 { MASK_MMX, CODE_FOR_ssaddv4hi3, "__builtin_ia32_paddsw", IX86_BUILTIN_PADDSW, 0, 0 },
10766 { MASK_MMX, CODE_FOR_sssubv8qi3, "__builtin_ia32_psubsb", IX86_BUILTIN_PSUBSB, 0, 0 },
10767 { MASK_MMX, CODE_FOR_sssubv4hi3, "__builtin_ia32_psubsw", IX86_BUILTIN_PSUBSW, 0, 0 },
10768 { MASK_MMX, CODE_FOR_usaddv8qi3, "__builtin_ia32_paddusb", IX86_BUILTIN_PADDUSB, 0, 0 },
10769 { MASK_MMX, CODE_FOR_usaddv4hi3, "__builtin_ia32_paddusw", IX86_BUILTIN_PADDUSW, 0, 0 },
10770 { MASK_MMX, CODE_FOR_ussubv8qi3, "__builtin_ia32_psubusb", IX86_BUILTIN_PSUBUSB, 0, 0 },
10771 { MASK_MMX, CODE_FOR_ussubv4hi3, "__builtin_ia32_psubusw", IX86_BUILTIN_PSUBUSW, 0, 0 },
10772
10773 { MASK_MMX, CODE_FOR_mulv4hi3, "__builtin_ia32_pmullw", IX86_BUILTIN_PMULLW, 0, 0 },
10774 { MASK_MMX, CODE_FOR_smulv4hi3_highpart, "__builtin_ia32_pmulhw", IX86_BUILTIN_PMULHW, 0, 0 },
47f339cf 10775 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_umulv4hi3_highpart, "__builtin_ia32_pmulhuw", IX86_BUILTIN_PMULHUW, 0, 0 },
eeb06b1b
BS
10776
10777 { MASK_MMX, CODE_FOR_mmx_anddi3, "__builtin_ia32_pand", IX86_BUILTIN_PAND, 0, 0 },
10778 { MASK_MMX, CODE_FOR_mmx_nanddi3, "__builtin_ia32_pandn", IX86_BUILTIN_PANDN, 0, 0 },
10779 { MASK_MMX, CODE_FOR_mmx_iordi3, "__builtin_ia32_por", IX86_BUILTIN_POR, 0, 0 },
10780 { MASK_MMX, CODE_FOR_mmx_xordi3, "__builtin_ia32_pxor", IX86_BUILTIN_PXOR, 0, 0 },
10781
47f339cf
BS
10782 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_uavgv8qi3, "__builtin_ia32_pavgb", IX86_BUILTIN_PAVGB, 0, 0 },
10783 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_uavgv4hi3, "__builtin_ia32_pavgw", IX86_BUILTIN_PAVGW, 0, 0 },
eeb06b1b
BS
10784
10785 { MASK_MMX, CODE_FOR_eqv8qi3, "__builtin_ia32_pcmpeqb", IX86_BUILTIN_PCMPEQB, 0, 0 },
10786 { MASK_MMX, CODE_FOR_eqv4hi3, "__builtin_ia32_pcmpeqw", IX86_BUILTIN_PCMPEQW, 0, 0 },
10787 { MASK_MMX, CODE_FOR_eqv2si3, "__builtin_ia32_pcmpeqd", IX86_BUILTIN_PCMPEQD, 0, 0 },
10788 { MASK_MMX, CODE_FOR_gtv8qi3, "__builtin_ia32_pcmpgtb", IX86_BUILTIN_PCMPGTB, 0, 0 },
10789 { MASK_MMX, CODE_FOR_gtv4hi3, "__builtin_ia32_pcmpgtw", IX86_BUILTIN_PCMPGTW, 0, 0 },
10790 { MASK_MMX, CODE_FOR_gtv2si3, "__builtin_ia32_pcmpgtd", IX86_BUILTIN_PCMPGTD, 0, 0 },
10791
47f339cf
BS
10792 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_umaxv8qi3, "__builtin_ia32_pmaxub", IX86_BUILTIN_PMAXUB, 0, 0 },
10793 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_smaxv4hi3, "__builtin_ia32_pmaxsw", IX86_BUILTIN_PMAXSW, 0, 0 },
10794 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_uminv8qi3, "__builtin_ia32_pminub", IX86_BUILTIN_PMINUB, 0, 0 },
10795 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_sminv4hi3, "__builtin_ia32_pminsw", IX86_BUILTIN_PMINSW, 0, 0 },
eeb06b1b
BS
10796
10797 { MASK_MMX, CODE_FOR_mmx_punpckhbw, "__builtin_ia32_punpckhbw", IX86_BUILTIN_PUNPCKHBW, 0, 0 },
10798 { MASK_MMX, CODE_FOR_mmx_punpckhwd, "__builtin_ia32_punpckhwd", IX86_BUILTIN_PUNPCKHWD, 0, 0 },
10799 { MASK_MMX, CODE_FOR_mmx_punpckhdq, "__builtin_ia32_punpckhdq", IX86_BUILTIN_PUNPCKHDQ, 0, 0 },
10800 { MASK_MMX, CODE_FOR_mmx_punpcklbw, "__builtin_ia32_punpcklbw", IX86_BUILTIN_PUNPCKLBW, 0, 0 },
10801 { MASK_MMX, CODE_FOR_mmx_punpcklwd, "__builtin_ia32_punpcklwd", IX86_BUILTIN_PUNPCKLWD, 0, 0 },
10802 { MASK_MMX, CODE_FOR_mmx_punpckldq, "__builtin_ia32_punpckldq", IX86_BUILTIN_PUNPCKLDQ, 0, 0 },
bd793c65
BS
10803
10804 /* Special. */
eeb06b1b
BS
10805 { MASK_MMX, CODE_FOR_mmx_packsswb, 0, IX86_BUILTIN_PACKSSWB, 0, 0 },
10806 { MASK_MMX, CODE_FOR_mmx_packssdw, 0, IX86_BUILTIN_PACKSSDW, 0, 0 },
10807 { MASK_MMX, CODE_FOR_mmx_packuswb, 0, IX86_BUILTIN_PACKUSWB, 0, 0 },
10808
10809 { MASK_SSE, CODE_FOR_cvtpi2ps, 0, IX86_BUILTIN_CVTPI2PS, 0, 0 },
10810 { MASK_SSE, CODE_FOR_cvtsi2ss, 0, IX86_BUILTIN_CVTSI2SS, 0, 0 },
10811
10812 { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
10813 { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
10814 { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLD, 0, 0 },
10815 { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLDI, 0, 0 },
10816 { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQ, 0, 0 },
10817 { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQI, 0, 0 },
10818
10819 { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLW, 0, 0 },
10820 { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLWI, 0, 0 },
10821 { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLD, 0, 0 },
10822 { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLDI, 0, 0 },
10823 { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQ, 0, 0 },
10824 { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQI, 0, 0 },
10825
10826 { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAW, 0, 0 },
10827 { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAWI, 0, 0 },
10828 { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRAD, 0, 0 },
10829 { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRADI, 0, 0 },
10830
10831 { MASK_SSE, CODE_FOR_mmx_psadbw, 0, IX86_BUILTIN_PSADBW, 0, 0 },
10832 { MASK_MMX, CODE_FOR_mmx_pmaddwd, 0, IX86_BUILTIN_PMADDWD, 0, 0 }
bd793c65
BS
10833
10834};
10835
8b60264b 10836static const struct builtin_description bdesc_1arg[] =
bd793c65 10837{
47f339cf 10838 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_pmovmskb, 0, IX86_BUILTIN_PMOVMSKB, 0, 0 },
eeb06b1b 10839 { MASK_SSE, CODE_FOR_sse_movmskps, 0, IX86_BUILTIN_MOVMSKPS, 0, 0 },
bd793c65 10840
eeb06b1b
BS
10841 { MASK_SSE, CODE_FOR_sqrtv4sf2, 0, IX86_BUILTIN_SQRTPS, 0, 0 },
10842 { MASK_SSE, CODE_FOR_rsqrtv4sf2, 0, IX86_BUILTIN_RSQRTPS, 0, 0 },
10843 { MASK_SSE, CODE_FOR_rcpv4sf2, 0, IX86_BUILTIN_RCPPS, 0, 0 },
bd793c65 10844
eeb06b1b
BS
10845 { MASK_SSE, CODE_FOR_cvtps2pi, 0, IX86_BUILTIN_CVTPS2PI, 0, 0 },
10846 { MASK_SSE, CODE_FOR_cvtss2si, 0, IX86_BUILTIN_CVTSS2SI, 0, 0 },
10847 { MASK_SSE, CODE_FOR_cvttps2pi, 0, IX86_BUILTIN_CVTTPS2PI, 0, 0 },
10848 { MASK_SSE, CODE_FOR_cvttss2si, 0, IX86_BUILTIN_CVTTSS2SI, 0, 0 }
bd793c65
BS
10849
10850};
10851
f6155fda
SS
10852void
10853ix86_init_builtins ()
10854{
10855 if (TARGET_MMX)
10856 ix86_init_mmx_sse_builtins ();
10857}
10858
10859/* Set up all the MMX/SSE builtins. This is not called if TARGET_MMX
bd793c65
BS
10860 is zero. Otherwise, if TARGET_SSE is not set, only expand the MMX
10861 builtins. */
10862void
f6155fda 10863ix86_init_mmx_sse_builtins ()
bd793c65 10864{
8b60264b 10865 const struct builtin_description * d;
77ebd435 10866 size_t i;
cbd5937a 10867 tree endlink = void_list_node;
bd793c65
BS
10868
10869 tree pchar_type_node = build_pointer_type (char_type_node);
10870 tree pfloat_type_node = build_pointer_type (float_type_node);
10871 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
10872 tree pdi_type_node = build_pointer_type (long_long_unsigned_type_node);
10873
10874 /* Comparisons. */
10875 tree int_ftype_v4sf_v4sf
10876 = build_function_type (integer_type_node,
10877 tree_cons (NULL_TREE, V4SF_type_node,
10878 tree_cons (NULL_TREE,
10879 V4SF_type_node,
10880 endlink)));
10881 tree v4si_ftype_v4sf_v4sf
10882 = build_function_type (V4SI_type_node,
10883 tree_cons (NULL_TREE, V4SF_type_node,
10884 tree_cons (NULL_TREE,
10885 V4SF_type_node,
10886 endlink)));
10887 /* MMX/SSE/integer conversions. */
bd793c65
BS
10888 tree int_ftype_v4sf
10889 = build_function_type (integer_type_node,
10890 tree_cons (NULL_TREE, V4SF_type_node,
10891 endlink));
10892 tree int_ftype_v8qi
10893 = build_function_type (integer_type_node,
10894 tree_cons (NULL_TREE, V8QI_type_node,
10895 endlink));
10896 tree int_ftype_v2si
10897 = build_function_type (integer_type_node,
10898 tree_cons (NULL_TREE, V2SI_type_node,
10899 endlink));
10900 tree v2si_ftype_int
10901 = build_function_type (V2SI_type_node,
10902 tree_cons (NULL_TREE, integer_type_node,
10903 endlink));
10904 tree v4sf_ftype_v4sf_int
21e1b5f1 10905 = build_function_type (V4SF_type_node,
bd793c65
BS
10906 tree_cons (NULL_TREE, V4SF_type_node,
10907 tree_cons (NULL_TREE, integer_type_node,
10908 endlink)));
10909 tree v4sf_ftype_v4sf_v2si
10910 = build_function_type (V4SF_type_node,
10911 tree_cons (NULL_TREE, V4SF_type_node,
10912 tree_cons (NULL_TREE, V2SI_type_node,
10913 endlink)));
10914 tree int_ftype_v4hi_int
10915 = build_function_type (integer_type_node,
10916 tree_cons (NULL_TREE, V4HI_type_node,
10917 tree_cons (NULL_TREE, integer_type_node,
10918 endlink)));
10919 tree v4hi_ftype_v4hi_int_int
332316cd 10920 = build_function_type (V4HI_type_node,
bd793c65
BS
10921 tree_cons (NULL_TREE, V4HI_type_node,
10922 tree_cons (NULL_TREE, integer_type_node,
10923 tree_cons (NULL_TREE,
10924 integer_type_node,
10925 endlink))));
10926 /* Miscellaneous. */
10927 tree v8qi_ftype_v4hi_v4hi
10928 = build_function_type (V8QI_type_node,
10929 tree_cons (NULL_TREE, V4HI_type_node,
10930 tree_cons (NULL_TREE, V4HI_type_node,
10931 endlink)));
10932 tree v4hi_ftype_v2si_v2si
10933 = build_function_type (V4HI_type_node,
10934 tree_cons (NULL_TREE, V2SI_type_node,
10935 tree_cons (NULL_TREE, V2SI_type_node,
10936 endlink)));
10937 tree v4sf_ftype_v4sf_v4sf_int
10938 = build_function_type (V4SF_type_node,
10939 tree_cons (NULL_TREE, V4SF_type_node,
10940 tree_cons (NULL_TREE, V4SF_type_node,
10941 tree_cons (NULL_TREE,
10942 integer_type_node,
10943 endlink))));
10944 tree v4hi_ftype_v8qi_v8qi
10945 = build_function_type (V4HI_type_node,
10946 tree_cons (NULL_TREE, V8QI_type_node,
10947 tree_cons (NULL_TREE, V8QI_type_node,
10948 endlink)));
10949 tree v2si_ftype_v4hi_v4hi
10950 = build_function_type (V2SI_type_node,
10951 tree_cons (NULL_TREE, V4HI_type_node,
10952 tree_cons (NULL_TREE, V4HI_type_node,
10953 endlink)));
10954 tree v4hi_ftype_v4hi_int
10955 = build_function_type (V4HI_type_node,
10956 tree_cons (NULL_TREE, V4HI_type_node,
10957 tree_cons (NULL_TREE, integer_type_node,
10958 endlink)));
bd793c65
BS
10959 tree v4hi_ftype_v4hi_di
10960 = build_function_type (V4HI_type_node,
10961 tree_cons (NULL_TREE, V4HI_type_node,
10962 tree_cons (NULL_TREE,
10963 long_long_integer_type_node,
10964 endlink)));
10965 tree v2si_ftype_v2si_di
10966 = build_function_type (V2SI_type_node,
10967 tree_cons (NULL_TREE, V2SI_type_node,
10968 tree_cons (NULL_TREE,
10969 long_long_integer_type_node,
10970 endlink)));
10971 tree void_ftype_void
10972 = build_function_type (void_type_node, endlink);
10973 tree void_ftype_pchar_int
10974 = build_function_type (void_type_node,
10975 tree_cons (NULL_TREE, pchar_type_node,
10976 tree_cons (NULL_TREE, integer_type_node,
10977 endlink)));
10978 tree void_ftype_unsigned
10979 = build_function_type (void_type_node,
10980 tree_cons (NULL_TREE, unsigned_type_node,
10981 endlink));
10982 tree unsigned_ftype_void
10983 = build_function_type (unsigned_type_node, endlink);
10984 tree di_ftype_void
10985 = build_function_type (long_long_unsigned_type_node, endlink);
10986 tree ti_ftype_void
10987 = build_function_type (intTI_type_node, endlink);
10988 tree v2si_ftype_v4sf
10989 = build_function_type (V2SI_type_node,
10990 tree_cons (NULL_TREE, V4SF_type_node,
10991 endlink));
10992 /* Loads/stores. */
10993 tree maskmovq_args = tree_cons (NULL_TREE, V8QI_type_node,
10994 tree_cons (NULL_TREE, V8QI_type_node,
10995 tree_cons (NULL_TREE,
10996 pchar_type_node,
10997 endlink)));
10998 tree void_ftype_v8qi_v8qi_pchar
10999 = build_function_type (void_type_node, maskmovq_args);
11000 tree v4sf_ftype_pfloat
11001 = build_function_type (V4SF_type_node,
11002 tree_cons (NULL_TREE, pfloat_type_node,
11003 endlink));
11004 tree v4sf_ftype_float
11005 = build_function_type (V4SF_type_node,
11006 tree_cons (NULL_TREE, float_type_node,
11007 endlink));
11008 tree v4sf_ftype_float_float_float_float
11009 = build_function_type (V4SF_type_node,
11010 tree_cons (NULL_TREE, float_type_node,
11011 tree_cons (NULL_TREE, float_type_node,
11012 tree_cons (NULL_TREE,
11013 float_type_node,
11014 tree_cons (NULL_TREE,
11015 float_type_node,
11016 endlink)))));
11017 /* @@@ the type is bogus */
11018 tree v4sf_ftype_v4sf_pv2si
11019 = build_function_type (V4SF_type_node,
11020 tree_cons (NULL_TREE, V4SF_type_node,
11021 tree_cons (NULL_TREE, pv2si_type_node,
11022 endlink)));
1255c85c
BS
11023 tree void_ftype_pv2si_v4sf
11024 = build_function_type (void_type_node,
11025 tree_cons (NULL_TREE, pv2si_type_node,
11026 tree_cons (NULL_TREE, V4SF_type_node,
bd793c65
BS
11027 endlink)));
11028 tree void_ftype_pfloat_v4sf
11029 = build_function_type (void_type_node,
11030 tree_cons (NULL_TREE, pfloat_type_node,
11031 tree_cons (NULL_TREE, V4SF_type_node,
11032 endlink)));
11033 tree void_ftype_pdi_di
11034 = build_function_type (void_type_node,
11035 tree_cons (NULL_TREE, pdi_type_node,
11036 tree_cons (NULL_TREE,
11037 long_long_unsigned_type_node,
11038 endlink)));
11039 /* Normal vector unops. */
11040 tree v4sf_ftype_v4sf
11041 = build_function_type (V4SF_type_node,
11042 tree_cons (NULL_TREE, V4SF_type_node,
11043 endlink));
0f290768 11044
bd793c65
BS
11045 /* Normal vector binops. */
11046 tree v4sf_ftype_v4sf_v4sf
11047 = build_function_type (V4SF_type_node,
11048 tree_cons (NULL_TREE, V4SF_type_node,
11049 tree_cons (NULL_TREE, V4SF_type_node,
11050 endlink)));
11051 tree v8qi_ftype_v8qi_v8qi
11052 = build_function_type (V8QI_type_node,
11053 tree_cons (NULL_TREE, V8QI_type_node,
11054 tree_cons (NULL_TREE, V8QI_type_node,
11055 endlink)));
11056 tree v4hi_ftype_v4hi_v4hi
11057 = build_function_type (V4HI_type_node,
11058 tree_cons (NULL_TREE, V4HI_type_node,
11059 tree_cons (NULL_TREE, V4HI_type_node,
11060 endlink)));
11061 tree v2si_ftype_v2si_v2si
11062 = build_function_type (V2SI_type_node,
11063 tree_cons (NULL_TREE, V2SI_type_node,
11064 tree_cons (NULL_TREE, V2SI_type_node,
11065 endlink)));
11066 tree ti_ftype_ti_ti
11067 = build_function_type (intTI_type_node,
11068 tree_cons (NULL_TREE, intTI_type_node,
11069 tree_cons (NULL_TREE, intTI_type_node,
11070 endlink)));
11071 tree di_ftype_di_di
11072 = build_function_type (long_long_unsigned_type_node,
11073 tree_cons (NULL_TREE, long_long_unsigned_type_node,
11074 tree_cons (NULL_TREE,
11075 long_long_unsigned_type_node,
11076 endlink)));
11077
47f339cf
BS
11078 tree v2si_ftype_v2sf
11079 = build_function_type (V2SI_type_node,
11080 tree_cons (NULL_TREE, V2SF_type_node,
11081 endlink));
11082 tree v2sf_ftype_v2si
11083 = build_function_type (V2SF_type_node,
11084 tree_cons (NULL_TREE, V2SI_type_node,
11085 endlink));
11086 tree v2si_ftype_v2si
11087 = build_function_type (V2SI_type_node,
11088 tree_cons (NULL_TREE, V2SI_type_node,
11089 endlink));
11090 tree v2sf_ftype_v2sf
11091 = build_function_type (V2SF_type_node,
11092 tree_cons (NULL_TREE, V2SF_type_node,
11093 endlink));
11094 tree v2sf_ftype_v2sf_v2sf
11095 = build_function_type (V2SF_type_node,
11096 tree_cons (NULL_TREE, V2SF_type_node,
11097 tree_cons (NULL_TREE,
11098 V2SF_type_node,
11099 endlink)));
11100 tree v2si_ftype_v2sf_v2sf
11101 = build_function_type (V2SI_type_node,
11102 tree_cons (NULL_TREE, V2SF_type_node,
11103 tree_cons (NULL_TREE,
11104 V2SF_type_node,
11105 endlink)));
11106
11107 tree void_ftype_pchar
11108 = build_function_type (void_type_node,
11109 tree_cons (NULL_TREE, pchar_type_node,
11110 endlink));
11111
bd793c65
BS
11112 /* Add all builtins that are more or less simple operations on two
11113 operands. */
11114 for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
11115 {
11116 /* Use one of the operands; the target can have a different mode for
11117 mask-generating compares. */
11118 enum machine_mode mode;
11119 tree type;
11120
11121 if (d->name == 0)
11122 continue;
11123 mode = insn_data[d->icode].operand[1].mode;
11124
bd793c65
BS
11125 switch (mode)
11126 {
11127 case V4SFmode:
11128 type = v4sf_ftype_v4sf_v4sf;
11129 break;
11130 case V8QImode:
11131 type = v8qi_ftype_v8qi_v8qi;
11132 break;
11133 case V4HImode:
11134 type = v4hi_ftype_v4hi_v4hi;
11135 break;
11136 case V2SImode:
11137 type = v2si_ftype_v2si_v2si;
11138 break;
11139 case TImode:
11140 type = ti_ftype_ti_ti;
11141 break;
11142 case DImode:
11143 type = di_ftype_di_di;
11144 break;
11145
11146 default:
11147 abort ();
11148 }
0f290768 11149
bd793c65
BS
11150 /* Override for comparisons. */
11151 if (d->icode == CODE_FOR_maskcmpv4sf3
11152 || d->icode == CODE_FOR_maskncmpv4sf3
11153 || d->icode == CODE_FOR_vmmaskcmpv4sf3
11154 || d->icode == CODE_FOR_vmmaskncmpv4sf3)
11155 type = v4si_ftype_v4sf_v4sf;
11156
eeb06b1b 11157 def_builtin (d->mask, d->name, type, d->code);
bd793c65
BS
11158 }
11159
11160 /* Add the remaining MMX insns with somewhat more complicated types. */
eeb06b1b
BS
11161 def_builtin (MASK_MMX, "__builtin_ia32_m_from_int", v2si_ftype_int, IX86_BUILTIN_M_FROM_INT);
11162 def_builtin (MASK_MMX, "__builtin_ia32_m_to_int", int_ftype_v2si, IX86_BUILTIN_M_TO_INT);
11163 def_builtin (MASK_MMX, "__builtin_ia32_mmx_zero", di_ftype_void, IX86_BUILTIN_MMX_ZERO);
11164 def_builtin (MASK_MMX, "__builtin_ia32_emms", void_ftype_void, IX86_BUILTIN_EMMS);
11165 def_builtin (MASK_MMX, "__builtin_ia32_ldmxcsr", void_ftype_unsigned, IX86_BUILTIN_LDMXCSR);
11166 def_builtin (MASK_MMX, "__builtin_ia32_stmxcsr", unsigned_ftype_void, IX86_BUILTIN_STMXCSR);
11167 def_builtin (MASK_MMX, "__builtin_ia32_psllw", v4hi_ftype_v4hi_di, IX86_BUILTIN_PSLLW);
11168 def_builtin (MASK_MMX, "__builtin_ia32_pslld", v2si_ftype_v2si_di, IX86_BUILTIN_PSLLD);
11169 def_builtin (MASK_MMX, "__builtin_ia32_psllq", di_ftype_di_di, IX86_BUILTIN_PSLLQ);
11170
11171 def_builtin (MASK_MMX, "__builtin_ia32_psrlw", v4hi_ftype_v4hi_di, IX86_BUILTIN_PSRLW);
11172 def_builtin (MASK_MMX, "__builtin_ia32_psrld", v2si_ftype_v2si_di, IX86_BUILTIN_PSRLD);
11173 def_builtin (MASK_MMX, "__builtin_ia32_psrlq", di_ftype_di_di, IX86_BUILTIN_PSRLQ);
11174
11175 def_builtin (MASK_MMX, "__builtin_ia32_psraw", v4hi_ftype_v4hi_di, IX86_BUILTIN_PSRAW);
11176 def_builtin (MASK_MMX, "__builtin_ia32_psrad", v2si_ftype_v2si_di, IX86_BUILTIN_PSRAD);
11177
11178 def_builtin (MASK_MMX, "__builtin_ia32_pshufw", v4hi_ftype_v4hi_int, IX86_BUILTIN_PSHUFW);
11179 def_builtin (MASK_MMX, "__builtin_ia32_pmaddwd", v2si_ftype_v4hi_v4hi, IX86_BUILTIN_PMADDWD);
0f290768 11180
bd793c65
BS
11181 /* comi/ucomi insns. */
11182 for (i = 0, d = bdesc_comi; i < sizeof (bdesc_comi) / sizeof *d; i++, d++)
eeb06b1b 11183 def_builtin (d->mask, d->name, int_ftype_v4sf_v4sf, d->code);
bd793c65 11184
1255c85c
BS
11185 def_builtin (MASK_MMX, "__builtin_ia32_packsswb", v8qi_ftype_v4hi_v4hi, IX86_BUILTIN_PACKSSWB);
11186 def_builtin (MASK_MMX, "__builtin_ia32_packssdw", v4hi_ftype_v2si_v2si, IX86_BUILTIN_PACKSSDW);
11187 def_builtin (MASK_MMX, "__builtin_ia32_packuswb", v8qi_ftype_v4hi_v4hi, IX86_BUILTIN_PACKUSWB);
bd793c65 11188
eeb06b1b
BS
11189 def_builtin (MASK_SSE, "__builtin_ia32_cvtpi2ps", v4sf_ftype_v4sf_v2si, IX86_BUILTIN_CVTPI2PS);
11190 def_builtin (MASK_SSE, "__builtin_ia32_cvtps2pi", v2si_ftype_v4sf, IX86_BUILTIN_CVTPS2PI);
11191 def_builtin (MASK_SSE, "__builtin_ia32_cvtsi2ss", v4sf_ftype_v4sf_int, IX86_BUILTIN_CVTSI2SS);
11192 def_builtin (MASK_SSE, "__builtin_ia32_cvtss2si", int_ftype_v4sf, IX86_BUILTIN_CVTSS2SI);
11193 def_builtin (MASK_SSE, "__builtin_ia32_cvttps2pi", v2si_ftype_v4sf, IX86_BUILTIN_CVTTPS2PI);
11194 def_builtin (MASK_SSE, "__builtin_ia32_cvttss2si", int_ftype_v4sf, IX86_BUILTIN_CVTTSS2SI);
bd793c65 11195
47f339cf
BS
11196 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_pextrw", int_ftype_v4hi_int, IX86_BUILTIN_PEXTRW);
11197 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_pinsrw", v4hi_ftype_v4hi_int_int, IX86_BUILTIN_PINSRW);
bd793c65 11198
47f339cf 11199 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_maskmovq", void_ftype_v8qi_v8qi_pchar, IX86_BUILTIN_MASKMOVQ);
bd793c65 11200
eeb06b1b
BS
11201 def_builtin (MASK_SSE, "__builtin_ia32_loadaps", v4sf_ftype_pfloat, IX86_BUILTIN_LOADAPS);
11202 def_builtin (MASK_SSE, "__builtin_ia32_loadups", v4sf_ftype_pfloat, IX86_BUILTIN_LOADUPS);
11203 def_builtin (MASK_SSE, "__builtin_ia32_loadss", v4sf_ftype_pfloat, IX86_BUILTIN_LOADSS);
11204 def_builtin (MASK_SSE, "__builtin_ia32_storeaps", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREAPS);
11205 def_builtin (MASK_SSE, "__builtin_ia32_storeups", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREUPS);
11206 def_builtin (MASK_SSE, "__builtin_ia32_storess", void_ftype_pfloat_v4sf, IX86_BUILTIN_STORESS);
bd793c65 11207
eeb06b1b
BS
11208 def_builtin (MASK_SSE, "__builtin_ia32_loadhps", v4sf_ftype_v4sf_pv2si, IX86_BUILTIN_LOADHPS);
11209 def_builtin (MASK_SSE, "__builtin_ia32_loadlps", v4sf_ftype_v4sf_pv2si, IX86_BUILTIN_LOADLPS);
1255c85c
BS
11210 def_builtin (MASK_SSE, "__builtin_ia32_storehps", void_ftype_pv2si_v4sf, IX86_BUILTIN_STOREHPS);
11211 def_builtin (MASK_SSE, "__builtin_ia32_storelps", void_ftype_pv2si_v4sf, IX86_BUILTIN_STORELPS);
bd793c65 11212
eeb06b1b 11213 def_builtin (MASK_SSE, "__builtin_ia32_movmskps", int_ftype_v4sf, IX86_BUILTIN_MOVMSKPS);
47f339cf 11214 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_pmovmskb", int_ftype_v8qi, IX86_BUILTIN_PMOVMSKB);
eeb06b1b 11215 def_builtin (MASK_SSE, "__builtin_ia32_movntps", void_ftype_pfloat_v4sf, IX86_BUILTIN_MOVNTPS);
47f339cf 11216 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_movntq", void_ftype_pdi_di, IX86_BUILTIN_MOVNTQ);
bd793c65 11217
47f339cf
BS
11218 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_sfence", void_ftype_void, IX86_BUILTIN_SFENCE);
11219 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_prefetch", void_ftype_pchar_int, IX86_BUILTIN_PREFETCH);
bd793c65 11220
47f339cf 11221 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_psadbw", v4hi_ftype_v8qi_v8qi, IX86_BUILTIN_PSADBW);
bd793c65 11222
eeb06b1b
BS
11223 def_builtin (MASK_SSE, "__builtin_ia32_rcpps", v4sf_ftype_v4sf, IX86_BUILTIN_RCPPS);
11224 def_builtin (MASK_SSE, "__builtin_ia32_rcpss", v4sf_ftype_v4sf, IX86_BUILTIN_RCPSS);
11225 def_builtin (MASK_SSE, "__builtin_ia32_rsqrtps", v4sf_ftype_v4sf, IX86_BUILTIN_RSQRTPS);
11226 def_builtin (MASK_SSE, "__builtin_ia32_rsqrtss", v4sf_ftype_v4sf, IX86_BUILTIN_RSQRTSS);
11227 def_builtin (MASK_SSE, "__builtin_ia32_sqrtps", v4sf_ftype_v4sf, IX86_BUILTIN_SQRTPS);
11228 def_builtin (MASK_SSE, "__builtin_ia32_sqrtss", v4sf_ftype_v4sf, IX86_BUILTIN_SQRTSS);
bd793c65 11229
eeb06b1b 11230 def_builtin (MASK_SSE, "__builtin_ia32_shufps", v4sf_ftype_v4sf_v4sf_int, IX86_BUILTIN_SHUFPS);
bd793c65 11231
47f339cf
BS
11232 /* Original 3DNow! */
11233 def_builtin (MASK_3DNOW, "__builtin_ia32_femms", void_ftype_void, IX86_BUILTIN_FEMMS);
11234 def_builtin (MASK_3DNOW, "__builtin_ia32_pavgusb", v8qi_ftype_v8qi_v8qi, IX86_BUILTIN_PAVGUSB);
11235 def_builtin (MASK_3DNOW, "__builtin_ia32_pf2id", v2si_ftype_v2sf, IX86_BUILTIN_PF2ID);
11236 def_builtin (MASK_3DNOW, "__builtin_ia32_pfacc", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFACC);
11237 def_builtin (MASK_3DNOW, "__builtin_ia32_pfadd", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFADD);
11238 def_builtin (MASK_3DNOW, "__builtin_ia32_pfcmpeq", v2si_ftype_v2sf_v2sf, IX86_BUILTIN_PFCMPEQ);
11239 def_builtin (MASK_3DNOW, "__builtin_ia32_pfcmpge", v2si_ftype_v2sf_v2sf, IX86_BUILTIN_PFCMPGE);
11240 def_builtin (MASK_3DNOW, "__builtin_ia32_pfcmpgt", v2si_ftype_v2sf_v2sf, IX86_BUILTIN_PFCMPGT);
11241 def_builtin (MASK_3DNOW, "__builtin_ia32_pfmax", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFMAX);
11242 def_builtin (MASK_3DNOW, "__builtin_ia32_pfmin", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFMIN);
11243 def_builtin (MASK_3DNOW, "__builtin_ia32_pfmul", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFMUL);
11244 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrcp", v2sf_ftype_v2sf, IX86_BUILTIN_PFRCP);
11245 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrcpit1", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFRCPIT1);
11246 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrcpit2", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFRCPIT2);
11247 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrsqrt", v2sf_ftype_v2sf, IX86_BUILTIN_PFRSQRT);
11248 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrsqit1", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFRSQIT1);
11249 def_builtin (MASK_3DNOW, "__builtin_ia32_pfsub", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFSUB);
11250 def_builtin (MASK_3DNOW, "__builtin_ia32_pfsubr", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFSUBR);
11251 def_builtin (MASK_3DNOW, "__builtin_ia32_pi2fd", v2sf_ftype_v2si, IX86_BUILTIN_PI2FD);
11252 def_builtin (MASK_3DNOW, "__builtin_ia32_pmulhrw", v4hi_ftype_v4hi_v4hi, IX86_BUILTIN_PMULHRW);
11253 def_builtin (MASK_3DNOW, "__builtin_ia32_prefetch_3dnow", void_ftype_pchar, IX86_BUILTIN_PREFETCH_3DNOW);
11254 def_builtin (MASK_3DNOW, "__builtin_ia32_prefetchw", void_ftype_pchar, IX86_BUILTIN_PREFETCHW);
11255
11256 /* 3DNow! extension as used in the Athlon CPU. */
11257 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pf2iw", v2si_ftype_v2sf, IX86_BUILTIN_PF2IW);
11258 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pfnacc", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFNACC);
11259 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pfpnacc", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFPNACC);
11260 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pi2fw", v2sf_ftype_v2si, IX86_BUILTIN_PI2FW);
11261 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pswapdsf", v2sf_ftype_v2sf, IX86_BUILTIN_PSWAPDSF);
11262 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pswapdsi", v2si_ftype_v2si, IX86_BUILTIN_PSWAPDSI);
11263
bd793c65 11264 /* Composite intrinsics. */
eeb06b1b
BS
11265 def_builtin (MASK_SSE, "__builtin_ia32_setps1", v4sf_ftype_float, IX86_BUILTIN_SETPS1);
11266 def_builtin (MASK_SSE, "__builtin_ia32_setps", v4sf_ftype_float_float_float_float, IX86_BUILTIN_SETPS);
11267 def_builtin (MASK_SSE, "__builtin_ia32_setzerops", ti_ftype_void, IX86_BUILTIN_CLRPS);
11268 def_builtin (MASK_SSE, "__builtin_ia32_loadps1", v4sf_ftype_pfloat, IX86_BUILTIN_LOADPS1);
11269 def_builtin (MASK_SSE, "__builtin_ia32_loadrps", v4sf_ftype_pfloat, IX86_BUILTIN_LOADRPS);
11270 def_builtin (MASK_SSE, "__builtin_ia32_storeps1", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREPS1);
11271 def_builtin (MASK_SSE, "__builtin_ia32_storerps", void_ftype_pfloat_v4sf, IX86_BUILTIN_STORERPS);
bd793c65
BS
11272}
11273
11274/* Errors in the source file can cause expand_expr to return const0_rtx
11275 where we expect a vector. To avoid crashing, use one of the vector
11276 clear instructions. */
11277static rtx
11278safe_vector_operand (x, mode)
11279 rtx x;
11280 enum machine_mode mode;
11281{
11282 if (x != const0_rtx)
11283 return x;
11284 x = gen_reg_rtx (mode);
11285
47f339cf 11286 if (VALID_MMX_REG_MODE (mode) || VALID_MMX_REG_MODE_3DNOW (mode))
bd793c65
BS
11287 emit_insn (gen_mmx_clrdi (mode == DImode ? x
11288 : gen_rtx_SUBREG (DImode, x, 0)));
11289 else
11290 emit_insn (gen_sse_clrti (mode == TImode ? x
11291 : gen_rtx_SUBREG (TImode, x, 0)));
11292 return x;
11293}
11294
11295/* Subroutine of ix86_expand_builtin to take care of binop insns. */
11296
11297static rtx
11298ix86_expand_binop_builtin (icode, arglist, target)
11299 enum insn_code icode;
11300 tree arglist;
11301 rtx target;
11302{
11303 rtx pat;
11304 tree arg0 = TREE_VALUE (arglist);
11305 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11306 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11307 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11308 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11309 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11310 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11311
11312 if (VECTOR_MODE_P (mode0))
11313 op0 = safe_vector_operand (op0, mode0);
11314 if (VECTOR_MODE_P (mode1))
11315 op1 = safe_vector_operand (op1, mode1);
11316
11317 if (! target
11318 || GET_MODE (target) != tmode
11319 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11320 target = gen_reg_rtx (tmode);
11321
11322 /* In case the insn wants input operands in modes different from
11323 the result, abort. */
11324 if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
11325 abort ();
11326
11327 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11328 op0 = copy_to_mode_reg (mode0, op0);
11329 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11330 op1 = copy_to_mode_reg (mode1, op1);
11331
11332 pat = GEN_FCN (icode) (target, op0, op1);
11333 if (! pat)
11334 return 0;
11335 emit_insn (pat);
11336 return target;
11337}
11338
11339/* Subroutine of ix86_expand_builtin to take care of stores. */
11340
11341static rtx
11342ix86_expand_store_builtin (icode, arglist, shuffle)
11343 enum insn_code icode;
11344 tree arglist;
11345 int shuffle;
11346{
11347 rtx pat;
11348 tree arg0 = TREE_VALUE (arglist);
11349 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11350 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11351 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11352 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11353 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11354
11355 if (VECTOR_MODE_P (mode1))
11356 op1 = safe_vector_operand (op1, mode1);
11357
11358 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11359 if (shuffle >= 0 || ! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11360 op1 = copy_to_mode_reg (mode1, op1);
11361 if (shuffle >= 0)
11362 emit_insn (gen_sse_shufps (op1, op1, op1, GEN_INT (shuffle)));
11363 pat = GEN_FCN (icode) (op0, op1);
11364 if (pat)
11365 emit_insn (pat);
11366 return 0;
11367}
11368
11369/* Subroutine of ix86_expand_builtin to take care of unop insns. */
11370
11371static rtx
11372ix86_expand_unop_builtin (icode, arglist, target, do_load)
11373 enum insn_code icode;
11374 tree arglist;
11375 rtx target;
11376 int do_load;
11377{
11378 rtx pat;
11379 tree arg0 = TREE_VALUE (arglist);
11380 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11381 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11382 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11383
11384 if (! target
11385 || GET_MODE (target) != tmode
11386 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11387 target = gen_reg_rtx (tmode);
11388 if (do_load)
11389 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11390 else
11391 {
11392 if (VECTOR_MODE_P (mode0))
11393 op0 = safe_vector_operand (op0, mode0);
11394
11395 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11396 op0 = copy_to_mode_reg (mode0, op0);
11397 }
11398
11399 pat = GEN_FCN (icode) (target, op0);
11400 if (! pat)
11401 return 0;
11402 emit_insn (pat);
11403 return target;
11404}
11405
11406/* Subroutine of ix86_expand_builtin to take care of three special unop insns:
11407 sqrtss, rsqrtss, rcpss. */
11408
11409static rtx
11410ix86_expand_unop1_builtin (icode, arglist, target)
11411 enum insn_code icode;
11412 tree arglist;
11413 rtx target;
11414{
11415 rtx pat;
11416 tree arg0 = TREE_VALUE (arglist);
11417 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11418 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11419 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11420
11421 if (! target
11422 || GET_MODE (target) != tmode
11423 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11424 target = gen_reg_rtx (tmode);
11425
11426 if (VECTOR_MODE_P (mode0))
11427 op0 = safe_vector_operand (op0, mode0);
11428
11429 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11430 op0 = copy_to_mode_reg (mode0, op0);
11431
11432 pat = GEN_FCN (icode) (target, op0, op0);
11433 if (! pat)
11434 return 0;
11435 emit_insn (pat);
11436 return target;
11437}
11438
11439/* Subroutine of ix86_expand_builtin to take care of comparison insns. */
11440
11441static rtx
11442ix86_expand_sse_compare (d, arglist, target)
8b60264b 11443 const struct builtin_description *d;
bd793c65
BS
11444 tree arglist;
11445 rtx target;
11446{
11447 rtx pat;
11448 tree arg0 = TREE_VALUE (arglist);
11449 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11450 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11451 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11452 rtx op2;
11453 enum machine_mode tmode = insn_data[d->icode].operand[0].mode;
11454 enum machine_mode mode0 = insn_data[d->icode].operand[1].mode;
11455 enum machine_mode mode1 = insn_data[d->icode].operand[2].mode;
11456 enum rtx_code comparison = d->comparison;
11457
11458 if (VECTOR_MODE_P (mode0))
11459 op0 = safe_vector_operand (op0, mode0);
11460 if (VECTOR_MODE_P (mode1))
11461 op1 = safe_vector_operand (op1, mode1);
11462
11463 /* Swap operands if we have a comparison that isn't available in
11464 hardware. */
11465 if (d->flag)
11466 {
21e1b5f1
BS
11467 rtx tmp = gen_reg_rtx (mode1);
11468 emit_move_insn (tmp, op1);
bd793c65 11469 op1 = op0;
21e1b5f1 11470 op0 = tmp;
bd793c65 11471 }
21e1b5f1
BS
11472
11473 if (! target
11474 || GET_MODE (target) != tmode
11475 || ! (*insn_data[d->icode].operand[0].predicate) (target, tmode))
bd793c65
BS
11476 target = gen_reg_rtx (tmode);
11477
11478 if (! (*insn_data[d->icode].operand[1].predicate) (op0, mode0))
11479 op0 = copy_to_mode_reg (mode0, op0);
11480 if (! (*insn_data[d->icode].operand[2].predicate) (op1, mode1))
11481 op1 = copy_to_mode_reg (mode1, op1);
11482
11483 op2 = gen_rtx_fmt_ee (comparison, mode0, op0, op1);
11484 pat = GEN_FCN (d->icode) (target, op0, op1, op2);
11485 if (! pat)
11486 return 0;
11487 emit_insn (pat);
11488 return target;
11489}
11490
11491/* Subroutine of ix86_expand_builtin to take care of comi insns. */
11492
11493static rtx
11494ix86_expand_sse_comi (d, arglist, target)
8b60264b 11495 const struct builtin_description *d;
bd793c65
BS
11496 tree arglist;
11497 rtx target;
11498{
11499 rtx pat;
11500 tree arg0 = TREE_VALUE (arglist);
11501 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11502 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11503 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11504 rtx op2;
11505 enum machine_mode mode0 = insn_data[d->icode].operand[0].mode;
11506 enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
11507 enum rtx_code comparison = d->comparison;
11508
11509 if (VECTOR_MODE_P (mode0))
11510 op0 = safe_vector_operand (op0, mode0);
11511 if (VECTOR_MODE_P (mode1))
11512 op1 = safe_vector_operand (op1, mode1);
11513
11514 /* Swap operands if we have a comparison that isn't available in
11515 hardware. */
11516 if (d->flag)
11517 {
11518 rtx tmp = op1;
11519 op1 = op0;
11520 op0 = tmp;
bd793c65
BS
11521 }
11522
11523 target = gen_reg_rtx (SImode);
11524 emit_move_insn (target, const0_rtx);
11525 target = gen_rtx_SUBREG (QImode, target, 0);
11526
11527 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11528 op0 = copy_to_mode_reg (mode0, op0);
11529 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11530 op1 = copy_to_mode_reg (mode1, op1);
11531
11532 op2 = gen_rtx_fmt_ee (comparison, mode0, op0, op1);
11533 pat = GEN_FCN (d->icode) (op0, op1, op2);
11534 if (! pat)
11535 return 0;
11536 emit_insn (pat);
29628f27
BS
11537 emit_insn (gen_rtx_SET (VOIDmode,
11538 gen_rtx_STRICT_LOW_PART (VOIDmode, target),
11539 gen_rtx_fmt_ee (comparison, QImode,
11540 gen_rtx_REG (CCmode, FLAGS_REG),
11541 const0_rtx)));
bd793c65
BS
11542
11543 return target;
11544}
11545
11546/* Expand an expression EXP that calls a built-in function,
11547 with result going to TARGET if that's convenient
11548 (and in mode MODE if that's convenient).
11549 SUBTARGET may be used as the target for computing one of EXP's operands.
11550 IGNORE is nonzero if the value is to be ignored. */
11551
11552rtx
11553ix86_expand_builtin (exp, target, subtarget, mode, ignore)
11554 tree exp;
11555 rtx target;
11556 rtx subtarget ATTRIBUTE_UNUSED;
11557 enum machine_mode mode ATTRIBUTE_UNUSED;
11558 int ignore ATTRIBUTE_UNUSED;
11559{
8b60264b 11560 const struct builtin_description *d;
77ebd435 11561 size_t i;
bd793c65
BS
11562 enum insn_code icode;
11563 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
11564 tree arglist = TREE_OPERAND (exp, 1);
11565 tree arg0, arg1, arg2, arg3;
11566 rtx op0, op1, op2, pat;
11567 enum machine_mode tmode, mode0, mode1, mode2;
8752c357 11568 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
bd793c65
BS
11569
11570 switch (fcode)
11571 {
11572 case IX86_BUILTIN_EMMS:
11573 emit_insn (gen_emms ());
11574 return 0;
11575
11576 case IX86_BUILTIN_SFENCE:
11577 emit_insn (gen_sfence ());
11578 return 0;
11579
11580 case IX86_BUILTIN_M_FROM_INT:
11581 target = gen_reg_rtx (DImode);
11582 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
11583 emit_move_insn (gen_rtx_SUBREG (SImode, target, 0), op0);
11584 return target;
11585
11586 case IX86_BUILTIN_M_TO_INT:
11587 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
11588 op0 = copy_to_mode_reg (DImode, op0);
11589 target = gen_reg_rtx (SImode);
11590 emit_move_insn (target, gen_rtx_SUBREG (SImode, op0, 0));
11591 return target;
11592
11593 case IX86_BUILTIN_PEXTRW:
11594 icode = CODE_FOR_mmx_pextrw;
11595 arg0 = TREE_VALUE (arglist);
11596 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11597 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11598 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11599 tmode = insn_data[icode].operand[0].mode;
11600 mode0 = insn_data[icode].operand[1].mode;
11601 mode1 = insn_data[icode].operand[2].mode;
11602
11603 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11604 op0 = copy_to_mode_reg (mode0, op0);
11605 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11606 {
11607 /* @@@ better error message */
11608 error ("selector must be an immediate");
11609 return const0_rtx;
11610 }
11611 if (target == 0
11612 || GET_MODE (target) != tmode
11613 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11614 target = gen_reg_rtx (tmode);
11615 pat = GEN_FCN (icode) (target, op0, op1);
11616 if (! pat)
11617 return 0;
11618 emit_insn (pat);
11619 return target;
11620
11621 case IX86_BUILTIN_PINSRW:
11622 icode = CODE_FOR_mmx_pinsrw;
11623 arg0 = TREE_VALUE (arglist);
11624 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11625 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11626 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11627 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11628 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
11629 tmode = insn_data[icode].operand[0].mode;
11630 mode0 = insn_data[icode].operand[1].mode;
11631 mode1 = insn_data[icode].operand[2].mode;
11632 mode2 = insn_data[icode].operand[3].mode;
11633
11634 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11635 op0 = copy_to_mode_reg (mode0, op0);
11636 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11637 op1 = copy_to_mode_reg (mode1, op1);
11638 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11639 {
11640 /* @@@ better error message */
11641 error ("selector must be an immediate");
11642 return const0_rtx;
11643 }
11644 if (target == 0
11645 || GET_MODE (target) != tmode
11646 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11647 target = gen_reg_rtx (tmode);
11648 pat = GEN_FCN (icode) (target, op0, op1, op2);
11649 if (! pat)
11650 return 0;
11651 emit_insn (pat);
11652 return target;
11653
11654 case IX86_BUILTIN_MASKMOVQ:
11655 icode = CODE_FOR_mmx_maskmovq;
11656 /* Note the arg order is different from the operand order. */
11657 arg1 = TREE_VALUE (arglist);
11658 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
11659 arg0 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11660 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11661 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11662 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
11663 mode0 = insn_data[icode].operand[0].mode;
11664 mode1 = insn_data[icode].operand[1].mode;
11665 mode2 = insn_data[icode].operand[2].mode;
11666
11667 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11668 op0 = copy_to_mode_reg (mode0, op0);
11669 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11670 op1 = copy_to_mode_reg (mode1, op1);
11671 if (! (*insn_data[icode].operand[2].predicate) (op2, mode2))
11672 op2 = copy_to_mode_reg (mode2, op2);
11673 pat = GEN_FCN (icode) (op0, op1, op2);
11674 if (! pat)
11675 return 0;
11676 emit_insn (pat);
11677 return 0;
11678
11679 case IX86_BUILTIN_SQRTSS:
11680 return ix86_expand_unop1_builtin (CODE_FOR_vmsqrtv4sf2, arglist, target);
11681 case IX86_BUILTIN_RSQRTSS:
11682 return ix86_expand_unop1_builtin (CODE_FOR_vmrsqrtv4sf2, arglist, target);
11683 case IX86_BUILTIN_RCPSS:
11684 return ix86_expand_unop1_builtin (CODE_FOR_vmrcpv4sf2, arglist, target);
11685
11686 case IX86_BUILTIN_LOADAPS:
11687 return ix86_expand_unop_builtin (CODE_FOR_sse_movaps, arglist, target, 1);
11688
11689 case IX86_BUILTIN_LOADUPS:
11690 return ix86_expand_unop_builtin (CODE_FOR_sse_movups, arglist, target, 1);
11691
11692 case IX86_BUILTIN_STOREAPS:
11693 return ix86_expand_store_builtin (CODE_FOR_sse_movaps, arglist, -1);
11694 case IX86_BUILTIN_STOREUPS:
11695 return ix86_expand_store_builtin (CODE_FOR_sse_movups, arglist, -1);
11696
11697 case IX86_BUILTIN_LOADSS:
11698 return ix86_expand_unop_builtin (CODE_FOR_sse_loadss, arglist, target, 1);
11699
11700 case IX86_BUILTIN_STORESS:
11701 return ix86_expand_store_builtin (CODE_FOR_sse_storess, arglist, -1);
11702
0f290768 11703 case IX86_BUILTIN_LOADHPS:
bd793c65
BS
11704 case IX86_BUILTIN_LOADLPS:
11705 icode = (fcode == IX86_BUILTIN_LOADHPS
11706 ? CODE_FOR_sse_movhps : CODE_FOR_sse_movlps);
11707 arg0 = TREE_VALUE (arglist);
11708 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11709 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11710 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11711 tmode = insn_data[icode].operand[0].mode;
11712 mode0 = insn_data[icode].operand[1].mode;
11713 mode1 = insn_data[icode].operand[2].mode;
11714
11715 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11716 op0 = copy_to_mode_reg (mode0, op0);
11717 op1 = gen_rtx_MEM (mode1, copy_to_mode_reg (Pmode, op1));
11718 if (target == 0
11719 || GET_MODE (target) != tmode
11720 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11721 target = gen_reg_rtx (tmode);
11722 pat = GEN_FCN (icode) (target, op0, op1);
11723 if (! pat)
11724 return 0;
11725 emit_insn (pat);
11726 return target;
0f290768 11727
bd793c65
BS
11728 case IX86_BUILTIN_STOREHPS:
11729 case IX86_BUILTIN_STORELPS:
11730 icode = (fcode == IX86_BUILTIN_STOREHPS
11731 ? CODE_FOR_sse_movhps : CODE_FOR_sse_movlps);
11732 arg0 = TREE_VALUE (arglist);
11733 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11734 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11735 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11736 mode0 = insn_data[icode].operand[1].mode;
11737 mode1 = insn_data[icode].operand[2].mode;
11738
11739 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11740 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11741 op1 = copy_to_mode_reg (mode1, op1);
11742
11743 pat = GEN_FCN (icode) (op0, op0, op1);
11744 if (! pat)
11745 return 0;
11746 emit_insn (pat);
11747 return 0;
11748
11749 case IX86_BUILTIN_MOVNTPS:
11750 return ix86_expand_store_builtin (CODE_FOR_sse_movntv4sf, arglist, -1);
11751 case IX86_BUILTIN_MOVNTQ:
11752 return ix86_expand_store_builtin (CODE_FOR_sse_movntdi, arglist, -1);
11753
11754 case IX86_BUILTIN_LDMXCSR:
11755 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
11756 target = assign_386_stack_local (SImode, 0);
11757 emit_move_insn (target, op0);
11758 emit_insn (gen_ldmxcsr (target));
11759 return 0;
11760
11761 case IX86_BUILTIN_STMXCSR:
11762 target = assign_386_stack_local (SImode, 0);
11763 emit_insn (gen_stmxcsr (target));
11764 return copy_to_mode_reg (SImode, target);
11765
11766 case IX86_BUILTIN_PREFETCH:
7a9aba6c 11767 icode = CODE_FOR_prefetch_sse;
bd793c65
BS
11768 arg0 = TREE_VALUE (arglist);
11769 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11770 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11771 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
332316cd
BS
11772 mode0 = insn_data[icode].operand[0].mode;
11773 mode1 = insn_data[icode].operand[1].mode;
bd793c65 11774
332316cd 11775 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
bd793c65
BS
11776 {
11777 /* @@@ better error message */
11778 error ("selector must be an immediate");
11779 return const0_rtx;
11780 }
11781
332316cd 11782 op0 = copy_to_mode_reg (Pmode, op0);
bd793c65
BS
11783 pat = GEN_FCN (icode) (op0, op1);
11784 if (! pat)
11785 return 0;
11786 emit_insn (pat);
11787 return target;
0f290768 11788
bd793c65
BS
11789 case IX86_BUILTIN_SHUFPS:
11790 icode = CODE_FOR_sse_shufps;
11791 arg0 = TREE_VALUE (arglist);
11792 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11793 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11794 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11795 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11796 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
11797 tmode = insn_data[icode].operand[0].mode;
11798 mode0 = insn_data[icode].operand[1].mode;
11799 mode1 = insn_data[icode].operand[2].mode;
11800 mode2 = insn_data[icode].operand[3].mode;
11801
11802 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11803 op0 = copy_to_mode_reg (mode0, op0);
11804 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11805 op1 = copy_to_mode_reg (mode1, op1);
11806 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11807 {
11808 /* @@@ better error message */
11809 error ("mask must be an immediate");
11810 return const0_rtx;
11811 }
11812 if (target == 0
11813 || GET_MODE (target) != tmode
11814 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11815 target = gen_reg_rtx (tmode);
11816 pat = GEN_FCN (icode) (target, op0, op1, op2);
11817 if (! pat)
11818 return 0;
11819 emit_insn (pat);
11820 return target;
11821
11822 case IX86_BUILTIN_PSHUFW:
11823 icode = CODE_FOR_mmx_pshufw;
11824 arg0 = TREE_VALUE (arglist);
11825 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11826 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11827 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11828 tmode = insn_data[icode].operand[0].mode;
29628f27
BS
11829 mode1 = insn_data[icode].operand[1].mode;
11830 mode2 = insn_data[icode].operand[2].mode;
bd793c65 11831
29628f27
BS
11832 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
11833 op0 = copy_to_mode_reg (mode1, op0);
11834 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
bd793c65
BS
11835 {
11836 /* @@@ better error message */
11837 error ("mask must be an immediate");
11838 return const0_rtx;
11839 }
11840 if (target == 0
11841 || GET_MODE (target) != tmode
11842 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11843 target = gen_reg_rtx (tmode);
29628f27 11844 pat = GEN_FCN (icode) (target, op0, op1);
bd793c65
BS
11845 if (! pat)
11846 return 0;
11847 emit_insn (pat);
11848 return target;
11849
47f339cf
BS
11850 case IX86_BUILTIN_FEMMS:
11851 emit_insn (gen_femms ());
11852 return NULL_RTX;
11853
11854 case IX86_BUILTIN_PAVGUSB:
11855 return ix86_expand_binop_builtin (CODE_FOR_pavgusb, arglist, target);
11856
11857 case IX86_BUILTIN_PF2ID:
11858 return ix86_expand_unop_builtin (CODE_FOR_pf2id, arglist, target, 0);
11859
11860 case IX86_BUILTIN_PFACC:
11861 return ix86_expand_binop_builtin (CODE_FOR_pfacc, arglist, target);
11862
11863 case IX86_BUILTIN_PFADD:
11864 return ix86_expand_binop_builtin (CODE_FOR_addv2sf3, arglist, target);
11865
11866 case IX86_BUILTIN_PFCMPEQ:
11867 return ix86_expand_binop_builtin (CODE_FOR_eqv2sf3, arglist, target);
11868
11869 case IX86_BUILTIN_PFCMPGE:
11870 return ix86_expand_binop_builtin (CODE_FOR_gev2sf3, arglist, target);
11871
11872 case IX86_BUILTIN_PFCMPGT:
11873 return ix86_expand_binop_builtin (CODE_FOR_gtv2sf3, arglist, target);
11874
11875 case IX86_BUILTIN_PFMAX:
11876 return ix86_expand_binop_builtin (CODE_FOR_pfmaxv2sf3, arglist, target);
11877
11878 case IX86_BUILTIN_PFMIN:
11879 return ix86_expand_binop_builtin (CODE_FOR_pfminv2sf3, arglist, target);
11880
11881 case IX86_BUILTIN_PFMUL:
11882 return ix86_expand_binop_builtin (CODE_FOR_mulv2sf3, arglist, target);
11883
11884 case IX86_BUILTIN_PFRCP:
11885 return ix86_expand_unop_builtin (CODE_FOR_pfrcpv2sf2, arglist, target, 0);
11886
11887 case IX86_BUILTIN_PFRCPIT1:
11888 return ix86_expand_binop_builtin (CODE_FOR_pfrcpit1v2sf3, arglist, target);
11889
11890 case IX86_BUILTIN_PFRCPIT2:
11891 return ix86_expand_binop_builtin (CODE_FOR_pfrcpit2v2sf3, arglist, target);
11892
11893 case IX86_BUILTIN_PFRSQIT1:
11894 return ix86_expand_binop_builtin (CODE_FOR_pfrsqit1v2sf3, arglist, target);
11895
11896 case IX86_BUILTIN_PFRSQRT:
11897 return ix86_expand_unop_builtin (CODE_FOR_pfrsqrtv2sf2, arglist, target, 0);
11898
11899 case IX86_BUILTIN_PFSUB:
11900 return ix86_expand_binop_builtin (CODE_FOR_subv2sf3, arglist, target);
11901
11902 case IX86_BUILTIN_PFSUBR:
11903 return ix86_expand_binop_builtin (CODE_FOR_subrv2sf3, arglist, target);
11904
11905 case IX86_BUILTIN_PI2FD:
11906 return ix86_expand_unop_builtin (CODE_FOR_floatv2si2, arglist, target, 0);
11907
11908 case IX86_BUILTIN_PMULHRW:
11909 return ix86_expand_binop_builtin (CODE_FOR_pmulhrwv4hi3, arglist, target);
11910
11911 case IX86_BUILTIN_PREFETCH_3DNOW:
47f339cf 11912 case IX86_BUILTIN_PREFETCHW:
f4365627 11913 icode = CODE_FOR_prefetch_3dnow;
47f339cf
BS
11914 arg0 = TREE_VALUE (arglist);
11915 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
f4365627 11916 op1 = (fcode == IX86_BUILTIN_PREFETCH_3DNOW ? const0_rtx : const1_rtx);
47f339cf 11917 mode0 = insn_data[icode].operand[0].mode;
f4365627 11918 pat = GEN_FCN (icode) (copy_to_mode_reg (Pmode, op0), op1);
47f339cf
BS
11919 if (! pat)
11920 return NULL_RTX;
11921 emit_insn (pat);
11922 return NULL_RTX;
11923
11924 case IX86_BUILTIN_PF2IW:
11925 return ix86_expand_unop_builtin (CODE_FOR_pf2iw, arglist, target, 0);
11926
11927 case IX86_BUILTIN_PFNACC:
11928 return ix86_expand_binop_builtin (CODE_FOR_pfnacc, arglist, target);
11929
11930 case IX86_BUILTIN_PFPNACC:
11931 return ix86_expand_binop_builtin (CODE_FOR_pfpnacc, arglist, target);
11932
11933 case IX86_BUILTIN_PI2FW:
11934 return ix86_expand_unop_builtin (CODE_FOR_pi2fw, arglist, target, 0);
11935
11936 case IX86_BUILTIN_PSWAPDSI:
11937 return ix86_expand_unop_builtin (CODE_FOR_pswapdv2si2, arglist, target, 0);
11938
11939 case IX86_BUILTIN_PSWAPDSF:
11940 return ix86_expand_unop_builtin (CODE_FOR_pswapdv2sf2, arglist, target, 0);
11941
bd793c65
BS
11942 /* Composite intrinsics. */
11943 case IX86_BUILTIN_SETPS1:
11944 target = assign_386_stack_local (SFmode, 0);
11945 arg0 = TREE_VALUE (arglist);
f4ef873c 11946 emit_move_insn (adjust_address (target, SFmode, 0),
bd793c65
BS
11947 expand_expr (arg0, NULL_RTX, VOIDmode, 0));
11948 op0 = gen_reg_rtx (V4SFmode);
f4ef873c 11949 emit_insn (gen_sse_loadss (op0, adjust_address (target, V4SFmode, 0)));
bd793c65
BS
11950 emit_insn (gen_sse_shufps (op0, op0, op0, GEN_INT (0)));
11951 return op0;
0f290768 11952
bd793c65
BS
11953 case IX86_BUILTIN_SETPS:
11954 target = assign_386_stack_local (V4SFmode, 0);
bd793c65
BS
11955 arg0 = TREE_VALUE (arglist);
11956 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11957 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11958 arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
d2037d01 11959 emit_move_insn (adjust_address (target, SFmode, 0),
bd793c65 11960 expand_expr (arg0, NULL_RTX, VOIDmode, 0));
d2037d01 11961 emit_move_insn (adjust_address (target, SFmode, 4),
bd793c65 11962 expand_expr (arg1, NULL_RTX, VOIDmode, 0));
d2037d01 11963 emit_move_insn (adjust_address (target, SFmode, 8),
bd793c65 11964 expand_expr (arg2, NULL_RTX, VOIDmode, 0));
d2037d01 11965 emit_move_insn (adjust_address (target, SFmode, 12),
bd793c65
BS
11966 expand_expr (arg3, NULL_RTX, VOIDmode, 0));
11967 op0 = gen_reg_rtx (V4SFmode);
11968 emit_insn (gen_sse_movaps (op0, target));
11969 return op0;
11970
11971 case IX86_BUILTIN_CLRPS:
11972 target = gen_reg_rtx (TImode);
11973 emit_insn (gen_sse_clrti (target));
11974 return target;
11975
11976 case IX86_BUILTIN_LOADRPS:
11977 target = ix86_expand_unop_builtin (CODE_FOR_sse_movaps, arglist,
11978 gen_reg_rtx (V4SFmode), 1);
11979 emit_insn (gen_sse_shufps (target, target, target, GEN_INT (0x1b)));
11980 return target;
11981
11982 case IX86_BUILTIN_LOADPS1:
11983 target = ix86_expand_unop_builtin (CODE_FOR_sse_loadss, arglist,
11984 gen_reg_rtx (V4SFmode), 1);
11985 emit_insn (gen_sse_shufps (target, target, target, const0_rtx));
11986 return target;
11987
11988 case IX86_BUILTIN_STOREPS1:
11989 return ix86_expand_store_builtin (CODE_FOR_sse_movaps, arglist, 0);
11990 case IX86_BUILTIN_STORERPS:
11991 return ix86_expand_store_builtin (CODE_FOR_sse_movaps, arglist, 0x1B);
11992
11993 case IX86_BUILTIN_MMX_ZERO:
11994 target = gen_reg_rtx (DImode);
11995 emit_insn (gen_mmx_clrdi (target));
11996 return target;
11997
11998 default:
11999 break;
12000 }
12001
12002 for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
12003 if (d->code == fcode)
12004 {
12005 /* Compares are treated specially. */
12006 if (d->icode == CODE_FOR_maskcmpv4sf3
12007 || d->icode == CODE_FOR_vmmaskcmpv4sf3
12008 || d->icode == CODE_FOR_maskncmpv4sf3
12009 || d->icode == CODE_FOR_vmmaskncmpv4sf3)
12010 return ix86_expand_sse_compare (d, arglist, target);
12011
12012 return ix86_expand_binop_builtin (d->icode, arglist, target);
12013 }
12014
12015 for (i = 0, d = bdesc_1arg; i < sizeof (bdesc_1arg) / sizeof *d; i++, d++)
12016 if (d->code == fcode)
12017 return ix86_expand_unop_builtin (d->icode, arglist, target, 0);
0f290768 12018
bd793c65
BS
12019 for (i = 0, d = bdesc_comi; i < sizeof (bdesc_comi) / sizeof *d; i++, d++)
12020 if (d->code == fcode)
12021 return ix86_expand_sse_comi (d, arglist, target);
0f290768 12022
bd793c65
BS
12023 /* @@@ Should really do something sensible here. */
12024 return 0;
bd793c65 12025}
4211a8fb
JH
12026
12027/* Store OPERAND to the memory after reload is completed. This means
f710504c 12028 that we can't easily use assign_stack_local. */
4211a8fb
JH
12029rtx
12030ix86_force_to_memory (mode, operand)
12031 enum machine_mode mode;
12032 rtx operand;
12033{
898d374d 12034 rtx result;
4211a8fb
JH
12035 if (!reload_completed)
12036 abort ();
898d374d
JH
12037 if (TARGET_64BIT && TARGET_RED_ZONE)
12038 {
12039 result = gen_rtx_MEM (mode,
12040 gen_rtx_PLUS (Pmode,
12041 stack_pointer_rtx,
12042 GEN_INT (-RED_ZONE_SIZE)));
12043 emit_move_insn (result, operand);
12044 }
12045 else if (TARGET_64BIT && !TARGET_RED_ZONE)
4211a8fb 12046 {
898d374d 12047 switch (mode)
4211a8fb 12048 {
898d374d
JH
12049 case HImode:
12050 case SImode:
12051 operand = gen_lowpart (DImode, operand);
12052 /* FALLTHRU */
12053 case DImode:
4211a8fb 12054 emit_insn (
898d374d
JH
12055 gen_rtx_SET (VOIDmode,
12056 gen_rtx_MEM (DImode,
12057 gen_rtx_PRE_DEC (DImode,
12058 stack_pointer_rtx)),
12059 operand));
12060 break;
12061 default:
12062 abort ();
12063 }
12064 result = gen_rtx_MEM (mode, stack_pointer_rtx);
12065 }
12066 else
12067 {
12068 switch (mode)
12069 {
12070 case DImode:
12071 {
12072 rtx operands[2];
12073 split_di (&operand, 1, operands, operands + 1);
12074 emit_insn (
12075 gen_rtx_SET (VOIDmode,
12076 gen_rtx_MEM (SImode,
12077 gen_rtx_PRE_DEC (Pmode,
12078 stack_pointer_rtx)),
12079 operands[1]));
12080 emit_insn (
12081 gen_rtx_SET (VOIDmode,
12082 gen_rtx_MEM (SImode,
12083 gen_rtx_PRE_DEC (Pmode,
12084 stack_pointer_rtx)),
12085 operands[0]));
12086 }
12087 break;
12088 case HImode:
12089 /* It is better to store HImodes as SImodes. */
12090 if (!TARGET_PARTIAL_REG_STALL)
12091 operand = gen_lowpart (SImode, operand);
12092 /* FALLTHRU */
12093 case SImode:
4211a8fb 12094 emit_insn (
898d374d
JH
12095 gen_rtx_SET (VOIDmode,
12096 gen_rtx_MEM (GET_MODE (operand),
12097 gen_rtx_PRE_DEC (SImode,
12098 stack_pointer_rtx)),
12099 operand));
12100 break;
12101 default:
12102 abort ();
4211a8fb 12103 }
898d374d 12104 result = gen_rtx_MEM (mode, stack_pointer_rtx);
4211a8fb 12105 }
898d374d 12106 return result;
4211a8fb
JH
12107}
12108
12109/* Free operand from the memory. */
12110void
12111ix86_free_from_memory (mode)
12112 enum machine_mode mode;
12113{
898d374d
JH
12114 if (!TARGET_64BIT || !TARGET_RED_ZONE)
12115 {
12116 int size;
12117
12118 if (mode == DImode || TARGET_64BIT)
12119 size = 8;
12120 else if (mode == HImode && TARGET_PARTIAL_REG_STALL)
12121 size = 2;
12122 else
12123 size = 4;
12124 /* Use LEA to deallocate stack space. In peephole2 it will be converted
12125 to pop or add instruction if registers are available. */
12126 emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
12127 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
12128 GEN_INT (size))));
12129 }
4211a8fb 12130}
a946dd00 12131
f84aa48a
JH
12132/* Put float CONST_DOUBLE in the constant pool instead of fp regs.
12133 QImode must go into class Q_REGS.
12134 Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and
892a2d68 12135 movdf to do mem-to-mem moves through integer regs. */
f84aa48a
JH
12136enum reg_class
12137ix86_preferred_reload_class (x, class)
12138 rtx x;
12139 enum reg_class class;
12140{
12141 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
12142 {
12143 /* SSE can't load any constant directly yet. */
12144 if (SSE_CLASS_P (class))
12145 return NO_REGS;
12146 /* Floats can load 0 and 1. */
12147 if (MAYBE_FLOAT_CLASS_P (class) && standard_80387_constant_p (x))
12148 {
12149 /* Limit class to non-SSE. Use GENERAL_REGS if possible. */
12150 if (MAYBE_SSE_CLASS_P (class))
12151 return (reg_class_subset_p (class, GENERAL_REGS)
12152 ? GENERAL_REGS : FLOAT_REGS);
12153 else
12154 return class;
12155 }
12156 /* General regs can load everything. */
12157 if (reg_class_subset_p (class, GENERAL_REGS))
12158 return GENERAL_REGS;
12159 /* In case we haven't resolved FLOAT or SSE yet, give up. */
12160 if (MAYBE_FLOAT_CLASS_P (class) || MAYBE_SSE_CLASS_P (class))
12161 return NO_REGS;
12162 }
12163 if (MAYBE_MMX_CLASS_P (class) && CONSTANT_P (x))
12164 return NO_REGS;
12165 if (GET_MODE (x) == QImode && ! reg_class_subset_p (class, Q_REGS))
12166 return Q_REGS;
12167 return class;
12168}
12169
12170/* If we are copying between general and FP registers, we need a memory
12171 location. The same is true for SSE and MMX registers.
12172
12173 The macro can't work reliably when one of the CLASSES is class containing
12174 registers from multiple units (SSE, MMX, integer). We avoid this by never
12175 combining those units in single alternative in the machine description.
12176 Ensure that this constraint holds to avoid unexpected surprises.
12177
12178 When STRICT is false, we are being called from REGISTER_MOVE_COST, so do not
12179 enforce these sanity checks. */
12180int
12181ix86_secondary_memory_needed (class1, class2, mode, strict)
12182 enum reg_class class1, class2;
12183 enum machine_mode mode;
12184 int strict;
12185{
12186 if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
12187 || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
12188 || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
12189 || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
12190 || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
12191 || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2))
12192 {
12193 if (strict)
12194 abort ();
12195 else
12196 return 1;
12197 }
12198 return (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2)
12199 || (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
12200 && (mode) != SImode)
12201 || (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
12202 && (mode) != SImode));
12203}
12204/* Return the cost of moving data from a register in class CLASS1 to
a4f31c00 12205 one in class CLASS2.
f84aa48a
JH
12206
12207 It is not required that the cost always equal 2 when FROM is the same as TO;
12208 on some machines it is expensive to move between registers if they are not
12209 general registers. */
12210int
12211ix86_register_move_cost (mode, class1, class2)
12212 enum machine_mode mode;
12213 enum reg_class class1, class2;
12214{
12215 /* In case we require secondary memory, compute cost of the store followed
12216 by load. In case of copying from general_purpose_register we may emit
12217 multiple stores followed by single load causing memory size mismatch
12218 stall. Count this as arbitarily high cost of 20. */
12219 if (ix86_secondary_memory_needed (class1, class2, mode, 0))
12220 {
92d0fb09 12221 int add_cost = 0;
62415523 12222 if (CLASS_MAX_NREGS (class1, mode) > CLASS_MAX_NREGS (class2, mode))
92d0fb09 12223 add_cost = 20;
62415523 12224 return (MEMORY_MOVE_COST (mode, class1, 0)
92d0fb09 12225 + MEMORY_MOVE_COST (mode, class2, 1) + add_cost);
f84aa48a 12226 }
92d0fb09 12227 /* Moves between SSE/MMX and integer unit are expensive. */
62415523
JH
12228 if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
12229 || SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
fa79946e
JH
12230 return ix86_cost->mmxsse_to_integer;
12231 if (MAYBE_FLOAT_CLASS_P (class1))
12232 return ix86_cost->fp_move;
12233 if (MAYBE_SSE_CLASS_P (class1))
12234 return ix86_cost->sse_move;
12235 if (MAYBE_MMX_CLASS_P (class1))
12236 return ix86_cost->mmx_move;
f84aa48a
JH
12237 return 2;
12238}
12239
a946dd00
JH
12240/* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */
12241int
12242ix86_hard_regno_mode_ok (regno, mode)
12243 int regno;
12244 enum machine_mode mode;
12245{
12246 /* Flags and only flags can only hold CCmode values. */
12247 if (CC_REGNO_P (regno))
12248 return GET_MODE_CLASS (mode) == MODE_CC;
12249 if (GET_MODE_CLASS (mode) == MODE_CC
12250 || GET_MODE_CLASS (mode) == MODE_RANDOM
12251 || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
12252 return 0;
12253 if (FP_REGNO_P (regno))
12254 return VALID_FP_MODE_P (mode);
12255 if (SSE_REGNO_P (regno))
12256 return VALID_SSE_REG_MODE (mode);
12257 if (MMX_REGNO_P (regno))
47f339cf 12258 return VALID_MMX_REG_MODE (mode) || VALID_MMX_REG_MODE_3DNOW (mode);
a946dd00
JH
12259 /* We handle both integer and floats in the general purpose registers.
12260 In future we should be able to handle vector modes as well. */
12261 if (!VALID_INT_MODE_P (mode) && !VALID_FP_MODE_P (mode))
12262 return 0;
12263 /* Take care for QImode values - they can be in non-QI regs, but then
12264 they do cause partial register stalls. */
d2836273 12265 if (regno < 4 || mode != QImode || TARGET_64BIT)
a946dd00
JH
12266 return 1;
12267 return reload_in_progress || reload_completed || !TARGET_PARTIAL_REG_STALL;
12268}
fa79946e
JH
12269
12270/* Return the cost of moving data of mode M between a
12271 register and memory. A value of 2 is the default; this cost is
12272 relative to those in `REGISTER_MOVE_COST'.
12273
12274 If moving between registers and memory is more expensive than
12275 between two registers, you should define this macro to express the
a4f31c00
AJ
12276 relative cost.
12277
fa79946e
JH
12278 Model also increased moving costs of QImode registers in non
12279 Q_REGS classes.
12280 */
12281int
12282ix86_memory_move_cost (mode, class, in)
12283 enum machine_mode mode;
12284 enum reg_class class;
12285 int in;
12286{
12287 if (FLOAT_CLASS_P (class))
12288 {
12289 int index;
12290 switch (mode)
12291 {
12292 case SFmode:
12293 index = 0;
12294 break;
12295 case DFmode:
12296 index = 1;
12297 break;
12298 case XFmode:
12299 case TFmode:
12300 index = 2;
12301 break;
12302 default:
12303 return 100;
12304 }
12305 return in ? ix86_cost->fp_load [index] : ix86_cost->fp_store [index];
12306 }
12307 if (SSE_CLASS_P (class))
12308 {
12309 int index;
12310 switch (GET_MODE_SIZE (mode))
12311 {
12312 case 4:
12313 index = 0;
12314 break;
12315 case 8:
12316 index = 1;
12317 break;
12318 case 16:
12319 index = 2;
12320 break;
12321 default:
12322 return 100;
12323 }
12324 return in ? ix86_cost->sse_load [index] : ix86_cost->sse_store [index];
12325 }
12326 if (MMX_CLASS_P (class))
12327 {
12328 int index;
12329 switch (GET_MODE_SIZE (mode))
12330 {
12331 case 4:
12332 index = 0;
12333 break;
12334 case 8:
12335 index = 1;
12336 break;
12337 default:
12338 return 100;
12339 }
12340 return in ? ix86_cost->mmx_load [index] : ix86_cost->mmx_store [index];
12341 }
12342 switch (GET_MODE_SIZE (mode))
12343 {
12344 case 1:
12345 if (in)
12346 return (Q_CLASS_P (class) ? ix86_cost->int_load[0]
12347 : ix86_cost->movzbl_load);
12348 else
12349 return (Q_CLASS_P (class) ? ix86_cost->int_store[0]
12350 : ix86_cost->int_store[0] + 4);
12351 break;
12352 case 2:
12353 return in ? ix86_cost->int_load[1] : ix86_cost->int_store[1];
12354 default:
12355 /* Compute number of 32bit moves needed. TFmode is moved as XFmode. */
12356 if (mode == TFmode)
12357 mode = XFmode;
3bb7e126 12358 return ((in ? ix86_cost->int_load[2] : ix86_cost->int_store[2])
fa79946e
JH
12359 * (int) GET_MODE_SIZE (mode) / 4);
12360 }
12361}
0ecf09f9 12362
2cc07db4
RH
12363#ifdef DO_GLOBAL_CTORS_BODY
12364static void
12365ix86_svr3_asm_out_constructor (symbol, priority)
12366 rtx symbol;
12367 int priority ATTRIBUTE_UNUSED;
12368{
12369 init_section ();
12370 fputs ("\tpushl $", asm_out_file);
12371 assemble_name (asm_out_file, XSTR (symbol, 0));
12372 fputc ('\n', asm_out_file);
12373}
12374#endif
This page took 2.947392 seconds and 5 git commands to generate.