1848b8605Smrg
2848b8605Smrg#ifndef _X86SSE_H_
3848b8605Smrg#define _X86SSE_H_
4848b8605Smrg
5848b8605Smrg#if defined(__i386__) || defined(__386__)
6848b8605Smrg
7848b8605Smrg/* It is up to the caller to ensure that instructions issued are
8848b8605Smrg * suitable for the host cpu.  There are no checks made in this module
9848b8605Smrg * for mmx/sse/sse2 support on the cpu.
10848b8605Smrg */
11848b8605Smrgstruct x86_reg {
12848b8605Smrg   unsigned file:3;
13848b8605Smrg   unsigned idx:3;
14848b8605Smrg   unsigned mod:2;		/* mod_REG if this is just a register */
15848b8605Smrg   int      disp:24;		/* only +/- 23bits of offset - should be enough... */
16848b8605Smrg};
17848b8605Smrg
18848b8605Smrgstruct x86_function {
19848b8605Smrg   unsigned size;
20848b8605Smrg   unsigned char *store;
21848b8605Smrg   unsigned char *csr;
22848b8605Smrg   unsigned stack_offset;
23848b8605Smrg   int need_emms;
24848b8605Smrg   const char *fn;
25848b8605Smrg};
26848b8605Smrg
27848b8605Smrgenum x86_reg_file {
28848b8605Smrg   file_REG32,
29848b8605Smrg   file_MMX,
30848b8605Smrg   file_XMM,
31848b8605Smrg   file_x87
32848b8605Smrg};
33848b8605Smrg
34848b8605Smrg/* Values for mod field of modr/m byte
35848b8605Smrg */
36848b8605Smrgenum x86_reg_mod {
37848b8605Smrg   mod_INDIRECT,
38848b8605Smrg   mod_DISP8,
39848b8605Smrg   mod_DISP32,
40848b8605Smrg   mod_REG
41848b8605Smrg};
42848b8605Smrg
43848b8605Smrgenum x86_reg_name {
44848b8605Smrg   reg_AX,
45848b8605Smrg   reg_CX,
46848b8605Smrg   reg_DX,
47848b8605Smrg   reg_BX,
48848b8605Smrg   reg_SP,
49848b8605Smrg   reg_BP,
50848b8605Smrg   reg_SI,
51848b8605Smrg   reg_DI
52848b8605Smrg};
53848b8605Smrg
54848b8605Smrg
55848b8605Smrgenum x86_cc {
56848b8605Smrg   cc_O,			/* overflow */
57848b8605Smrg   cc_NO,			/* not overflow */
58848b8605Smrg   cc_NAE,			/* not above or equal / carry */
59848b8605Smrg   cc_AE,			/* above or equal / not carry */
60848b8605Smrg   cc_E,			/* equal / zero */
61848b8605Smrg   cc_NE			/* not equal / not zero */
62848b8605Smrg};
63848b8605Smrg
64848b8605Smrgenum sse_cc {
65848b8605Smrg   cc_Equal,
66848b8605Smrg   cc_LessThan,
67848b8605Smrg   cc_LessThanEqual,
68848b8605Smrg   cc_Unordered,
69848b8605Smrg   cc_NotEqual,
70848b8605Smrg   cc_NotLessThan,
71848b8605Smrg   cc_NotLessThanEqual,
72848b8605Smrg   cc_Ordered
73848b8605Smrg};
74848b8605Smrg
75848b8605Smrg#define cc_Z  cc_E
76848b8605Smrg#define cc_NZ cc_NE
77848b8605Smrg
78848b8605Smrg/* Begin/end/retreive function creation:
79848b8605Smrg */
80848b8605Smrg
81848b8605Smrg
82848b8605Smrgvoid x86_init_func( struct x86_function *p );
83848b8605Smrgint x86_init_func_size( struct x86_function *p, unsigned code_size );
84848b8605Smrgvoid x86_release_func( struct x86_function *p );
85848b8605Smrgvoid (*x86_get_func( struct x86_function *p ))( void );
86848b8605Smrg
87848b8605Smrg
88848b8605Smrg
89848b8605Smrg/* Create and manipulate registers and regmem values:
90848b8605Smrg */
91848b8605Smrgstruct x86_reg x86_make_reg( enum x86_reg_file file,
92848b8605Smrg			     enum x86_reg_name idx );
93848b8605Smrg
94848b8605Smrgstruct x86_reg x86_make_disp( struct x86_reg reg,
95848b8605Smrg			      int disp );
96848b8605Smrg
97848b8605Smrgstruct x86_reg x86_deref( struct x86_reg reg );
98848b8605Smrg
99848b8605Smrgstruct x86_reg x86_get_base_reg( struct x86_reg reg );
100848b8605Smrg
101848b8605Smrg
102848b8605Smrg/* Labels, jumps and fixup:
103848b8605Smrg */
104848b8605Smrgunsigned char *x86_get_label( struct x86_function *p );
105848b8605Smrg
106848b8605Smrgvoid x86_jcc( struct x86_function *p,
107848b8605Smrg	      enum x86_cc cc,
108848b8605Smrg	      unsigned char *label );
109848b8605Smrg
110848b8605Smrgunsigned char *x86_jcc_forward( struct x86_function *p,
111848b8605Smrg			  enum x86_cc cc );
112848b8605Smrg
113848b8605Smrgunsigned char *x86_jmp_forward( struct x86_function *p);
114848b8605Smrg
115848b8605Smrgunsigned char *x86_call_forward( struct x86_function *p);
116848b8605Smrg
117848b8605Smrgvoid x86_fixup_fwd_jump( struct x86_function *p,
118848b8605Smrg			 unsigned char *fixup );
119848b8605Smrg
120848b8605Smrgvoid x86_jmp( struct x86_function *p, unsigned char *label );
121848b8605Smrg
122848b8605Smrg/* void x86_call( struct x86_function *p, void (*label)() ); */
123848b8605Smrgvoid x86_call( struct x86_function *p, struct x86_reg reg);
124848b8605Smrg
125848b8605Smrg/* michal:
126848b8605Smrg * Temporary. As I need immediate operands, and dont want to mess with the codegen,
127848b8605Smrg * I load the immediate into general purpose register and use it.
128848b8605Smrg */
129848b8605Smrgvoid x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm );
130848b8605Smrg
131848b8605Smrg
132848b8605Smrg/* Macro for sse_shufps() and sse2_pshufd():
133848b8605Smrg */
134848b8605Smrg#define SHUF(_x,_y,_z,_w)       (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6))
135848b8605Smrg#define SHUF_NOOP               RSW(0,1,2,3)
136848b8605Smrg#define GET_SHUF(swz, idx)      (((swz) >> ((idx)*2)) & 0x3)
137848b8605Smrg
138848b8605Smrgvoid mmx_emms( struct x86_function *p );
139848b8605Smrgvoid mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
140848b8605Smrgvoid mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
141848b8605Smrgvoid mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
142848b8605Smrgvoid mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
143848b8605Smrg
144848b8605Smrgvoid sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
145848b8605Smrgvoid sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
146848b8605Smrgvoid sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
147848b8605Smrgvoid sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
148848b8605Smrgvoid sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
149848b8605Smrgvoid sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
150848b8605Smrgvoid sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0,
151848b8605Smrg                  unsigned char shuf );
152848b8605Smrgvoid sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
153848b8605Smrgvoid sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
154848b8605Smrg
155848b8605Smrgvoid sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
156848b8605Smrgvoid sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
157848b8605Smrgvoid sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
158848b8605Smrgvoid sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
159848b8605Smrgvoid sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
160848b8605Smrgvoid sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
161848b8605Smrgvoid sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src,
162848b8605Smrg                unsigned char cc );
163848b8605Smrgvoid sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
164848b8605Smrgvoid sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
165848b8605Smrgvoid sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
166848b8605Smrgvoid sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
167848b8605Smrgvoid sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
168848b8605Smrgvoid sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
169848b8605Smrgvoid sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
170848b8605Smrgvoid sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
171848b8605Smrgvoid sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
172848b8605Smrgvoid sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
173848b8605Smrgvoid sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
174848b8605Smrgvoid sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
175848b8605Smrgvoid sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
176848b8605Smrgvoid sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
177848b8605Smrgvoid sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
178848b8605Smrgvoid sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
179848b8605Smrgvoid sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
180848b8605Smrgvoid sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0,
181848b8605Smrg                 unsigned char shuf );
182848b8605Smrgvoid sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src );
183848b8605Smrg
184848b8605Smrgvoid x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
185848b8605Smrgvoid x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
186848b8605Smrgvoid x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
187848b8605Smrgvoid x86_dec( struct x86_function *p, struct x86_reg reg );
188848b8605Smrgvoid x86_inc( struct x86_function *p, struct x86_reg reg );
189848b8605Smrgvoid x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
190848b8605Smrgvoid x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
191848b8605Smrgvoid x86_mul( struct x86_function *p, struct x86_reg src );
192848b8605Smrgvoid x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
193848b8605Smrgvoid x86_pop( struct x86_function *p, struct x86_reg reg );
194848b8605Smrgvoid x86_push( struct x86_function *p, struct x86_reg reg );
195848b8605Smrgvoid x86_ret( struct x86_function *p );
196848b8605Smrgvoid x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
197848b8605Smrgvoid x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
198848b8605Smrgvoid x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
199848b8605Smrgvoid x86_sahf( struct x86_function *p );
200848b8605Smrg
201848b8605Smrgvoid x87_f2xm1( struct x86_function *p );
202848b8605Smrgvoid x87_fabs( struct x86_function *p );
203848b8605Smrgvoid x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
204848b8605Smrgvoid x87_faddp( struct x86_function *p, struct x86_reg dst );
205848b8605Smrgvoid x87_fchs( struct x86_function *p );
206848b8605Smrgvoid x87_fclex( struct x86_function *p );
207848b8605Smrgvoid x87_fcom( struct x86_function *p, struct x86_reg dst );
208848b8605Smrgvoid x87_fcomp( struct x86_function *p, struct x86_reg dst );
209848b8605Smrgvoid x87_fcos( struct x86_function *p );
210848b8605Smrgvoid x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
211848b8605Smrgvoid x87_fdivp( struct x86_function *p, struct x86_reg dst );
212848b8605Smrgvoid x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
213848b8605Smrgvoid x87_fdivrp( struct x86_function *p, struct x86_reg dst );
214848b8605Smrgvoid x87_fild( struct x86_function *p, struct x86_reg arg );
215848b8605Smrgvoid x87_fist( struct x86_function *p, struct x86_reg dst );
216848b8605Smrgvoid x87_fistp( struct x86_function *p, struct x86_reg dst );
217848b8605Smrgvoid x87_fld( struct x86_function *p, struct x86_reg arg );
218848b8605Smrgvoid x87_fld1( struct x86_function *p );
219848b8605Smrgvoid x87_fldcw( struct x86_function *p, struct x86_reg arg );
220848b8605Smrgvoid x87_fldl2e( struct x86_function *p );
221848b8605Smrgvoid x87_fldln2( struct x86_function *p );
222848b8605Smrgvoid x87_fldz( struct x86_function *p );
223848b8605Smrgvoid x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
224848b8605Smrgvoid x87_fmulp( struct x86_function *p, struct x86_reg dst );
225848b8605Smrgvoid x87_fnclex( struct x86_function *p );
226848b8605Smrgvoid x87_fprndint( struct x86_function *p );
227848b8605Smrgvoid x87_fscale( struct x86_function *p );
228848b8605Smrgvoid x87_fsin( struct x86_function *p );
229848b8605Smrgvoid x87_fsincos( struct x86_function *p );
230848b8605Smrgvoid x87_fsqrt( struct x86_function *p );
231848b8605Smrgvoid x87_fst( struct x86_function *p, struct x86_reg dst );
232848b8605Smrgvoid x87_fstp( struct x86_function *p, struct x86_reg dst );
233848b8605Smrgvoid x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
234848b8605Smrgvoid x87_fsubp( struct x86_function *p, struct x86_reg dst );
235848b8605Smrgvoid x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
236848b8605Smrgvoid x87_fsubrp( struct x86_function *p, struct x86_reg dst );
237848b8605Smrgvoid x87_fxch( struct x86_function *p, struct x86_reg dst );
238848b8605Smrgvoid x87_fxtract( struct x86_function *p );
239848b8605Smrgvoid x87_fyl2x( struct x86_function *p );
240848b8605Smrgvoid x87_fyl2xp1( struct x86_function *p );
241848b8605Smrgvoid x87_fwait( struct x86_function *p );
242848b8605Smrgvoid x87_fnstsw( struct x86_function *p, struct x86_reg dst );
243848b8605Smrgvoid x87_fucompp( struct x86_function *p );
244848b8605Smrgvoid x87_fucomp( struct x86_function *p, struct x86_reg arg );
245848b8605Smrgvoid x87_fucom( struct x86_function *p, struct x86_reg arg );
246848b8605Smrg
247848b8605Smrg
248848b8605Smrg
249848b8605Smrg/* Retreive a reference to one of the function arguments, taking into
250848b8605Smrg * account any push/pop activity.  Note - doesn't track explict
251848b8605Smrg * manipulation of ESP by other instructions.
252848b8605Smrg */
253848b8605Smrgstruct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg );
254848b8605Smrg
255848b8605Smrg#endif
256848b8605Smrg#endif
257