1 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/builtins.c gcc-4.1-20050818T1605UTC/gcc/builtins.c
2 --- gcc-4.1-20050818T1605UTC/gcc.orig/builtins.c 2005-08-18 16:22:46.000000000 +0000
3 +++ gcc-4.1-20050818T1605UTC/gcc/builtins.c 2005-08-18 16:25:02.000000000 +0000
5 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
8 +#ifndef FUNCTION_VALUE_REGNO_P_APPLY_RESULT
9 +#define FUNCTION_VALUE_REGNO_P_APPLY_RESULT FUNCTION_VALUE_REGNO_P
12 +#ifndef FUNCTION_ARG_REGNO_P_APPLY_ARGS
13 +#define FUNCTION_ARG_REGNO_P_APPLY_ARGS FUNCTION_ARG_REGNO_P
16 /* Define the names of the builtin function types and codes. */
17 const char *const built_in_class_names[4]
18 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
20 size += GET_MODE_SIZE (Pmode);
22 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
23 - if (FUNCTION_ARG_REGNO_P (regno))
24 + if (FUNCTION_ARG_REGNO_P_APPLY_ARGS (regno))
26 mode = reg_raw_mode[regno];
31 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
32 - if (FUNCTION_VALUE_REGNO_P (regno))
33 + if (FUNCTION_VALUE_REGNO_P_APPLY_RESULT (regno))
35 mode = reg_raw_mode[regno];
37 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/caller-save.c gcc-4.1-20050818T1605UTC/gcc/caller-save.c
38 --- gcc-4.1-20050818T1605UTC/gcc.orig/caller-save.c 2005-06-28 08:15:34.000000000 +0000
39 +++ gcc-4.1-20050818T1605UTC/gcc/caller-save.c 2005-08-18 16:25:02.000000000 +0000
42 rtx insn = chain->insn;
43 enum rtx_code code = GET_CODE (insn);
44 + rtx reg ATTRIBUTE_UNUSED;
49 CLEAR_HARD_REG_SET (this_insn_sets);
50 note_stores (PATTERN (insn), mark_set_regs, NULL);
52 +#ifdef CALL_INSN_SETS
53 + reg = CALL_INSN_SETS (insn);
56 + mark_set_regs (reg, NULL_RTX, NULL);
58 /* Compute which hard regs must be saved before this call. */
59 AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set);
60 AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets);
61 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386-modes.def gcc-4.1-20050818T1605UTC/gcc/config/i386/i386-modes.def
62 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386-modes.def 2005-06-28 08:16:53.000000000 +0000
63 +++ gcc-4.1-20050818T1605UTC/gcc/config/i386/i386-modes.def 2005-08-18 16:25:02.000000000 +0000
68 +/* This mode is used to cover all MMX and all x87 registers. */
69 +RANDOM_MODE (ALLREGS);
72 VECTOR_MODES (INT, 4); /* V4QI V2HI */
73 VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
74 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386-protos.h gcc-4.1-20050818T1605UTC/gcc/config/i386/i386-protos.h
75 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386-protos.h 2005-08-18 16:01:16.000000000 +0000
76 +++ gcc-4.1-20050818T1605UTC/gcc/config/i386/i386-protos.h 2005-08-18 16:25:02.000000000 +0000
78 extern bool ix86_expand_int_vcond (rtx[]);
79 extern int ix86_expand_int_addcc (rtx[]);
80 extern void ix86_expand_call (rtx, rtx, rtx, rtx, rtx, int);
81 +extern bool ix86_epilogue_uses (int);
82 +extern rtx ix86_call_insn_sets (rtx);
83 +extern rtx ix86_call_insn_uses (rtx);
84 extern void x86_initialize_trampoline (rtx, rtx, rtx);
85 extern rtx ix86_zero_extend_to_Pmode (rtx);
86 extern void ix86_split_long_move (rtx[]);
88 extern enum machine_mode ix86_fp_compare_mode (enum rtx_code);
90 extern rtx ix86_libcall_value (enum machine_mode);
91 -extern bool ix86_function_value_regno_p (int);
92 -extern bool ix86_function_arg_regno_p (int);
93 +extern bool ix86_function_value_regno_p (int, bool);
94 +extern bool ix86_function_arg_regno_p (int, bool);
95 extern int ix86_function_arg_boundary (enum machine_mode, tree);
96 extern int ix86_return_in_memory (tree);
97 extern void ix86_va_start (tree, rtx);
99 extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
100 extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
101 extern int ix86_mode_needed (int, rtx);
102 -extern void emit_i387_cw_initialization (int);
103 +extern int ix86_mode_after (int, int, rtx);
104 +extern int ix86_mode_entry (int);
105 +extern int ix86_mode_exit (int);
106 +extern void ix86_emit_mode_set (int, int);
107 extern bool ix86_fp_jump_nontrivial_p (enum rtx_code);
108 extern void x86_order_regs_for_local_alloc (void);
109 extern void x86_function_profiler (FILE *, int);
110 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386.c gcc-4.1-20050818T1605UTC/gcc/config/i386/i386.c
111 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386.c 2005-08-18 16:01:16.000000000 +0000
112 +++ gcc-4.1-20050818T1605UTC/gcc/config/i386/i386.c 2005-08-18 16:25:02.000000000 +0000
113 @@ -2273,12 +2273,13 @@
115 /* Return true when register may be used to pass function parameters. */
117 -ix86_function_arg_regno_p (int regno)
118 +ix86_function_arg_regno_p (int regno, bool from_builtin)
122 return (regno < REGPARM_MAX
123 - || (TARGET_MMX && MMX_REGNO_P (regno)
124 + || (TARGET_MMX && !(TARGET_80387 && from_builtin)
125 + && MMX_REGNO_P (regno)
126 && (regno < FIRST_MMX_REG + MMX_REGPARM_MAX))
127 || (TARGET_SSE && SSE_REGNO_P (regno)
128 && (regno < FIRST_SSE_REG + SSE_REGPARM_MAX)));
129 @@ -3387,14 +3388,14 @@
131 /* Return true if N is a possible register number of function value. */
133 -ix86_function_value_regno_p (int regno)
134 +ix86_function_value_regno_p (int regno, bool from_builtin)
137 || (regno == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)
138 || (regno == FIRST_SSE_REG && TARGET_SSE))
142 + if (!TARGET_64BIT && !(TARGET_80387 && from_builtin)
143 && (regno == FIRST_MMX_REG && TARGET_MMX))
146 @@ -7714,12 +7715,152 @@
150 -/* Return needed mode for entity in optimize_mode_switching pass. */
151 +/* Return needed mode for entity in optimize_mode_switching pass.
152 + Returned mode should match ix86_mode_entry () for function calls. */
155 ix86_mode_needed (int entity, rtx insn)
157 - enum attr_i387_cw mode;
160 + if (entity == I387_FPU_MODE)
162 + /* If a function call uses MMX registers, select MMX FPU mode and
163 + if function call uses x87 registers, select x87 FPU mode. */
171 + for (link = CALL_INSN_FUNCTION_USAGE (insn);
173 + link = XEXP (link, 1))
175 + if (GET_CODE (XEXP (link, 0)) == USE)
177 + reg = XEXP (XEXP (link, 0), 0);
181 + if (MMX_REG_P (reg))
184 + if (FP_REG_P (reg))
190 + /* Mixing of x87 and MMX registers is not allowed
191 + in function call. */
192 + gcc_assert (!mmx || !x87);
195 + return FPU_MODE_MMX;
197 + /* Fall back to default mode. */
198 + return FPU_MODE_X87;
201 + /* Parse ASM operands to check input and output constraints. If
202 + an ASM uses MMX registers, select MMX mode and if it uses x87
203 + registers, select x87 mode. Mixing of MMX and x87 constraints
204 + is not allowed. If no MMX or x87 input and output registers
205 + are used, switch to default mode. */
206 + if (NONJUMP_INSN_P (insn))
208 + rtx pat = PATTERN (insn);
209 + int noperands = asm_noperands (pat);
211 + if (noperands >= 0)
213 + const char **constraints;
218 + constraints = alloca (noperands * sizeof (char *));
219 + decode_asm_operands (pat, NULL, NULL, constraints, NULL);
221 + for (i = 0; i < noperands; i++)
223 + const char *c = constraints[i];
224 + enum reg_class class;
228 + if (ISDIGIT ((unsigned char) c[0]) && c[1] == '\0')
229 + c = constraints[c[0] - '0'];
251 + class = REG_CLASS_FROM_LETTER (cc);
253 + if (MMX_CLASS_P (class))
256 + if (FLOAT_CLASS_P (class))
260 + len = CONSTRAINT_LEN (cc, c);
263 + while (--len && *c);
267 + /* Mixing x87 and MMX registers in ASM is not allowed. */
269 + error_for_asm (insn, "mixing of x87 and MMX registers "
270 + "is not allowed in %<asm%>");
273 + return FPU_MODE_MMX;
275 + /* Fall back to default mode. */
276 + return FPU_MODE_X87;
280 + if (recog_memoized (insn) < 0)
281 + return FPU_MODE_ANY;
283 + unit = get_attr_unit (insn);
288 + return FPU_MODE_MMX;
291 + return FPU_MODE_X87;
294 + return FPU_MODE_ANY;
299 /* The mode UNINITIALIZED is used to store control word after a
300 function call or ASM pattern. The mode ANY specify that function
301 @@ -7766,21 +7907,132 @@
305 -/* Output code to initialize control word copies used by trunc?f?i and
306 - rounding patterns. CURRENT_MODE is set to current control word,
307 - while NEW_MODE is set to new control word. */
309 +/* Switch FPU mode to appropriate mode after function call in
310 + optimize_mode_switchig pass. Returned mode should match
311 + ix86_mode_exit (). */
314 +ix86_mode_after (int entity, int mode, rtx insn)
316 + if (entity == I387_FPU_MODE)
318 + /* Switch FPU to MMX mode after funciton call if function value
319 + is returned in MMX register and similar for x87 reg.
320 + If no value is returned in MMX or x87 reg, fall back to
324 + rtx reg = SET_DEST (PATTERN (insn));
328 + if (reg && MMX_REG_P (reg))
329 + new_mode = FPU_MODE_MMX;
331 + new_mode = FPU_MODE_X87;
333 + /* Call insn should never operate in FPU_MODE_ANY. */
334 + if ((mode != FPU_MODE_ANY) && (new_mode != mode))
335 + ix86_fpu_mode_changed = 1;
344 +/* Switch FPU mode of function entry to appropriate mode in
345 + optimize_mode_switchig pass. Returned mode should match
346 + ix86_mode_needed () for function calls. */
349 +ix86_mode_entry (int entity)
351 + if (entity == I387_FPU_MODE)
353 + if (! current_function_args_info.maybe_vaarg)
355 + if (current_function_args_info.mmx_nregs != MMX_REGPARM_MAX)
356 + return FPU_MODE_MMX;
358 + /* ??? Handle x87 registers for fpregparm. */
361 + /* Fall back to default mode. */
362 + return FPU_MODE_X87;
365 + return I387_CW_ANY;
368 +/* Switch FPU mode of function exit to appropriate mode in
369 + optimize_mode_switchig pass. Returned mode should match
370 + ix86_mode_after () for function calls. */
373 +ix86_mode_exit (int entity)
375 + if (entity == I387_FPU_MODE)
377 + rtx reg = current_function_return_rtx;
379 + /* If MMX output register is specified, switch FPU mode
380 + of function exit to MMX mode. */
381 + if (reg && MMX_REG_P (reg))
382 + return FPU_MODE_MMX;
384 + /* Fall back to default mode. */
385 + return FPU_MODE_X87;
388 + return I387_CW_ANY;
391 +/* Emit mode switching instructions in optimize_mode_switching pass. */
394 -emit_i387_cw_initialization (int mode)
395 +ix86_emit_mode_set (int entity, int mode)
397 - rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
399 + rtx stored_mode, new_mode;
404 - rtx reg = gen_reg_rtx (HImode);
405 + if (entity == I387_FPU_MODE)
413 + emit_insn (gen_emms ());
414 + ix86_fpu_mode_changed = 1;
418 + emit_insn (gen_efpu ());
419 + ix86_fpu_mode_changed = 1;
423 + gcc_unreachable ();
427 + /* Output code to initialize control word copies used by trunc?f?i
428 + and rounding patterns. STORED_MODE is set to current control
429 + word, while NEW_MODE is set to new control word. */
431 + if ((mode == I387_CW_UNINITIALIZED) || (mode == I387_CW_ANY))
434 + stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
435 emit_insn (gen_x86_fnstcw_1 (stored_mode));
437 + reg = gen_reg_rtx (HImode);
438 emit_move_insn (reg, stored_mode);
440 if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
441 @@ -12598,6 +12850,7 @@
443 f = ggc_alloc_cleared (sizeof (struct machine_function));
444 f->use_fast_prologue_epilogue_nregs = -1;
445 + f->optimize_mode_switching[I387_FPU_MODE] = TARGET_80387 && TARGET_MMX;
449 @@ -13196,7 +13449,77 @@
456 +/* Return true to prevent register allocator from allocating registers
457 + from the unit that is not active. */
460 +ix86_epilogue_uses (int regno)
464 + if (! ix86_fpu_mode_changed)
467 + mode = ix86_mode_exit (I387_FPU_MODE);
469 + if (mode == FPU_MODE_MMX)
470 + return FP_REGNO_P (regno);
472 + return MMX_REGNO_P (regno);
475 +/* Return RTX code of additional register that CALL_INSN uses.
476 + This function is used to maintain correct register life
477 + information before CALL_INSN in case of MMX/x87 switching. */
480 +ix86_call_insn_uses (rtx insn)
484 + if (! ix86_fpu_mode_changed)
487 + gcc_assert (CALL_P (insn));
489 + mode = ix86_mode_needed (I387_FPU_MODE, insn);
490 + if (mode == FPU_MODE_MMX)
491 + return gen_rtx_REG (ALLREGSmode, FIRST_FLOAT_REG);
493 + return gen_rtx_REG (ALLREGSmode, FIRST_MMX_REG);
498 +/* Return RTX code of additional register that CALL_INSN sets.
499 + This function is used to maintain correct register life
500 + information after CALL_INSN in case of MMX/x87 switching. */
503 +ix86_call_insn_sets (rtx insn)
507 + if (! ix86_fpu_mode_changed)
510 + gcc_assert (CALL_P (insn));
512 + /* Current mode in call to ix86_mode_after is set to FPU_MODE_ANY
513 + to prevent setting of ix86_fpu_mode_changed variable. */
514 + mode = ix86_mode_after (I387_FPU_MODE, FPU_MODE_ANY, insn);
515 + if (mode == FPU_MODE_MMX)
516 + return gen_rtx_REG (ALLREGSmode, FIRST_FLOAT_REG);
518 + return gen_rtx_REG (ALLREGSmode, FIRST_MMX_REG);
524 /* Emit RTL insns to initialize the variable parts of a trampoline.
525 FNADDR is an RTX for the address of the function's pure code.
526 CXT is an RTX for the static chain value for the function. */
527 @@ -13676,9 +13999,11 @@
528 IX86_BUILTIN_MONITOR,
531 + IX86_BUILTIN_VEC_INIT_V2SF,
532 IX86_BUILTIN_VEC_INIT_V2SI,
533 IX86_BUILTIN_VEC_INIT_V4HI,
534 IX86_BUILTIN_VEC_INIT_V8QI,
535 + IX86_BUILTIN_VEC_EXT_V2SF,
536 IX86_BUILTIN_VEC_EXT_V2DF,
537 IX86_BUILTIN_VEC_EXT_V2DI,
538 IX86_BUILTIN_VEC_EXT_V4SF,
539 @@ -13860,24 +14185,24 @@
540 { MASK_SSE, CODE_FOR_sse_cvtsi2ss, 0, IX86_BUILTIN_CVTSI2SS, 0, 0 },
541 { MASK_SSE | MASK_64BIT, CODE_FOR_sse_cvtsi2ssq, 0, IX86_BUILTIN_CVTSI642SS, 0, 0 },
543 - { MASK_MMX, CODE_FOR_mmx_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
544 - { MASK_MMX, CODE_FOR_mmx_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
545 - { MASK_MMX, CODE_FOR_mmx_ashlv2si3, 0, IX86_BUILTIN_PSLLD, 0, 0 },
546 - { MASK_MMX, CODE_FOR_mmx_ashlv2si3, 0, IX86_BUILTIN_PSLLDI, 0, 0 },
547 + { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
548 + { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
549 + { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLD, 0, 0 },
550 + { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLDI, 0, 0 },
551 { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQ, 0, 0 },
552 { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQI, 0, 0 },
554 - { MASK_MMX, CODE_FOR_mmx_lshrv4hi3, 0, IX86_BUILTIN_PSRLW, 0, 0 },
555 - { MASK_MMX, CODE_FOR_mmx_lshrv4hi3, 0, IX86_BUILTIN_PSRLWI, 0, 0 },
556 - { MASK_MMX, CODE_FOR_mmx_lshrv2si3, 0, IX86_BUILTIN_PSRLD, 0, 0 },
557 - { MASK_MMX, CODE_FOR_mmx_lshrv2si3, 0, IX86_BUILTIN_PSRLDI, 0, 0 },
558 + { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLW, 0, 0 },
559 + { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLWI, 0, 0 },
560 + { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLD, 0, 0 },
561 + { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLDI, 0, 0 },
562 { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQ, 0, 0 },
563 { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQI, 0, 0 },
565 - { MASK_MMX, CODE_FOR_mmx_ashrv4hi3, 0, IX86_BUILTIN_PSRAW, 0, 0 },
566 - { MASK_MMX, CODE_FOR_mmx_ashrv4hi3, 0, IX86_BUILTIN_PSRAWI, 0, 0 },
567 - { MASK_MMX, CODE_FOR_mmx_ashrv2si3, 0, IX86_BUILTIN_PSRAD, 0, 0 },
568 - { MASK_MMX, CODE_FOR_mmx_ashrv2si3, 0, IX86_BUILTIN_PSRADI, 0, 0 },
569 + { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAW, 0, 0 },
570 + { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAWI, 0, 0 },
571 + { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRAD, 0, 0 },
572 + { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRADI, 0, 0 },
574 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_psadbw, 0, IX86_BUILTIN_PSADBW, 0, 0 },
575 { MASK_MMX, CODE_FOR_mmx_pmaddwd, 0, IX86_BUILTIN_PMADDWD, 0, 0 },
576 @@ -14642,6 +14967,11 @@
577 v16qi_ftype_pcchar, IX86_BUILTIN_LDDQU);
579 /* Access to the vec_init patterns. */
580 + ftype = build_function_type_list (V2SF_type_node, float_type_node,
581 + integer_type_node, NULL_TREE);
582 + def_builtin (MASK_3DNOW, "__builtin_ia32_vec_init_v2sf",
583 + ftype, IX86_BUILTIN_VEC_INIT_V2SF);
585 ftype = build_function_type_list (V2SI_type_node, integer_type_node,
586 integer_type_node, NULL_TREE);
587 def_builtin (MASK_MMX, "__builtin_ia32_vec_init_v2si",
588 @@ -14663,6 +14993,11 @@
589 ftype, IX86_BUILTIN_VEC_INIT_V8QI);
591 /* Access to the vec_extract patterns. */
592 + ftype = build_function_type_list (float_type_node, V2SF_type_node,
593 + integer_type_node, NULL_TREE);
594 + def_builtin (MASK_3DNOW, "__builtin_ia32_vec_ext_v2sf",
595 + ftype, IX86_BUILTIN_VEC_EXT_V2DF);
597 ftype = build_function_type_list (double_type_node, V2DF_type_node,
598 integer_type_node, NULL_TREE);
599 def_builtin (MASK_SSE, "__builtin_ia32_vec_ext_v2df",
600 @@ -15137,7 +15472,7 @@
603 case IX86_BUILTIN_EMMS:
604 - emit_insn (gen_mmx_emms ());
605 + /* emms insn is emitted automatically. */
608 case IX86_BUILTIN_SFENCE:
609 @@ -15354,7 +15689,7 @@
612 case IX86_BUILTIN_FEMMS:
613 - emit_insn (gen_mmx_femms ());
614 + /* femms insn is emitted automatically. */
617 case IX86_BUILTIN_PAVGUSB:
618 @@ -15500,11 +15835,13 @@
619 return ix86_expand_unop_builtin (CODE_FOR_sse3_lddqu, arglist,
622 + case IX86_BUILTIN_VEC_INIT_V2SF:
623 case IX86_BUILTIN_VEC_INIT_V2SI:
624 case IX86_BUILTIN_VEC_INIT_V4HI:
625 case IX86_BUILTIN_VEC_INIT_V8QI:
626 return ix86_expand_vec_init_builtin (TREE_TYPE (exp), arglist, target);
628 + case IX86_BUILTIN_VEC_EXT_V2SF:
629 case IX86_BUILTIN_VEC_EXT_V2DF:
630 case IX86_BUILTIN_VEC_EXT_V2DI:
631 case IX86_BUILTIN_VEC_EXT_V4SF:
632 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386.h gcc-4.1-20050818T1605UTC/gcc/config/i386/i386.h
633 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386.h 2005-08-18 16:01:16.000000000 +0000
634 +++ gcc-4.1-20050818T1605UTC/gcc/config/i386/i386.h 2005-08-18 16:25:02.000000000 +0000
637 #define HARD_REGNO_NREGS(REGNO, MODE) \
638 (FP_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO) \
639 - ? (COMPLEX_MODE_P (MODE) ? 2 : 1) \
640 + ? ((MODE) == ALLREGSmode \
642 + : (COMPLEX_MODE_P (MODE) ? 2 : 1)) \
643 : ((MODE) == XFmode \
644 ? (TARGET_64BIT ? 2 : 3) \
647 ((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode \
648 || (MODE) == V2SImode || (MODE) == SImode)
650 -/* ??? No autovectorization into MMX or 3DNOW until we can reliably
651 - place emms and femms instructions. */
652 -#define UNITS_PER_SIMD_WORD (TARGET_SSE ? 16 : UNITS_PER_WORD)
653 +#define UNITS_PER_SIMD_WORD \
654 + (TARGET_SSE ? 16 : TARGET_MMX ? 8 : UNITS_PER_WORD)
656 #define VALID_FP_MODE_P(MODE) \
657 ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \
658 @@ -1436,8 +1437,16 @@
659 #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) \
660 ix86_return_pops_args ((FUNDECL), (FUNTYPE), (SIZE))
662 +/* 1 if N is the number of a register in which the values of
663 + called function may come back. */
664 #define FUNCTION_VALUE_REGNO_P(N) \
665 - ix86_function_value_regno_p (N)
666 + ix86_function_value_regno_p ((N), false)
668 +/* 1 if N is the number of a register in which the value of
669 + __builtin_return builtin function may come back. */
671 +#define FUNCTION_VALUE_REGNO_P_APPLY_RESULT(N) \
672 + ix86_function_value_regno_p ((N), true)
674 /* Define how to find the value returned by a library function
675 assuming the value has mode MODE. */
676 @@ -1452,7 +1461,13 @@
677 #define APPLY_RESULT_SIZE (8+108)
679 /* 1 if N is a possible register number for function argument passing. */
680 -#define FUNCTION_ARG_REGNO_P(N) ix86_function_arg_regno_p (N)
681 +#define FUNCTION_ARG_REGNO_P(N) ix86_function_arg_regno_p ((N), false)
683 +/* 1 if N is a possible register number for function argument passing
684 + from __builtin_apply_args and __builtin_apply builtin functions. */
686 +#define FUNCTION_ARG_REGNO_P_APPLY_ARGS(N) \
687 + ix86_function_arg_regno_p ((N), true)
689 /* Define a data type for recording info about an argument list
690 during the scan of that argument list. This data type should
691 @@ -1534,6 +1549,23 @@
693 #define EXIT_IGNORE_STACK 1
695 +/* Define this macro as a C expression that is nonzero for registers
696 + that are used by the epilogue or the return' pattern. The stack
697 + and frame pointer registers are already be assumed to be used as
700 +#define EPILOGUE_USES(REGNO) ix86_epilogue_uses (REGNO)
702 +/* Define this macro as a C expression that returns RTL expression of
703 + additional hard register set by call_insn. */
705 +#define CALL_INSN_SETS(INSN) ix86_call_insn_sets (INSN)
707 +/* Define this macro as a C expression that returns RTL expression of
708 + additional hard register used by call_insn. */
710 +#define CALL_INSN_USES(INSN) ix86_call_insn_uses (INSN)
712 /* Output assembler code for a block containing the constant parts
713 of a trampoline, leaving space for the variable parts. */
715 @@ -2169,6 +2201,10 @@
716 extern rtx ix86_compare_op1; /* operand 1 for comparisons */
717 extern rtx ix86_compare_emitted;
720 +/* x87 FPU modes for x87/MMX switching. */
721 +enum ix86_fpu_mode { FPU_MODE_X87, FPU_MODE_MMX, FPU_MODE_ANY };
723 /* To properly truncate FP values into integers, we need to set i387 control
724 word. We can't emit proper mode switching code before reload, as spills
725 generated by reload may truncate values incorrectly, but we still can avoid
726 @@ -2190,6 +2226,7 @@
734 @@ -2219,7 +2256,12 @@
735 refer to the mode-switched entity in question. */
737 #define NUM_MODES_FOR_MODE_SWITCHING \
738 - { I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY }
739 + { I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, I387_CW_ANY, FPU_MODE_ANY }
741 +/* Define this macro if the port needs extra register life analysis
742 + after mode switching. */
744 +#define LIFE_ANALYSIS_AFTER_MODE_SWITCHING ix86_fpu_mode_changed
746 /* ENTITY is an integer specifying a mode-switched entity. If
747 `OPTIMIZE_MODE_SWITCHING' is defined, you must define this macro to
748 @@ -2229,6 +2271,22 @@
750 #define MODE_NEEDED(ENTITY, I) ix86_mode_needed ((ENTITY), (I))
752 +/* This macro determines the mode that an INSN results in (if different
753 + from the incoming mode). */
755 +#define MODE_AFTER(ENTITY, MODE, I) \
756 + ix86_mode_after ((ENTITY), (MODE), (I))
758 +/* This macro specifies a mode that ENTITY is assumed to be
759 + switched to at function entry. */
761 +#define MODE_ENTRY(ENTITY) ix86_mode_entry (ENTITY)
763 +/* This macro specifies a mode that ENTITY is assumed to be
764 + switched to at function exit. */
766 +#define MODE_EXIT(ENTITY) ix86_mode_exit (ENTITY)
768 /* This macro specifies the order in which modes for ENTITY are
769 processed. 0 is the highest priority. */
771 @@ -2238,10 +2296,8 @@
772 is the set of hard registers live at the point where the insn(s)
773 are to be inserted. */
775 -#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
776 - ((MODE) != I387_CW_ANY && (MODE) != I387_CW_UNINITIALIZED \
777 - ? emit_i387_cw_initialization (MODE), 0 \
779 +#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
780 + ix86_emit_mode_set ((ENTITY), (MODE))
783 /* Avoid renaming of stack registers, as doing so in combination with
784 @@ -2265,6 +2321,7 @@
785 int save_varrargs_registers;
786 int accesses_prev_frame;
787 int optimize_mode_switching[MAX_386_ENTITIES];
788 + int fpu_mode_changed;
789 /* Set by ix86_compute_frame_layout and used by prologue/epilogue expander to
790 determine the style used. */
791 int use_fast_prologue_epilogue;
792 @@ -2276,6 +2333,7 @@
793 #define ix86_stack_locals (cfun->machine->stack_locals)
794 #define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
795 #define ix86_optimize_mode_switching (cfun->machine->optimize_mode_switching)
796 +#define ix86_fpu_mode_changed (cfun->machine->fpu_mode_changed)
798 /* Control behavior of x86_file_start. */
799 #define X86_FILE_START_VERSION_DIRECTIVE false
800 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386.md gcc-4.1-20050818T1605UTC/gcc/config/i386/i386.md
801 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/i386.md 2005-08-18 16:01:16.000000000 +0000
802 +++ gcc-4.1-20050818T1605UTC/gcc/config/i386/i386.md 2005-08-18 16:25:02.000000000 +0000
823 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
824 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/mm3dnow.h gcc-4.1-20050818T1605UTC/gcc/config/i386/mm3dnow.h
825 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/mm3dnow.h 2005-06-28 08:16:53.000000000 +0000
826 +++ gcc-4.1-20050818T1605UTC/gcc/config/i386/mm3dnow.h 2005-08-18 16:25:02.000000000 +0000
827 @@ -172,14 +172,13 @@
828 static __inline __m64
829 _m_from_float (float __A)
831 - return (__m64)(__v2sf){ __A, 0 };
832 + return (__m64) __builtin_ia32_vec_init_v2sf (__A, 0);
835 static __inline float
836 _m_to_float (__m64 __A)
838 - union { __v2sf v; float a[2]; } __tmp = { (__v2sf)__A };
840 + return __builtin_ia32_vec_ext_v2sf ((__v2sf)__A, 0);
844 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/mmx.md gcc-4.1-20050818T1605UTC/gcc/config/i386/mmx.md
845 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/mmx.md 2005-06-28 08:16:53.000000000 +0000
846 +++ gcc-4.1-20050818T1605UTC/gcc/config/i386/mmx.md 2005-08-18 16:25:02.000000000 +0000
848 ;; the same register file, and 3dNOW! adds a number of extensions to
849 ;; the base integer MMX isa.
851 -;; Note! Except for the basic move instructions, *all* of these
852 -;; patterns are outside the normal optabs namespace. This is because
853 -;; use of these registers requires the insertion of emms or femms
854 -;; instructions to return to normal fpu mode. The compiler doesn't
855 -;; know how to do that itself, which means it's up to the user. Which
856 -;; means that we should never use any of these patterns except at the
857 -;; direction of the user via a builtin.
859 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
860 (define_mode_macro MMXMODEI [V8QI V4HI V2SI])
863 (match_operand 2 "const_int_operand" "")]
866 - ix86_expand_vector_set (false, operands[0], operands[1],
867 + ix86_expand_vector_set (true, operands[0], operands[1],
868 INTVAL (operands[2]));
872 (match_operand 2 "const_int_operand" "")]
875 - ix86_expand_vector_extract (false, operands[0], operands[1],
876 + ix86_expand_vector_extract (true, operands[0], operands[1],
877 INTVAL (operands[2]));
881 (match_operand 1 "" "")]
884 - ix86_expand_vector_init (false, operands[0], operands[1]);
885 + ix86_expand_vector_init (true, operands[0], operands[1]);
891 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
893 +(define_expand "neg<mode>2"
894 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
897 + (match_operand:MMXMODEI 1 "nonimmediate_operand" "")))]
899 + "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
901 +(define_expand "add<mode>3"
902 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
903 + (plus:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
904 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
906 + "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
908 (define_insn "mmx_add<mode>3"
909 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
912 [(set_attr "type" "mmxadd")
913 (set_attr "mode" "DI")])
915 +(define_expand "sub<mode>3"
916 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
917 + (minus:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "")
918 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
920 + "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
922 (define_insn "mmx_sub<mode>3"
923 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
926 [(set_attr "type" "mmxadd")
927 (set_attr "mode" "DI")])
929 +(define_expand "mulv4hi3"
930 + [(set (match_operand:V4HI 0 "register_operand" "")
931 + (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
932 + (match_operand:V4HI 2 "nonimmediate_operand" "")))]
934 + "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
936 (define_insn "mmx_mulv4hi3"
937 [(set (match_operand:V4HI 0 "register_operand" "=y")
938 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
940 [(set_attr "type" "mmxmul")
941 (set_attr "mode" "DI")])
943 +(define_expand "umaxv8qi3"
944 + [(set (match_operand:V8QI 0 "register_operand" "")
945 + (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "")
946 + (match_operand:V8QI 2 "nonimmediate_operand" "")))]
947 + "(TARGET_SSE || TARGET_3DNOW_A)"
948 + "ix86_fixup_binary_operands_no_copy (UMAX, V8QImode, operands);")
950 (define_insn "mmx_umaxv8qi3"
951 [(set (match_operand:V8QI 0 "register_operand" "=y")
952 (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
954 [(set_attr "type" "mmxadd")
955 (set_attr "mode" "DI")])
957 +(define_expand "smaxv4hi3"
958 + [(set (match_operand:V4HI 0 "register_operand" "")
959 + (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
960 + (match_operand:V4HI 2 "nonimmediate_operand" "")))]
961 + "(TARGET_SSE || TARGET_3DNOW_A)"
962 + "ix86_fixup_binary_operands_no_copy (SMAX, V4HImode, operands);")
964 (define_insn "mmx_smaxv4hi3"
965 [(set (match_operand:V4HI 0 "register_operand" "=y")
966 (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
968 [(set_attr "type" "mmxadd")
969 (set_attr "mode" "DI")])
971 +(define_expand "uminv8qi3"
972 + [(set (match_operand:V8QI 0 "register_operand" "")
973 + (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "")
974 + (match_operand:V8QI 2 "nonimmediate_operand" "")))]
975 + "(TARGET_SSE || TARGET_3DNOW_A)"
976 + "ix86_fixup_binary_operands_no_copy (UMAX, V8QImode, operands);")
978 (define_insn "mmx_uminv8qi3"
979 [(set (match_operand:V8QI 0 "register_operand" "=y")
980 (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0")
982 [(set_attr "type" "mmxadd")
983 (set_attr "mode" "DI")])
985 +(define_expand "sminv4hi3"
986 + [(set (match_operand:V4HI 0 "register_operand" "")
987 + (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "")
988 + (match_operand:V4HI 2 "nonimmediate_operand" "")))]
989 + "(TARGET_SSE || TARGET_3DNOW_A)"
990 + "ix86_fixup_binary_operands_no_copy (SMIN, V4HImode, operands);")
992 (define_insn "mmx_sminv4hi3"
993 [(set (match_operand:V4HI 0 "register_operand" "=y")
994 (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
996 [(set_attr "type" "mmxadd")
997 (set_attr "mode" "DI")])
999 -(define_insn "mmx_ashr<mode>3"
1000 +(define_insn "ashr<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_lshr<mode>3"
1009 +(define_insn "lshr<mode>3"
1010 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
1012 (match_operand:MMXMODE24 1 "register_operand" "0")
1014 [(set_attr "type" "mmxshft")
1015 (set_attr "mode" "DI")])
1017 -(define_insn "mmx_ashl<mode>3"
1018 +(define_insn "ashl<mode>3"
1019 [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
1021 (match_operand:MMXMODE24 1 "register_operand" "0")
1022 @@ -853,12 +902,66 @@
1023 [(set_attr "type" "mmxcmp")
1024 (set_attr "mode" "DI")])
1026 +(define_expand "vcond<mode>"
1027 + [(set (match_operand:MMXMODE12 0 "register_operand" "")
1028 + (if_then_else:MMXMODE12
1029 + (match_operator 3 ""
1030 + [(match_operand:MMXMODE12 4 "nonimmediate_operand" "")
1031 + (match_operand:MMXMODE12 5 "nonimmediate_operand" "")])
1032 + (match_operand:MMXMODE12 1 "general_operand" "")
1033 + (match_operand:MMXMODE12 2 "general_operand" "")))]
1036 + if (ix86_expand_int_vcond (operands))
1042 +(define_expand "vconduv8qi"
1043 + [(set (match_operand:V8QI 0 "register_operand" "")
1044 + (if_then_else:V8QI
1045 + (match_operator 3 ""
1046 + [(match_operand:V8QI 4 "nonimmediate_operand" "")
1047 + (match_operand:V8QI 5 "nonimmediate_operand" "")])
1048 + (match_operand:V8QI 1 "general_operand" "")
1049 + (match_operand:V8QI 2 "general_operand" "")))]
1052 + if (ix86_expand_int_vcond (operands))
1058 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1060 ;; Parallel integral logical operations
1062 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1064 +(define_expand "one_cmpl<mode>2"
1065 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
1066 + (xor:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1070 + int i, n = GET_MODE_NUNITS (<MODE>mode);
1071 + rtvec v = rtvec_alloc (n);
1073 + for (i = 0; i < n; ++i)
1074 + RTVEC_ELT (v, i) = constm1_rtx;
1076 + operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
1079 +(define_expand "and<mode>3"
1080 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
1081 + (and:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1082 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1084 + "ix86_fixup_binary_operands_no_copy (AND, <MODE>mode, operands);")
1086 (define_insn "mmx_and<mode>3"
1087 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1089 @@ -879,6 +982,13 @@
1090 [(set_attr "type" "mmxadd")
1091 (set_attr "mode" "DI")])
1093 +(define_expand "ior<mode>3"
1094 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
1095 + (ior:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1096 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1098 + "ix86_fixup_binary_operands_no_copy (IOR, <MODE>mode, operands);")
1100 (define_insn "mmx_ior<mode>3"
1101 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1103 @@ -889,6 +999,13 @@
1104 [(set_attr "type" "mmxadd")
1105 (set_attr "mode" "DI")])
1107 +(define_expand "xor<mode>3"
1108 + [(set (match_operand:MMXMODEI 0 "register_operand" "")
1109 + (xor:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
1110 + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
1112 + "ix86_fixup_binary_operands_no_copy (XOR, <MODE>mode, operands);")
1114 (define_insn "mmx_xor<mode>3"
1115 [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1117 @@ -1147,7 +1264,7 @@
1118 (match_operand 2 "const_int_operand" "")]
1121 - ix86_expand_vector_set (false, operands[0], operands[1],
1122 + ix86_expand_vector_set (true, operands[0], operands[1],
1123 INTVAL (operands[2]));
1126 @@ -1205,7 +1322,7 @@
1127 (match_operand 2 "const_int_operand" "")]
1130 - ix86_expand_vector_extract (false, operands[0], operands[1],
1131 + ix86_expand_vector_extract (true, operands[0], operands[1],
1132 INTVAL (operands[2]));
1135 @@ -1215,7 +1332,7 @@
1136 (match_operand 1 "" "")]
1139 - ix86_expand_vector_init (false, operands[0], operands[1]);
1140 + ix86_expand_vector_init (true, operands[0], operands[1]);
1144 @@ -1225,7 +1342,7 @@
1145 (match_operand 2 "const_int_operand" "")]
1148 - ix86_expand_vector_set (false, operands[0], operands[1],
1149 + ix86_expand_vector_set (true, operands[0], operands[1],
1150 INTVAL (operands[2]));
1153 @@ -1236,7 +1353,7 @@
1154 (match_operand 2 "const_int_operand" "")]
1157 - ix86_expand_vector_extract (false, operands[0], operands[1],
1158 + ix86_expand_vector_extract (true, operands[0], operands[1],
1159 INTVAL (operands[2]));
1162 @@ -1246,7 +1363,7 @@
1163 (match_operand 1 "" "")]
1166 - ix86_expand_vector_init (false, operands[0], operands[1]);
1167 + ix86_expand_vector_init (true, operands[0], operands[1]);
1171 @@ -1256,7 +1373,7 @@
1172 (match_operand 2 "const_int_operand" "")]
1175 - ix86_expand_vector_set (false, operands[0], operands[1],
1176 + ix86_expand_vector_set (true, operands[0], operands[1],
1177 INTVAL (operands[2]));
1180 @@ -1267,7 +1384,7 @@
1181 (match_operand 2 "const_int_operand" "")]
1184 - ix86_expand_vector_extract (false, operands[0], operands[1],
1185 + ix86_expand_vector_extract (true, operands[0], operands[1],
1186 INTVAL (operands[2]));
1189 @@ -1277,7 +1394,7 @@
1190 (match_operand 1 "" "")]
1193 - ix86_expand_vector_init (false, operands[0], operands[1]);
1194 + ix86_expand_vector_init (true, operands[0], operands[1]);
1198 @@ -1386,48 +1503,20 @@
1199 [(set_attr "type" "mmxcvt")
1200 (set_attr "mode" "DI")])
1202 -(define_insn "mmx_emms"
1203 - [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
1204 - (clobber (reg:XF 8))
1205 - (clobber (reg:XF 9))
1206 - (clobber (reg:XF 10))
1207 - (clobber (reg:XF 11))
1208 - (clobber (reg:XF 12))
1209 - (clobber (reg:XF 13))
1210 - (clobber (reg:XF 14))
1211 - (clobber (reg:XF 15))
1212 - (clobber (reg:DI 29))
1213 - (clobber (reg:DI 30))
1214 - (clobber (reg:DI 31))
1215 - (clobber (reg:DI 32))
1216 - (clobber (reg:DI 33))
1217 - (clobber (reg:DI 34))
1218 - (clobber (reg:DI 35))
1219 - (clobber (reg:DI 36))]
1222 - [(set_attr "type" "mmx")
1223 - (set_attr "memory" "unknown")])
1224 +(define_insn "efpu"
1225 + [(set (reg:ALLREGS FIRSTFP_REG)
1226 + (unspec_volatile:ALLREGS [(reg:ALLREGS FIRSTMMX_REG)]
1228 + "TARGET_80387 && TARGET_MMX"
1230 + [(set_attr "length" "0")])
1232 +(define_insn "emms"
1233 + [(set (reg:ALLREGS FIRSTMMX_REG)
1234 + (unspec_volatile:ALLREGS [(reg:ALLREGS FIRSTFP_REG)]
1236 + "TARGET_80387 && TARGET_MMX"
1238 + return TARGET_3DNOW ? "femms" : "emms";
1241 -(define_insn "mmx_femms"
1242 - [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
1243 - (clobber (reg:XF 8))
1244 - (clobber (reg:XF 9))
1245 - (clobber (reg:XF 10))
1246 - (clobber (reg:XF 11))
1247 - (clobber (reg:XF 12))
1248 - (clobber (reg:XF 13))
1249 - (clobber (reg:XF 14))
1250 - (clobber (reg:XF 15))
1251 - (clobber (reg:DI 29))
1252 - (clobber (reg:DI 30))
1253 - (clobber (reg:DI 31))
1254 - (clobber (reg:DI 32))
1255 - (clobber (reg:DI 33))
1256 - (clobber (reg:DI 34))
1257 - (clobber (reg:DI 35))
1258 - (clobber (reg:DI 36))]
1261 - [(set_attr "type" "mmx")
1262 - (set_attr "memory" "none")])
1263 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/sse.md gcc-4.1-20050818T1605UTC/gcc/config/i386/sse.md
1264 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/i386/sse.md 2005-08-18 16:01:16.000000000 +0000
1265 +++ gcc-4.1-20050818T1605UTC/gcc/config/i386/sse.md 2005-08-18 16:25:02.000000000 +0000
1268 "cvtpi2ps\t{%2, %0|%0, %2}"
1269 [(set_attr "type" "ssecvt")
1270 + (set_attr "unit" "mmx")
1271 (set_attr "mode" "V4SF")])
1273 (define_insn "sse_cvtps2pi"
1274 @@ -3508,6 +3509,7 @@
1275 movhps\t{%2, %0|%0, %2}
1276 movlps\t{%1, %0|%0, %1}"
1277 [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov,ssemov")
1278 + (set_attr "unit" "*,mmx,*,*,*,*")
1279 (set_attr "mode" "TI,TI,TI,V4SF,V2SF,V2SF")])
1281 (define_expand "vec_setv2di"
1282 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/config/sh/sh.h gcc-4.1-20050818T1605UTC/gcc/config/sh/sh.h
1283 --- gcc-4.1-20050818T1605UTC/gcc.orig/config/sh/sh.h 2005-08-18 16:01:22.000000000 +0000
1284 +++ gcc-4.1-20050818T1605UTC/gcc/config/sh/sh.h 2005-08-18 16:25:02.000000000 +0000
1285 @@ -3311,7 +3311,7 @@
1286 ? get_attr_fp_mode (INSN) \
1289 -#define MODE_AFTER(MODE, INSN) \
1290 +#define MODE_AFTER(ENTITY, MODE, INSN) \
1292 && recog_memoized (INSN) >= 0 \
1293 && get_attr_fp_set (INSN) != FP_SET_NONE \
1294 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/doc/tm.texi gcc-4.1-20050818T1605UTC/gcc/doc/tm.texi
1295 --- gcc-4.1-20050818T1605UTC/gcc.orig/doc/tm.texi 2005-08-18 16:01:28.000000000 +0000
1296 +++ gcc-4.1-20050818T1605UTC/gcc/doc/tm.texi 2005-08-18 16:25:02.000000000 +0000
1297 @@ -4227,6 +4227,16 @@
1298 compiler knows this regardless of @code{EXIT_IGNORE_STACK}.
1301 +@defmac CALL_INSN_SETS (@var{INSN})
1302 +Define this macro as a C expression that returns RTL expression of
1303 +additional hard register set by call_insn.
1306 +@defmac CALL_INSN_USES (@var{INSN})
1307 +Define this macro as a C expression that returns RTL expression of
1308 +additional hard register used by call_insn.
1311 @defmac EPILOGUE_USES (@var{regno})
1312 Define this macro as a C expression that is nonzero for registers that are
1313 used by the epilogue or the @samp{return} pattern. The stack and frame
1314 @@ -8376,6 +8386,13 @@
1315 switch is needed / supplied.
1318 +@defmac LIFE_ANALYSIS_AFTER_MODE_SWITCHING
1319 +Define this macro if the port needs extra register life analysis after
1320 +mode switching. This macro should be defined if mode switching inserts
1321 +instructions that change global registers to maintain consistent global
1322 +register life information.
1325 @defmac MODE_NEEDED (@var{entity}, @var{insn})
1326 @var{entity} is an integer specifying a mode-switched entity. If
1327 @code{OPTIMIZE_MODE_SWITCHING} is defined, you must define this macro to
1328 @@ -8384,9 +8401,9 @@
1329 be switched into prior to the execution of @var{insn}.
1332 -@defmac MODE_AFTER (@var{mode}, @var{insn})
1333 -If this macro is defined, it is evaluated for every @var{insn} during
1334 -mode switching. It determines the mode that an insn results in (if
1335 +@defmac MODE_AFTER (@var{entity}, @var{mode}, @var{insn})
1336 +If this macro is defined, it is evaluated for every @var{entity} that needs
1337 +mode switching. It determines the mode that an @var{insn} results in (if
1338 different from the incoming mode).
1341 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/flow.c gcc-4.1-20050818T1605UTC/gcc/flow.c
1342 --- gcc-4.1-20050818T1605UTC/gcc.orig/flow.c 2005-08-18 16:00:40.000000000 +0000
1343 +++ gcc-4.1-20050818T1605UTC/gcc/flow.c 2005-08-18 16:25:02.000000000 +0000
1344 @@ -1830,10 +1830,11 @@
1350 + rtx cond = NULL_RTX;
1351 + rtx reg ATTRIBUTE_UNUSED;
1355 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
1356 cond = COND_EXEC_TEST (PATTERN (insn));
1358 @@ -1856,6 +1857,13 @@
1359 mark_set_1 (pbi, CLOBBER, XEXP (XEXP (note, 0), 0),
1360 cond, insn, pbi->flags);
1362 +#ifdef CALL_INSN_SETS
1363 + reg = CALL_INSN_SETS (insn);
1366 + mark_set_1 (pbi, SET, reg, cond, insn, pbi->flags);
1369 /* Calls change all call-used and global registers; sibcalls do not
1370 clobber anything that must be preserved at end-of-function,
1371 except for return values. */
1372 @@ -1894,10 +1902,11 @@
1374 if (! insn_is_dead && CALL_P (insn))
1377 + rtx cond = NULL_RTX;
1378 + rtx reg ATTRIBUTE_UNUSED;
1383 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
1384 cond = COND_EXEC_TEST (PATTERN (insn));
1386 @@ -1910,6 +1919,13 @@
1387 of which mark_used_regs knows how to handle. */
1388 mark_used_regs (pbi, XEXP (XEXP (note, 0), 0), cond, insn);
1390 +#ifdef CALL_INSN_USES
1391 + reg = CALL_INSN_USES (insn);
1394 + mark_used_reg (pbi, reg, cond, insn);
1397 /* The stack ptr is used (honorarily) by a CALL insn. */
1398 if ((flags & PROP_REG_INFO)
1399 && !REGNO_REG_SET_P (pbi->reg_live, STACK_POINTER_REGNUM))
1400 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/mode-switching.c gcc-4.1-20050818T1605UTC/gcc/mode-switching.c
1401 --- gcc-4.1-20050818T1605UTC/gcc.orig/mode-switching.c 2005-08-18 16:00:42.000000000 +0000
1402 +++ gcc-4.1-20050818T1605UTC/gcc/mode-switching.c 2005-08-18 16:25:02.000000000 +0000
1404 RESET_BIT (transp[bb->index], j);
1407 - last_mode = MODE_AFTER (last_mode, insn);
1408 + last_mode = MODE_AFTER (e, last_mode, insn);
1410 /* Update LIVE_NOW. */
1411 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1412 @@ -730,6 +730,14 @@
1414 optimize_mode_switching (NULL);
1417 + /* Mode switching can insert instructions that
1418 + change global registers life data. */
1419 +#ifdef LIFE_ANALYSIS_AFTER_MODE_SWITCHING
1420 + if (LIFE_ANALYSIS_AFTER_MODE_SWITCHING)
1421 + life_analysis (NULL, PROP_REG_INFO);
1424 #endif /* OPTIMIZE_MODE_SWITCHING */
1427 diff -uNr gcc-4.1-20050818T1605UTC/gcc.orig/reg-stack.c gcc-4.1-20050818T1605UTC/gcc/reg-stack.c
1428 --- gcc-4.1-20050818T1605UTC/gcc.orig/reg-stack.c 2005-08-18 16:00:43.000000000 +0000
1429 +++ gcc-4.1-20050818T1605UTC/gcc/reg-stack.c 2005-08-18 16:25:02.000000000 +0000
1430 @@ -1579,6 +1579,41 @@
1434 + case UNSPEC_VOLATILE:
1435 + switch (XINT (pat_src, 1))
1439 + case UNSPECV_EFPU:
1440 + /* There should be no stack registers live
1442 + gcc_assert (regstack->top == -1);
1444 + /* Mark all x87 registers as used. */
1445 + for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
1447 + regstack->reg[++regstack->top] = i;
1448 + SET_HARD_REG_BIT (regstack->reg_set, i);
1452 + case UNSPECV_EMMS:
1453 + /* All stack registers should be alive
1455 + gcc_assert (regstack->top == REG_STACK_SIZE - 1);
1457 + /* Mark all x87 registers as empty. */
1458 + for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
1459 + CLEAR_HARD_REG_BIT (regstack->reg_set, i);
1461 + regstack->top = -1;
1465 + gcc_unreachable ();
1470 switch (XINT (pat_src, 1))
1472 @@ -2269,6 +2304,25 @@
1473 if (NOTE_P (insn) || INSN_DELETED_P (insn))
1474 return control_flow_insn_deleted;
1476 +#ifdef CALL_INSN_SETS
1477 + if (CALL_P (insn))
1479 + rtx reg = CALL_INSN_SETS (insn);
1481 + if (reg && STACK_REG_P (reg))
1485 + for (count = hard_regno_nregs[REGNO (reg)][GET_MODE (reg)];
1488 + regstack->reg[++regstack->top] = REGNO (reg) + count;
1489 + SET_HARD_REG_BIT (regstack->reg_set, REGNO (reg) + count);
1495 /* If there is a REG_UNUSED note on a stack register on this insn,
1496 the indicated reg must be popped. The REG_UNUSED note is removed,
1497 since the form of the newly emitted pop insn references the reg,
1498 @@ -2544,6 +2598,15 @@
1499 basic_block block = e->dest;
1500 block_info bi = BLOCK_INFO (block);
1504 + /* Check if all stack registers are live at function entry.
1505 + This is the case where stack registers are disabled and no
1506 + register initialization is needed. */
1508 + for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
1509 + if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
1512 for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
1513 if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
1514 @@ -2552,11 +2615,14 @@
1516 bi->stack_in.reg[++top] = reg;
1518 - init = gen_rtx_SET (VOIDmode,
1519 - FP_MODE_REG (FIRST_STACK_REG, SFmode),
1521 - insert_insn_on_edge (init, e);
1523 + if (numregs != REG_STACK_SIZE)
1525 + init = gen_rtx_SET (VOIDmode,
1526 + FP_MODE_REG (FIRST_STACK_REG, SFmode),
1528 + insert_insn_on_edge (init, e);
1533 bi->stack_in.top = top;
1534 @@ -2575,13 +2641,34 @@
1538 - retvalue = stack_result (current_function_decl);
1539 value_reg_low = value_reg_high = -1;
1542 +#ifdef EPILOGUE_USES
1547 + for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
1548 + if (EPILOGUE_USES (i))
1553 + value_reg_low = FIRST_STACK_REG;
1554 + value_reg_high = value_reg_low + numregs - 1;
1559 + if (value_reg_low < 0)
1561 - value_reg_low = REGNO (retvalue);
1562 - value_reg_high = value_reg_low
1563 - + hard_regno_nregs[value_reg_low][GET_MODE (retvalue)] - 1;
1564 + retvalue = stack_result (current_function_decl);
1567 + value_reg_low = REGNO (retvalue);
1568 + value_reg_high = value_reg_low
1569 + + hard_regno_nregs[value_reg_low][GET_MODE (retvalue)] - 1;
1573 output_stack = &BLOCK_INFO (EXIT_BLOCK_PTR)->stack_in;