1 --- gcc/gcc/builtins.c 2005-07-12 11:19:59.000000000 +0200
2 +++ gcc/gcc/builtins.c 2005-07-18 06:14:15.000000000 +0200
3 @@ -52,6 +52,14 @@ Software Foundation, 51 Franklin Street,
4 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
7 +#ifndef FUNCTION_VALUE_REGNO_P_APPLY_RESULT
8 +#define FUNCTION_VALUE_REGNO_P_APPLY_RESULT FUNCTION_VALUE_REGNO_P
11 +#ifndef FUNCTION_ARG_REGNO_P_APPLY_ARGS
12 +#define FUNCTION_ARG_REGNO_P_APPLY_ARGS FUNCTION_ARG_REGNO_P
15 /* Define the names of the builtin function types and codes. */
16 const char *const built_in_class_names[4]
17 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
18 @@ -1079,7 +1087,7 @@ apply_args_size (void)
19 size += GET_MODE_SIZE (Pmode);
21 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
22 - if (FUNCTION_ARG_REGNO_P (regno))
23 + if (FUNCTION_ARG_REGNO_P_APPLY_ARGS (regno))
25 mode = reg_raw_mode[regno];
27 @@ -1117,7 +1125,7 @@ apply_result_size (void)
30 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
31 - if (FUNCTION_VALUE_REGNO_P (regno))
32 + if (FUNCTION_VALUE_REGNO_P_APPLY_RESULT (regno))
34 mode = reg_raw_mode[regno];
36 --- gcc/gcc/caller-save.c 2005-06-25 03:59:25.000000000 +0200
37 +++ gcc/gcc/caller-save.c 2005-07-18 06:14:15.000000000 +0200
38 @@ -377,6 +377,7 @@ save_call_clobbered_regs (void)
40 rtx insn = chain->insn;
41 enum rtx_code code = GET_CODE (insn);
42 + rtx reg ATTRIBUTE_UNUSED;
46 @@ -450,6 +451,12 @@ save_call_clobbered_regs (void)
47 CLEAR_HARD_REG_SET (this_insn_sets);
48 note_stores (PATTERN (insn), mark_set_regs, NULL);
50 +#ifdef CALL_INSN_SETS
51 + reg = CALL_INSN_SETS (insn);
54 + mark_set_regs (reg, NULL_RTX, NULL);
56 /* Compute which hard regs must be saved before this call. */
57 AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set);
58 AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets);
59 --- gcc/gcc/config/i386/i386.c 2005-07-14 09:46:16.000000000 +0200
60 +++ gcc/gcc/config/i386/i386.c 2005-07-18 06:14:15.000000000 +0200
61 @@ -2067,12 +2067,13 @@ ix86_return_pops_args (tree fundecl, tre
63 /* Return true when register may be used to pass function parameters. */
65 -ix86_function_arg_regno_p (int regno)
66 +ix86_function_arg_regno_p (int regno, bool from_builtin)
70 return (regno < REGPARM_MAX
71 - || (TARGET_MMX && MMX_REGNO_P (regno)
72 + || (TARGET_MMX && !(TARGET_80387 && from_builtin)
73 + && MMX_REGNO_P (regno)
74 && (regno < FIRST_MMX_REG + MMX_REGPARM_MAX))
75 || (TARGET_SSE && SSE_REGNO_P (regno)
76 && (regno < FIRST_SSE_REG + SSE_REGPARM_MAX)));
77 @@ -3181,14 +3182,14 @@ ix86_function_arg_boundary (enum machine
79 /* Return true if N is a possible register number of function value. */
81 -ix86_function_value_regno_p (int regno)
82 +ix86_function_value_regno_p (int regno, bool from_builtin)
85 || (regno == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)
86 || (regno == FIRST_SSE_REG && TARGET_SSE))
90 + if (!TARGET_64BIT && !(TARGET_80387 && from_builtin)
91 && (regno == FIRST_MMX_REG && TARGET_MMX))
94 @@ -7450,12 +7451,152 @@ output_387_binary_op (rtx insn, rtx *ope
98 -/* Return needed mode for entity in optimize_mode_switching pass. */
99 +/* Return needed mode for entity in optimize_mode_switching pass.
100 + Returned mode should match ix86_mode_entry () for function calls. */
103 ix86_mode_needed (int entity, rtx insn)
105 - enum attr_i387_cw mode;
108 + if (entity == I387_FPU_MODE)
110 + /* If a function call uses MMX registers, select MMX FPU mode and
111 + if function call uses x87 registers, select x87 FPU mode. */
119 + for (link = CALL_INSN_FUNCTION_USAGE (insn);
121 + link = XEXP (link, 1))
123 + if (GET_CODE (XEXP (link, 0)) == USE)
125 + reg = XEXP (XEXP (link, 0), 0);
129 + if (MMX_REG_P (reg))
132 + if (FP_REG_P (reg))
138 + /* Mixing of x87 and MMX registers is not allowed
139 + in function call. */
140 + gcc_assert (!mmx || !x87);
143 + return FPU_MODE_MMX;
145 + /* Fall back to default mode. */
146 + return FPU_MODE_X87;
149 + /* Parse ASM operands to check input and output constraints. If
150 + an ASM uses MMX registers, select MMX mode and if it uses x87
151 + registers, select x87 mode. Mixing of MMX and x87 constraints
152 + is not allowed. If no MMX or x87 input and output registers
153 + are used, switch to default mode. */
154 + if (NONJUMP_INSN_P (insn))
156 + rtx pat = PATTERN (insn);
157 + int noperands = asm_noperands (pat);
159 + if (noperands >= 0)
161 + const char **constraints;
166 + constraints = alloca (noperands * sizeof (char *));
167 + decode_asm_operands (pat, NULL, NULL, constraints, NULL);
169 + for (i = 0; i < noperands; i++)
171 + const char *c = constraints[i];
172 + enum reg_class class;
176 + if (ISDIGIT ((unsigned char) c[0]) && c[1] == '\0')
177 + c = constraints[c[0] - '0'];
199 + class = REG_CLASS_FROM_LETTER (cc);
201 + if (MMX_CLASS_P (class))
204 + if (FLOAT_CLASS_P (class))
208 + len = CONSTRAINT_LEN (cc, c);
211 + while (--len && *c);
215 + /* Mixing x87 and MMX registers in ASM is not allowed. */
217 + error_for_asm (insn, "mixing of x87 and MMX registers "
218 + "is not allowed in %<asm%>");
221 + return FPU_MODE_MMX;
223 + /* Fall back to default mode. */
224 + return FPU_MODE_X87;
228 + if (recog_memoized (insn) < 0)
229 + return FPU_MODE_ANY;
231 + unit = get_attr_unit (insn);
236 + return FPU_MODE_MMX;
239 + return FPU_MODE_X87;
242 + return FPU_MODE_ANY;
247 /* The mode UNINITIALIZED is used to store control word after a
248 function call or ASM pattern. The mode ANY specify that function
249 @@ -7502,21 +7643,132 @@ ix86_mode_needed (int entity, rtx insn)
253 -/* Output code to initialize control word copies used by trunc?f?i and
254 - rounding patterns. CURRENT_MODE is set to current control word,
255 - while NEW_MODE is set to new control word. */
257 +/* Switch FPU mode to appropriate mode after function call in
258 + optimize_mode_switchig pass. Returned mode should match
259 + ix86_mode_exit (). */
262 +ix86_mode_after (int entity, int mode, rtx insn)
264 + if (entity == I387_FPU_MODE)
266 + /* Switch FPU to MMX mode after funciton call if function value
267 + is returned in MMX register and similar for x87 reg.
268 + If no value is returned in MMX or x87 reg, fall back to
272 + rtx reg = SET_DEST (PATTERN (insn));
276 + if (reg && MMX_REG_P (reg))
277 + new_mode = FPU_MODE_MMX;
279 + new_mode = FPU_MODE_X87;
281 + /* Call insn should never operate in FPU_MODE_ANY. */
282 + if ((mode != FPU_MODE_ANY) && (new_mode != mode))
283 + ix86_fpu_mode_changed = 1;
292 +/* Switch FPU mode of function entry to appropriate mode in
293 + optimize_mode_switchig pass. Returned mode should match
294 + ix86_mode_needed () for function calls. */
297 +ix86_mode_entry (int entity)
299 + if (entity == I387_FPU_MODE)
301 + if (! current_function_args_info.maybe_vaarg)
303 + if (current_function_args_info.mmx_nregs != MMX_REGPARM_MAX)
304 + return FPU_MODE_MMX;
306 + /* ??? Handle x87 registers for fpregparm. */
309 + /* Fall back to default mode. */
310 + return FPU_MODE_X87;
313 + return I387_CW_ANY;
316 +/* Switch FPU mode of function exit to appropriate mode in
317 + optimize_mode_switchig pass. Returned mode should match
318 + ix86_mode_after () for function calls. */
321 +ix86_mode_exit (int entity)
323 + if (entity == I387_FPU_MODE)
325 + rtx reg = current_function_return_rtx;
327 + /* If MMX output register is specified, switch FPU mode
328 + of function exit to MMX mode. */
329 + if (reg && MMX_REG_P (reg))
330 + return FPU_MODE_MMX;
332 + /* Fall back to default mode. */
333 + return FPU_MODE_X87;
336 + return I387_CW_ANY;
339 +/* Emit mode switching instructions in optimize_mode_switching pass. */
342 -emit_i387_cw_initialization (int mode)
343 +ix86_emit_mode_set (int entity, int mode)
345 - rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
347 + rtx stored_mode, new_mode;
352 - rtx reg = gen_reg_rtx (HImode);
353 + if (entity == I387_FPU_MODE)
361 + emit_insn (gen_emms ());
362 + ix86_fpu_mode_changed = 1;
366 + emit_insn (gen_efpu ());
367 + ix86_fpu_mode_changed = 1;
371 + gcc_unreachable ();
375 + /* Output code to initialize control word copies used by trunc?f?i
376 + and rounding patterns. STORED_MODE is set to current control
377 + word, while NEW_MODE is set to new control word. */
379 + if ((mode == I387_CW_UNINITIALIZED) || (mode == I387_CW_ANY))
382 + stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
383 emit_insn (gen_x86_fnstcw_1 (stored_mode));
385 + reg = gen_reg_rtx (HImode);
386 emit_move_insn (reg, stored_mode);
388 if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
389 @@ -12279,6 +12531,7 @@ ix86_init_machine_status (void)
391 f = ggc_alloc_cleared (sizeof (struct machine_function));
392 f->use_fast_prologue_epilogue_nregs = -1;
393 + f->optimize_mode_switching[I387_FPU_MODE] = TARGET_80387 && TARGET_MMX;
397 @@ -12877,7 +13130,77 @@ ix86_local_alignment (tree type, int ali
404 +/* Return true to prevent register allocator from allocating registers
405 + from the unit that is not active. */
408 +ix86_epilogue_uses (int regno)
412 + if (! ix86_fpu_mode_changed)
415 + mode = ix86_mode_exit (I387_FPU_MODE);
417 + if (mode == FPU_MODE_MMX)
418 + return FP_REGNO_P (regno);
420 + return MMX_REGNO_P (regno);
423 +/* Return RTX code of additional register that CALL_INSN uses.
424 + This function is used to maintain correct register life
425 + information before CALL_INSN in case of MMX/x87 switching. */
428 +ix86_call_insn_uses (rtx insn)
432 + if (! ix86_fpu_mode_changed)
435 + gcc_assert (CALL_P (insn));
437 + mode = ix86_mode_needed (I387_FPU_MODE, insn);
438 + if (mode == FPU_MODE_MMX)
439 + return gen_rtx_REG (ALLREGSmode, FIRST_FLOAT_REG);
441 + return gen_rtx_REG (ALLREGSmode, FIRST_MMX_REG);
446 +/* Return RTX code of additional register that CALL_INSN sets.
447 + This function is used to maintain correct register life
448 + information after CALL_INSN in case of MMX/x87 switching. */
451 +ix86_call_insn_sets (rtx insn)
455 + if (! ix86_fpu_mode_changed)
458 + gcc_assert (CALL_P (insn));
460 + /* Current mode in call to ix86_mode_after is set to FPU_MODE_ANY
461 + to prevent setting of ix86_fpu_mode_changed variable. */
462 + mode = ix86_mode_after (I387_FPU_MODE, FPU_MODE_ANY, insn);
463 + if (mode == FPU_MODE_MMX)
464 + return gen_rtx_REG (ALLREGSmode, FIRST_FLOAT_REG);
466 + return gen_rtx_REG (ALLREGSmode, FIRST_MMX_REG);
472 /* Emit RTL insns to initialize the variable parts of a trampoline.
473 FNADDR is an RTX for the address of the function's pure code.
474 CXT is an RTX for the static chain value for the function. */
475 @@ -13357,9 +13680,11 @@ enum ix86_builtins
476 IX86_BUILTIN_MONITOR,
479 + IX86_BUILTIN_VEC_INIT_V2SF,
480 IX86_BUILTIN_VEC_INIT_V2SI,
481 IX86_BUILTIN_VEC_INIT_V4HI,
482 IX86_BUILTIN_VEC_INIT_V8QI,
483 + IX86_BUILTIN_VEC_EXT_V2SF,
484 IX86_BUILTIN_VEC_EXT_V2DF,
485 IX86_BUILTIN_VEC_EXT_V2DI,
486 IX86_BUILTIN_VEC_EXT_V4SF,
487 @@ -13541,24 +13866,24 @@ static const struct builtin_description
488 { MASK_SSE, CODE_FOR_sse_cvtsi2ss, 0, IX86_BUILTIN_CVTSI2SS, 0, 0 },
489 { MASK_SSE | MASK_64BIT, CODE_FOR_sse_cvtsi2ssq, 0, IX86_BUILTIN_CVTSI642SS, 0, 0 },
491 - { MASK_MMX, CODE_FOR_mmx_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
492 - { MASK_MMX, CODE_FOR_mmx_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
493 - { MASK_MMX, CODE_FOR_mmx_ashlv2si3, 0, IX86_BUILTIN_PSLLD, 0, 0 },
494 - { MASK_MMX, CODE_FOR_mmx_ashlv2si3, 0, IX86_BUILTIN_PSLLDI, 0, 0 },
495 + { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
496 + { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
497 + { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLD, 0, 0 },
498 + { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLDI, 0, 0 },
499 { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQ, 0, 0 },
500 { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQI, 0, 0 },
502 - { MASK_MMX, CODE_FOR_mmx_lshrv4hi3, 0, IX86_BUILTIN_PSRLW, 0, 0 },
503 - { MASK_MMX, CODE_FOR_mmx_lshrv4hi3, 0, IX86_BUILTIN_PSRLWI, 0, 0 },
504 - { MASK_MMX, CODE_FOR_mmx_lshrv2si3, 0, IX86_BUILTIN_PSRLD, 0, 0 },
505 - { MASK_MMX, CODE_FOR_mmx_lshrv2si3, 0, IX86_BUILTIN_PSRLDI, 0, 0 },
506 + { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLW, 0, 0 },
507 + { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLWI, 0, 0 },
508 + { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLD, 0, 0 },
509 + { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLDI, 0, 0 },
510 { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQ, 0, 0 },
511 { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQI, 0, 0 },
513 - { MASK_MMX, CODE_FOR_mmx_ashrv4hi3, 0, IX86_BUILTIN_PSRAW, 0, 0 },
514 - { MASK_MMX, CODE_FOR_mmx_ashrv4hi3, 0, IX86_BUILTIN_PSRAWI, 0, 0 },
515 - { MASK_MMX, CODE_FOR_mmx_ashrv2si3, 0, IX86_BUILTIN_PSRAD, 0, 0 },
516 - { MASK_MMX, CODE_FOR_mmx_ashrv2si3, 0, IX86_BUILTIN_PSRADI, 0, 0 },
517 + { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAW, 0, 0 },
518 + { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAWI, 0, 0 },
519 + { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRAD, 0, 0 },
520 + { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRADI, 0, 0 },
522 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_psadbw, 0, IX86_BUILTIN_PSADBW, 0, 0 },
523 { MASK_MMX, CODE_FOR_mmx_pmaddwd, 0, IX86_BUILTIN_PMADDWD, 0, 0 },
524 @@ -14323,6 +14648,11 @@ ix86_init_mmx_sse_builtins (void)
525 v16qi_ftype_pcchar, IX86_BUILTIN_LDDQU);
527 /* Access to the vec_init patterns. */
528 + ftype = build_function_type_list (V2SF_type_node, float_type_node,
529 + integer_type_node, NULL_TREE);
530 + def_builtin (MASK_3DNOW, "__builtin_ia32_vec_init_v2sf",
531 + ftype, IX86_BUILTIN_VEC_INIT_V2SF);
533 ftype = build_function_type_list (V2SI_type_node, integer_type_node,
534 integer_type_node, NULL_TREE);
535 def_builtin (MASK_MMX, "__builtin_ia32_vec_init_v2si",
536 @@ -14344,6 +14674,11 @@ ix86_init_mmx_sse_builtins (void)
537 ftype, IX86_BUILTIN_VEC_INIT_V8QI);
539 /* Access to the vec_extract patterns. */
540 + ftype = build_function_type_list (float_type_node, V2SF_type_node,
541 + integer_type_node, NULL_TREE);
542 + def_builtin (MASK_3DNOW, "__builtin_ia32_vec_ext_v2sf",
543 + ftype, IX86_BUILTIN_VEC_EXT_V2DF);
545 ftype = build_function_type_list (double_type_node, V2DF_type_node,
546 integer_type_node, NULL_TREE);
547 def_builtin (MASK_SSE, "__builtin_ia32_vec_ext_v2df",
548 @@ -14818,7 +15153,7 @@ ix86_expand_builtin (tree exp, rtx targe
551 case IX86_BUILTIN_EMMS:
552 - emit_insn (gen_mmx_emms ());
553 + /* emms insn is emitted automatically. */
556 case IX86_BUILTIN_SFENCE:
557 @@ -15035,7 +15370,7 @@ ix86_expand_builtin (tree exp, rtx targe
560 case IX86_BUILTIN_FEMMS:
561 - emit_insn (gen_mmx_femms ());
562 + /* femms insn is emitted automatically. */
565 case IX86_BUILTIN_PAVGUSB:
566 @@ -15181,11 +15516,13 @@ ix86_expand_builtin (tree exp, rtx targe
567 return ix86_expand_unop_builtin (CODE_FOR_sse3_lddqu, arglist,
570 + case IX86_BUILTIN_VEC_INIT_V2SF:
571 case IX86_BUILTIN_VEC_INIT_V2SI:
572 case IX86_BUILTIN_VEC_INIT_V4HI:
573 case IX86_BUILTIN_VEC_INIT_V8QI:
574 return ix86_expand_vec_init_builtin (TREE_TYPE (exp), arglist, target);
576 + case IX86_BUILTIN_VEC_EXT_V2SF:
577 case IX86_BUILTIN_VEC_EXT_V2DF:
578 case IX86_BUILTIN_VEC_EXT_V2DI:
579 case IX86_BUILTIN_VEC_EXT_V4SF:
580 --- gcc/gcc/config/i386/i386.h 2005-07-14 09:46:21.000000000 +0200
581 +++ gcc/gcc/config/i386/i386.h 2005-07-18 06:14:15.000000000 +0200
582 @@ -819,7 +819,9 @@ do { \
584 #define HARD_REGNO_NREGS(REGNO, MODE) \
585 (FP_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO) \
586 - ? (COMPLEX_MODE_P (MODE) ? 2 : 1) \
587 + ? ((MODE) == ALLREGSmode \
589 + : (COMPLEX_MODE_P (MODE) ? 2 : 1)) \
590 : ((MODE) == XFmode \
591 ? (TARGET_64BIT ? 2 : 3) \
593 @@ -841,9 +843,8 @@ do { \
594 ((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode \
595 || (MODE) == V2SImode || (MODE) == SImode)
597 -/* ??? No autovectorization into MMX or 3DNOW until we can reliably
598 - place emms and femms instructions. */
599 -#define UNITS_PER_SIMD_WORD (TARGET_SSE ? 16 : UNITS_PER_WORD)
600 +#define UNITS_PER_SIMD_WORD \
601 + (TARGET_SSE ? 16 : TARGET_MMX ? 8 : UNITS_PER_WORD)
603 #define VALID_FP_MODE_P(MODE) \
604 ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \
605 @@ -1433,8 +1434,16 @@ enum reg_class
606 #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) \
607 ix86_return_pops_args ((FUNDECL), (FUNTYPE), (SIZE))
609 +/* 1 if N is the number of a register in which the values of
610 + called function may come back. */
611 #define FUNCTION_VALUE_REGNO_P(N) \
612 - ix86_function_value_regno_p (N)
613 + ix86_function_value_regno_p ((N), false)
615 +/* 1 if N is the number of a register in which the value of
616 + __builtin_return builtin function may come back. */
618 +#define FUNCTION_VALUE_REGNO_P_APPLY_RESULT(N) \
619 + ix86_function_value_regno_p ((N), true)
621 /* Define how to find the value returned by a library function
622 assuming the value has mode MODE. */
623 @@ -1449,7 +1458,13 @@ enum reg_class
624 #define APPLY_RESULT_SIZE (8+108)
626 /* 1 if N is a possible register number for function argument passing. */
627 -#define FUNCTION_ARG_REGNO_P(N) ix86_function_arg_regno_p (N)
628 +#define FUNCTION_ARG_REGNO_P(N) ix86_function_arg_regno_p ((N), false)
630 +/* 1 if N is a possible register number for function argument passing
631 + from __builtin_apply_args and __builtin_apply builtin functions. */
633 +#define FUNCTION_ARG_REGNO_P_APPLY_ARGS(N) \
634 + ix86_function_arg_regno_p ((N), true)
636 /* Define a data type for recording info about an argument list
637 during the scan of that argument list. This data type should
638 @@ -1531,6 +1546,23 @@ typedef struct ix86_args {
640 #define EXIT_IGNORE_STACK 1
642 +/* Define this macro as a C expression that is nonzero for registers
643 + that are used by the epilogue or the return' pattern. The stack
644 + and frame pointer registers are already be assumed to be used as
647 +#define EPILOGUE_USES(REGNO) ix86_epilogue_uses (REGNO)
649 +/* Define this macro as a C expression that returns RTL expression of
650 + additional hard register set by call_insn. */
652 +#define CALL_INSN_SETS(INSN) ix86_call_insn_sets (INSN)
654 +/* Define this macro as a C expression that returns RTL expression of
655 + additional hard register used by call_insn. */
657 +#define CALL_INSN_USES(INSN) ix86_call_insn_uses (INSN)
659 /* Output assembler code for a block containing the constant parts
660 of a trampoline, leaving space for the variable parts. */
662 @@ -2167,6 +2199,10 @@ extern rtx ix86_compare_op0; /* operand
663 extern rtx ix86_compare_op1; /* operand 1 for comparisons */
664 extern rtx ix86_compare_emitted;
667 +/* x87 FPU modes for x87/MMX switching. */
668 +enum ix86_fpu_mode { FPU_MODE_X87, FPU_MODE_MMX, FPU_MODE_ANY };
670 /* To properly truncate FP values into integers, we need to set i387 control
671 word. We can't emit proper mode switching code before reload, as spills
672 generated by reload may truncate values incorrectly, but we still can avoid
673 @@ -2188,6 +2224,7 @@ enum ix86_entity
681 @@ -2217,7 +2254,12 @@ enum ix86_stack_slot
682 refer to the mode-switched entity in question. */
684 #define NUM_MODES_FOR_MODE_SWITCHING \
685 - { I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY }
686 + { I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, FPU_MODE_ANY }
688 +/* Define this macro if the port needs extra register life analysis
689 + after mode switching. */
691 +#define LIFE_ANALYSIS_AFTER_MODE_SWITCHING ix86_fpu_mode_changed
693 /* ENTITY is an integer specifying a mode-switched entity. If
694 `OPTIMIZE_MODE_SWITCHING' is defined, you must define this macro to
695 @@ -2227,6 +2269,22 @@ enum ix86_stack_slot
697 #define MODE_NEEDED(ENTITY, I) ix86_mode_needed ((ENTITY), (I))
699 +/* This macro determines the mode that an INSN results in (if different
700 + from the incoming mode). */
702 +#define MODE_AFTER(ENTITY, MODE, I) \
703 + ix86_mode_after ((ENTITY), (MODE), (I))
705 +/* This macro specifies a mode that ENTITY is assumed to be
706 + switched to at function entry. */
708 +#define MODE_ENTRY(ENTITY) ix86_mode_entry (ENTITY)
710 +/* This macro specifies a mode that ENTITY is assumed to be
711 + switched to at function exit. */
713 +#define MODE_EXIT(ENTITY) ix86_mode_exit (ENTITY)
715 /* This macro specifies the order in which modes for ENTITY are
716 processed. 0 is the highest priority. */
718 @@ -2236,10 +2294,8 @@ enum ix86_stack_slot
719 is the set of hard registers live at the point where the insn(s)
720 are to be inserted. */
722 -#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
723 - ((MODE) != I387_CW_ANY && (MODE) != I387_CW_UNINITIALIZED \
724 - ? emit_i387_cw_initialization (MODE), 0 \
726 +#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
727 + ix86_emit_mode_set ((ENTITY), (MODE))
730 /* Avoid renaming of stack registers, as doing so in combination with
731 @@ -2263,6 +2319,7 @@ struct machine_function GTY(())
732 int save_varrargs_registers;
733 int accesses_prev_frame;
734 int optimize_mode_switching[MAX_386_ENTITIES];
735 + int fpu_mode_changed;
736 /* Set by ix86_compute_frame_layout and used by prologue/epilogue expander to
737 determine the style used. */
738 int use_fast_prologue_epilogue;
739 @@ -2274,6 +2331,7 @@ struct machine_function GTY(())
740 #define ix86_stack_locals (cfun->machine->stack_locals)
741 #define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
742 #define ix86_optimize_mode_switching (cfun->machine->optimize_mode_switching)
743 +#define ix86_fpu_mode_changed (cfun->machine->fpu_mode_changed)
745 /* Control behavior of x86_file_start. */
746 #define X86_FILE_START_VERSION_DIRECTIVE false
747 --- gcc/gcc/config/i386/i386.md 2005-07-12 11:20:12.000000000 +0200
748 +++ gcc/gcc/config/i386/i386.md 2005-07-18 06:14:15.000000000 +0200
769 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
770 --- gcc/gcc/config/i386/i386-modes.def 2005-06-25 03:21:07.000000000 +0200
771 +++ gcc/gcc/config/i386/i386-modes.def 2005-07-18 06:14:15.000000000 +0200
772 @@ -62,6 +62,9 @@ CC_MODE (CCZ);
776 +/* This mode is used to cover all MMX and all x87 registers. */
777 +RANDOM_MODE (ALLREGS);
780 VECTOR_MODES (INT, 4); /* V4QI V2HI */
781 VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
782 --- gcc/gcc/config/i386/i386-protos.h 2005-07-14 09:46:16.000000000 +0200
783 +++ gcc/gcc/config/i386/i386-protos.h 2005-07-18 06:14:15.000000000 +0200
784 @@ -152,6 +152,9 @@ extern bool ix86_expand_fp_vcond (rtx[])
785 extern bool ix86_expand_int_vcond (rtx[]);
786 extern int ix86_expand_int_addcc (rtx[]);
787 extern void ix86_expand_call (rtx, rtx, rtx, rtx, rtx, int);
788 +extern bool ix86_epilogue_uses (int);
789 +extern rtx ix86_call_insn_sets (rtx);
790 +extern rtx ix86_call_insn_uses (rtx);
791 extern void x86_initialize_trampoline (rtx, rtx, rtx);
792 extern rtx ix86_zero_extend_to_Pmode (rtx);
793 extern void ix86_split_long_move (rtx[]);
794 @@ -168,8 +171,8 @@ extern int ix86_attr_length_address_defa
795 extern enum machine_mode ix86_fp_compare_mode (enum rtx_code);
797 extern rtx ix86_libcall_value (enum machine_mode);
798 -extern bool ix86_function_value_regno_p (int);
799 -extern bool ix86_function_arg_regno_p (int);
800 +extern bool ix86_function_value_regno_p (int, bool);
801 +extern bool ix86_function_arg_regno_p (int, bool);
802 extern int ix86_function_arg_boundary (enum machine_mode, tree);
803 extern int ix86_return_in_memory (tree);
804 extern void ix86_va_start (tree, rtx);
805 @@ -190,7 +193,10 @@ extern bool ix86_cannot_change_mode_clas
806 extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
807 extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
808 extern int ix86_mode_needed (int, rtx);
809 -extern void emit_i387_cw_initialization (int);
810 +extern int ix86_mode_after (int, int, rtx);
811 +extern int ix86_mode_entry (int);
812 +extern int ix86_mode_exit (int);
813 +extern void ix86_emit_mode_set (int, int);
814 extern bool ix86_fp_jump_nontrivial_p (enum rtx_code);
815 extern void x86_order_regs_for_local_alloc (void);
816 extern void x86_function_profiler (FILE *, int);
817 --- gcc/gcc/config/i386/mm3dnow.h 2005-06-25 03:21:23.000000000 +0200
818 +++ gcc/gcc/config/i386/mm3dnow.h 2005-07-18 06:14:15.000000000 +0200
819 @@ -172,14 +172,13 @@ _m_prefetchw (void *__P)
820 static __inline __m64
821 _m_from_float (float __A)
823 - return (__m64)(__v2sf){ __A, 0 };
824 + return (__m64) __builtin_ia32_vec_init_v2sf (__A, 0);
827 static __inline float
828 _m_to_float (__m64 __A)
830 - union { __v2sf v; float a[2]; } __tmp = { (__v2sf)__A };
832 + return __builtin_ia32_vec_ext_v2sf ((__v2sf)__A, 0);
836 --- gcc/gcc/config/i386/mmx.md 2005-06-25 03:21:23.000000000 +0200
837 +++ gcc/gcc/config/i386/mmx.md 2005-07-18 06:14:15.000000000 +0200
839 ;; the same register file, and 3dNOW! adds a number of extensions to
840 ;; the base integer MMX isa.
842 -;; Note! Except for the basic move instructions, *all* of these
843 -;; patterns are outside the normal optabs namespace. This is because
844 -;; use of these registers requires the insertion of emms or femms
845 -;; instructions to return to normal fpu mode. The compiler doesn't
846 -;; know how to do that itself, which means it's up to the user. Which
847 -;; means that we should never use any of these patterns except at the
848 -;; direction of the user via a builtin.
850 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
851 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
854 (match_operand 2 "const_int_operand" "")]
857 - ix86_expand_vector_set (false, operands[0], operands[1],
858 + ix86_expand_vector_set (true, operands[0], operands[1],
859 INTVAL (operands[2]));
863 (match_operand 2 "const_int_operand" "")]
866 - ix86_expand_vector_extract (false, operands[0], operands[1],
867 + ix86_expand_vector_extract (true, operands[0], operands[1],
868 INTVAL (operands[2]));
872 (match_operand 1 "" "")]
875 - ix86_expand_vector_init (false, operands[0], operands[1]);
876 + ix86_expand_vector_init (true, operands[0], operands[1]);
882 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
884 +(define_expand "neg<mode>2"
885 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
888 + (match_operand:MMXMODEI 1 "nonimmediate_operand" "")))]
890 + "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
892 +(define_expand "add<mode>3"
893 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
894 + (plus:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
895 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
897 + "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
899 (define_insn "mmx_add<mode>3"
900 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
903 [(set_attr "type" "mmxadd")
904 (set_attr "mode" "DI")])
906 +(define_expand "sub<mode>3"
907 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
908 + (minus:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "")
909 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
911 + "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
913 (define_insn "mmx_sub<mode>3"
914 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
917 [(set_attr "type" "mmxadd")
918 (set_attr "mode" "DI")])
920 +(define_expand "mulv4hi3"
921 + [(set (match_operand:V4HI 0 "register_operand" "")
922 + (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
923 + (match_operand:V4HI 2 "nonimmediate_operand" "")))]
925 + "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
927 (define_insn "mmx_mulv4hi3"
928 [(set (match_operand:V4HI 0 "register_operand" "=y")
929 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
931 [(set_attr "type" "mmxmul")
932 (set_attr "mode" "DI")])
934 +(define_expand "umaxv8qi3"
935 + [(set (match_operand:V8QI 0 "register_operand" "")
936 + (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "")
937 + (match_operand:V8QI 2 "nonimmediate_operand" "")))]
938 + "(TARGET_SSE || TARGET_3DNOW_A)"
939 + "ix86_fixup_binary_operands_no_copy (UMAX, V8QImode, operands);")
941 (define_insn "mmx_umaxv8qi3"
942 [(set (match_operand:V8QI 0 "register_operand" "=y")
943 (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
945 [(set_attr "type" "mmxadd")
946 (set_attr "mode" "DI")])
948 +(define_expand "smaxv4hi3"
949 + [(set (match_operand:V4HI 0 "register_operand" "")
950 + (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
951 + (match_operand:V4HI 2 "nonimmediate_operand" "")))]
952 + "(TARGET_SSE || TARGET_3DNOW_A)"
953 + "ix86_fixup_binary_operands_no_copy (SMAX, V4HImode, operands);")
955 (define_insn "mmx_smaxv4hi3"
956 [(set (match_operand:V4HI 0 "register_operand" "=y")
957 (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
959 [(set_attr "type" "mmxadd")
960 (set_attr "mode" "DI")])
962 +(define_expand "uminv8qi3"
963 + [(set (match_operand:V8QI 0 "register_operand" "")
964 + (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "")
965 + (match_operand:V8QI 2 "nonimmediate_operand" "")))]
966 + "(TARGET_SSE || TARGET_3DNOW_A)"
967 + "ix86_fixup_binary_operands_no_copy (UMAX, V8QImode, operands);")
969 (define_insn "mmx_uminv8qi3"
970 [(set (match_operand:V8QI 0 "register_operand" "=y")
971 (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
973 [(set_attr "type" "mmxadd")
974 (set_attr "mode" "DI")])
976 +(define_expand "sminv4hi3"
977 + [(set (match_operand:V4HI 0 "register_operand" "")
978 + (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
979 + (match_operand:V4HI 2 "nonimmediate_operand" "")))]
980 + "(TARGET_SSE || TARGET_3DNOW_A)"
981 + "ix86_fixup_binary_operands_no_copy (SMIN, V4HImode, operands);")
983 (define_insn "mmx_sminv4hi3"
984 [(set (match_operand:V4HI 0 "register_operand" "=y")
985 (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
987 [(set_attr "type" "mmxadd")
988 (set_attr "mode" "DI")])
990 -(define_insn "mmx_ashr<mode>3"
991 +(define_insn "ashr<mode>3"
992 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
994 (match_operand:MMXMODE24 1 "register_operand" "0")
996 [(set_attr "type" "mmxshft")
997 (set_attr "mode" "DI")])
999 -(define_insn "mmx_lshr<mode>3"
1000 +(define_insn "lshr<mode>3"
1001 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
1003 (match_operand:MMXMODE24 1 "register_operand" "0")
1005 [(set_attr "type" "mmxshft")
1006 (set_attr "mode" "DI")])
1008 -(define_insn "mmx_ashl<mode>3"
1009 +(define_insn "ashl<mode>3"
1010 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
1012 (match_operand:MMXMODE24 1 "register_operand" "0")
1013 @@ -853,12 +902,66 @@
1014 [(set_attr "type" "mmxcmp")
1015 (set_attr "mode" "DI")])
1017 +(define_expand "vcond<mode>"
1018 + [(set (match_operand:MMXMODE12 0 "register_operand" "")
1019 + (if_then_else:MMXMODE12
1020 + (match_operator 3 ""
1021 + [(match_operand:MMXMODE12 4 "nonimmediate_operand" "")
1022 + (match_operand:MMXMODE12 5 "nonimmediate_operand" "")])
1023 + (match_operand:MMXMODE12 1 "general_operand" "")
1024 + (match_operand:MMXMODE12 2 "general_operand" "")))]
1027 + if (ix86_expand_int_vcond (operands))
1033 +(define_expand "vconduv8qi"
1034 + [(set (match_operand:V8QI 0 "register_operand" "")
1035 + (if_then_else:V8QI
1036 + (match_operator 3 ""
1037 + [(match_operand:V8QI 4 "nonimmediate_operand" "")
1038 + (match_operand:V8QI 5 "nonimmediate_operand" "")])
1039 + (match_operand:V8QI 1 "general_operand" "")
1040 + (match_operand:V8QI 2 "general_operand" "")))]
1043 + if (ix86_expand_int_vcond (operands))
1049 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1051 ;; Parallel integral logical operations
1053 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1055 +(define_expand "one_cmpl<mode>2"
1056 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
1057 + (xor:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1061 + int i, n = GET_MODE_NUNITS (<MODE>mode);
1062 + rtvec v = rtvec_alloc (n);
1064 + for (i = 0; i < n; ++i)
1065 + RTVEC_ELT (v, i) = constm1_rtx;
1067 + operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
1070 +(define_expand "and<mode>3"
1071 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
1072 + (and:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1073 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1075 + "ix86_fixup_binary_operands_no_copy (AND, <MODE>mode, operands);")
1077 (define_insn "mmx_and<mode>3"
1078 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1080 @@ -879,6 +982,13 @@
1081 [(set_attr "type" "mmxadd")
1082 (set_attr "mode" "DI")])
1084 +(define_expand "ior<mode>3"
1085 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
1086 + (ior:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1087 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1089 + "ix86_fixup_binary_operands_no_copy (IOR, <MODE>mode, operands);")
1091 (define_insn "mmx_ior<mode>3"
1092 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1094 @@ -889,6 +999,13 @@
1095 [(set_attr "type" "mmxadd")
1096 (set_attr "mode" "DI")])
1098 +(define_expand "xor<mode>3"
1099 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
1100 + (xor:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1101 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1103 + "ix86_fixup_binary_operands_no_copy (XOR, <MODE>mode, operands);")
1105 (define_insn "mmx_xor<mode>3"
1106 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1108 @@ -1147,7 +1264,7 @@
1109 (match_operand 2 "const_int_operand" "")]
1112 - ix86_expand_vector_set (false, operands[0], operands[1],
1113 + ix86_expand_vector_set (true, operands[0], operands[1],
1114 INTVAL (operands[2]));
1117 @@ -1205,7 +1322,7 @@
1118 (match_operand 2 "const_int_operand" "")]
1121 - ix86_expand_vector_extract (false, operands[0], operands[1],
1122 + ix86_expand_vector_extract (true, operands[0], operands[1],
1123 INTVAL (operands[2]));
1126 @@ -1215,7 +1332,7 @@
1127 (match_operand 1 "" "")]
1130 - ix86_expand_vector_init (false, operands[0], operands[1]);
1131 + ix86_expand_vector_init (true, operands[0], operands[1]);
1135 @@ -1225,7 +1342,7 @@
1136 (match_operand 2 "const_int_operand" "")]
1139 - ix86_expand_vector_set (false, operands[0], operands[1],
1140 + ix86_expand_vector_set (true, operands[0], operands[1],
1141 INTVAL (operands[2]));
1144 @@ -1236,7 +1353,7 @@
1145 (match_operand 2 "const_int_operand" "")]
1148 - ix86_expand_vector_extract (false, operands[0], operands[1],
1149 + ix86_expand_vector_extract (true, operands[0], operands[1],
1150 INTVAL (operands[2]));
1153 @@ -1246,7 +1363,7 @@
1154 (match_operand 1 "" "")]
1157 - ix86_expand_vector_init (false, operands[0], operands[1]);
1158 + ix86_expand_vector_init (true, operands[0], operands[1]);
1162 @@ -1256,7 +1373,7 @@
1163 (match_operand 2 "const_int_operand" "")]
1166 - ix86_expand_vector_set (false, operands[0], operands[1],
1167 + ix86_expand_vector_set (true, operands[0], operands[1],
1168 INTVAL (operands[2]));
1171 @@ -1267,7 +1384,7 @@
1172 (match_operand 2 "const_int_operand" "")]
1175 - ix86_expand_vector_extract (false, operands[0], operands[1],
1176 + ix86_expand_vector_extract (true, operands[0], operands[1],
1177 INTVAL (operands[2]));
1180 @@ -1277,7 +1394,7 @@
1181 (match_operand 1 "" "")]
1184 - ix86_expand_vector_init (false, operands[0], operands[1]);
1185 + ix86_expand_vector_init (true, operands[0], operands[1]);
1189 @@ -1386,48 +1503,20 @@
1190 [(set_attr "type" "mmxcvt")
1191 (set_attr "mode" "DI")])
1193 -(define_insn "mmx_emms"
1194 - [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1195 - (clobber (reg:XF 8))
1196 - (clobber (reg:XF 9))
1197 - (clobber (reg:XF 10))
1198 - (clobber (reg:XF 11))
1199 - (clobber (reg:XF 12))
1200 - (clobber (reg:XF 13))
1201 - (clobber (reg:XF 14))
1202 - (clobber (reg:XF 15))
1203 - (clobber (reg:DI 29))
1204 - (clobber (reg:DI 30))
1205 - (clobber (reg:DI 31))
1206 - (clobber (reg:DI 32))
1207 - (clobber (reg:DI 33))
1208 - (clobber (reg:DI 34))
1209 - (clobber (reg:DI 35))
1210 - (clobber (reg:DI 36))]
1213 - [(set_attr "type" "mmx")
1214 - (set_attr "memory" "unknown")])
1215 +(define_insn "efpu"
1216 + [(set (reg:ALLREGS FIRSTFP_REG)
1217 + (unspec_volatile:ALLREGS [(reg:ALLREGS FIRSTMMX_REG)]
1219 + "TARGET_80387 && TARGET_MMX"
1221 + [(set_attr "length" "0")])
1223 +(define_insn "emms"
1224 + [(set (reg:ALLREGS FIRSTMMX_REG)
1225 + (unspec_volatile:ALLREGS [(reg:ALLREGS FIRSTFP_REG)]
1227 + "TARGET_80387 && TARGET_MMX"
1229 + return TARGET_3DNOW ? "femms" : "emms";
1232 -(define_insn "mmx_femms"
1233 - [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1234 - (clobber (reg:XF 8))
1235 - (clobber (reg:XF 9))
1236 - (clobber (reg:XF 10))
1237 - (clobber (reg:XF 11))
1238 - (clobber (reg:XF 12))
1239 - (clobber (reg:XF 13))
1240 - (clobber (reg:XF 14))
1241 - (clobber (reg:XF 15))
1242 - (clobber (reg:DI 29))
1243 - (clobber (reg:DI 30))
1244 - (clobber (reg:DI 31))
1245 - (clobber (reg:DI 32))
1246 - (clobber (reg:DI 33))
1247 - (clobber (reg:DI 34))
1248 - (clobber (reg:DI 35))
1249 - (clobber (reg:DI 36))]
1252 - [(set_attr "type" "mmx")
1253 - (set_attr "memory" "none")])
1254 --- gcc/gcc/config/i386/sse.md 2005-06-29 19:27:19.000000000 +0200
1255 +++ gcc/gcc/config/i386/sse.md 2005-07-18 06:14:15.000000000 +0200
1258 "cvtpi2ps\t{%2, %0|%0, %2}"
1259 [(set_attr "type" "ssecvt")
1260 + (set_attr "unit" "mmx")
1261 (set_attr "mode" "V4SF")])
1263 (define_insn "sse_cvtps2pi"
1264 @@ -3508,6 +3509,7 @@
1265 movhps\t{%2, %0|%0, %2}
1266 movlps\t{%1, %0|%0, %1}"
1267 [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov,ssemov")
1268 + (set_attr "unit" "*,mmx,*,*,*,*")
1269 (set_attr "mode" "TI,TI,TI,V4SF,V2SF,V2SF")])
1271 (define_expand "vec_setv2di"
1272 --- gcc/gcc/config/sh/sh.h 2005-07-03 23:08:07.000000000 +0200
1273 +++ gcc/gcc/config/sh/sh.h 2005-07-18 06:14:15.000000000 +0200
1274 @@ -3301,7 +3301,7 @@ extern struct rtx_def *sp_switch;
1275 ? get_attr_fp_mode (INSN) \
1278 -#define MODE_AFTER(MODE, INSN) \
1279 +#define MODE_AFTER(ENTITY, MODE, INSN) \
1281 && recog_memoized (INSN) >= 0 \
1282 && get_attr_fp_set (INSN) != FP_SET_NONE \
1283 --- gcc/gcc/doc/tm.texi 2005-07-13 19:27:39.000000000 +0200
1284 +++ gcc/gcc/doc/tm.texi 2005-07-18 06:14:15.000000000 +0200
1285 @@ -4227,6 +4227,16 @@ stack adjustment in a function that has
1286 compiler knows this regardless of @code{EXIT_IGNORE_STACK}.
1289 +@defmac CALL_INSN_SETS (@var{INSN})
1290 +Define this macro as a C expression that returns RTL expression of
1291 +additional hard register set by call_insn.
1294 +@defmac CALL_INSN_USES (@var{INSN})
1295 +Define this macro as a C expression that returns RTL expression of
1296 +additional hard register used by call_insn.
1299 @defmac EPILOGUE_USES (@var{regno})
1300 Define this macro as a C expression that is nonzero for registers that are
1301 used by the epilogue or the @samp{return} pattern. The stack and frame
1302 @@ -8376,6 +8386,13 @@ represented as numbers 0 @dots{} N @minu
1303 switch is needed / supplied.
1306 +@defmac LIFE_ANALYSIS_AFTER_MODE_SWITCHING
1307 +Define this macro if the port needs extra register life analysis after
1308 +mode switching. This macro should be defined if mode switching inserts
1309 +instructions that change global registers to maintain consistent global
1310 +register life information.
1313 @defmac MODE_NEEDED (@var{entity}, @var{insn})
1314 @var{entity} is an integer specifying a mode-switched entity. If
1315 @code{OPTIMIZE_MODE_SWITCHING} is defined, you must define this macro to
1316 @@ -8384,9 +8401,9 @@ return an integer value not larger than
1317 be switched into prior to the execution of @var{insn}.
1320 -@defmac MODE_AFTER (@var{mode}, @var{insn})
1321 -If this macro is defined, it is evaluated for every @var{insn} during
1322 -mode switching. It determines the mode that an insn results in (if
1323 +@defmac MODE_AFTER (@var{entity}, @var{mode}, @var{insn})
1324 +If this macro is defined, it is evaluated for every @var{entity} that needs
1325 +mode switching. It determines the mode that an @var{insn} results in (if
1326 different from the incoming mode).
1329 --- gcc/gcc/flow.c 2005-07-05 18:19:55.000000000 +0200
1330 +++ gcc/gcc/flow.c 2005-07-18 06:14:15.000000000 +0200
1331 @@ -1830,10 +1830,11 @@ propagate_one_insn (struct propagate_blo
1337 + rtx cond = NULL_RTX;
1338 + rtx reg ATTRIBUTE_UNUSED;
1342 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
1343 cond = COND_EXEC_TEST (PATTERN (insn));
1345 @@ -1856,6 +1857,13 @@ propagate_one_insn (struct propagate_blo
1346 mark_set_1 (pbi, CLOBBER, XEXP (XEXP (note, 0), 0),
1347 cond, insn, pbi->flags);
1349 +#ifdef CALL_INSN_SETS
1350 + reg = CALL_INSN_SETS (insn);
1353 + mark_set_1 (pbi, SET, reg, cond, insn, pbi->flags);
1356 /* Calls change all call-used and global registers; sibcalls do not
1357 clobber anything that must be preserved at end-of-function,
1358 except for return values. */
1359 @@ -1894,10 +1902,11 @@ propagate_one_insn (struct propagate_blo
1361 if (! insn_is_dead && CALL_P (insn))
1364 + rtx cond = NULL_RTX;
1365 + rtx reg ATTRIBUTE_UNUSED;
1370 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
1371 cond = COND_EXEC_TEST (PATTERN (insn));
1373 @@ -1910,6 +1919,13 @@ propagate_one_insn (struct propagate_blo
1374 of which mark_used_regs knows how to handle. */
1375 mark_used_regs (pbi, XEXP (XEXP (note, 0), 0), cond, insn);
1377 +#ifdef CALL_INSN_USES
1378 + reg = CALL_INSN_USES (insn);
1381 + mark_used_reg (pbi, reg, cond, insn);
1384 /* The stack ptr is used (honorarily) by a CALL insn. */
1385 if ((flags & PROP_REG_INFO)
1386 && !REGNO_REG_SET_P (pbi->reg_live, STACK_POINTER_REGNUM))
1387 --- gcc/gcc/mode-switching.c 2005-07-05 18:20:07.000000000 +0200
1388 +++ gcc/gcc/mode-switching.c 2005-07-18 06:14:15.000000000 +0200
1389 @@ -473,7 +473,7 @@ optimize_mode_switching (FILE *file)
1390 RESET_BIT (transp[bb->index], j);
1393 - last_mode = MODE_AFTER (last_mode, insn);
1394 + last_mode = MODE_AFTER (e, last_mode, insn);
1396 /* Update LIVE_NOW. */
1397 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1398 @@ -730,6 +730,14 @@ rest_of_handle_mode_switching (void)
1400 optimize_mode_switching (NULL);
1403 + /* Mode switching can insert instructions that
1404 + change global registers life data. */
1405 +#ifdef LIFE_ANALYSIS_AFTER_MODE_SWITCHING
1406 + if (LIFE_ANALYSIS_AFTER_MODE_SWITCHING)
1407 + life_analysis (NULL, PROP_REG_INFO);
1410 #endif /* OPTIMIZE_MODE_SWITCHING */
1413 --- gcc/gcc/reg-stack.c 2005-07-14 09:39:54.000000000 +0200
1414 +++ gcc/gcc/reg-stack.c 2005-07-18 06:14:15.000000000 +0200
1415 @@ -1579,6 +1579,41 @@ subst_stack_regs_pat (rtx insn, stack re
1419 + case UNSPEC_VOLATILE:
1420 + switch (XINT (pat_src, 1))
1424 + case UNSPECV_EFPU:
1425 + /* There should be no stack registers live
1427 + gcc_assert (regstack->top == -1);
1429 + /* Mark all x87 registers as used. */
1430 + for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
1432 + regstack->reg[++regstack->top] = i;
1433 + SET_HARD_REG_BIT (regstack->reg_set, i);
1437 + case UNSPECV_EMMS:
1438 + /* All stack registers should be alive
1440 + gcc_assert (regstack->top == REG_STACK_SIZE - 1);
1442 + /* Mark all x87 registers as empty. */
1443 + for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
1444 + CLEAR_HARD_REG_BIT (regstack->reg_set, i);
1446 + regstack->top = -1;
1450 + gcc_unreachable ();
1455 switch (XINT (pat_src, 1))
1457 @@ -2269,6 +2304,25 @@ subst_stack_regs (rtx insn, stack regsta
1458 if (NOTE_P (insn) || INSN_DELETED_P (insn))
1459 return control_flow_insn_deleted;
1461 +#ifdef CALL_INSN_SETS
1462 + if (CALL_P (insn))
1464 + rtx reg = CALL_INSN_SETS (insn);
1466 + if (reg && STACK_REG_P (reg))
1470 + for (count = hard_regno_nregs[REGNO (reg)][GET_MODE (reg)];
1473 + regstack->reg[++regstack->top] = REGNO (reg) + count;
1474 + SET_HARD_REG_BIT (regstack->reg_set, REGNO (reg) + count);
1480 /* If there is a REG_UNUSED note on a stack register on this insn,
1481 the indicated reg must be popped. The REG_UNUSED note is removed,
1482 since the form of the newly emitted pop insn references the reg,
1483 @@ -2544,6 +2598,15 @@ convert_regs_entry (void)
1484 basic_block block = e->dest;
1485 block_info bi = BLOCK_INFO (block);
1489 + /* Check if all stack registers are live at function entry.
1490 + This is the case where stack registers are disabled and no
1491 + register initialization is needed. */
1493 + for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
1494 + if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
1497 for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
1498 if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
1499 @@ -2552,11 +2615,14 @@ convert_regs_entry (void)
1501 bi->stack_in.reg[++top] = reg;
1503 - init = gen_rtx_SET (VOIDmode,
1504 - FP_MODE_REG (FIRST_STACK_REG, SFmode),
1506 - insert_insn_on_edge (init, e);
1508 + if (numregs != REG_STACK_SIZE)
1510 + init = gen_rtx_SET (VOIDmode,
1511 + FP_MODE_REG (FIRST_STACK_REG, SFmode),
1513 + insert_insn_on_edge (init, e);
1518 bi->stack_in.top = top;
1519 @@ -2575,13 +2641,34 @@ convert_regs_exit (void)
1523 - retvalue = stack_result (current_function_decl);
1524 value_reg_low = value_reg_high = -1;
1527 +#ifdef EPILOGUE_USES
1532 + for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
1533 + if (EPILOGUE_USES (i))
1538 + value_reg_low = FIRST_STACK_REG;
1539 + value_reg_high = value_reg_low + numregs - 1;
1544 + if (value_reg_low < 0)
1546 - value_reg_low = REGNO (retvalue);
1547 - value_reg_high = value_reg_low
1548 - + hard_regno_nregs[value_reg_low][GET_MODE (retvalue)] - 1;
1549 + retvalue = stack_result (current_function_decl);
1552 + value_reg_low = REGNO (retvalue);
1553 + value_reg_high = value_reg_low
1554 + + hard_regno_nregs[value_reg_low][GET_MODE (retvalue)] - 1;
1558 output_stack = &BLOCK_INFO (EXIT_BLOCK_PTR)->stack_in;