SOURCES: gcc-mmx-x87-fpu-mode-switching-and-mmx-vectorizer.patch (...

pluto pluto at pld-linux.org
Sat Jul 23 17:50:43 CEST 2005


Author: pluto                        Date: Sat Jul 23 15:50:43 2005 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- fix mmx/x87 interactions.

---- Files affected:
SOURCES:
   gcc-mmx-x87-fpu-mode-switching-and-mmx-vectorizer.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/gcc-mmx-x87-fpu-mode-switching-and-mmx-vectorizer.patch
diff -u /dev/null SOURCES/gcc-mmx-x87-fpu-mode-switching-and-mmx-vectorizer.patch:1.1
--- /dev/null	Sat Jul 23 17:50:43 2005
+++ SOURCES/gcc-mmx-x87-fpu-mode-switching-and-mmx-vectorizer.patch	Sat Jul 23 17:50:38 2005
@@ -0,0 +1,1558 @@
+--- gcc/gcc/builtins.c	2005-07-12 11:19:59.000000000 +0200
++++ gcc/gcc/builtins.c	2005-07-18 06:14:15.000000000 +0200
+@@ -52,6 +52,14 @@ Software Foundation, 51 Franklin Street,
+ #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
+ #endif
+ 
++#ifndef FUNCTION_VALUE_REGNO_P_APPLY_RESULT
++#define FUNCTION_VALUE_REGNO_P_APPLY_RESULT FUNCTION_VALUE_REGNO_P
++#endif
++
++#ifndef FUNCTION_ARG_REGNO_P_APPLY_ARGS
++#define FUNCTION_ARG_REGNO_P_APPLY_ARGS FUNCTION_ARG_REGNO_P
++#endif
++
+ /* Define the names of the builtin function types and codes.  */
+ const char *const built_in_class_names[4]
+   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
+@@ -1079,7 +1087,7 @@ apply_args_size (void)
+ 	size += GET_MODE_SIZE (Pmode);
+ 
+       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+-	if (FUNCTION_ARG_REGNO_P (regno))
++	if (FUNCTION_ARG_REGNO_P_APPLY_ARGS (regno))
+ 	  {
+ 	    mode = reg_raw_mode[regno];
+ 
+@@ -1117,7 +1125,7 @@ apply_result_size (void)
+       size = 0;
+ 
+       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+-	if (FUNCTION_VALUE_REGNO_P (regno))
++	if (FUNCTION_VALUE_REGNO_P_APPLY_RESULT (regno))
+ 	  {
+ 	    mode = reg_raw_mode[regno];
+ 
+--- gcc/gcc/caller-save.c	2005-06-25 03:59:25.000000000 +0200
++++ gcc/gcc/caller-save.c	2005-07-18 06:14:15.000000000 +0200
+@@ -377,6 +377,7 @@ save_call_clobbered_regs (void)
+     {
+       rtx insn = chain->insn;
+       enum rtx_code code = GET_CODE (insn);
++      rtx reg ATTRIBUTE_UNUSED;
+ 
+       next = chain->next;
+ 
+@@ -450,6 +451,12 @@ save_call_clobbered_regs (void)
+ 	      CLEAR_HARD_REG_SET (this_insn_sets);
+ 	      note_stores (PATTERN (insn), mark_set_regs, NULL);
+ 
++#ifdef CALL_INSN_SETS
++	      reg = CALL_INSN_SETS (insn);
++
++	      if (reg)
++		mark_set_regs (reg, NULL_RTX, NULL);
++#endif
+ 	      /* Compute which hard regs must be saved before this call.  */
+ 	      AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set);
+ 	      AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets);
+--- gcc/gcc/config/i386/i386.c	2005-07-14 09:46:16.000000000 +0200
++++ gcc/gcc/config/i386/i386.c	2005-07-18 06:14:15.000000000 +0200
+@@ -2067,12 +2067,13 @@ ix86_return_pops_args (tree fundecl, tre
+ 
+ /* Return true when register may be used to pass function parameters.  */
+ bool
+-ix86_function_arg_regno_p (int regno)
++ix86_function_arg_regno_p (int regno, bool from_builtin)
+ {
+   int i;
+   if (!TARGET_64BIT)
+     return (regno < REGPARM_MAX
+-	    || (TARGET_MMX && MMX_REGNO_P (regno)
++	    || (TARGET_MMX && !(TARGET_80387 && from_builtin)
++		&& MMX_REGNO_P (regno) 
+ 		&& (regno < FIRST_MMX_REG + MMX_REGPARM_MAX))
+ 	    || (TARGET_SSE && SSE_REGNO_P (regno)
+ 		&& (regno < FIRST_SSE_REG + SSE_REGPARM_MAX)));
+@@ -3181,14 +3182,14 @@ ix86_function_arg_boundary (enum machine
+ 
+ /* Return true if N is a possible register number of function value.  */
+ bool
+-ix86_function_value_regno_p (int regno)
++ix86_function_value_regno_p (int regno, bool from_builtin)
+ {
+   if (regno == 0
+       || (regno == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)
+       || (regno == FIRST_SSE_REG && TARGET_SSE))
+     return true;
+ 
+-  if (!TARGET_64BIT
++  if (!TARGET_64BIT && !(TARGET_80387 && from_builtin)
+       && (regno == FIRST_MMX_REG && TARGET_MMX))
+ 	return true;
+ 
+@@ -7450,12 +7451,152 @@ output_387_binary_op (rtx insn, rtx *ope
+   return buf;
+ }
+ 
+-/* Return needed mode for entity in optimize_mode_switching pass.  */
++/* Return needed mode for entity in optimize_mode_switching pass.
++   Returned mode should match ix86_mode_entry () for function calls.  */
+ 
+ int
+ ix86_mode_needed (int entity, rtx insn)
+ {
+-  enum attr_i387_cw mode;
++  int unit, mode;
++
++  if (entity == I387_FPU_MODE)
++    {
++      /* If a function call uses MMX registers, select MMX FPU mode and
++	 if function call uses x87 registers, select x87 FPU mode.  */
++      if (CALL_P (insn))
++	{
++	  rtx link;
++	  rtx reg;
++	  bool mmx = false;
++	  bool x87 = false;
++
++	  for (link = CALL_INSN_FUNCTION_USAGE (insn);
++	       link;
++	       link = XEXP (link, 1))
++	    {
++	      if (GET_CODE (XEXP (link, 0)) == USE)
++		{
++		  reg = XEXP (XEXP (link, 0), 0);
++
++		  if (reg)
++		    {
++		      if (MMX_REG_P (reg))
++			mmx = true;
++
++		      if (FP_REG_P (reg))
++			x87 = true;
++		    }
++		}
++	    }
++
++	  /* Mixing of x87 and MMX registers is not allowed
++	     in function call.  */
++	  gcc_assert (!mmx || !x87);
++
++	  if (mmx)
++	    return FPU_MODE_MMX;
++
++	  /* Fall back to default mode.  */
++	  return FPU_MODE_X87;
++	}
++
++      /* Parse ASM operands to check input and output constraints.  If
++	 an ASM uses MMX registers, select MMX mode and if it uses x87
++	 registers, select x87 mode.  Mixing of MMX and x87 constraints
++	 is not allowed.  If no MMX or x87 input and output registers
++	 are used, switch to default mode.  */
++      if (NONJUMP_INSN_P (insn))
++	{
++	  rtx pat = PATTERN (insn);
++	  int noperands = asm_noperands (pat);
++
++	  if (noperands >= 0)
++	    {
++	      const char **constraints;
++	      int i;
++	      bool mmx = false;
++	      bool x87 = false;
++
++	      constraints = alloca (noperands * sizeof (char *));
++	      decode_asm_operands (pat, NULL, NULL, constraints, NULL);
++
++	      for (i = 0; i < noperands; i++)
++		{
++		  const char *c = constraints[i];
++		  enum reg_class class;
++
++		  if (c[0] == '%')
++		    c++;
++		  if (ISDIGIT ((unsigned char) c[0]) && c[1] == '\0')
++		    c = constraints[c[0] - '0'];
++
++		  while (*c)
++		    {
++		      char cc = *c;
++		      int len;
++		      switch (cc)
++			{
++			case ',':
++			  cc++;
++			  continue;
++			case '=':
++			case '+':
++			case '*':
++			case '%':
++			case '!':
++			case '#':
++			case '&':
++			case '?':
++			  break;
++
++			default:
++			  class = REG_CLASS_FROM_LETTER (cc);
++
++			  if (MMX_CLASS_P (class))
++			    mmx = true;
++
++			  if (FLOAT_CLASS_P (class))
++			    x87 = true;
++			}
++
++		      len = CONSTRAINT_LEN (cc, c);
++		      do
++			c++;
++		      while (--len && *c);
++		    }
++		}
++
++	      /* Mixing x87 and MMX registers in ASM is not allowed.  */
++	      if (mmx && x87)
++		error_for_asm (insn, "mixing of x87 and MMX registers "
++			       "is not allowed in %<asm%>");
++
++	      if (mmx)
++		return FPU_MODE_MMX;
++
++	      /* Fall back to default mode.  */
++	      return FPU_MODE_X87;
++	    }
++	}
++
++      if (recog_memoized (insn) < 0)
++	return FPU_MODE_ANY;
++
++      unit = get_attr_unit (insn);
++
++      switch (unit)
++	{
++	case UNIT_MMX:
++	  return FPU_MODE_MMX;
++
++	case UNIT_I387:
++	  return FPU_MODE_X87;
++	
++	default:
++	  return FPU_MODE_ANY;
++
++	}
++    }
+ 
+   /* The mode UNINITIALIZED is used to store control word after a
+      function call or ASM pattern.  The mode ANY specify that function
+@@ -7502,21 +7643,132 @@ ix86_mode_needed (int entity, rtx insn)
+   return I387_CW_ANY;
+ }
+ 
+-/* Output code to initialize control word copies used by trunc?f?i and
+-   rounding patterns.  CURRENT_MODE is set to current control word,
+-   while NEW_MODE is set to new control word.  */
++
++/* Switch FPU mode to appropriate mode after function call in
++   optimize_mode_switchig pass.  Returned mode should match
++   ix86_mode_exit ().  */
++
++int
++ix86_mode_after (int entity, int mode, rtx insn)
++{
++  if (entity == I387_FPU_MODE)
++    {
++      /* Switch FPU to MMX mode after funciton call if function value
++	 is returned in MMX register and similar for x87 reg.
++ 	 If no value is returned in MMX or x87 reg, fall back to
++	 default mode.  */
++     if (CALL_P (insn))
++	{
++	  rtx reg = SET_DEST (PATTERN (insn));
++
++	  int new_mode;
++
++	  if (reg && MMX_REG_P (reg))
++	    new_mode = FPU_MODE_MMX;
++	  else
++	    new_mode = FPU_MODE_X87;
++
++	  /* Call insn should never operate in FPU_MODE_ANY.  */
++	  if ((mode != FPU_MODE_ANY) && (new_mode != mode))
++	    ix86_fpu_mode_changed = 1;
++
++	  return new_mode;
++	}
++    }
++
++  return mode;
++}
++
++/* Switch FPU mode of function entry to appropriate mode in
++   optimize_mode_switchig pass.  Returned mode should match
++   ix86_mode_needed () for function calls.  */
++
++int
++ix86_mode_entry (int entity)
++{
++  if (entity == I387_FPU_MODE)
++    {
++      if (! current_function_args_info.maybe_vaarg)
++	{
++	  if (current_function_args_info.mmx_nregs != MMX_REGPARM_MAX)
++	    return FPU_MODE_MMX;
++
++	  /* ??? Handle x87 registers for fpregparm.  */
++	}
++
++      /* Fall back to default mode.  */
++      return FPU_MODE_X87;
++    }
++
++  return I387_CW_ANY;
++}
++
++/* Switch FPU mode of function exit to appropriate mode in
++   optimize_mode_switchig pass. Returned mode should match
++   ix86_mode_after () for function calls.  */
++
++int
++ix86_mode_exit (int entity) 
++{
++  if (entity == I387_FPU_MODE)
++    {
++      rtx reg = current_function_return_rtx;
++
++      /* If MMX output register is specified, switch FPU mode
++	 of function exit to MMX  mode.  */
++      if (reg && MMX_REG_P (reg))
++	return FPU_MODE_MMX;
++
++      /* Fall back to default mode.  */
++      return FPU_MODE_X87;
++    }
++
++  return I387_CW_ANY;
++}
++
++/* Emit mode switching instructions in optimize_mode_switching pass.  */
+ 
+ void
+-emit_i387_cw_initialization (int mode)
++ix86_emit_mode_set (int entity, int mode)
+ {
+-  rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
+-  rtx new_mode;
++  rtx stored_mode, new_mode;
++  rtx reg;
+ 
+   int slot;
+ 
+-  rtx reg = gen_reg_rtx (HImode);
++  if (entity == I387_FPU_MODE)
++    {
++      switch (mode)
++	{
++	case FPU_MODE_ANY:
++	  return;
++
++	case FPU_MODE_X87:
++	  emit_insn (gen_emms ());
++	  ix86_fpu_mode_changed = 1;
++	  return;
++
++	case FPU_MODE_MMX:
++	  emit_insn (gen_efpu ());
++	  ix86_fpu_mode_changed = 1;
++	  return;
++
++	default:
++	  gcc_unreachable ();
++	}
++    }
++
++  /* Output code to initialize control word copies used by trunc?f?i
++     and rounding patterns.  STORED_MODE is set to current control
++     word, while NEW_MODE is set to new control word.  */
+ 
++  if ((mode == I387_CW_UNINITIALIZED) || (mode == I387_CW_ANY))
++    return;
++ 
++  stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
+   emit_insn (gen_x86_fnstcw_1 (stored_mode));
++
++  reg = gen_reg_rtx (HImode);
+   emit_move_insn (reg, stored_mode);
+ 
+   if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+@@ -12279,6 +12531,7 @@ ix86_init_machine_status (void)
+ 
+   f = ggc_alloc_cleared (sizeof (struct machine_function));
+   f->use_fast_prologue_epilogue_nregs = -1;
++  f->optimize_mode_switching[I387_FPU_MODE] = TARGET_80387 && TARGET_MMX;
+ 
+   return f;
+ }
+@@ -12877,7 +13130,77 @@ ix86_local_alignment (tree type, int ali
+     }
+   return align;
+ }
++
+ 
++
++/* Return true to prevent register allocator from allocating registers
++   from the unit that is not active.  */
++
++bool
++ix86_epilogue_uses (int regno)
++{
++  int mode;
++
++  if (! ix86_fpu_mode_changed)
++    return false;
++
++  mode = ix86_mode_exit (I387_FPU_MODE);
++
++  if (mode == FPU_MODE_MMX)
++    return FP_REGNO_P (regno);
++  else
++    return MMX_REGNO_P (regno);
++}
++
++/* Return RTX code of additional register that CALL_INSN uses.
++   This function is used to maintain correct register life
++   information before CALL_INSN in case of MMX/x87 switching.  */
++
++rtx
++ix86_call_insn_uses (rtx insn)
++{
++  int mode;
++
++  if (! ix86_fpu_mode_changed)
++    return NULL_RTX;
++
++  gcc_assert (CALL_P (insn));
++
++  mode = ix86_mode_needed (I387_FPU_MODE, insn);
++  if (mode == FPU_MODE_MMX)
++    return gen_rtx_REG (ALLREGSmode, FIRST_FLOAT_REG);
++  else
++    return gen_rtx_REG (ALLREGSmode, FIRST_MMX_REG);
++
++  return NULL_RTX;
++}
++
++/* Return RTX code of additional register that CALL_INSN sets.
++   This function is used to maintain correct register life
++   information after CALL_INSN in case of MMX/x87 switching.  */
++
++rtx
++ix86_call_insn_sets (rtx insn)
++{
++  int mode;
++
++  if (! ix86_fpu_mode_changed)
++    return NULL_RTX;
++
++  gcc_assert (CALL_P (insn));
++
++  /* Current mode in call to ix86_mode_after is set to FPU_MODE_ANY
++     to prevent setting of ix86_fpu_mode_changed variable.  */
++  mode = ix86_mode_after (I387_FPU_MODE, FPU_MODE_ANY, insn);
++  if (mode == FPU_MODE_MMX)
++    return gen_rtx_REG (ALLREGSmode, FIRST_FLOAT_REG);
++  else
++    return gen_rtx_REG (ALLREGSmode, FIRST_MMX_REG);
++
++  return NULL_RTX;
++}
++
++
+ /* Emit RTL insns to initialize the variable parts of a trampoline.
+    FNADDR is an RTX for the address of the function's pure code.
+    CXT is an RTX for the static chain value for the function.  */
+@@ -13357,9 +13680,11 @@ enum ix86_builtins
+   IX86_BUILTIN_MONITOR,
+   IX86_BUILTIN_MWAIT,
+ 
++  IX86_BUILTIN_VEC_INIT_V2SF,
+   IX86_BUILTIN_VEC_INIT_V2SI,
+   IX86_BUILTIN_VEC_INIT_V4HI,
+   IX86_BUILTIN_VEC_INIT_V8QI,
++  IX86_BUILTIN_VEC_EXT_V2SF,
+   IX86_BUILTIN_VEC_EXT_V2DF,
+   IX86_BUILTIN_VEC_EXT_V2DI,
+   IX86_BUILTIN_VEC_EXT_V4SF,
+@@ -13541,24 +13866,24 @@ static const struct builtin_description 
+   { MASK_SSE, CODE_FOR_sse_cvtsi2ss, 0, IX86_BUILTIN_CVTSI2SS, 0, 0 },
+   { MASK_SSE | MASK_64BIT, CODE_FOR_sse_cvtsi2ssq, 0, IX86_BUILTIN_CVTSI642SS, 0, 0 },
+ 
+-  { MASK_MMX, CODE_FOR_mmx_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_ashlv2si3, 0, IX86_BUILTIN_PSLLD, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_ashlv2si3, 0, IX86_BUILTIN_PSLLDI, 0, 0 },
++  { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
++  { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
++  { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLD, 0, 0 },
++  { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLDI, 0, 0 },
+   { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQ, 0, 0 },
+   { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQI, 0, 0 },
+ 
+-  { MASK_MMX, CODE_FOR_mmx_lshrv4hi3, 0, IX86_BUILTIN_PSRLW, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_lshrv4hi3, 0, IX86_BUILTIN_PSRLWI, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_lshrv2si3, 0, IX86_BUILTIN_PSRLD, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_lshrv2si3, 0, IX86_BUILTIN_PSRLDI, 0, 0 },
++  { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLW, 0, 0 },
++  { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLWI, 0, 0 },
++  { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLD, 0, 0 },
++  { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLDI, 0, 0 },
+   { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQ, 0, 0 },
+   { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQI, 0, 0 },
+ 
+-  { MASK_MMX, CODE_FOR_mmx_ashrv4hi3, 0, IX86_BUILTIN_PSRAW, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_ashrv4hi3, 0, IX86_BUILTIN_PSRAWI, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_ashrv2si3, 0, IX86_BUILTIN_PSRAD, 0, 0 },
+-  { MASK_MMX, CODE_FOR_mmx_ashrv2si3, 0, IX86_BUILTIN_PSRADI, 0, 0 },
++  { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAW, 0, 0 },
++  { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAWI, 0, 0 },
++  { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRAD, 0, 0 },
++  { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRADI, 0, 0 },
+ 
+   { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_psadbw, 0, IX86_BUILTIN_PSADBW, 0, 0 },
+   { MASK_MMX, CODE_FOR_mmx_pmaddwd, 0, IX86_BUILTIN_PMADDWD, 0, 0 },
+@@ -14323,6 +14648,11 @@ ix86_init_mmx_sse_builtins (void)
+ 	       v16qi_ftype_pcchar, IX86_BUILTIN_LDDQU);
+ 
+   /* Access to the vec_init patterns.  */
++  ftype = build_function_type_list (V2SF_type_node, float_type_node,
++				    integer_type_node, NULL_TREE);
++  def_builtin (MASK_3DNOW, "__builtin_ia32_vec_init_v2sf",
++	       ftype, IX86_BUILTIN_VEC_INIT_V2SF);
++
+   ftype = build_function_type_list (V2SI_type_node, integer_type_node,
+ 				    integer_type_node, NULL_TREE);
+   def_builtin (MASK_MMX, "__builtin_ia32_vec_init_v2si",
+@@ -14344,6 +14674,11 @@ ix86_init_mmx_sse_builtins (void)
+ 	       ftype, IX86_BUILTIN_VEC_INIT_V8QI);
+ 
+   /* Access to the vec_extract patterns.  */
++  ftype = build_function_type_list (float_type_node, V2SF_type_node,
++				    integer_type_node, NULL_TREE);
++  def_builtin (MASK_3DNOW, "__builtin_ia32_vec_ext_v2sf",
++	       ftype, IX86_BUILTIN_VEC_EXT_V2DF);
++
+   ftype = build_function_type_list (double_type_node, V2DF_type_node,
+ 				    integer_type_node, NULL_TREE);
+   def_builtin (MASK_SSE, "__builtin_ia32_vec_ext_v2df",
+@@ -14818,7 +15153,7 @@ ix86_expand_builtin (tree exp, rtx targe
+   switch (fcode)
+     {
+     case IX86_BUILTIN_EMMS:
+-      emit_insn (gen_mmx_emms ());
++      /* emms insn is emitted automatically.  */
+       return 0;
+ 
+     case IX86_BUILTIN_SFENCE:
+@@ -15035,7 +15370,7 @@ ix86_expand_builtin (tree exp, rtx targe
+       return target;
+ 
+     case IX86_BUILTIN_FEMMS:
+-      emit_insn (gen_mmx_femms ());
++      /* femms insn is emitted automatically.  */
+       return NULL_RTX;
+ 
+     case IX86_BUILTIN_PAVGUSB:
+@@ -15181,11 +15516,13 @@ ix86_expand_builtin (tree exp, rtx targe
+       return ix86_expand_unop_builtin (CODE_FOR_sse3_lddqu, arglist,
+ 				       target, 1);
+ 
++    case IX86_BUILTIN_VEC_INIT_V2SF:
+     case IX86_BUILTIN_VEC_INIT_V2SI:
+     case IX86_BUILTIN_VEC_INIT_V4HI:
+     case IX86_BUILTIN_VEC_INIT_V8QI:
+       return ix86_expand_vec_init_builtin (TREE_TYPE (exp), arglist, target);
+ 
++    case IX86_BUILTIN_VEC_EXT_V2SF:
+     case IX86_BUILTIN_VEC_EXT_V2DF:
+     case IX86_BUILTIN_VEC_EXT_V2DI:
+     case IX86_BUILTIN_VEC_EXT_V4SF:
+--- gcc/gcc/config/i386/i386.h	2005-07-14 09:46:21.000000000 +0200
++++ gcc/gcc/config/i386/i386.h	2005-07-18 06:14:15.000000000 +0200
+@@ -819,7 +819,9 @@ do {									\
+ 
+ #define HARD_REGNO_NREGS(REGNO, MODE)   \
+   (FP_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO)	\
+-   ? (COMPLEX_MODE_P (MODE) ? 2 : 1)					\
++   ? ((MODE) == ALLREGSmode						\
++      ? 8								\
++      : (COMPLEX_MODE_P (MODE) ? 2 : 1))				\
+    : ((MODE) == XFmode							\
+       ? (TARGET_64BIT ? 2 : 3)						\
<<Diff was trimmed, longer than 597 lines>>



More information about the pld-cvs-commit mailing list