Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
915119a5
Commit
915119a5
authored
Sep 08, 2000
by
Bernd Schmidt
Committed by
Bernd Schmidt
Sep 08, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MMX/SSE patterns for i386
From-SVN: r36270
parent
8e49e00a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1678 additions
and
13 deletions
+1678
-13
gcc/ChangeLog
+36
-0
gcc/config/i386/i386-protos.h
+2
-0
gcc/config/i386/i386.c
+19
-0
gcc/config/i386/i386.h
+2
-0
gcc/config/i386/i386.md
+1619
-13
No files found.
gcc/ChangeLog
View file @
915119a5
2000-09-08 Bernd Schmidt <bernds@redhat.co.uk>
* i386-protos.h (sse_comparison_operator, mmx_reg_operand): Declare
new functions.
* i386.c (sse_comparison_operator, mmx_reg_operand): New functions.
* i386.md (attr "type"): Add sse and mmx types.
(attr "memory"): Handle them without a crash.
(movsi_1, movdi_2): Allow MMX regs.
(movdi splits): Don't split moves involving MMX regs.
(setcc_4): Remove '*' from pattern name so we get a gen_setcc4.
(movv4sf_internal, movv4si_internal, movv8qi_internal,
movv4hi_internal, movv2si_internal, movv8qi, movv4hi, movv2si,
movv4sf, movv4si, pushv4sf, pushv4si, pushv8qi, pushv4hi, pushv2si,
sse_movaps, sse_movups, sse_movmskps, mmx_pmovmskb, mmx_maskmovq,
sse_movntv4sf, sse_movntdi, sse_movhlps, sse_movlhps, sse_movhps,
sse_movlps, sse_loadss, sse_movss, sse_storess, sse_shufps,
addv4sf3, vmaddv4sf3, subv4sf3, vmsubv4sf3, mulv4sf3, vmmulv4sf3,
divv4sf3, vmdivv4sf3, rcpv4sf2, vmrcpv4sf2, rsqrtv4sf2, vmrsqrtv4sf2,
sqrtv4sf2, vmsqrtv4sf2, sse_andti3, sse_nandti3, sse_iorti3,
sse_xorti3, maskcmpv4sf3, maskncmpv4sf3, vmmaskcmpv4sf3,
vmmaskncmpv4sf3, sse_comi, sse_ucomi, sse_unpckhps, sse_unpcklps,
smaxv4sf3, vmsmaxv4sf3, sminv4sf3, vmsminv4sf3, cvtpi2ps, cvtps2pi,
cvttps2pi, cvtsi2ss, cvtss2si, cvttss2si, addv8qi3, addv4hi3,
addv2si3, ssaddv8qi3, ssaddv4hi3, usaddv8qi3, usaddv4hi3, subv8qi3,
subv4hi3, subv2si3, sssubv8qi3, sssubv4hi3, ussubv8qi3, ussubv4hi3,
mulv4hi3, smulv4hi3_highpart, umulv4hi3_highpart, mmx_pmaddwd,
mmx_iordi3, mmx_xordi3, mmx_anddi3, mmx_nanddi3, mmx_uavgv8qi3,
mmx_uavgv4hi3, mmx_psadbw, mmx_pinsrw, mmx_pextrw, mmx_pshufw,
eqv8qi3, eqv4hi3, eqv2si3, gtv8qi3, gtv4hi3, gtv2si3, umaxv8qi3,
smaxv4hi3, uminv8qi3, sminv4hi3, ashrv4hi3, ashrv2si3, lshrv4hi3,
lshrv2si3, mmx_lshrdi3, ashlv4hi3, ashlv2si3, mmx_ashldi3,
mmx_packsswb, mmx_packssdw, mmx_packuswb, mmx_punpckhbw,
mmx_punpckhwd, mmx_punpckhdq, mmx_punpcklbw, mmx_punpcklwd,
mmx_punpckldq, emms, sfence, ldmxcsr, prefetch, stmxcsr, sse_clrti,
mmx_clrdi): New patterns.
2000-09-08 Richard Earnshaw <rearnsha@arm.com>
2000-09-08 Richard Earnshaw <rearnsha@arm.com>
* arm.c: Don't include tm.h directly.
* arm.c: Don't include tm.h directly.
...
...
gcc/config/i386/i386-protos.h
View file @
915119a5
...
@@ -51,11 +51,13 @@ extern int const1_operand PARAMS ((rtx, enum machine_mode));
...
@@ -51,11 +51,13 @@ extern int const1_operand PARAMS ((rtx, enum machine_mode));
extern
int
const248_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
const248_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
incdec_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
incdec_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
reg_no_sp_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
reg_no_sp_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
mmx_reg_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
general_no_elim_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
general_no_elim_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
nonmemory_no_elim_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
nonmemory_no_elim_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
q_regs_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
q_regs_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
non_q_regs_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
non_q_regs_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
no_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
no_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
sse_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
fcmov_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
fcmov_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
uno_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
uno_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
cmp_fp_expander_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
cmp_fp_expander_operand
PARAMS
((
rtx
,
enum
machine_mode
));
...
...
gcc/config/i386/i386.c
View file @
915119a5
...
@@ -1174,6 +1174,14 @@ reg_no_sp_operand (op, mode)
...
@@ -1174,6 +1174,14 @@ reg_no_sp_operand (op, mode)
return
register_operand
(
op
,
mode
);
return
register_operand
(
op
,
mode
);
}
}
int
mmx_reg_operand
(
op
,
mode
)
register
rtx
op
;
enum
machine_mode
mode
;
{
return
MMX_REG_P
(
op
);
}
/* Return false if this is any eliminable register. Otherwise
/* Return false if this is any eliminable register. Otherwise
general_operand. */
general_operand. */
...
@@ -1264,6 +1272,17 @@ no_comparison_operator (op, mode)
...
@@ -1264,6 +1272,17 @@ no_comparison_operator (op, mode)
}
}
}
}
/* Return 1 if OP is a comparison that can be used in the CMPSS/CMPPS
insns. */
int
sse_comparison_operator
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
ATTRIBUTE_UNUSED
;
{
enum
rtx_code
code
=
GET_CODE
(
op
);
return
code
==
EQ
||
code
==
LT
||
code
==
LE
||
code
==
UNORDERED
;
}
/* Return 1 if OP is a comparison operator that can be issued by fcmov. */
/* Return 1 if OP is a comparison operator that can be issued by fcmov. */
int
int
...
...
gcc/config/i386/i386.h
View file @
915119a5
...
@@ -2584,6 +2584,7 @@ do { long l; \
...
@@ -2584,6 +2584,7 @@ do { long l; \
{"const1_operand", {CONST_INT}}, \
{"const1_operand", {CONST_INT}}, \
{"const248_operand", {CONST_INT}}, \
{"const248_operand", {CONST_INT}}, \
{"incdec_operand", {CONST_INT}}, \
{"incdec_operand", {CONST_INT}}, \
{"mmx_reg_operand", {REG}}, \
{"reg_no_sp_operand", {SUBREG, REG}}, \
{"reg_no_sp_operand", {SUBREG, REG}}, \
{"general_no_elim_operand", {CONST_INT, CONST_DOUBLE, CONST, \
{"general_no_elim_operand", {CONST_INT, CONST_DOUBLE, CONST, \
SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}}, \
SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}}, \
...
@@ -2592,6 +2593,7 @@ do { long l; \
...
@@ -2592,6 +2593,7 @@ do { long l; \
{"non_q_regs_operand", {SUBREG, REG}}, \
{"non_q_regs_operand", {SUBREG, REG}}, \
{"no_comparison_operator", {EQ, NE, LT, GE, LTU, GTU, LEU, GEU}}, \
{"no_comparison_operator", {EQ, NE, LT, GE, LTU, GTU, LEU, GEU}}, \
{"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU}}, \
{"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU}}, \
{"sse_comparison_operator", {EQ, LT, LE, UNORDERED }}, \
{"uno_comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, \
{"uno_comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, \
GTU, UNORDERED, ORDERED}}, \
GTU, UNORDERED, ORDERED}}, \
{"cmp_fp_expander_operand", {CONST_DOUBLE, SUBREG, REG, MEM}}, \
{"cmp_fp_expander_operand", {CONST_DOUBLE, SUBREG, REG, MEM}}, \
...
...
gcc/config/i386/i386.md
View file @
915119a5
...
@@ -71,7 +71,25 @@
...
@@ -71,7 +71,25 @@
;; 9 This is an `
fnstsw' operation.
;; 9 This is an `
fnstsw' operation.
;; 10 This is a
`sahf' operation.
;; 10 This is a
`sahf' operation.
;; 11 This is a `
fstcw' operation
;; 11 This is a `
fstcw' operation
;;
;; For SSE/MMX support:
;; 30 This is
`fix', guaranteed to be truncating.
;; 31 This is a `
emms' operation.
;; 32 This is a
`maskmov' operation.
;; 33 This is a `
movmsk' operation.
;; 34 This is a
`non-temporal' move.
;; 35 This is a `
prefetch' operation.
;; 36 This is used to distinguish COMISS from UCOMISS.
;; 37 This is a
`ldmxcsr' operation.
;; 38 This is a forced `
movaps' instruction (rather than whatever movti does)
;; 39 This is a forced
`movups' instruction (rather than whatever movti does)
;; 40 This is a `
stmxcsr' operation.
;; 41 This is a
`shuffle' operation.
;; 42 This is a `
rcp' operation.
;; 43 This is a
`rsqsrt' operation.
;; 44 This is a `
sfence' operation.
;; 45 This is a noop to prevent excessive combiner cleverness.
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
;; from i386.c.
;; from i386.c.
...
@@ -84,7 +102,7 @@
...
@@ -84,7 +102,7 @@
;; A basic instruction type. Refinements due to arguments to be
;; A basic instruction type. Refinements due to arguments to be
;; provided in other attributes.
;; provided in other attributes.
(define_attr "type"
(define_attr "type"
"other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld"
"other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld
,sse,mmx
"
(const_string "other"))
(const_string "other"))
;; Main data type used by the insn
;; Main data type used by the insn
...
@@ -234,7 +252,7 @@
...
@@ -234,7 +252,7 @@
(const_string "store")
(const_string "store")
(match_operand 1 "memory_operand" "")
(match_operand 1 "memory_operand" "")
(const_string "load")
(const_string "load")
(and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp")
(and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp
,sse,mmx
")
(match_operand 2 "memory_operand" ""))
(match_operand 2 "memory_operand" ""))
(const_string "load")
(const_string "load")
(and (eq_attr "type" "icmov")
(and (eq_attr "type" "icmov")
...
@@ -1530,15 +1548,19 @@
...
@@ -1530,15 +1548,19 @@
(set_attr "length_immediate" "1")])
(set_attr "length_immediate" "1")])
(define_insn "*movsi_1"
(define_insn "*movsi_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m")
[(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m
,!*y,!r
")
(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin"))]
(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin
,r,*y
"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
"*
{
{
switch (get_attr_type (insn))
switch (get_attr_type (insn))
{
{
case TYPE_MMX:
return \"movd\\t{%1, %0|%0, %1}\";
case TYPE_LEA:
case TYPE_LEA:
return \"lea{l}\\t{%1, %0|%0, %1}\";
return \"lea{l}\\t{%1, %0|%0, %1}\";
default:
default:
if (flag_pic && SYMBOLIC_CONST (operands[1]))
if (flag_pic && SYMBOLIC_CONST (operands[1]))
abort();
abort();
...
@@ -1546,12 +1568,15 @@
...
@@ -1546,12 +1568,15 @@
}
}
}"
}"
[(set (attr "type")
[(set (attr "type")
(cond [(and (ne (symbol_ref "flag_pic") (const_int 0))
(cond [(ior (match_operand:SI 0 "mmx_reg_operand" "")
(match_operand:SI 1 "mmx_reg_operand" ""))
(const_string "mmx")
(and (ne (symbol_ref "flag_pic") (const_int 0))
(match_operand:SI 1 "symbolic_operand" ""))
(match_operand:SI 1 "symbolic_operand" ""))
(const_string "lea")
(const_string "lea")
]
]
(const_string "imov")))
(const_string "imov")))
(set_attr "modrm" "0,*,0,*")
(set_attr "modrm" "0,*,0,*
,*,*
")
(set_attr "mode" "SI")])
(set_attr "mode" "SI")])
(define_insn "*swapsi"
(define_insn "*swapsi"
...
@@ -1983,15 +2008,20 @@
...
@@ -1983,15 +2008,20 @@
"#")
"#")
(define_insn "*movdi_2"
(define_insn "*movdi_2"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,o
,!m*y,!*y
")
(match_operand:DI 1 "general_operand" "riFo,riF"))]
(match_operand:DI 1 "general_operand" "riFo,riF
,*y,m
"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"#")
"@
#
#
movq\\t{%1, %0|%0, %1}
movq\\t{%1, %0|%0, %1}"
[(set_attr "type" "*,*,mmx,mmx")])
(define_split
(define_split
[(set (match_operand:DI 0 "push_operand" "")
[(set (match_operand:DI 0 "push_operand" "")
(match_operand:DI 1 "general_operand" ""))]
(match_operand:DI 1 "general_operand" ""))]
"reload_completed"
"reload_completed
&& ! MMX_REG_P (operands[1])
"
[(const_int 0)]
[(const_int 0)]
"if (!ix86_split_long_move (operands)) abort (); DONE;")
"if (!ix86_split_long_move (operands)) abort (); DONE;")
...
@@ -1999,7 +2029,7 @@
...
@@ -1999,7 +2029,7 @@
(define_split
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand" "")
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(match_operand:DI 1 "general_operand" ""))]
(match_operand:DI 1 "general_operand" ""))]
"reload_completed"
"reload_completed
&& ! MMX_REG_P (operands[0]) && ! MMX_REG_P (operands[1])
"
[(set (match_dup 2) (match_dup 5))
[(set (match_dup 2) (match_dup 5))
(set (match_dup 3) (match_dup 6))]
(set (match_dup 3) (match_dup 6))]
"if (ix86_split_long_move (operands)) DONE;")
"if (ix86_split_long_move (operands)) DONE;")
...
@@ -7864,7 +7894,7 @@
...
@@ -7864,7 +7894,7 @@
[
(set_attr "type" "setcc")
[
(set_attr "type" "setcc")
(set_attr "mode" "QI")])
(set_attr "mode" "QI")])
(define_insn "
*
setcc_4"
(define_insn "setcc_4"
[
(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
[
(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
(match_operator:QI 1 "uno_comparison_operator"
(match_operator:QI 1 "uno_comparison_operator"
[
(reg:CC 17) (const_int 0)
]
))]
[
(reg:CC 17) (const_int 0)
]
))]
...
@@ -11170,3 +11200,1579 @@
...
@@ -11170,3 +11200,1579 @@
CODE_LABEL_NUMBER (operands
[
2
]
));
CODE_LABEL_NUMBER (operands
[
2
]
));
RET;
RET;
}")
}")
;; Pentium III SIMD instructions.
;; Moves for SSE/MMX regs.
(define_insn "movv4sf_internal"
[
(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
(match_operand:V4SF 1 "general_operand" "xm,x"))]
"TARGET_SSE"
;; @@@ let's try to use movaps here.
"movaps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "movv4si_internal"
[
(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
(match_operand:V4SI 1 "general_operand" "xm,x"))]
"TARGET_SSE"
;; @@@ let's try to use movaps here.
"movaps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "movv8qi_internal"
[
(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
(match_operand:V8QI 1 "general_operand" "ym,y"))]
"TARGET_MMX"
"movq
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "mmx")
]
)
(define_insn "movv4hi_internal"
[
(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
(match_operand:V4HI 1 "general_operand" "ym,y"))]
"TARGET_MMX"
"movq
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "mmx")
]
)
(define_insn "movv2si_internal"
[
(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
(match_operand:V2SI 1 "general_operand" "ym,y"))]
"TARGET_MMX"
"movq
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "mmx")
]
)
(define_expand "movti"
[
(set (match_operand:TI 0 "general_operand" "")
(match_operand:TI 1 "general_operand" ""))]
"TARGET_SSE"
"
{
/
*
For constants other than zero into memory. We do not know how the
instructions used to build constants modify the upper 64 bits
of the register, once we have that information we may be able
to handle some of them more efficiently.
*
/
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands
[
0
]
, TImode)
&& CONSTANT_P (operands
[
1
]
))
{
rtx addr = gen_reg_rtx (Pmode);
emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
operands[1] = gen_rtx_MEM (TImode, addr);
}
/
* Make operand1 a register if it isn't already. *
/
if ((reload_in_progress | reload_completed) == 0
&& !register_operand (operands
[
0
]
, TImode)
&& !register_operand (operands
[
1
]
, TImode)
&& operands
[
1
]
!= CONST0_RTX (TImode))
{
rtx temp = force_reg (TImode, operands
[
1
]
);
emit_move_insn (operands
[
0
]
, temp);
DONE;
}
}")
(define_expand "movv4sf"
[
(set (match_operand:V4SF 0 "general_operand" "")
(match_operand:V4SF 1 "general_operand" ""))]
"TARGET_SSE"
"
{
/
*
For constants other than zero into memory. We do not know how the
instructions used to build constants modify the upper 64 bits
of the register, once we have that information we may be able
to handle some of them more efficiently.
*
/
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands
[
0
]
, V4SFmode)
&& CONSTANT_P (operands
[
1
]
))
{
rtx addr = gen_reg_rtx (Pmode);
emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
operands[1] = gen_rtx_MEM (V4SFmode, addr);
}
/
* Make operand1 a register if it isn't already. *
/
if ((reload_in_progress | reload_completed) == 0
&& !register_operand (operands
[
0
]
, V4SFmode)
&& !register_operand (operands
[
1
]
, V4SFmode)
&& operands
[
1
]
!= CONST0_RTX (V4SFmode))
{
rtx temp = force_reg (V4SFmode, operands
[
1
]
);
emit_move_insn (operands
[
0
]
, temp);
DONE;
}
}")
(define_expand "movv4si"
[
(set (match_operand:V4SI 0 "general_operand" "")
(match_operand:V4SI 1 "general_operand" ""))]
"TARGET_MMX"
"
{
/
*
For constants other than zero into memory. We do not know how the
instructions used to build constants modify the upper 64 bits
of the register, once we have that information we may be able
to handle some of them more efficiently.
*
/
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands
[
0
]
, V4SImode)
&& CONSTANT_P (operands
[
1
]
))
{
rtx addr = gen_reg_rtx (Pmode);
emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
operands[1] = gen_rtx_MEM (V4SImode, addr);
}
/
* Make operand1 a register if it isn't already. *
/
if ((reload_in_progress | reload_completed) == 0
&& !register_operand (operands
[
0
]
, V4SImode)
&& !register_operand (operands
[
1
]
, V4SImode)
&& operands
[
1
]
!= CONST0_RTX (V4SImode))
{
rtx temp = force_reg (V4SImode, operands
[
1
]
);
emit_move_insn (operands
[
0
]
, temp);
DONE;
}
}")
(define_expand "movv2si"
[
(set (match_operand:V2SI 0 "general_operand" "")
(match_operand:V2SI 1 "general_operand" ""))]
"TARGET_MMX"
"
{
/
*
For constants other than zero into memory. We do not know how the
instructions used to build constants modify the upper 64 bits
of the register, once we have that information we may be able
to handle some of them more efficiently.
*
/
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands
[
0
]
, V2SImode)
&& CONSTANT_P (operands
[
1
]
))
{
rtx addr = gen_reg_rtx (Pmode);
emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
operands[1] = gen_rtx_MEM (V2SImode, addr);
}
/
* Make operand1 a register if it isn't already. *
/
if ((reload_in_progress | reload_completed) == 0
&& !register_operand (operands
[
0
]
, V2SImode)
&& !register_operand (operands
[
1
]
, V2SImode)
&& operands
[
1
]
!= CONST0_RTX (V2SImode))
{
rtx temp = force_reg (V2SImode, operands
[
1
]
);
emit_move_insn (operands
[
0
]
, temp);
DONE;
}
}")
(define_expand "movv4hi"
[
(set (match_operand:V4HI 0 "general_operand" "")
(match_operand:V4HI 1 "general_operand" ""))]
"TARGET_MMX"
"
{
/
*
For constants other than zero into memory. We do not know how the
instructions used to build constants modify the upper 64 bits
of the register, once we have that information we may be able
to handle some of them more efficiently.
*
/
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands
[
0
]
, V4HImode)
&& CONSTANT_P (operands
[
1
]
))
{
rtx addr = gen_reg_rtx (Pmode);
emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
operands[1] = gen_rtx_MEM (V4HImode, addr);
}
/
* Make operand1 a register if it isn't already. *
/
if ((reload_in_progress | reload_completed) == 0
&& !register_operand (operands
[
0
]
, V4HImode)
&& !register_operand (operands
[
1
]
, V4HImode)
&& operands
[
1
]
!= CONST0_RTX (V4HImode))
{
rtx temp = force_reg (V4HImode, operands
[
1
]
);
emit_move_insn (operands
[
0
]
, temp);
DONE;
}
}")
(define_expand "movv8qi"
[
(set (match_operand:V8QI 0 "general_operand" "")
(match_operand:V8QI 1 "general_operand" ""))]
"TARGET_MMX"
"
{
/
*
For constants other than zero into memory. We do not know how the
instructions used to build constants modify the upper 64 bits
of the register, once we have that information we may be able
to handle some of them more efficiently.
*
/
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands
[
0
]
, V8QImode)
&& CONSTANT_P (operands
[
1
]
))
{
rtx addr = gen_reg_rtx (Pmode);
emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
operands[1] = gen_rtx_MEM (V8QImode, addr);
}
/
* Make operand1 a register if it isn't already. *
/
if ((reload_in_progress | reload_completed) == 0
&& !register_operand (operands
[
0
]
, V8QImode)
&& !register_operand (operands
[
1
]
, V8QImode)
&& operands
[
1
]
!= CONST0_RTX (V8QImode))
{
rtx temp = force_reg (V8QImode, operands
[
1
]
);
emit_move_insn (operands
[
0
]
, temp);
DONE;
}
}")
(define_insn_and_split "
*
pushti"
[
(set (match_operand:TI 0 "push_operand" "=<")
(match_operand:TI 1 "nonmemory_operand" "x"))]
"TARGET_SSE"
"#"
""
[
(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
(set (mem:TI (reg:SI 7)) (match_dup 1))]
""
[
(set_attr "type" "sse")
]
)
(define_insn_and_split "
*
pushv4sf"
[
(set (match_operand:V4SF 0 "push_operand" "=<")
(match_operand:V4SF 1 "nonmemory_operand" "x"))]
"TARGET_SSE"
"#"
""
[
(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
(set (mem:V4SF (reg:SI 7)) (match_dup 1))]
""
[
(set_attr "type" "sse")
]
)
(define_insn_and_split "
*
pushv4si"
[
(set (match_operand:V4SI 0 "push_operand" "=<")
(match_operand:V4SI 1 "nonmemory_operand" "x"))]
"TARGET_SSE"
"#"
""
[
(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
(set (mem:V4SI (reg:SI 7)) (match_dup 1))]
""
[
(set_attr "type" "sse")
]
)
(define_insn_and_split "
*
pushv2si"
[
(set (match_operand:V2SI 0 "push_operand" "=<")
(match_operand:V2SI 1 "nonmemory_operand" "y"))]
"TARGET_MMX"
"#"
""
[
(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
(set (mem:V2SI (reg:SI 7)) (match_dup 1))]
""
[
(set_attr "type" "mmx")
]
)
(define_insn_and_split "
*
pushv4hi"
[
(set (match_operand:V4HI 0 "push_operand" "=<")
(match_operand:V4HI 1 "nonmemory_operand" "y"))]
"TARGET_MMX"
"#"
""
[
(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
(set (mem:V4HI (reg:SI 7)) (match_dup 1))]
""
[
(set_attr "type" "mmx")
]
)
(define_insn_and_split "
*
pushv8qi"
[
(set (match_operand:V8QI 0 "push_operand" "=<")
(match_operand:V8QI 1 "nonmemory_operand" "y"))]
"TARGET_MMX"
"#"
""
[
(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
(set (mem:V8QI (reg:SI 7)) (match_dup 1))]
""
[
(set_attr "type" "mmx")
]
)
(define_insn "movti_internal"
[
(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
(match_operand:TI 1 "general_operand" "xm,x"))]
"TARGET_SSE"
"@
movaps
\\
t{%1, %0|%0, %1}
movaps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
;; These two patterns are useful for specifying exactly whether to use
;; movaps or movups
(define_insn "sse_movaps"
[
(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
(unspec:V4SF
[
(match_operand:V4SF 1 "general_operand" "xm,x")
]
38))]
"TARGET_SSE"
"@
movaps
\\
t{%1, %0|%0, %1}
movaps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_movups"
[
(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
(unspec:V4SF
[
(match_operand:V4SF 1 "general_operand" "xm,x")
]
39))]
"TARGET_SSE"
"@
movups
\\
t{%1, %0|%0, %1}
movups
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
;; SSE Strange Moves.
(define_insn "sse_movmskps"
[
(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[
(match_operand:V4SF 1 "register_operand" "x")
]
33))]
"TARGET_SSE"
"movmskps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "mmx_pmovmskb"
[
(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[
(match_operand:V8QI 1 "register_operand" "y")
]
33))]
"TARGET_SSE"
"pmovmskb
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "mmx_maskmovq"
[
(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
(unspec:V8QI
[
(match_operand:V8QI 1 "register_operand" "y")
(match_operand:V8QI 2 "register_operand" "y")] 32))]
"TARGET_SSE"
;; @@@ check ordering of operands in intel/nonintel syntax
"maskmovq
\\
t{%2, %1|%1, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_movntv4sf"
[
(set (match_operand:V4SF 0 "memory_operand" "=m")
(unspec:V4SF
[
(match_operand:V4SF 1 "register_operand" "x")
]
34))]
"TARGET_SSE"
"movntps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_movntdi"
[
(set (match_operand:DI 0 "memory_operand" "=m")
(unspec:DI
[
(match_operand:DI 1 "register_operand" "x")
]
34))]
"TARGET_SSE"
"movntq
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_movhlps"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF
(match_operand:V4SF 1 "register_operand" "0")
(vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
(parallel
[
(const_int 2)
(const_int 3)
(const_int 0)
(const_int 1)]))
(const_int 3)))]
"TARGET_SSE"
"movhlps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_movlhps"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF
(match_operand:V4SF 1 "register_operand" "0")
(vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
(parallel
[
(const_int 2)
(const_int 3)
(const_int 0)
(const_int 1)]))
(const_int 12)))]
"TARGET_SSE"
"movlhps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_movhps"
[
(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
(vec_merge:V4SF
(match_operand:V4SF 1 "nonimmediate_operand" "0,0")
(match_operand:V4SF 2 "nonimmediate_operand" "m,x")
(const_int 12)))]
"TARGET_SSE && (GET_CODE (operands
[
1
]
) == MEM || GET_CODE (operands
[
2
]
) == MEM)"
"movhps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_movlps"
[
(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
(vec_merge:V4SF
(match_operand:V4SF 1 "nonimmediate_operand" "0,0")
(match_operand:V4SF 2 "nonimmediate_operand" "m,x")
(const_int 3)))]
"TARGET_SSE && (GET_CODE (operands
[
1
]
) == MEM || GET_CODE (operands
[
2
]
) == MEM)"
"movlps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_loadss"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF
(match_operand:V4SF 1 "memory_operand" "m")
(vec_duplicate:V4SF (float:SF (const_int 0)))
(const_int 1)))]
"TARGET_SSE"
"movss
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_movss"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF
(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "register_operand" "x")
(const_int 1)))]
"TARGET_SSE"
"movss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_storess"
[
(set (match_operand:SF 0 "memory_operand" "=m")
(vec_select:SF
(match_operand:V4SF 1 "register_operand" "x")
(parallel
[
(const_int 0)
]
)))]
"TARGET_SSE"
"movss
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_shufps"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(unspec:V4SF
[
(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")
(match_operand:SI 3 "immediate_operand" "i")] 41))]
"TARGET_SSE"
;; @@@ check operand order for intel/nonintel syntax
"shufps
\\
t{%3, %2, %0|%0, %2, %3}"
[
(set_attr "type" "sse")
]
)
;; SSE arithmetic
(define_insn "addv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"addps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmaddv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
"addss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "subv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"subps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmsubv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
"subss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "mulv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"mulps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmmulv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
"mulss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "divv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(div:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"divps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmdivv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
"divss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
;; SSE square root/reciprocal
(define_insn "rcpv4sf2"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(unspec:V4SF
[
(match_operand:V4SF 1 "register_operand" "xm")
]
42))]
"TARGET_SSE"
"rcpps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmrcpv4sf2"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (unspec:V4SF
[
(match_operand:V4SF 1 "register_operand" "xm")
]
42)
(match_operand:V4SF 2 "register_operand" "0")
(const_int 1)))]
"TARGET_SSE"
"rcpss
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "rsqrtv4sf2"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(unspec:V4SF
[
(match_operand:V4SF 1 "register_operand" "xm")
]
43))]
"TARGET_SSE"
"rsqrtps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmrsqrtv4sf2"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (unspec:V4SF
[
(match_operand:V4SF 1 "register_operand" "xm")
]
43)
(match_operand:V4SF 2 "register_operand" "0")
(const_int 1)))]
"TARGET_SSE"
"rsqrtss
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "sqrtv4sf2"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
"TARGET_SSE"
"sqrtps
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmsqrtv4sf2"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
(match_operand:V4SF 2 "register_operand" "0")
(const_int 1)))]
"TARGET_SSE"
"sqrtss
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
;; SSE logical operations.
;; These are not called andti3 etc. because we really really don't want
;; the compiler to widen DImode ands to TImode ands and then try to move
;; into DImode subregs of SSE registers, and them together, and move out
;; of DImode subregs again!
(define_insn "sse_andti3"
[
(set (match_operand:TI 0 "register_operand" "=x")
(and:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"andps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_nandti3"
[
(set (match_operand:TI 0 "register_operand" "=x")
(and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"andnps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_iorti3"
[
(set (match_operand:TI 0 "register_operand" "=x")
(ior:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"iorps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_xorti3"
[
(set (match_operand:TI 0 "register_operand" "=x")
(xor:TI (match_operand:TI 1 "register_operand" "0")
(match_operand:TI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"xorps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
;; Use xor, but don't show input operands so they aren't live before
;; this insn.
(define_insn "sse_clrti"
[
(set (match_operand:TI 0 "register_operand" "=x")
(unspec:TI
[
(const_int 0)
]
45))]
"TARGET_SSE"
"xorps
\\
t{%0, %0|%0, %0}"
[
(set_attr "type" "sse")
]
)
;; SSE mask-generating compares
(define_insn "maskcmpv4sf3"
[
(set (match_operand:V4SI 0 "register_operand" "=x")
(match_operator:V4SI 3 "sse_comparison_operator"
[
(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
"TARGET_SSE"
"
*
{
switch (GET_CODE (operands
[
3
]
))
{
case EQ:
return
\"
cmpeqps
\\
t{%2, %0|%0, %2}
\"
;
case LT:
return
\"
cmpltps
\\
t{%2, %0|%0, %2}
\"
;
case LE:
return
\"
cmpleps
\\
t{%2, %0|%0, %2}
\"
;
case UNORDERED:
return
\"
cmpunordps
\\
t{%2, %0|%0, %2}
\"
;
default:
abort ();
}
}"
[
(set_attr "type" "sse")
]
)
(define_insn "maskncmpv4sf3"
[
(set (match_operand:V4SI 0 "register_operand" "=x")
(not:V4SI
(match_operator:V4SI 3 "sse_comparison_operator"
[
(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
"TARGET_SSE"
"
*
{
switch (GET_CODE (operands
[
3
]
))
{
case EQ:
return
\"
cmpneqps
\\
t{%2, %0|%0, %2}
\"
;
case LT:
return
\"
cmpnltps
\\
t{%2, %0|%0, %2}
\"
;
case LE:
return
\"
cmpnleps
\\
t{%2, %0|%0, %2}
\"
;
case UNORDERED:
return
\"
cmpordps
\\
t{%2, %0|%0, %2}
\"
;
default:
abort ();
}
}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmmaskcmpv4sf3"
[
(set (match_operand:V4SI 0 "register_operand" "=x")
(vec_merge:V4SI
(match_operator:V4SI 3 "sse_comparison_operator"
[
(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "x")])
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
"
*
{
switch (GET_CODE (operands
[
3
]
))
{
case EQ:
return
\"
cmpeqss
\\
t{%2, %0|%0, %2}
\"
;
case LT:
return
\"
cmpltss
\\
t{%2, %0|%0, %2}
\"
;
case LE:
return
\"
cmpless
\\
t{%2, %0|%0, %2}
\"
;
case UNORDERED:
return
\"
cmpunordss
\\
t{%2, %0|%0, %2}
\"
;
default:
abort ();
}
}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmmaskncmpv4sf3"
[
(set (match_operand:V4SI 0 "register_operand" "=x")
(vec_merge:V4SI
(not:V4SI
(match_operator:V4SI 3 "sse_comparison_operator"
[
(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "x")]))
(subreg:V4SI (match_dup 1) 0)
(const_int 1)))]
"TARGET_SSE"
"
*
{
switch (GET_CODE (operands
[
3
]
))
{
case EQ:
return
\"
cmpneqss
\\
t{%2, %0|%0, %2}
\"
;
case LT:
return
\"
cmpnltss
\\
t{%2, %0|%0, %2}
\"
;
case LE:
return
\"
cmpnless
\\
t{%2, %0|%0, %2}
\"
;
case UNORDERED:
return
\"
cmpordss
\\
t{%2, %0|%0, %2}
\"
;
default:
abort ();
}
}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_comi"
[
(set (reg:CCFP 17)
(match_operator:CCFP 2 "sse_comparison_operator"
[
(vec_select:SF
(match_operand:V4SF 0 "register_operand" "x")
(parallel
[
(const_int 0)
]
))
(vec_select:SF
(match_operand:V4SF 1 "register_operand" "x")
(parallel
[
(const_int 0)
]
))]))]
"TARGET_SSE"
"comiss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_ucomi"
[
(set (reg:CCFPU 17)
(match_operator:CCFPU 2 "sse_comparison_operator"
[
(vec_select:SF
(match_operand:V4SF 0 "register_operand" "x")
(parallel
[
(const_int 0)
]
))
(vec_select:SF
(match_operand:V4SF 1 "register_operand" "x")
(parallel
[
(const_int 0)
]
))]))]
"TARGET_SSE"
"ucomiss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
;; SSE unpack
(define_insn "sse_unpckhps"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF
(vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
(parallel
[
(const_int 2)
(const_int 0)
(const_int 3)
(const_int 1)]))
(vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
(parallel
[
(const_int 0)
(const_int 2)
(const_int 1)
(const_int 3)]))
(const_int 5)))]
"TARGET_SSE"
"unpckhps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sse_unpcklps"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF
(vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
(parallel
[
(const_int 0)
(const_int 2)
(const_int 1)
(const_int 3)]))
(vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
(parallel
[
(const_int 2)
(const_int 0)
(const_int 3)
(const_int 1)]))
(const_int 5)))]
"TARGET_SSE"
"unpcklps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
;; SSE min/max
(define_insn "smaxv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"maxps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmsmaxv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
"maxss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sminv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE"
"minps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "vmsminv4sf3"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
"minss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
;; SSE
<->
integer/MMX conversions
(define_insn "cvtpi2ps"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
(vec_duplicate:V4SF
(float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
(const_int 12)))]
"TARGET_SSE"
"cvtpi2ps
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "cvtps2pi"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
(parallel
[
(const_int 0)
(const_int 1)])))]
"TARGET_SSE"
"cvtps2pi
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "cvttps2pi"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(vec_select:V2SI (unspec:V4SI
[
(match_operand:V4SF 1 "register_operand" "xm")
]
30)
(parallel
[
(const_int 0)
(const_int 1)])))]
"TARGET_SSE"
"cvttps2pi
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "cvtsi2ss"
[
(set (match_operand:V4SF 0 "register_operand" "=x")
(vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
(vec_duplicate:V4SF
(float:SF (match_operand:SI 2 "register_operand" "rm")))
(const_int 15)))]
"TARGET_SSE"
"cvtsi2ss
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "cvtss2si"
[
(set (match_operand:SI 0 "register_operand" "=y")
(vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
(parallel
[
(const_int 0)
]
)))]
"TARGET_SSE"
"cvtss2si
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "cvttss2si"
[
(set (match_operand:SI 0 "register_operand" "=y")
(vec_select:SI (unspec:V4SI
[
(match_operand:V4SF 1 "register_operand" "xm")
]
30)
(parallel
[
(const_int 0)
]
)))]
"TARGET_SSE"
"cvttss2si
\\
t{%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
;; MMX insns
;; MMX arithmetic
(define_insn "addv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"paddb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "addv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"paddw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "addv2si3"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
(match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"paddd
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "ssaddv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"paddsb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "ssaddv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"paddsw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "usaddv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"paddusb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "usaddv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"paddusw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "subv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"psubb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "subv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"psubw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "subv2si3"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
(match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"psubd
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "sssubv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"psubsb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "sssubv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"psubsw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "ussubv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"psubusb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "ussubv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"psubusw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mulv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"pmullw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "smulv4hi3_highpart"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(truncate:V4HI
(lshiftrt:V4SI
(mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
(sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
(const_int 16))))]
"TARGET_MMX"
"pmulhw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "umulv4hi3_highpart"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(truncate:V4HI
(lshiftrt:V4SI
(mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
(zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
(const_int 16))))]
"TARGET_MMX"
"pmulhuw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_pmaddwd"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(plus:V2SI
(mult:V2SI
(sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
(parallel
[
(const_int 0)
(const_int 2)])))
(sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
(parallel
[
(const_int 0)
(const_int 2)]))))
(mult:V2SI
(sign_extend:V2SI (vec_select:V2HI (match_dup 1)
(parallel
[
(const_int 1)
(const_int 3)])))
(sign_extend:V2SI (vec_select:V2HI (match_dup 2)
(parallel
[
(const_int 1)
(const_int 3)]))))))]
"TARGET_MMX"
"pmaddwd
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
;; MMX logical operations
;; Note we don't want to declare these as regular iordi3 insns to prevent
;; normal code that also wants to use the FPU from getting broken.
;; The UNSPECs are there to prevent the combiner from getting overly clever.
(define_insn "mmx_iordi3"
[
(set (match_operand:DI 0 "register_operand" "=y")
(unspec:DI
[
(ior:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
"TARGET_MMX"
"por
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_xordi3"
[
(set (match_operand:DI 0 "register_operand" "=y")
(unspec:DI
[
(xor:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
"TARGET_MMX"
"pxor
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
;; Same as pxor, but don't show input operands so that we don't think
;; they are live.
(define_insn "mmx_clrdi"
[
(set (match_operand:DI 0 "register_operand" "=y")
(unspec:DI
[
(const_int 0)
]
45))]
"TARGET_MMX"
"pxor
\\
t{%0, %0|%0, %0}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_anddi3"
[
(set (match_operand:DI 0 "register_operand" "=y")
(unspec:DI
[
(and:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
"TARGET_MMX"
"pand
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_nanddi3"
[
(set (match_operand:DI 0 "register_operand" "=y")
(unspec:DI
[
(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
(match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
"TARGET_MMX"
"pandn
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
;; MMX unsigned averages/sum of absolute differences
(define_insn "mmx_uavgv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(ashiftrt:V8QI
(plus:V8QI (plus:V8QI
(match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym"))
(vec_const:V8QI (parallel
[
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)])))
(const_int 1)))]
"TARGET_SSE"
"pavgbn
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "mmx_uavgv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(ashiftrt:V4HI
(plus:V4HI (plus:V4HI
(match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym"))
(vec_const:V4HI (parallel
[
(const_int 1)
(const_int 1)
(const_int 1)
(const_int 1)])))
(const_int 1)))]
"TARGET_SSE"
"pavgwn
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "mmx_psadbw"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(abs:V8QI (minus:V8QI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "nonimmediate_operand" "ym"))))]
"TARGET_SSE"
"padbw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
;; MMX insert/extract/shuffle
(define_insn "mmx_pinsrw"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
(vec_duplicate:V4HI
(truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
(match_operand:SI 3 "immediate_operand" "i")))]
"TARGET_SSE"
;; @@@ check operand order for intel/nonintel syntax.
"pinsrw
\\
t%3, {%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "mmx_pextrw"
[
(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
(parallel
[
(match_operand:SI 2 "immediate_operand" "i")
]
))))]
"TARGET_SSE"
;; @@@ check operand order for intel/nonintel syntax.
"pextrw
\\
t%2, {%1, %0|%0, %1}"
[
(set_attr "type" "sse")
]
)
(define_insn "mmx_pshufw"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(unspec:V4HI
[
(match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")
(match_operand:SI 3 "immediate_operand" "i")] 41))]
"TARGET_SSE"
;; @@@ check operand order for intel/nonintel syntax
"pshufw
\\
t %3,{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
;; MMX mask-generating comparisons
(define_insn "eqv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"pcmpeqb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "eqv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"pcmpeqw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "eqv2si3"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
(match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"pcmpeqd
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "gtv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"pcmpgtb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "gtv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"pcmpgtw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "gtv2si3"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
(match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
"TARGET_MMX"
"pcmpgtd
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
;; MMX max/min insns
(define_insn "umaxv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_SSE"
"pmaxub
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "smaxv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_SSE"
"pmaxsw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "uminv8qi3"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
(match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
"TARGET_SSE"
"pminub
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
(define_insn "sminv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
"TARGET_SSE"
"pminsw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "sse")
]
)
;; MMX shifts
(define_insn "ashrv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:DI 2 "nonmemory_operand" "yi")))]
"TARGET_MMX"
"psraw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "ashrv2si3"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
(match_operand:DI 2 "nonmemory_operand" "yi")))]
"TARGET_MMX"
"psrad
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "lshrv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:DI 2 "nonmemory_operand" "yi")))]
"TARGET_MMX"
"psrlw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "lshrv2si3"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
(match_operand:DI 2 "nonmemory_operand" "yi")))]
"TARGET_MMX"
"psrld
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
;; See logical MMX insns.
(define_insn "mmx_lshrdi3"
[
(set (match_operand:DI 0 "register_operand" "=y")
(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "nonmemory_operand" "yi")))]
"TARGET_MMX"
"psrlq
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "ashlv4hi3"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
(match_operand:DI 2 "nonmemory_operand" "yi")))]
"TARGET_MMX"
"psllw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "ashlv2si3"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
(match_operand:DI 2 "nonmemory_operand" "yi")))]
"TARGET_MMX"
"pslld
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
;; See logical MMX insns.
(define_insn "mmx_ashldi3"
[
(set (match_operand:DI 0 "register_operand" "=y")
(ashift:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "nonmemory_operand" "yi")))]
"TARGET_MMX"
"psllq
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
;; MMX pack/unpack insns.
(define_insn "mmx_packsswb"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(vec_concat:V8QI
(ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
(ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
"TARGET_MMX"
"packsswb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_packssdw"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(vec_concat:V4HI
(ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
(ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
"TARGET_MMX"
"packssdw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_packuswb"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(vec_concat:V8QI
(us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
(us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
"TARGET_MMX"
"packuswb
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_punpckhbw"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(vec_merge:V8QI
(vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
(parallel
[
(const_int 4)
(const_int 0)
(const_int 5)
(const_int 1)
(const_int 6)
(const_int 2)
(const_int 7)
(const_int 3)]))
(vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
(parallel
[
(const_int 0)
(const_int 4)
(const_int 1)
(const_int 5)
(const_int 2)
(const_int 6)
(const_int 3)
(const_int 7)]))
(const_int 85)))]
"TARGET_MMX"
"punpckhbw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_punpckhwd"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(vec_merge:V4HI
(vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
(parallel
[
(const_int 0)
(const_int 2)
(const_int 1)
(const_int 3)]))
(vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
(parallel
[
(const_int 2)
(const_int 0)
(const_int 3)
(const_int 1)]))
(const_int 5)))]
"TARGET_MMX"
"punpckhbw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_punpckhdq"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(vec_merge:V2SI
(vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
(parallel
[
(const_int 0)
(const_int 1)]))
(vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
(parallel
[
(const_int 1)
(const_int 0)]))
(const_int 1)))]
"TARGET_MMX"
"punpckhbw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_punpcklbw"
[
(set (match_operand:V8QI 0 "register_operand" "=y")
(vec_merge:V8QI
(vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
(parallel
[
(const_int 0)
(const_int 4)
(const_int 1)
(const_int 5)
(const_int 2)
(const_int 6)
(const_int 3)
(const_int 7)]))
(vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
(parallel
[
(const_int 4)
(const_int 0)
(const_int 5)
(const_int 1)
(const_int 6)
(const_int 2)
(const_int 7)
(const_int 3)]))
(const_int 85)))]
"TARGET_MMX"
"punpcklbw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_punpcklwd"
[
(set (match_operand:V4HI 0 "register_operand" "=y")
(vec_merge:V4HI
(vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
(parallel
[
(const_int 2)
(const_int 0)
(const_int 3)
(const_int 1)]))
(vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
(parallel
[
(const_int 0)
(const_int 2)
(const_int 1)
(const_int 3)]))
(const_int 5)))]
"TARGET_MMX"
"punpcklbw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
(define_insn "mmx_punpckldq"
[
(set (match_operand:V2SI 0 "register_operand" "=y")
(vec_merge:V2SI
(vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
(parallel
[
(const_int 1)
(const_int 0)]))
(vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
(parallel
[
(const_int 0)
(const_int 1)]))
(const_int 1)))]
"TARGET_MMX"
"punpcklbw
\\
t{%2, %0|%0, %2}"
[
(set_attr "type" "mmx")
]
)
;; Miscellaneous stuff
(define_insn "emms"
[
(unspec_volatile [(const_int 0)
]
31)
(clobber (reg:XF 8))
(clobber (reg:XF 9))
(clobber (reg:XF 10))
(clobber (reg:XF 11))
(clobber (reg:XF 12))
(clobber (reg:XF 13))
(clobber (reg:XF 14))
(clobber (reg:XF 15))
(clobber (reg:DI 27))
(clobber (reg:DI 28))
(clobber (reg:DI 29))
(clobber (reg:DI 30))
(clobber (reg:DI 31))
(clobber (reg:DI 32))
(clobber (reg:DI 33))
(clobber (reg:DI 34))]
"TARGET_MMX"
"emms"
[
(set_attr "type" "mmx")
]
)
(define_insn "ldmxcsr"
[
(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")
]
37)]
"TARGET_MMX"
"ldmxcsr
\\
t%0"
[
(set_attr "type" "mmx")
]
)
(define_insn "stmxcsr"
[
(set (match_operand:SI 0 "memory_operand" "=m")
(unspec_volatile:SI
[
(const_int 0)
]
40))]
"TARGET_MMX"
"stmxcsr
\\
t%0"
[
(set_attr "type" "mmx")
]
)
(define_expand "sfence"
[
(set (match_dup 0)
(unspec:BLK
[
(match_dup 0)
]
44))]
"TARGET_SSE"
"
{
operands
[
0
]
= gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
MEM_VOLATILE_P (operands
[
0
]
) = 1;
}")
(define_insn "
*
sfence_insn"
[
(set (match_operand:BLK 0 "" "")
(unspec:BLK
[
(match_dup 0)
]
44))]
"TARGET_SSE"
"sfence"
[
(set_attr "type" "sse")
]
)
(define_insn "prefetch"
[
(unspec
[
(match_operand:SI 0 "address_operand" "p")
(match_operand:SI 1 "address_operand" "p")] 35)]
"TARGET_SSE"
"
*
{
switch (INTVAL (operands
[
1
]
))
{
case 0:
return
\"
prefetcht0
\\
t%0
\"
;
case 1:
return
\"
prefetcht1
\\
t%0
\"
;
case 2:
return
\"
prefetcht2
\\
t%0
\"
;
case 3:
return
\"
prefetchnta
\\
t%0
\"
;
default:
abort ();
}
}"
[
(set_attr "type" "sse")
]
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment