aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-12-17 13:40:39 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-12-17 13:40:39 -0800
commit6c4ccfd8a18c297fbdd017cd07dc307a7a7c6d89 (patch)
treed0080e8895d8639f626812843872da4bc308e876 /gcc
parent128691426dcb9e2a3cb57c89bc863d03c1009d82 (diff)
downloadgcc-6c4ccfd8a18c297fbdd017cd07dc307a7a7c6d89.zip
gcc-6c4ccfd8a18c297fbdd017cd07dc307a7a7c6d89.tar.gz
gcc-6c4ccfd8a18c297fbdd017cd07dc307a7a7c6d89.tar.bz2
i386.c (x86_64_reg_class_name): Re-indent.
* config/i386/i386.c (x86_64_reg_class_name): Re-indent. (classify_argument, examine_argument, construct_container, merge_classes): Remove prototypes. (type_natural_mode): Split out from ... (function_arg): ... here. (gen_reg_or_parallel): Remove alt_mode argument. Update callers. Use orig_mode unless it's BLKmode. (construct_container): Add orig_mode argument. Update callers. Use gen_reg_or_parallel for SSE registers. (ix86_function_value): Use type_natural_mode. (ix86_gimplify_va_arg): Likewise. (ix86_hard_regno_mode_ok): Always accept all SSE, MMX, 3DNOW modes in SSE registers; always accept all MMX, 3DNOW modes in MMX registers. * config/i386/i386.h (VALID_SSE2_REG_MODE): Don't include VALID_MMX_REG_MODE. * config/i386/i386.md (attribute mode): Add V1DF. (movsi_1): Use 'x' instead of 'Y' constraints. (movsi_1_nointernunit, movdi_2, movdi_1_rex64): Likewise. (movdi_1_rex64_nointerunit): Likewise. (movdf_nointeger, movdf_integer): Likewise. Handle SSE1. (movsf_1, movsf_1_nointerunit): Line up constraint alternatives. (swapsf): Use fp_register_operand, don't disable for TARGET_SSE. (swapdf): Likewise. (swapxf): Enable only for TARGET_80387. (movv2sf, movv2sf_internal, pushv2sf): Enable for MMX. (movtf): Remove double-check for TARGET_64BIT. (movv2df_internal): Enable for SSE1. (movv8hi_internal, movv16qi_internal): Likewise. (movv2df, movv8hi, movv16qi): Likewise. (pushv2di, pushv8hi, pushv16qi, pushv4si): Likewise. (pushdi2_rex64, movv4sf_internal, movv4si_internal, movv2di_internal, movv8qi_internal, movv4hi_internal, movv2sf_internal, movv2df_internal, movv8hi_internal, movv16qi_internal, movti_internal): Add leading '*' to name. From-SVN: r92336
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog37
-rw-r--r--gcc/config/i386/i386.c201
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/config/i386/i386.md229
4 files changed, 287 insertions, 183 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 50a1432..4e51583 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,40 @@
+2004-12-17 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (x86_64_reg_class_name): Re-indent.
+ (classify_argument, examine_argument, construct_container,
+ merge_classes): Remove prototypes.
+ (type_natural_mode): Split out from ...
+ (function_arg): ... here.
+ (gen_reg_or_parallel): Remove alt_mode argument. Update callers.
+ Use orig_mode unless it's BLKmode.
+ (construct_container): Add orig_mode argument. Update callers.
+ Use gen_reg_or_parallel for SSE registers.
+ (ix86_function_value): Use type_natural_mode.
+ (ix86_gimplify_va_arg): Likewise.
+ (ix86_hard_regno_mode_ok): Always accept all SSE, MMX, 3DNOW modes in
+ SSE registers; always accept all MMX, 3DNOW modes in MMX registers.
+ * config/i386/i386.h (VALID_SSE2_REG_MODE): Don't include
+ VALID_MMX_REG_MODE.
+ * config/i386/i386.md (attribute mode): Add V1DF.
+ (movsi_1): Use 'x' instead of 'Y' constraints.
+ (movsi_1_nointernunit, movdi_2, movdi_1_rex64): Likewise.
+ (movdi_1_rex64_nointerunit): Likewise.
+ (movdf_nointeger, movdf_integer): Likewise. Handle SSE1.
+ (movsf_1, movsf_1_nointerunit): Line up constraint alternatives.
+ (swapsf): Use fp_register_operand, don't disable for TARGET_SSE.
+ (swapdf): Likewise.
+ (swapxf): Enable only for TARGET_80387.
+ (movv2sf, movv2sf_internal, pushv2sf): Enable for MMX.
+ (movtf): Remove double-check for TARGET_64BIT.
+ (movv2df_internal): Enable for SSE1.
+ (movv8hi_internal, movv16qi_internal): Likewise.
+ (movv2df, movv8hi, movv16qi): Likewise.
+ (pushv2di, pushv8hi, pushv16qi, pushv4si): Likewise.
+ (pushdi2_rex64, movv4sf_internal, movv4si_internal, movv2di_internal,
+ movv8qi_internal, movv4hi_internal, movv2sf_internal,
+ movv2df_internal, movv8hi_internal, movv16qi_internal,
+ movti_internal): Add leading '*' to name.
+
2004-12-17 Dale Johannesen <dalej@apple.com>
* c-decl.c (diagnose_mismatched_decls): Accept mismatched
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 06c8bb0..bb54c22 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -951,17 +951,12 @@ enum x86_64_reg_class
X86_64_COMPLEX_X87_CLASS,
X86_64_MEMORY_CLASS
};
-static const char * const x86_64_reg_class_name[] =
- {"no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup", "x87", "x87up", "cplx87", "no"};
+static const char * const x86_64_reg_class_name[] = {
+ "no", "integer", "integerSI", "sse", "sseSF", "sseDF",
+ "sseup", "x87", "x87up", "cplx87", "no"
+};
#define MAX_CLASSES 4
-static int classify_argument (enum machine_mode, tree,
- enum x86_64_reg_class [MAX_CLASSES], int);
-static int examine_argument (enum machine_mode, tree, int, int *, int *);
-static rtx construct_container (enum machine_mode, tree, int, int, int,
- const int *, int);
-static enum x86_64_reg_class merge_classes (enum x86_64_reg_class,
- enum x86_64_reg_class);
/* Table of constants used by fldpi, fldln2, etc.... */
static REAL_VALUE_TYPE ext_80387_constants_table [5];
@@ -2040,6 +2035,71 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
return;
}
+/* Return the "natural" mode for TYPE. In most cases, this is just TYPE_MODE.
+ But in the case of vector types, it is some vector mode.
+
+ When we have only some of our vector isa extensions enabled, then there
+ are some modes for which vector_mode_supported_p is false. For these
+ modes, the generic vector support in gcc will choose some non-vector mode
+ in order to implement the type. By computing the natural mode, we'll
+ select the proper ABI location for the operand and not depend on whatever
+ the middle-end decides to do with these vector types. */
+
+static enum machine_mode
+type_natural_mode (tree type)
+{
+ enum machine_mode mode = TYPE_MODE (type);
+
+ if (TREE_CODE (type) == VECTOR_TYPE && !VECTOR_MODE_P (mode))
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ if ((size == 8 || size == 16)
+ /* ??? Generic code allows us to create width 1 vectors. Ignore. */
+ && TYPE_VECTOR_SUBPARTS (type) > 1)
+ {
+ enum machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
+
+ if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
+ mode = MIN_MODE_VECTOR_FLOAT;
+ else
+ mode = MIN_MODE_VECTOR_INT;
+
+ /* Get the mode which has this inner mode and number of units. */
+ for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
+ if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
+ && GET_MODE_INNER (mode) == innermode)
+ return mode;
+
+ abort ();
+ }
+ }
+
+ return mode;
+}
+
+/* We want to pass a value in REGNO whose "natural" mode is MODE. However,
+ this may not agree with the mode that the type system has chosen for the
+ register, which is ORIG_MODE. If ORIG_MODE is not BLKmode, then we can
+ go ahead and use it. Otherwise we have to build a PARALLEL instead. */
+
+static rtx
+gen_reg_or_parallel (enum machine_mode mode, enum machine_mode orig_mode,
+ unsigned int regno)
+{
+ rtx tmp;
+
+ if (orig_mode != BLKmode)
+ tmp = gen_rtx_REG (orig_mode, regno);
+ else
+ {
+ tmp = gen_rtx_REG (mode, regno);
+ tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
+ tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
+ }
+
+ return tmp;
+}
+
/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
of this code is to classify each 8bytes of incoming argument by the register
class and assign registers accordingly. */
@@ -2442,12 +2502,14 @@ examine_argument (enum machine_mode mode, tree type, int in_return,
}
return 1;
}
+
/* Construct container for the argument used by GCC interface. See
FUNCTION_ARG for the detailed description. */
+
static rtx
-construct_container (enum machine_mode mode, tree type, int in_return,
- int nintregs, int nsseregs, const int * intreg,
- int sse_regno)
+construct_container (enum machine_mode mode, enum machine_mode orig_mode,
+ tree type, int in_return, int nintregs, int nsseregs,
+ const int *intreg, int sse_regno)
{
enum machine_mode tmpmode;
int bytes =
@@ -2477,7 +2539,8 @@ construct_container (enum machine_mode mode, tree type, int in_return,
}
if (!n)
return NULL;
- if (!examine_argument (mode, type, in_return, &needed_intregs, &needed_sseregs))
+ if (!examine_argument (mode, type, in_return, &needed_intregs,
+ &needed_sseregs))
return NULL;
if (needed_intregs > nintregs || needed_sseregs > nsseregs)
return NULL;
@@ -2493,7 +2556,7 @@ construct_container (enum machine_mode mode, tree type, int in_return,
case X86_64_SSE_CLASS:
case X86_64_SSESF_CLASS:
case X86_64_SSEDF_CLASS:
- return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
+ return gen_reg_or_parallel (mode, orig_mode, SSE_REGNO (sse_regno));
case X86_64_X87_CLASS:
case X86_64_COMPLEX_X87_CLASS:
return gen_rtx_REG (mode, FIRST_STACK_REG);
@@ -2581,19 +2644,18 @@ construct_container (enum machine_mode mode, tree type, int in_return,
(TYPE is null for libcalls where that information may not be available.) */
void
-function_arg_advance (CUMULATIVE_ARGS *cum, /* current arg information */
- enum machine_mode mode, /* current arg mode */
- tree type, /* type of the argument or 0 if lib support */
- int named) /* whether or not the argument was named */
+function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
{
int bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
if (TARGET_DEBUG_ARG)
- fprintf (stderr,
- "function_adv (sz=%d, wds=%2d, nregs=%d, ssenregs=%d, mode=%s, named=%d)\n\n",
- words, cum->words, cum->nregs, cum->sse_nregs, GET_MODE_NAME (mode), named);
+ fprintf (stderr, "function_adv (sz=%d, wds=%2d, nregs=%d, ssenregs=%d, "
+ "mode=%s, named=%d)\n\n",
+ words, cum->words, cum->nregs, cum->sse_nregs,
+ GET_MODE_NAME (mode), named);
if (TARGET_64BIT)
{
int int_nregs, sse_nregs;
@@ -2651,34 +2713,6 @@ function_arg_advance (CUMULATIVE_ARGS *cum, /* current arg information */
return;
}
-/* A subroutine of function_arg. We want to pass a parameter whose nominal
- type is MODE in REGNO. We try to minimize ABI variation, so MODE may not
- actually be valid for REGNO with the current ISA. In this case, ALT_MODE
- is used instead. It must be the same size as MODE, and must be known to
- be valid for REGNO. Finally, ORIG_MODE is the original mode of the
- parameter, as seen by the type system. This may be different from MODE
- when we're mucking with things minimizing ABI variations.
-
- Returns a REG or a PARALLEL as appropriate. */
-
-static rtx
-gen_reg_or_parallel (enum machine_mode mode, enum machine_mode alt_mode,
- enum machine_mode orig_mode, unsigned int regno)
-{
- rtx tmp;
-
- if (HARD_REGNO_MODE_OK (regno, mode))
- tmp = gen_rtx_REG (mode, regno);
- else
- {
- tmp = gen_rtx_REG (alt_mode, regno);
- tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
- tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
- }
-
- return tmp;
-}
-
/* Define where to put the arguments to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
@@ -2705,26 +2739,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
/* To simplify the code below, represent vector types with a vector mode
even if MMX/SSE are not active. */
- if (type
- && TREE_CODE (type) == VECTOR_TYPE
- && (bytes == 8 || bytes == 16)
- && GET_MODE_CLASS (TYPE_MODE (type)) != MODE_VECTOR_INT
- && GET_MODE_CLASS (TYPE_MODE (type)) != MODE_VECTOR_FLOAT)
- {
- enum machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
- enum machine_mode newmode
- = TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
- ? MIN_MODE_VECTOR_FLOAT : MIN_MODE_VECTOR_INT;
-
- /* Get the mode which has this inner mode and number of units. */
- for (; newmode != VOIDmode; newmode = GET_MODE_WIDER_MODE (newmode))
- if (GET_MODE_NUNITS (newmode) == TYPE_VECTOR_SUBPARTS (type)
- && GET_MODE_INNER (newmode) == innermode)
- {
- mode = newmode;
- break;
- }
- }
+ if (type && TREE_CODE (type) == VECTOR_TYPE)
+ mode = type_natural_mode (type);
/* Handle a hidden AL argument containing number of registers for varargs
x86-64 functions. For i386 ABI just return constm1_rtx to avoid
@@ -2741,7 +2757,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
return constm1_rtx;
}
if (TARGET_64BIT)
- ret = construct_container (mode, type, 0, cum->nregs, cum->sse_nregs,
+ ret = construct_container (mode, orig_mode, type, 0, cum->nregs,
+ cum->sse_nregs,
&x86_64_int_parameter_registers [cum->regno],
cum->sse_regno);
else
@@ -2793,7 +2810,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
"changes the ABI");
}
if (cum->sse_nregs)
- ret = gen_reg_or_parallel (mode, TImode, orig_mode,
+ ret = gen_reg_or_parallel (mode, orig_mode,
cum->sse_regno + FIRST_SSE_REG);
}
break;
@@ -2810,7 +2827,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
"changes the ABI");
}
if (cum->mmx_nregs)
- ret = gen_reg_or_parallel (mode, DImode, orig_mode,
+ ret = gen_reg_or_parallel (mode, orig_mode,
cum->mmx_regno + FIRST_MMX_REG);
}
break;
@@ -2972,11 +2989,12 @@ ix86_function_value (tree valtype)
{
if (TARGET_64BIT)
{
- rtx ret = construct_container (TYPE_MODE (valtype), valtype, 1,
- REGPARM_MAX, SSE_REGPARM_MAX,
+ rtx ret = construct_container (type_natural_mode (valtype),
+ TYPE_MODE (valtype), valtype,
+ 1, REGPARM_MAX, SSE_REGPARM_MAX,
x86_64_int_return_registers, 0);
- /* For zero sized structures, construct_container return NULL, but we need
- to keep rest of compiler happy by returning meaningful value. */
+ /* For zero sized structures, construct_container return NULL, but we
+ need to keep rest of compiler happy by returning meaningful value. */
if (!ret)
ret = gen_rtx_REG (TYPE_MODE (valtype), 0);
return ret;
@@ -3342,11 +3360,11 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
size = int_size_in_bytes (type);
rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
- container = construct_container (TYPE_MODE (type), type, 0,
- REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0);
- /*
- * Pull the value out of the saved registers ...
- */
+ container = construct_container (type_natural_mode (type), TYPE_MODE (type),
+ type, 0, REGPARM_MAX, SSE_REGPARM_MAX,
+ intreg, 0);
+
+ /* Pull the value out of the saved registers. */
addr = create_tmp_var (ptr_type_node, "addr");
DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
@@ -14032,18 +14050,21 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
return VALID_FP_MODE_P (mode);
if (SSE_REGNO_P (regno))
{
- if (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
- return 1;
- if (TARGET_SSE && VALID_SSE_REG_MODE (mode))
- return 1;
- return 0;
+ /* We implement the move patterns for all vector modes into and
+ out of SSE registers, even when no operation instructions
+ are available. */
+ return (VALID_SSE_REG_MODE (mode)
+ || VALID_SSE2_REG_MODE (mode)
+ || VALID_MMX_REG_MODE (mode)
+ || VALID_MMX_REG_MODE_3DNOW (mode));
}
if (MMX_REGNO_P (regno))
{
- if (TARGET_3DNOW && VALID_MMX_REG_MODE_3DNOW (mode))
- return 1;
- if (TARGET_MMX && VALID_MMX_REG_MODE (mode))
- return 1;
+ /* We implement the move patterns for 3DNOW modes even in MMX mode,
+ so if the register is available at all, then we can move data of
+ the given mode into or out of it. */
+ return (VALID_MMX_REG_MODE (mode)
+ || VALID_MMX_REG_MODE_3DNOW (mode));
}
/* We handle both integer and floats in the general purpose registers.
In future we should be able to handle vector modes as well. */
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 9063d85..5bcd607 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1075,8 +1075,7 @@ do { \
#define VALID_SSE2_REG_MODE(MODE) \
((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \
- || (MODE) == V2DImode || (MODE) == DFmode \
- || VALID_MMX_REG_MODE (MODE))
+ || (MODE) == V2DImode || (MODE) == DFmode)
#define VALID_SSE_REG_MODE(MODE) \
((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6065321..f270f74 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -199,7 +199,7 @@
;; Main data type used by the insn
(define_attr "mode"
- "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
+ "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
(const_string "unknown"))
;; The CPU unit operations uses.
@@ -1122,8 +1122,10 @@
(set_attr "length_immediate" "1")])
(define_insn "*movsi_1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
- (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand"
+ "=r ,m ,!*y,!rm,!*y,!*x,!rm,!*x")
+ (match_operand:SI 1 "general_operand"
+ "rinm,rin,*y ,*y ,rm ,*x ,*x ,rm"))]
"(TARGET_INTER_UNIT_MOVES || optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
@@ -1161,8 +1163,10 @@
(set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
(define_insn "*movsi_1_nointernunit"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
- (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand"
+ "=r ,m ,!*y,!m,!*y,!*x,!m,!*x")
+ (match_operand:SI 1 "general_operand"
+ "rinm,rin,*y ,*y,m ,*x ,*x,m"))]
"(!TARGET_INTER_UNIT_MOVES && !optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
@@ -1784,7 +1788,7 @@
"!TARGET_64BIT"
"#")
-(define_insn "pushdi2_rex64"
+(define_insn "*pushdi2_rex64"
[(set (match_operand:DI 0 "push_operand" "=<,!<")
(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
"TARGET_64BIT"
@@ -1895,8 +1899,8 @@
(set_attr "length_immediate" "1")])
(define_insn "*movdi_2"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
- (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*x,!*x")
+ (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*x,*x,m"))]
"!TARGET_64BIT
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"@
@@ -1929,8 +1933,10 @@
"ix86_split_long_move (operands); DONE;")
(define_insn "*movdi_1_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
- (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand"
+ "=r,r ,r,mr,!mr,!*y,!rm,!*y,!*x,!rm,!*x,!*x,!*y")
+ (match_operand:DI 1 "general_operand"
+ "Z ,rem,i,re,n ,*y ,*y ,rm ,*x ,*x ,rm ,*y ,*x"))]
"TARGET_64BIT
&& (TARGET_INTER_UNIT_MOVES || optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
@@ -1986,8 +1992,10 @@
(set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
(define_insn "*movdi_1_rex64_nointerunit"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
- (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand"
+ "=r,r ,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
+ (match_operand:DI 1 "general_operand"
+ "Z,rem,i,re,n ,*y ,*y,m ,*Y ,*Y,m"))]
"TARGET_64BIT
&& (!TARGET_INTER_UNIT_MOVES && !optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
@@ -2179,8 +2187,10 @@
(set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
(define_insn "*movsf_1"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
- (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand"
+ "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
+ (match_operand:SF 1 "general_operand"
+ "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
"(TARGET_INTER_UNIT_MOVES || optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
@@ -2267,8 +2277,10 @@
(const_string "SF")))])
(define_insn "*movsf_1_nointerunit"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
- (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand"
+ "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!m,!*y")
+ (match_operand:SF 1 "general_operand"
+ "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,m ,*y,*y"))]
"(!TARGET_INTER_UNIT_MOVES && !optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
@@ -2355,11 +2367,11 @@
(const_string "SF")))])
(define_insn "*swapsf"
- [(set (match_operand:SF 0 "register_operand" "+f")
- (match_operand:SF 1 "register_operand" "+f"))
+ [(set (match_operand:SF 0 "fp_register_operand" "+f")
+ (match_operand:SF 1 "fp_register_operand" "+f"))
(set (match_dup 1)
(match_dup 0))]
- "reload_completed || !TARGET_SSE"
+ "reload_completed || TARGET_80387"
{
if (STACK_TOP_P (operands[0]))
return "fxch\t%1";
@@ -2431,8 +2443,10 @@
;; when optimizing for size.
(define_insn "*movdf_nointeger"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
- (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand"
+ "=f#x,m ,f#x,*r ,o ,x#f,x#f,x#f ,m")
+ (match_operand:DF 1 "general_operand"
+ "fm#x,f#x,G ,*roF,F*r,C ,x#f,xHm#f,x#f"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
&& (reload_in_progress || reload_completed
@@ -2470,24 +2484,25 @@
abort ();
}
case 6:
+ case 7:
+ case 8:
switch (get_attr_mode (insn))
{
case MODE_V4SF:
return "movaps\t{%1, %0|%0, %1}";
case MODE_V2DF:
return "movapd\t{%1, %0|%0, %1}";
+ case MODE_TI:
+ return "movdqa\t{%1, %0|%0, %1}";
+ case MODE_DI:
+ return "movq\t{%1, %0|%0, %1}";
case MODE_DF:
return "movsd\t{%1, %0|%0, %1}";
+ case MODE_V1DF:
+ return "movlpd\t{%1, %0|%0, %1}";
default:
abort ();
}
- case 7:
- if (get_attr_mode (insn) == MODE_V2DF)
- return "movlpd\t{%1, %0|%0, %1}";
- else
- return "movsd\t{%1, %0|%0, %1}";
- case 8:
- return "movsd\t{%1, %0|%0, %1}";
default:
abort();
@@ -2497,6 +2512,17 @@
(set (attr "mode")
(cond [(eq_attr "alternative" "3,4")
(const_string "SI")
+
+ /* For SSE1, we have many fewer alternatives. */
+ (eq (symbol_ref "TARGET_SSE2") (const_int 0))
+ (cond [(eq_attr "alternative" "5,6")
+ (if_then_else
+ (ne (symbol_ref "optimize_size") (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ ]
+ (const_string "DI"))
+
/* xorps is one byte shorter. */
(eq_attr "alternative" "5")
(cond [(ne (symbol_ref "optimize_size")
@@ -2504,8 +2530,10 @@
(const_string "V4SF")
(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
(const_int 0))
- (const_string "TI")]
+ (const_string "TI")
+ ]
(const_string "V2DF"))
+
/* For architectures resolving dependencies on
whole SSE registers use APD move to break dependency
chains, otherwise use short move to avoid extra work.
@@ -2513,12 +2541,13 @@
movaps encodes one byte shorter. */
(eq_attr "alternative" "6")
(cond
- [(ne (symbol_ref "optimize_size")
- (const_int 0))
- (const_string "V4SF")
- (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
- (const_int 0))
- (const_string "V2DF")]
+ [(ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
+ (const_int 0))
+ (const_string "V2DF")
+ ]
(const_string "DF"))
/* For architectures resolving dependencies on register
parts we may avoid extra work to zero out upper part
@@ -2527,13 +2556,16 @@
(if_then_else
(ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
(const_int 0))
- (const_string "V2DF")
- (const_string "DF"))]
- (const_string "DF")))])
+ (const_string "V1DF")
+ (const_string "DF"))
+ ]
+ (const_string "DF")))])
(define_insn "*movdf_integer"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
- (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand"
+ "=f#Yr,m ,f#Yr,r#Yf ,o ,Y#rf,Y#rf,Y#rf ,m")
+ (match_operand:DF 1 "general_operand"
+ "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y#rf,Ym#rf,Y#rf"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
&& (reload_in_progress || reload_completed
@@ -2572,24 +2604,25 @@
abort ();
}
case 6:
+ case 7:
+ case 8:
switch (get_attr_mode (insn))
{
case MODE_V4SF:
return "movaps\t{%1, %0|%0, %1}";
case MODE_V2DF:
return "movapd\t{%1, %0|%0, %1}";
+ case MODE_TI:
+ return "movdqa\t{%1, %0|%0, %1}";
+ case MODE_DI:
+ return "movq\t{%1, %0|%0, %1}";
case MODE_DF:
return "movsd\t{%1, %0|%0, %1}";
+ case MODE_V1DF:
+ return "movlpd\t{%1, %0|%0, %1}";
default:
abort ();
}
- case 7:
- if (get_attr_mode (insn) == MODE_V2DF)
- return "movlpd\t{%1, %0|%0, %1}";
- else
- return "movsd\t{%1, %0|%0, %1}";
- case 8:
- return "movsd\t{%1, %0|%0, %1}";
default:
abort();
@@ -2599,6 +2632,17 @@
(set (attr "mode")
(cond [(eq_attr "alternative" "3,4")
(const_string "SI")
+
+ /* For SSE1, we have many fewer alternatives. */
+ (eq (symbol_ref "TARGET_SSE2") (const_int 0))
+ (cond [(eq_attr "alternative" "5,6")
+ (if_then_else
+ (ne (symbol_ref "optimize_size") (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ ]
+ (const_string "DI"))
+
/* xorps is one byte shorter. */
(eq_attr "alternative" "5")
(cond [(ne (symbol_ref "optimize_size")
@@ -2606,21 +2650,24 @@
(const_string "V4SF")
(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
(const_int 0))
- (const_string "TI")]
+ (const_string "TI")
+ ]
(const_string "V2DF"))
+
/* For architectures resolving dependencies on
whole SSE registers use APD move to break dependency
- chains, otherwise use short move to avoid extra work.
+ chains, otherwise use short move to avoid extra work.
movaps encodes one byte shorter. */
(eq_attr "alternative" "6")
(cond
- [(ne (symbol_ref "optimize_size")
- (const_int 0))
- (const_string "V4SF")
- (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
- (const_int 0))
- (const_string "V2DF")]
+ [(ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
+ (const_int 0))
+ (const_string "V2DF")
+ ]
(const_string "DF"))
/* For architectures resolving dependencies on register
parts we may avoid extra work to zero out upper part
@@ -2629,9 +2676,10 @@
(if_then_else
(ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
(const_int 0))
- (const_string "V2DF")
- (const_string "DF"))]
- (const_string "DF")))])
+ (const_string "V1DF")
+ (const_string "DF"))
+ ]
+ (const_string "DF")))])
(define_split
[(set (match_operand:DF 0 "nonimmediate_operand" "")
@@ -2648,11 +2696,11 @@
"ix86_split_long_move (operands); DONE;")
(define_insn "*swapdf"
- [(set (match_operand:DF 0 "register_operand" "+f")
- (match_operand:DF 1 "register_operand" "+f"))
+ [(set (match_operand:DF 0 "fp_register_operand" "+f")
+ (match_operand:DF 1 "fp_register_operand" "+f"))
(set (match_dup 1)
(match_dup 0))]
- "reload_completed || !TARGET_SSE2"
+ "reload_completed || TARGET_80387"
{
if (STACK_TOP_P (operands[0]))
return "fxch\t%1";
@@ -2843,7 +2891,7 @@
(match_operand:XF 1 "register_operand" "+f"))
(set (match_dup 1)
(match_dup 0))]
- ""
+ "TARGET_80387"
{
if (STACK_TOP_P (operands[0]))
return "fxch\t%1";
@@ -19759,7 +19807,7 @@
;; Moves for SSE/MMX regs.
-(define_insn "movv4sf_internal"
+(define_insn "*movv4sf_internal"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE"
@@ -19784,7 +19832,7 @@
operands[2] = CONST0_RTX (V4SFmode);
})
-(define_insn "movv4si_internal"
+(define_insn "*movv4si_internal"
[(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE"
@@ -19824,7 +19872,7 @@
(const_string "TI"))]
(const_string "TI")))])
-(define_insn "movv2di_internal"
+(define_insn "*movv2di_internal"
[(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE"
@@ -19878,7 +19926,7 @@
operands[2] = CONST0_RTX (V2DFmode);
})
-(define_insn "movv8qi_internal"
+(define_insn "*movv8qi_internal"
[(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
(match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
"TARGET_MMX
@@ -19894,7 +19942,7 @@
[(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
(set_attr "mode" "DI")])
-(define_insn "movv4hi_internal"
+(define_insn "*movv4hi_internal"
[(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
(match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
"TARGET_MMX
@@ -19926,10 +19974,10 @@
[(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
(set_attr "mode" "DI")])
-(define_insn "movv2sf_internal"
+(define_insn "*movv2sf_internal"
[(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
(match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
- "TARGET_3DNOW
+ "TARGET_MMX
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"@
pxor\t%0, %0
@@ -19959,17 +20007,14 @@
(match_operand:TF 1 "nonimmediate_operand" ""))]
"TARGET_64BIT"
{
- if (TARGET_64BIT)
- ix86_expand_move (TFmode, operands);
- else
- ix86_expand_vector_move (TFmode, operands);
+ ix86_expand_move (TFmode, operands);
DONE;
})
-(define_insn "movv2df_internal"
+(define_insn "*movv2df_internal"
[(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
- "TARGET_SSE2
+ "TARGET_SSE
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (which_alternative)
@@ -19991,7 +20036,9 @@
}
[(set_attr "type" "ssemov")
(set (attr "mode")
- (cond [(eq_attr "alternative" "0,1")
+ (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
+ (const_string "V4SF")
+ (eq_attr "alternative" "0,1")
(if_then_else
(ne (symbol_ref "optimize_size")
(const_int 0))
@@ -20007,10 +20054,10 @@
(const_string "V2DF"))]
(const_string "V2DF")))])
-(define_insn "movv8hi_internal"
+(define_insn "*movv8hi_internal"
[(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
- "TARGET_SSE2
+ "TARGET_SSE
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (which_alternative)
@@ -20048,10 +20095,10 @@
(const_string "TI"))]
(const_string "TI")))])
-(define_insn "movv16qi_internal"
+(define_insn "*movv16qi_internal"
[(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
- "TARGET_SSE2
+ "TARGET_SSE
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (which_alternative)
@@ -20092,7 +20139,7 @@
(define_expand "movv2df"
[(set (match_operand:V2DF 0 "nonimmediate_operand" "")
(match_operand:V2DF 1 "nonimmediate_operand" ""))]
- "TARGET_SSE2"
+ "TARGET_SSE"
{
ix86_expand_vector_move (V2DFmode, operands);
DONE;
@@ -20101,7 +20148,7 @@
(define_expand "movv8hi"
[(set (match_operand:V8HI 0 "nonimmediate_operand" "")
(match_operand:V8HI 1 "nonimmediate_operand" ""))]
- "TARGET_SSE2"
+ "TARGET_SSE"
{
ix86_expand_vector_move (V8HImode, operands);
DONE;
@@ -20110,7 +20157,7 @@
(define_expand "movv16qi"
[(set (match_operand:V16QI 0 "nonimmediate_operand" "")
(match_operand:V16QI 1 "nonimmediate_operand" ""))]
- "TARGET_SSE2"
+ "TARGET_SSE"
{
ix86_expand_vector_move (V16QImode, operands);
DONE;
@@ -20173,7 +20220,7 @@
(define_expand "movv2sf"
[(set (match_operand:V2SF 0 "nonimmediate_operand" "")
(match_operand:V2SF 1 "nonimmediate_operand" ""))]
- "TARGET_3DNOW"
+ "TARGET_MMX"
{
ix86_expand_vector_move (V2SFmode, operands);
DONE;
@@ -20194,19 +20241,19 @@
(define_insn "*pushv2di"
[(set (match_operand:V2DI 0 "push_operand" "=<")
(match_operand:V2DI 1 "register_operand" "x"))]
- "TARGET_SSE2"
+ "TARGET_SSE"
"#")
(define_insn "*pushv8hi"
[(set (match_operand:V8HI 0 "push_operand" "=<")
(match_operand:V8HI 1 "register_operand" "x"))]
- "TARGET_SSE2"
+ "TARGET_SSE"
"#")
(define_insn "*pushv16qi"
[(set (match_operand:V16QI 0 "push_operand" "=<")
(match_operand:V16QI 1 "register_operand" "x"))]
- "TARGET_SSE2"
+ "TARGET_SSE"
"#")
(define_insn "*pushv4sf"
@@ -20218,7 +20265,7 @@
(define_insn "*pushv4si"
[(set (match_operand:V4SI 0 "push_operand" "=<")
(match_operand:V4SI 1 "register_operand" "x"))]
- "TARGET_SSE2"
+ "TARGET_SSE"
"#")
(define_insn "*pushv2si"
@@ -20242,7 +20289,7 @@
(define_insn "*pushv2sf"
[(set (match_operand:V2SF 0 "push_operand" "=<")
(match_operand:V2SF 1 "register_operand" "y"))]
- "TARGET_3DNOW"
+ "TARGET_MMX"
"#")
(define_split
@@ -20268,7 +20315,7 @@
operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
-(define_insn "movti_internal"
+(define_insn "*movti_internal"
[(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE && !TARGET_64BIT
@@ -22196,7 +22243,7 @@
[(set (match_operand:V2SI 0 "register_operand" "=y")
(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
(match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
- "TARGET_3DNOW"
+ "TARGET_3DNOW"
"pfcmpgt\\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxcmp")
(set_attr "mode" "V2SF")])