#define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000/* Accumulate outgoing args */
#define MASK_MMX 0x00010000 /* Support MMX regs/builtins */
#define MASK_SSE 0x00020000 /* Support SSE regs/builtins */
-#define MASK_128BIT_LONG_DOUBLE 0x00040000 /* long double size is 128bit */
+#define MASK_SSE2 0x00040000 /* Support SSE2 regs/builtins */
+#define MASK_128BIT_LONG_DOUBLE 0x00080000 /* long double size is 128bit */
+#define MASK_MIX_SSE_I387 0x00100000 /* Mix SSE and i387 instructions */
/* Temporary codegen switches */
#define MASK_INTEL_SYNTAX 0x00000200
#define ASSEMBLER_DIALECT ((target_flags & MASK_INTEL_SYNTAX) != 0)
-#define TARGET_SSE ((target_flags & MASK_SSE) != 0)
+#define TARGET_SSE ((target_flags & (MASK_SSE | MASK_SSE2)) != 0)
+#define TARGET_SSE2 ((target_flags & MASK_SSE2) != 0)
+#define TARGET_MIX_SSE_I387 ((target_flags & MASK_MIX_SSE_I387) != 0)
#define TARGET_MMX ((target_flags & MASK_MMX) != 0)
#define TARGET_SWITCHES \
{ "no-mmx", -MASK_MMX, \
N_("Do not support MMX builtins") }, \
{ "sse", MASK_SSE, \
- N_("Support MMX and SSE builtins") }, \
+ N_("Support MMX and SSE builtins and code generation") }, \
{ "no-sse", -MASK_SSE, \
- N_("Do not support MMX and SSE builtins") }, \
+ N_("Do not support MMX and SSE builtins and code generation") }, \
+ { "sse2", MASK_SSE2, \
+ N_("Support MMX, SSE and SSE2 builtins and code generation") }, \
+ { "no-sse2", -MASK_SSE2, \
+ N_("Do not support MMX, SSE and SSE2 builtins and code generation") }, \
+ { "mix-sse-i387", MASK_MIX_SSE_I387, \
+ N_("Use both SSE and i387 instruction sets for floating point arithmetics") },\
+ { "nomix-sse-i387", -MASK_MIX_SSE_I387, \
+ N_("Use both SSE and i387 instruction sets for floating point arithmetics") },\
{ "128bit-long-double", MASK_128BIT_LONG_DOUBLE, \
N_("sizeof(long double) is 16.") }, \
{ "96bit-long-double", -MASK_128BIT_LONG_DOUBLE, \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
#define VALID_SSE_REG_MODE(MODE) \
- ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode)
+ ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode \
+ || (MODE) == SFmode || (TARGET_SSE2 && (MODE) == DFmode))
#define VALID_MMX_REG_MODE(MODE) \
((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode \
FLOAT_REGS,
SSE_REGS,
MMX_REGS,
- FLOAT_INT_REGS, /* FLOAT_REGS and GENERAL_REGS. */
+ FP_TOP_SSE_REGS,
+ FP_SECOND_SSE_REGS,
+ FLOAT_SSE_REGS,
+ FLOAT_INT_REGS,
+ INT_SSE_REGS,
+ FLOAT_INT_SSE_REGS,
ALL_REGS, LIM_REG_CLASSES
};
"FLOAT_REGS", \
"SSE_REGS", \
"MMX_REGS", \
+ "FP_TOP_SSE_REGS", \
+ "FP_SECOND_SSE_REGS", \
+ "FLOAT_SSE_REGS", \
"FLOAT_INT_REGS", \
+ "INT_SSE_REGS", \
+ "FLOAT_INT_SSE_REGS", \
"ALL_REGS" }
/* Define which registers fit in which classes.
{ 0xff00, 0x0 }, /* FLOAT_REGS */ \
{ 0x1fe00000, 0x0 }, /* SSE_REGS */ \
{ 0xe0000000, 0x1f }, /* MMX_REGS */ \
+{ 0x1fe00100, 0x0 }, /* FP_TOP_SSE_REG */ \
+{ 0x1fe00200, 0x0 }, /* FP_SECOND_SSE_REG */ \
+{ 0x1fe0ff00, 0x0 }, /* FLOAT_SSE_REGS */ \
{ 0x1ffff, 0x0 }, /* FLOAT_INT_REGS */ \
+{ 0x1fe100ff, 0x0 }, /* INT_SSE_REGS */ \
+{ 0x1fe1ffff, 0x0 }, /* FLOAT_INT_SSE_REGS */ \
{ 0xffffffff, 0x1f } \
}
#define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
#define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG)
+#define ANY_FP_REG_P(X) (REG_P (X) && ANY_FP_REGNO_P (REGNO (X)))
+#define ANY_FP_REGNO_P(n) (FP_REGNO_P (n) || SSE_REGNO_P (n))
#define SSE_REGNO_P(n) ((n) >= FIRST_SSE_REG && (n) <= LAST_SSE_REG)
+#define SSE_REG_P(n) (REG_P (n) && SSE_REGNO_P (REGNO (n)))
+
+#define SSE_FLOAT_MODE_P(m) \
+ ((TARGET_SSE && (m) == SFmode) || (TARGET_SSE2 && (m) == DFmode))
#define MMX_REGNO_P(n) ((n) >= FIRST_MMX_REG && (n) <= LAST_MMX_REG)
#define MMX_REG_P(xop) (REG_P (xop) && MMX_REGNO_P (REGNO (xop)))
(C) == 'b' ? BREG : \
(C) == 'c' ? CREG : \
(C) == 'd' ? DREG : \
- (C) == 'x' ? SSE_REGS : \
- (C) == 'y' ? MMX_REGS : \
+ (C) == 'x' ? TARGET_SSE ? SSE_REGS : NO_REGS : \
+ (C) == 'Y' ? TARGET_SSE2? SSE_REGS : NO_REGS : \
+ (C) == 'y' ? TARGET_MMX ? MMX_REGS : NO_REGS : \
(C) == 'A' ? AD_REGS : \
(C) == 'D' ? DIREG : \
(C) == 'S' ? SIREG : NO_REGS)
"ix86_expand_move (SFmode, operands); DONE;")
(define_insn "*pushsf"
- [(set (match_operand:SF 0 "push_operand" "=<,<")
- (match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
+ [(set (match_operand:SF 0 "push_operand" "=<,<,<")
+ (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x"))]
""
"*
{
case 1:
return \"push{l}\\t%1\";
+ case 2:
+ return \"#\";
default:
abort ();
}
}"
- [(set_attr "type" "multi,push")
- (set_attr "mode" "SF,SI")])
+ [(set_attr "type" "multi,push,multi")
+ (set_attr "mode" "SF,SI,SF")])
(define_split
[(set (match_operand:SF 0 "push_operand" "")
(define_split
[(set (match_operand:SF 0 "push_operand" "")
(match_operand:SF 1 "register_operand" ""))]
- "FP_REGNO_P (REGNO (operands[1]))"
+ "ANY_FP_REGNO_P (REGNO (operands[1]))"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
(set (mem:SF (reg:SI 7)) (match_dup 1))])
(define_insn "*movsf_1"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
- (match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,m")
+ (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,xm#rf,x#rf"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
|| GET_CODE (operands[1]) != CONST_DOUBLE
case 3:
case 4:
return \"mov{l}\\t{%1, %0|%0, %1}\";
+ case 5:
+ case 6:
+ return \"movss\\t{%1, %0|%0, %1}\";
default:
abort();
}
}"
- [(set_attr "type" "fmov,fmov,fmov,imov,imov")
- (set_attr "mode" "SF,SF,SF,SI,SI")])
+ [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse")
+ (set_attr "mode" "SF,SF,SF,SI,SI,SF,SF")])
(define_split
[(set (match_operand:SF 0 "nonimmediate_operand" "")
&& GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+ && !(SSE_REG_P (operands[0])
+ || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
&& (!(FP_REG_P (operands[0]) ||
(GET_CODE (operands[0]) == SUBREG
&& FP_REG_P (SUBREG_REG (operands[0]))))
(match_operand:SF 1 "register_operand" "+f"))
(set (match_dup 1)
(match_dup 0))]
- ""
+ "reload_completed || !TARGET_SSE2"
"*
{
if (STACK_TOP_P (operands[0]))
;; pattern for optimize_size too.
(define_insn "*pushdf_nointeger"
- [(set (match_operand:DF 0 "push_operand" "=<,<,<")
- (match_operand:DF 1 "general_no_elim_operand" "f,Fo#f,*r#f"))]
+ [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
+ (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y"))]
"!TARGET_INTEGER_DFMODE_MOVES"
"*
{
case 1:
case 2:
+ case 3:
return \"#\";
default:
}
}"
[(set_attr "type" "multi")
- (set_attr "mode" "DF,SI,SI")])
+ (set_attr "mode" "DF,SI,SI,DF")])
(define_insn "*pushdf_integer"
- [(set (match_operand:DF 0 "push_operand" "=<,<")
- (match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
+ [(set (match_operand:DF 0 "push_operand" "=<,<,<")
+ (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
"TARGET_INTEGER_DFMODE_MOVES"
"*
{
return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
case 1:
+ case 2:
return \"#\";
default:
}
}"
[(set_attr "type" "multi")
- (set_attr "mode" "DF,SI")])
+ (set_attr "mode" "DF,SI,DF")])
;; %%% Kill this when call knows how to work this out.
(define_split
[(set (match_operand:DF 0 "push_operand" "")
(match_operand:DF 1 "register_operand" ""))]
- "reload_completed && FP_REGNO_P (REGNO (operands[1]))"
+ "reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
(set (mem:DF (reg:SI 7)) (match_dup 1))]
"")
;; when optimizing for size.
(define_insn "*movdf_nointeger"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
- (match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,m")
+ (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,Ym#f,Y#f"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
&& (reload_in_progress || reload_completed
case 3:
case 4:
return \"#\";
+ case 5:
+ case 6:
+ return \"movsd\\t{%1, %0|%0, %1}\";
default:
abort();
}
}"
- [(set_attr "type" "fmov,fmov,fmov,multi,multi")
- (set_attr "mode" "DF,DF,DF,SI,SI")])
+ [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
+ (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
(define_insn "*movdf_integer"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
- (match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,m")
+ (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,Ym#rf,Y#rf"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& !optimize_size && TARGET_INTEGER_DFMODE_MOVES
&& (reload_in_progress || reload_completed
case 4:
return \"#\";
+ case 5:
+ case 6:
+ return \"movsd\\t{%1, %0|%0, %1}\";
+
default:
abort();
}
}"
- [(set_attr "type" "fmov,fmov,fmov,multi,multi")
- (set_attr "mode" "DF,DF,DF,SI,SI")])
+ [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
+ (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
(define_split
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(match_operand:DF 1 "general_operand" ""))]
"reload_completed
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- && ! (FP_REG_P (operands[0]) ||
+ && ! (ANY_FP_REG_P (operands[0]) ||
(GET_CODE (operands[0]) == SUBREG
- && FP_REG_P (SUBREG_REG (operands[0]))))
- && ! (FP_REG_P (operands[1]) ||
+ && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
+ && ! (ANY_FP_REG_P (operands[1]) ||
(GET_CODE (operands[1]) == SUBREG
- && FP_REG_P (SUBREG_REG (operands[1]))))"
+ && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
[(set (match_dup 2) (match_dup 5))
(set (match_dup 3) (match_dup 6))]
"if (ix86_split_long_move (operands)) DONE;")
&& GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+ && !(SSE_REG_P (operands[0])
+ || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
&& standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
[(set (match_dup 0)
(match_dup 1))]
(match_operand:DF 1 "register_operand" "+f"))
(set (match_dup 1)
(match_dup 0))]
- ""
+ "reload_completed || !TARGET_SSE2"
"*
{
if (STACK_TOP_P (operands[0]))
&& (GET_MODE (operands[0]) == XFmode
|| GET_MODE (operands[0]) == TFmode
|| GET_MODE (operands[0]) == DFmode)
- && (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
+ && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
[(const_int 0)]
"if (!ix86_split_long_move (operands)) abort (); DONE;")
(define_split
[(set (match_operand:XF 0 "push_operand" "")
(match_operand:XF 1 "register_operand" ""))]
- "FP_REGNO_P (REGNO (operands[1]))"
+ "ANY_FP_REGNO_P (REGNO (operands[1]))"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
(set (mem:XF (reg:SI 7)) (match_dup 1))])
(define_split
[(set (match_operand:TF 0 "push_operand" "")
(match_operand:TF 1 "register_operand" ""))]
- "FP_REGNO_P (REGNO (operands[1]))"
+ "ANY_FP_REGNO_P (REGNO (operands[1]))"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
(set (mem:TF (reg:SI 7)) (match_dup 1))])
"reload_completed
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
- && ! (FP_REG_P (operands[0]) ||
+ && ! (ANY_FP_REG_P (operands[0]) ||
(GET_CODE (operands[0]) == SUBREG
- && FP_REG_P (SUBREG_REG (operands[0]))))
- && ! (FP_REG_P (operands[1]) ||
+ && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
+ && ! (ANY_FP_REG_P (operands[1]) ||
(GET_CODE (operands[1]) == SUBREG
- && FP_REG_P (SUBREG_REG (operands[1]))))"
+ && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
[(set (match_dup 2) (match_dup 5))
(set (match_dup 3) (match_dup 6))
(set (match_dup 4) (match_dup 7))]