2 #if defined(__i386__) || defined(__386__)
4 #include "main/imports.h"
10 static unsigned char *cptr( void (*label
)() )
12 return (unsigned char *)(unsigned long)label
;
16 static void do_realloc( struct x86_function
*p
)
20 p
->store
= _mesa_exec_malloc(p
->size
);
24 unsigned used
= p
->csr
- p
->store
;
25 unsigned char *tmp
= p
->store
;
27 p
->store
= _mesa_exec_malloc(p
->size
);
28 memcpy(p
->store
, tmp
, used
);
29 p
->csr
= p
->store
+ used
;
34 /* Emit bytes to the instruction stream:
36 static unsigned char *reserve( struct x86_function
*p
, int bytes
)
38 if (p
->csr
+ bytes
- p
->store
> p
->size
)
42 unsigned char *csr
= p
->csr
;
50 static void emit_1b( struct x86_function
*p
, char b0
)
52 char *csr
= (char *)reserve(p
, 1);
56 static void emit_1i( struct x86_function
*p
, int i0
)
58 int *icsr
= (int *)reserve(p
, sizeof(i0
));
62 static void emit_1ub( struct x86_function
*p
, unsigned char b0
)
64 unsigned char *csr
= reserve(p
, 1);
68 static void emit_2ub( struct x86_function
*p
, unsigned char b0
, unsigned char b1
)
70 unsigned char *csr
= reserve(p
, 2);
75 static void emit_3ub( struct x86_function
*p
, unsigned char b0
, unsigned char b1
, unsigned char b2
)
77 unsigned char *csr
= reserve(p
, 3);
84 /* Build a modRM byte + possible displacement. No treatment of SIB
85 * indexing. BZZT - no way to encode an absolute address.
87 static void emit_modrm( struct x86_function
*p
,
89 struct x86_reg regmem
)
91 unsigned char val
= 0;
93 assert(reg
.mod
== mod_REG
);
95 val
|= regmem
.mod
<< 6; /* mod field */
96 val
|= reg
.idx
<< 3; /* reg field */
97 val
|= regmem
.idx
; /* r/m field */
101 /* Oh-oh we've stumbled into the SIB thing.
103 if (regmem
.file
== file_REG32
&&
104 regmem
.idx
== reg_SP
) {
105 emit_1ub(p
, 0x24); /* simplistic! */
108 switch (regmem
.mod
) {
113 emit_1b(p
, regmem
.disp
);
116 emit_1i(p
, regmem
.disp
);
125 static void emit_modrm_noreg( struct x86_function
*p
,
127 struct x86_reg regmem
)
129 struct x86_reg dummy
= x86_make_reg(file_REG32
, op
);
130 emit_modrm(p
, dummy
, regmem
);
133 /* Many x86 instructions have two opcodes to cope with the situations
134 * where the destination is a register or memory reference
135 * respectively. This function selects the correct opcode based on
136 * the arguments presented.
138 static void emit_op_modrm( struct x86_function
*p
,
139 unsigned char op_dst_is_reg
,
140 unsigned char op_dst_is_mem
,
146 emit_1ub(p
, op_dst_is_reg
);
147 emit_modrm(p
, dst
, src
);
152 assert(src
.mod
== mod_REG
);
153 emit_1ub(p
, op_dst_is_mem
);
154 emit_modrm(p
, src
, dst
);
168 /* Create and manipulate registers and regmem values:
170 struct x86_reg
x86_make_reg( enum x86_reg_file file
,
171 enum x86_reg_name idx
)
183 struct x86_reg
x86_make_disp( struct x86_reg reg
,
186 assert(reg
.file
== file_REG32
);
188 if (reg
.mod
== mod_REG
)
194 reg
.mod
= mod_INDIRECT
;
195 else if (reg
.disp
<= 127 && reg
.disp
>= -128)
198 reg
.mod
= mod_DISP32
;
203 struct x86_reg
x86_deref( struct x86_reg reg
)
205 return x86_make_disp(reg
, 0);
208 struct x86_reg
x86_get_base_reg( struct x86_reg reg
)
210 return x86_make_reg( reg
.file
, reg
.idx
);
213 unsigned char *x86_get_label( struct x86_function
*p
)
220 /***********************************************************************
225 void x86_jcc( struct x86_function
*p
,
227 unsigned char *label
)
229 int offset
= label
- (x86_get_label(p
) + 2);
231 if (offset
<= 127 && offset
>= -128) {
232 emit_1ub(p
, 0x70 + cc
);
233 emit_1b(p
, (char) offset
);
236 offset
= label
- (x86_get_label(p
) + 6);
237 emit_2ub(p
, 0x0f, 0x80 + cc
);
242 /* Always use a 32bit offset for forward jumps:
244 unsigned char *x86_jcc_forward( struct x86_function
*p
,
247 emit_2ub(p
, 0x0f, 0x80 + cc
);
249 return x86_get_label(p
);
252 unsigned char *x86_jmp_forward( struct x86_function
*p
)
256 return x86_get_label(p
);
259 unsigned char *x86_call_forward( struct x86_function
*p
)
263 return x86_get_label(p
);
266 /* Fixup offset from forward jump:
268 void x86_fixup_fwd_jump( struct x86_function
*p
,
269 unsigned char *fixup
)
271 *(int *)(fixup
- 4) = x86_get_label(p
) - fixup
;
274 void x86_jmp( struct x86_function
*p
, unsigned char *label
)
277 emit_1i(p
, label
- x86_get_label(p
) - 4);
281 /* This doesn't work once we start reallocating & copying the
282 * generated code on buffer fills, because the call is relative to the
285 void x86_call( struct x86_function
*p
, void (*label
)())
288 emit_1i(p
, cptr(label
) - x86_get_label(p
) - 4);
291 void x86_call( struct x86_function
*p
, struct x86_reg reg
)
294 emit_modrm_noreg(p
, 2, reg
);
300 * Temporary. As I need immediate operands, and dont want to mess with the codegen,
301 * I load the immediate into general purpose register and use it.
303 void x86_mov_reg_imm( struct x86_function
*p
, struct x86_reg dst
, int imm
)
305 assert(dst
.mod
== mod_REG
);
306 emit_1ub(p
, 0xb8 + dst
.idx
);
310 void x86_push( struct x86_function
*p
,
313 assert(reg
.mod
== mod_REG
);
314 emit_1ub(p
, 0x50 + reg
.idx
);
315 p
->stack_offset
+= 4;
318 void x86_pop( struct x86_function
*p
,
321 assert(reg
.mod
== mod_REG
);
322 emit_1ub(p
, 0x58 + reg
.idx
);
323 p
->stack_offset
-= 4;
326 void x86_inc( struct x86_function
*p
,
329 assert(reg
.mod
== mod_REG
);
330 emit_1ub(p
, 0x40 + reg
.idx
);
333 void x86_dec( struct x86_function
*p
,
336 assert(reg
.mod
== mod_REG
);
337 emit_1ub(p
, 0x48 + reg
.idx
);
340 void x86_ret( struct x86_function
*p
)
345 void x86_sahf( struct x86_function
*p
)
350 void x86_mov( struct x86_function
*p
,
354 emit_op_modrm( p
, 0x8b, 0x89, dst
, src
);
357 void x86_xor( struct x86_function
*p
,
361 emit_op_modrm( p
, 0x33, 0x31, dst
, src
);
364 void x86_cmp( struct x86_function
*p
,
368 emit_op_modrm( p
, 0x3b, 0x39, dst
, src
);
371 void x86_lea( struct x86_function
*p
,
376 emit_modrm( p
, dst
, src
);
379 void x86_test( struct x86_function
*p
,
384 emit_modrm( p
, dst
, src
);
387 void x86_add( struct x86_function
*p
,
391 emit_op_modrm(p
, 0x03, 0x01, dst
, src
);
394 void x86_mul( struct x86_function
*p
,
397 assert (src
.file
== file_REG32
&& src
.mod
== mod_REG
);
398 emit_op_modrm(p
, 0xf7, 0, x86_make_reg (file_REG32
, reg_SP
), src
);
401 void x86_sub( struct x86_function
*p
,
405 emit_op_modrm(p
, 0x2b, 0x29, dst
, src
);
408 void x86_or( struct x86_function
*p
,
412 emit_op_modrm( p
, 0x0b, 0x09, dst
, src
);
415 void x86_and( struct x86_function
*p
,
419 emit_op_modrm( p
, 0x23, 0x21, dst
, src
);
424 /***********************************************************************
429 void sse_movss( struct x86_function
*p
,
433 emit_2ub(p
, 0xF3, X86_TWOB
);
434 emit_op_modrm( p
, 0x10, 0x11, dst
, src
);
437 void sse_movaps( struct x86_function
*p
,
441 emit_1ub(p
, X86_TWOB
);
442 emit_op_modrm( p
, 0x28, 0x29, dst
, src
);
445 void sse_movups( struct x86_function
*p
,
449 emit_1ub(p
, X86_TWOB
);
450 emit_op_modrm( p
, 0x10, 0x11, dst
, src
);
453 void sse_movhps( struct x86_function
*p
,
457 assert(dst
.mod
!= mod_REG
|| src
.mod
!= mod_REG
);
458 emit_1ub(p
, X86_TWOB
);
459 emit_op_modrm( p
, 0x16, 0x17, dst
, src
); /* cf movlhps */
462 void sse_movlps( struct x86_function
*p
,
466 assert(dst
.mod
!= mod_REG
|| src
.mod
!= mod_REG
);
467 emit_1ub(p
, X86_TWOB
);
468 emit_op_modrm( p
, 0x12, 0x13, dst
, src
); /* cf movhlps */
471 void sse_maxps( struct x86_function
*p
,
475 emit_2ub(p
, X86_TWOB
, 0x5F);
476 emit_modrm( p
, dst
, src
);
479 void sse_maxss( struct x86_function
*p
,
483 emit_3ub(p
, 0xF3, X86_TWOB
, 0x5F);
484 emit_modrm( p
, dst
, src
);
487 void sse_divss( struct x86_function
*p
,
491 emit_3ub(p
, 0xF3, X86_TWOB
, 0x5E);
492 emit_modrm( p
, dst
, src
);
495 void sse_minps( struct x86_function
*p
,
499 emit_2ub(p
, X86_TWOB
, 0x5D);
500 emit_modrm( p
, dst
, src
);
503 void sse_subps( struct x86_function
*p
,
507 emit_2ub(p
, X86_TWOB
, 0x5C);
508 emit_modrm( p
, dst
, src
);
511 void sse_mulps( struct x86_function
*p
,
515 emit_2ub(p
, X86_TWOB
, 0x59);
516 emit_modrm( p
, dst
, src
);
519 void sse_mulss( struct x86_function
*p
,
523 emit_3ub(p
, 0xF3, X86_TWOB
, 0x59);
524 emit_modrm( p
, dst
, src
);
527 void sse_addps( struct x86_function
*p
,
531 emit_2ub(p
, X86_TWOB
, 0x58);
532 emit_modrm( p
, dst
, src
);
535 void sse_addss( struct x86_function
*p
,
539 emit_3ub(p
, 0xF3, X86_TWOB
, 0x58);
540 emit_modrm( p
, dst
, src
);
543 void sse_andnps( struct x86_function
*p
,
547 emit_2ub(p
, X86_TWOB
, 0x55);
548 emit_modrm( p
, dst
, src
);
551 void sse_andps( struct x86_function
*p
,
555 emit_2ub(p
, X86_TWOB
, 0x54);
556 emit_modrm( p
, dst
, src
);
559 void sse_rsqrtps( struct x86_function
*p
,
563 emit_2ub(p
, X86_TWOB
, 0x52);
564 emit_modrm( p
, dst
, src
);
567 void sse_rsqrtss( struct x86_function
*p
,
571 emit_3ub(p
, 0xF3, X86_TWOB
, 0x52);
572 emit_modrm( p
, dst
, src
);
576 void sse_movhlps( struct x86_function
*p
,
580 assert(dst
.mod
== mod_REG
&& src
.mod
== mod_REG
);
581 emit_2ub(p
, X86_TWOB
, 0x12);
582 emit_modrm( p
, dst
, src
);
585 void sse_movlhps( struct x86_function
*p
,
589 assert(dst
.mod
== mod_REG
&& src
.mod
== mod_REG
);
590 emit_2ub(p
, X86_TWOB
, 0x16);
591 emit_modrm( p
, dst
, src
);
594 void sse_orps( struct x86_function
*p
,
598 emit_2ub(p
, X86_TWOB
, 0x56);
599 emit_modrm( p
, dst
, src
);
602 void sse_xorps( struct x86_function
*p
,
606 emit_2ub(p
, X86_TWOB
, 0x57);
607 emit_modrm( p
, dst
, src
);
610 void sse_cvtps2pi( struct x86_function
*p
,
614 assert(dst
.file
== file_MMX
&&
615 (src
.file
== file_XMM
|| src
.mod
!= mod_REG
));
619 emit_2ub(p
, X86_TWOB
, 0x2d);
620 emit_modrm( p
, dst
, src
);
624 /* Shufps can also be used to implement a reduced swizzle when dest ==
627 void sse_shufps( struct x86_function
*p
,
632 emit_2ub(p
, X86_TWOB
, 0xC6);
633 emit_modrm(p
, dest
, arg0
);
637 void sse_cmpps( struct x86_function
*p
,
642 emit_2ub(p
, X86_TWOB
, 0xC2);
643 emit_modrm(p
, dest
, arg0
);
647 void sse_pmovmskb( struct x86_function
*p
,
651 emit_3ub(p
, 0x66, X86_TWOB
, 0xD7);
652 emit_modrm(p
, dest
, src
);
655 /***********************************************************************
660 * Perform a reduced swizzle:
662 void sse2_pshufd( struct x86_function
*p
,
667 emit_3ub(p
, 0x66, X86_TWOB
, 0x70);
668 emit_modrm(p
, dest
, arg0
);
672 void sse2_cvttps2dq( struct x86_function
*p
,
676 emit_3ub( p
, 0xF3, X86_TWOB
, 0x5B );
677 emit_modrm( p
, dst
, src
);
680 void sse2_cvtps2dq( struct x86_function
*p
,
684 emit_3ub(p
, 0x66, X86_TWOB
, 0x5B);
685 emit_modrm( p
, dst
, src
);
688 void sse2_packssdw( struct x86_function
*p
,
692 emit_3ub(p
, 0x66, X86_TWOB
, 0x6B);
693 emit_modrm( p
, dst
, src
);
696 void sse2_packsswb( struct x86_function
*p
,
700 emit_3ub(p
, 0x66, X86_TWOB
, 0x63);
701 emit_modrm( p
, dst
, src
);
704 void sse2_packuswb( struct x86_function
*p
,
708 emit_3ub(p
, 0x66, X86_TWOB
, 0x67);
709 emit_modrm( p
, dst
, src
);
712 void sse2_rcpps( struct x86_function
*p
,
716 emit_2ub(p
, X86_TWOB
, 0x53);
717 emit_modrm( p
, dst
, src
);
720 void sse2_rcpss( struct x86_function
*p
,
724 emit_3ub(p
, 0xF3, X86_TWOB
, 0x53);
725 emit_modrm( p
, dst
, src
);
728 void sse2_movd( struct x86_function
*p
,
732 emit_2ub(p
, 0x66, X86_TWOB
);
733 emit_op_modrm( p
, 0x6e, 0x7e, dst
, src
);
739 /***********************************************************************
742 void x87_fist( struct x86_function
*p
, struct x86_reg dst
)
745 emit_modrm_noreg(p
, 2, dst
);
748 void x87_fistp( struct x86_function
*p
, struct x86_reg dst
)
751 emit_modrm_noreg(p
, 3, dst
);
754 void x87_fild( struct x86_function
*p
, struct x86_reg arg
)
757 emit_modrm_noreg(p
, 0, arg
);
760 void x87_fldz( struct x86_function
*p
)
762 emit_2ub(p
, 0xd9, 0xee);
766 void x87_fldcw( struct x86_function
*p
, struct x86_reg arg
)
768 assert(arg
.file
== file_REG32
);
769 assert(arg
.mod
!= mod_REG
);
771 emit_modrm_noreg(p
, 5, arg
);
774 void x87_fld1( struct x86_function
*p
)
776 emit_2ub(p
, 0xd9, 0xe8);
779 void x87_fldl2e( struct x86_function
*p
)
781 emit_2ub(p
, 0xd9, 0xea);
784 void x87_fldln2( struct x86_function
*p
)
786 emit_2ub(p
, 0xd9, 0xed);
789 void x87_fwait( struct x86_function
*p
)
794 void x87_fnclex( struct x86_function
*p
)
796 emit_2ub(p
, 0xdb, 0xe2);
799 void x87_fclex( struct x86_function
*p
)
806 static void x87_arith_op( struct x86_function
*p
, struct x86_reg dst
, struct x86_reg arg
,
807 unsigned char dst0ub0
,
808 unsigned char dst0ub1
,
809 unsigned char arg0ub0
,
810 unsigned char arg0ub1
,
811 unsigned char argmem_noreg
)
813 assert(dst
.file
== file_x87
);
815 if (arg
.file
== file_x87
) {
817 emit_2ub(p
, dst0ub0
, dst0ub1
+arg
.idx
);
818 else if (arg
.idx
== 0)
819 emit_2ub(p
, arg0ub0
, arg0ub1
+arg
.idx
);
823 else if (dst
.idx
== 0) {
824 assert(arg
.file
== file_REG32
);
826 emit_modrm_noreg(p
, argmem_noreg
, arg
);
832 void x87_fmul( struct x86_function
*p
, struct x86_reg dst
, struct x86_reg arg
)
834 x87_arith_op(p
, dst
, arg
,
840 void x87_fsub( struct x86_function
*p
, struct x86_reg dst
, struct x86_reg arg
)
842 x87_arith_op(p
, dst
, arg
,
848 void x87_fsubr( struct x86_function
*p
, struct x86_reg dst
, struct x86_reg arg
)
850 x87_arith_op(p
, dst
, arg
,
856 void x87_fadd( struct x86_function
*p
, struct x86_reg dst
, struct x86_reg arg
)
858 x87_arith_op(p
, dst
, arg
,
864 void x87_fdiv( struct x86_function
*p
, struct x86_reg dst
, struct x86_reg arg
)
866 x87_arith_op(p
, dst
, arg
,
872 void x87_fdivr( struct x86_function
*p
, struct x86_reg dst
, struct x86_reg arg
)
874 x87_arith_op(p
, dst
, arg
,
880 void x87_fmulp( struct x86_function
*p
, struct x86_reg dst
)
882 assert(dst
.file
== file_x87
);
883 assert(dst
.idx
>= 1);
884 emit_2ub(p
, 0xde, 0xc8+dst
.idx
);
887 void x87_fsubp( struct x86_function
*p
, struct x86_reg dst
)
889 assert(dst
.file
== file_x87
);
890 assert(dst
.idx
>= 1);
891 emit_2ub(p
, 0xde, 0xe8+dst
.idx
);
894 void x87_fsubrp( struct x86_function
*p
, struct x86_reg dst
)
896 assert(dst
.file
== file_x87
);
897 assert(dst
.idx
>= 1);
898 emit_2ub(p
, 0xde, 0xe0+dst
.idx
);
901 void x87_faddp( struct x86_function
*p
, struct x86_reg dst
)
903 assert(dst
.file
== file_x87
);
904 assert(dst
.idx
>= 1);
905 emit_2ub(p
, 0xde, 0xc0+dst
.idx
);
908 void x87_fdivp( struct x86_function
*p
, struct x86_reg dst
)
910 assert(dst
.file
== file_x87
);
911 assert(dst
.idx
>= 1);
912 emit_2ub(p
, 0xde, 0xf8+dst
.idx
);
915 void x87_fdivrp( struct x86_function
*p
, struct x86_reg dst
)
917 assert(dst
.file
== file_x87
);
918 assert(dst
.idx
>= 1);
919 emit_2ub(p
, 0xde, 0xf0+dst
.idx
);
922 void x87_fucom( struct x86_function
*p
, struct x86_reg arg
)
924 assert(arg
.file
== file_x87
);
925 emit_2ub(p
, 0xdd, 0xe0+arg
.idx
);
928 void x87_fucomp( struct x86_function
*p
, struct x86_reg arg
)
930 assert(arg
.file
== file_x87
);
931 emit_2ub(p
, 0xdd, 0xe8+arg
.idx
);
934 void x87_fucompp( struct x86_function
*p
)
936 emit_2ub(p
, 0xda, 0xe9);
939 void x87_fxch( struct x86_function
*p
, struct x86_reg arg
)
941 assert(arg
.file
== file_x87
);
942 emit_2ub(p
, 0xd9, 0xc8+arg
.idx
);
945 void x87_fabs( struct x86_function
*p
)
947 emit_2ub(p
, 0xd9, 0xe1);
950 void x87_fchs( struct x86_function
*p
)
952 emit_2ub(p
, 0xd9, 0xe0);
955 void x87_fcos( struct x86_function
*p
)
957 emit_2ub(p
, 0xd9, 0xff);
961 void x87_fprndint( struct x86_function
*p
)
963 emit_2ub(p
, 0xd9, 0xfc);
966 void x87_fscale( struct x86_function
*p
)
968 emit_2ub(p
, 0xd9, 0xfd);
971 void x87_fsin( struct x86_function
*p
)
973 emit_2ub(p
, 0xd9, 0xfe);
976 void x87_fsincos( struct x86_function
*p
)
978 emit_2ub(p
, 0xd9, 0xfb);
981 void x87_fsqrt( struct x86_function
*p
)
983 emit_2ub(p
, 0xd9, 0xfa);
986 void x87_fxtract( struct x86_function
*p
)
988 emit_2ub(p
, 0xd9, 0xf4);
993 * Restrictions: -1.0 <= st0 <= 1.0
995 void x87_f2xm1( struct x86_function
*p
)
997 emit_2ub(p
, 0xd9, 0xf0);
1000 /* st1 = st1 * log2(st0);
1003 void x87_fyl2x( struct x86_function
*p
)
1005 emit_2ub(p
, 0xd9, 0xf1);
1008 /* st1 = st1 * log2(st0 + 1.0);
1011 * A fast operation, with restrictions: -.29 < st0 < .29
1013 void x87_fyl2xp1( struct x86_function
*p
)
1015 emit_2ub(p
, 0xd9, 0xf9);
1019 void x87_fld( struct x86_function
*p
, struct x86_reg arg
)
1021 if (arg
.file
== file_x87
)
1022 emit_2ub(p
, 0xd9, 0xc0 + arg
.idx
);
1025 emit_modrm_noreg(p
, 0, arg
);
1029 void x87_fst( struct x86_function
*p
, struct x86_reg dst
)
1031 if (dst
.file
== file_x87
)
1032 emit_2ub(p
, 0xdd, 0xd0 + dst
.idx
);
1035 emit_modrm_noreg(p
, 2, dst
);
1039 void x87_fstp( struct x86_function
*p
, struct x86_reg dst
)
1041 if (dst
.file
== file_x87
)
1042 emit_2ub(p
, 0xdd, 0xd8 + dst
.idx
);
1045 emit_modrm_noreg(p
, 3, dst
);
1049 void x87_fcom( struct x86_function
*p
, struct x86_reg dst
)
1051 if (dst
.file
== file_x87
)
1052 emit_2ub(p
, 0xd8, 0xd0 + dst
.idx
);
1055 emit_modrm_noreg(p
, 2, dst
);
1059 void x87_fcomp( struct x86_function
*p
, struct x86_reg dst
)
1061 if (dst
.file
== file_x87
)
1062 emit_2ub(p
, 0xd8, 0xd8 + dst
.idx
);
1065 emit_modrm_noreg(p
, 3, dst
);
1070 void x87_fnstsw( struct x86_function
*p
, struct x86_reg dst
)
1072 assert(dst
.file
== file_REG32
);
1074 if (dst
.idx
== reg_AX
&&
1076 emit_2ub(p
, 0xdf, 0xe0);
1079 emit_modrm_noreg(p
, 7, dst
);
1086 /***********************************************************************
1090 void mmx_emms( struct x86_function
*p
)
1092 assert(p
->need_emms
);
1093 emit_2ub(p
, 0x0f, 0x77);
1097 void mmx_packssdw( struct x86_function
*p
,
1099 struct x86_reg src
)
1101 assert(dst
.file
== file_MMX
&&
1102 (src
.file
== file_MMX
|| src
.mod
!= mod_REG
));
1106 emit_2ub(p
, X86_TWOB
, 0x6b);
1107 emit_modrm( p
, dst
, src
);
1110 void mmx_packuswb( struct x86_function
*p
,
1112 struct x86_reg src
)
1114 assert(dst
.file
== file_MMX
&&
1115 (src
.file
== file_MMX
|| src
.mod
!= mod_REG
));
1119 emit_2ub(p
, X86_TWOB
, 0x67);
1120 emit_modrm( p
, dst
, src
);
1123 void mmx_movd( struct x86_function
*p
,
1125 struct x86_reg src
)
1128 emit_1ub(p
, X86_TWOB
);
1129 emit_op_modrm( p
, 0x6e, 0x7e, dst
, src
);
1132 void mmx_movq( struct x86_function
*p
,
1134 struct x86_reg src
)
1137 emit_1ub(p
, X86_TWOB
);
1138 emit_op_modrm( p
, 0x6f, 0x7f, dst
, src
);
1142 /***********************************************************************
1147 /* Retreive a reference to one of the function arguments, taking into
1148 * account any push/pop activity:
1150 struct x86_reg
x86_fn_arg( struct x86_function
*p
,
1153 return x86_make_disp(x86_make_reg(file_REG32
, reg_SP
),
1154 p
->stack_offset
+ arg
* 4); /* ??? */
1158 void x86_init_func( struct x86_function
*p
)
1165 void x86_init_func_size( struct x86_function
*p
, unsigned code_size
)
1167 p
->size
= code_size
;
1168 p
->store
= _mesa_exec_malloc(code_size
);
1172 void x86_release_func( struct x86_function
*p
)
1174 _mesa_exec_free(p
->store
);
1181 void (*x86_get_func( struct x86_function
*p
))(void)
1183 if (DISASSEM
&& p
->store
)
1184 _mesa_printf("disassemble %p %p\n", p
->store
, p
->csr
);
1185 return (void (*)(void)) (unsigned long) p
->store
;
1190 void x86sse_dummy( void )
1196 #else /* USE_X86_ASM */
1198 int x86sse_c_dummy_var
; /* silence warning */
1200 #endif /* USE_X86_ASM */