diff options
author | Richard Henderson <rth@redhat.com> | 2004-12-17 13:40:39 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-12-17 13:40:39 -0800 |
commit | 6c4ccfd8a18c297fbdd017cd07dc307a7a7c6d89 (patch) | |
tree | d0080e8895d8639f626812843872da4bc308e876 /gcc | |
parent | 128691426dcb9e2a3cb57c89bc863d03c1009d82 (diff) | |
download | gcc-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/ChangeLog | 37 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 201 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 229 |
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")]) |