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
This commit is contained in:
Richard Henderson 2004-12-17 13:40:39 -08:00 committed by Richard Henderson
parent 128691426d
commit 6c4ccfd8a1
4 changed files with 287 additions and 183 deletions

View File

@ -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

View File

@ -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. */

View File

@ -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 \

View File

@ -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")])