x86_emulator: emulate shld and shrd instruction
cover x86_emulator: emulate shld and shrd instruction
This series of patches emulate instructions shld and shrd. As those instructions have three operands we introduce a decode set for the Src2 operand. By doing this, the opcode descriptor needs to be extend to 32 bit.
So this series of patches:
[1/5] extend the opcode descriptor to 32 bits [2/5] add Src2 decode set
[3/5] add a new "implied 1" Src decode type [4/5] add the assembler code for three operands [5/5] add the emulation of shld and shrd instructions
PATCH 1/5 x86_emulator: Extend the opcode descriptor
Extend the opcode descriptor to 32 bits. This is needed by the introduction of a new Src2 operand type.
--- arch/x86/kvm/x86_emulate.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/kvm/x86_emulate.c +4 -4
@@ -76,7 +76,7 @@ enum { Group1A, Group3_Byte, Group3, Group4, Group5, Group7, }; -static u16 opcode_table[256 ] = { +static u32 opcode_table[256 ] = {/* 0x00 - 0x07 */ ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -195,7 +195,7 @@ static u16 opcode_table[256] = { ImplicitOps, ImplicitOps, Group | Group4, Group | Group5, }; -static u16 twobyte_table[256 ] = { +static u32 twobyte_table[256 ] = {/* 0x00 - 0x0F */ 0 , Group | GroupDual | Group7,0 ,0 ,0 ,0 , ImplicitOps,0 , ImplicitOps, ImplicitOps,0 ,0 ,0 , ImplicitOps | ModRM,0 ,0 ,
@@ -253,7 +253,7 @@ static u16 twobyte_table[256] = {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 }; -static u16 group_table[] = { +static u32 group_table[] = { [Group1_80*8 ] = ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
@@ -297,7 +297,7 @@ static u16 group_table[] = { SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp, }; -static u16 group2_table[] = { +static u32 group2_table[] = { [Group7*8 ] = SrcNone | ModRM,0 ,0 ,0 , SrcNone | ModRM | DstMem | Mov,0 ,
Signature · 3 lines
1.6.0.3.514.g2f91b On Mon, 3 Nov 2008 15:42:49 +0100
Quoted 7 lines · Guillaume Thouvenin
This series of patches emulate instructions of shld and shrd instructions. As those instructions have three operands we introduce a decode set for the Src2 operand. By doing this, the opcode descriptor needs to be extend to 32 bit.
So this series of patches:
[1/5] extend the opcode descr
PATCH 2/5 x86_emulator: add Src2 decode set
In reply to Guillaume ThouveninInstruction like shld has three operands, so we need to add a Src2 decode set. We start with Src2None, Src2CL, and Src2ImmByte, Src2One to support shld/shrd and we will expand it later.
--- arch/x86/include/asm/kvm_x86_emulate.h | 1 + arch/x86/kvm/x86_emulate.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 0 deletions(-)
arch/x86/include/asm/kvm_x86_emulate.h +1 -0
@@ -123,6 +123,7 @@ struct decode_cache {u8 ad_bytes;u8 rex_prefix;struct operand src; +struct operand src2;struct operand dst;bool has_seg_override;u8 seg_override;
arch/x86/kvm/x86_emulate.c +29 -0
@@ -70,6 +70,12 @@#define Group (1<<14)/* Bits 3:5 of modrm byte extend opcode */ #define GroupDual (1<<15)/* Alternate decoding of mod == 3 */ #define GroupMask 0xff/* Group number stored in bits 0:7 */ +/* Source 2 operand type */ +#define Src2None (0<<29) +#define Src2CL (1<<29) +#define Src2ImmByte (2<<29) +#define Src2One (3<<29) +#define Src2Mask (7<<29)enum { Group1_80, Group1_81, Group1_82, Group1_83,
@@ -1043,6 +1049,29 @@ done_prefixes:break ; } +/* +* Decode and fetch the second source operand: register, memory +* or immediate. +*/ +switch (c->d & Src2Mask) { +case Src2None: +break ; +case Src2CL: + c->src2.bytes =1 ; + c->src2.val = c->regs[VCPU_REGS_RCX ] &0x8 ; +break ; +case Src2ImmByte: + c->src2.type =OP_IMM ; + c->src2.ptr = (unsigned long *)c->eip; + c->src2.bytes =1 ; + c->src2.val =insn_fetch (u8,1 , c->eip); +break ; +case Src2One: + c->src2.bytes =1 ; + c->src2.val =1 ; +break ; + } +/* Decode and fetch the destination operand: register or memory. */ switch (c->d & DstMask) {case ImplicitOps:
Signature · 1 line
1.6.0.3.514.g2f91b
PATCH 3/5 x86_emulator: add a new "implied 1" Src decode type
In reply to Guillaume ThouveninAdd SrcOne operand type when we need to decode an
implied '1' like with regular shift instruction
--- arch/x86/kvm/x86_emulate.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
arch/x86/kvm/x86_emulate.c +5 -0
@@ -58,6 +58,7 @@#define SrcMem32 (4<<4)/* Memory operand (32-bit). */ #define SrcImm (5<<4)/* Immediate operand. */ #define SrcImmByte (6<<4)/* 8-bit sign-extended immediate operand. */ +#define SrcOne (7<<4)/* Implied '1' */ #define SrcMask (7<<4)/* Generic ModRM decode. */ #define ModRM (1<<7)
@@ -1047,6 +1048,10 @@ done_prefixes: c->src.bytes =1 ; c->src.val =insn_fetch (s8,1 , c->eip);break ; +case SrcOne: + c->src.bytes =1 ; + c->src.val =1 ; +break ; }/*
Signature · 1 line
1.6.0.3.514.g2f91b
PATCH 4/5 x86_emulator: add the assembler code for three operands
In reply to Guillaume ThouveninAdd the assembler code for three operands
--- arch/x86/kvm/x86_emulate.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)
arch/x86/kvm/x86_emulate.c +29 -0
@@ -366,6 +366,35 @@ static u32 group2_table[] = {"andl %" _msk",%" _LO32 _tmp"; " \"orl %" _LO32 _tmp",%" _sav"; " +/* Instruction has three operands */ +/* In the switch we only implement case 4 because we know that for shld instruction +* bytes are equal to 4. When eveything will be fine, we will add others cases. + */ +#define __emulate_3op (_op,_src,_src2,_dst,_eflags,_by,_bx,_wx,_wy,_lx,_ly,_qx,_qy) \ + do { \ + unsigned long _tmp; \ + \ + switch((_dst).bytes) { \ + case 4: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op" %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _ly ((_src).val) , _ly ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + break; \ + default: \ + printk(KERN_INFO "__emulate_3op: case need to be added \n"); \ + } \ + } while (0) + +#define emulate_3op (_op, _src, _src2, _dst, _eflags) \ + __emulate_3op(_op, _src, _src2, _dst, _eflags, \ + "b", "c", "b", "c", "b", "r", "b", "c") +/* Raw emulation: instruction has two explicit operands. */ #define __emulate_2op_nobyte (_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ do { \
Signature · 1 line
1.6.0.3.514.g2f91b
Re: [Patch 4/5] x86_emulator: add the assembler code for three operands
arch/x86/kvm/x86_emulate.c static u32 group2_table[] = { · line 371
Quoted 7 lines · Guillaume Thouvenin
Add the assembler code for three operands
arch/x86/kvm/x86_emulate.c +3
-0+/* Instruction has three operands */ +/* In the switch we only implement case 4 because we know that for shld instruction +* bytes are equal to 4. When eveything will be fine, we will add others cases.
No, shld is defined for 16, 32, and 64 bit operands. Need to implement those too.
Quoted 1 line
+#define
__emulate_3op(_op,_src,_src2,_dst,_eflags,_by,_bx,_wx,_wy,_lx,_ly,_qx,_qy)\
Since this is not a generic 3 operand implementation, it's better to call this something like __emulate_2op_cl() to give attention to this fact.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Patch 4/5] x86_emulator: add the assembler code for three operands
Quoted 11 lines · On Tue, 04 Nov 2008 12:21:30 +0200 Avi Kivity <[email protected]> wrote:
arch/x86/kvm/x86_emulate.c static u32 group2_table[] = { · line 371
Quoted 7 lines · Guillaume Thouvenin
Add the assembler code for three operands
arch/x86/kvm/x86_emulate.c +3
-0+/* Instruction has three operands */ +/* In the switch we only implement case 4 because we know that for shld instruction +* bytes are equal to 4. When eveything will be fine, we will add others cases. No, shld is defined for 16, 32, and 64 bit operands. Need to implement those too.
I tried something like:
+/* Instruction has three operands */
+/* In the switch we only implement case 4 because we know that for shld instruction
+ * bytes are equal to 4. When eveything will be fine, we will add others cases.
+ */
+#define __emulate_2op_cl(_op,_src,_src2,_dst,_eflags,_by,_bx,_wx,_wy,_lx,_ly,_qx,_qy) \
+ do { \
+ unsigned long _tmp; \
+ \
+ switch((_dst).bytes) { \
+ case 2: \
+ __asm__ __volatile__ ( \
+ _PRE_EFLAGS("0", "5", "2") \
+ "mov %4, %%rcx \n\t" \
+ _op"w %%cl,%3,%1; \n\t" \
+ _POST_EFLAGS("0", "5", "2") \
+ : "=m" (_eflags), "=m" ((_dst).val), \
+ "=&r" (_tmp) \
+ : _wy ((_src).val) , _wy ((_src2).val), "i" (EFLAGS_MASK) \
+ : "%rcx" ); \
+ break; \
+ case 4: \
+ __asm__ __volatile__ ( \
+ _PRE_EFLAGS("0", "5", "2") \
+ "mov %4, %%rcx \n\t" \
+ _op"l %%cl,%3,%1; \n\t" \
+ _POST_EFLAGS("0", "5", "2") \
+ : "=m" (_eflags), "=m" ((_dst).val), \
+ "=&r" (_tmp) \
+ : _ly ((_src).val) , _ly ((_src2).val), "i" (EFLAGS_MASK) \
+ : "%rcx" ); \
+ break; \
+ case 8: \
+ __asm__ __volatile__ ( \
+ _PRE_EFLAGS("0", "5", "2") \
+ "mov %4, %%rcx \n\t" \
+ _op"q %%cl,%3,%1; \n\t" \
+ _POST_EFLAGS("0", "5", "2") \
+ : "=m" (_eflags), "=m" ((_dst).val), \
+ "=&r" (_tmp) \
+ : _ly ((_src).val) , _ly ((_src2).val), "i" (EFLAGS_MASK) \
+ : "%rcx" ); \
+ break; \+ } \
+ } while (0)
+
+#define emulate_2op_cl(_op, _src, _src2, _dst, _eflags) \
+ __emulate_2op_cl(_op, _src, _src2, _dst, _eflags, \
+ "b", "r", "b", "r", "b", "r", "b", "r")
+
but it doesn't work because shld can not be used with suffix 'l' or 'w' etc... Is the solution is to have a single case for all operand size like:
+#define __emulate_2op_cl(_op,_src,_src2,_dst,_eflags,_wx,_wy) \
+ do { \
+ unsigned long _tmp; \
+ \
+ __asm__ __volatile__ ( \
+ _PRE_EFLAGS("0", "5", "2") \
+ "mov %4, %%rcx \n\t" \
+ _op" %%cl,%3,%1; \n\t" \
+ _POST_EFLAGS("0", "5", "2") \
+ : "=m" (_eflags), "=m" ((_dst).val), \+ "=&r" (_tmp) \
+ : _wy ((_src).val) , _wy ((_src2).val), "i" (EFLAGS_MASK) \
+ : "%rcx" ); \
+ } while (0)
I tested the code and it seems to work.
Excuse me for the delay of this answer,
Regards,
Guillaume
Re: [Patch 4/5] x86_emulator: add the assembler code for three operands
Quoted 69 lines · Guillaume Thouvenin
Quoted 5 lines · On Tue, 04 Nov 2008 12:21:30 +0200 Avi Kivity <[email protected]> wrote:
Quoted 3 lines · Guillaume Thouvenin
Add the assembler code for three operands
Quoted 7 lines
arch/x86/kvm/x86_emulate.c static u32 group2_table[] = { · line 371
Quoted 5 lines
arch/x86/kvm/x86_emulate.c +3
-0+/* Instruction has three operands */ +/* In the switch we only implement case 4 because we know that for shld instruction +* bytes are equal to 4. When eveything will be fine, we will add others cases. No, shld is defined for 16, 32, and 64 bit operands. Need to implement those too.
I tried something like:
(quoted diff) +49
-0+/* Instruction has three operands */ +/* In the switch we only implement case 4 because we know that for shld instruction + * bytes are equal to 4. When eveything will be fine, we will add others cases. + */ +#define __emulate_2op_cl(_op,_src,_src2,_dst,_eflags,_by,_bx,_wx,_wy,_lx,_ly,_qx,_qy) \ + do { \ + unsigned long _tmp; \ + \ + switch((_dst).bytes) { \ + case 2: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op"w %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _wy ((_src).val) , _wy ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + break; \ + case 4: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op"l %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _ly ((_src).val) , _ly ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + break; \ + case 8: \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op"q %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _ly ((_src).val) , _ly ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + break; \ + } \ + } while (0) + +#define emulate_2op_cl(_op, _src, _src2, _dst, _eflags) \ + __emulate_2op_cl(_op, _src, _src2, _dst, _eflags, \ + "b", "r", "b", "r", "b", "r", "b", "r") +
Quoted 4 lines
but it doesn't work because shld can not be used with suffix 'l' or 'w' etc... Is the solution is to have a single case for all operand size like:
It does work, perhaps the variables were defined with the wrong size.
This works:
int shld(void)
{
unsigned short w1 = 3, w2 = 5; unsigned int l1 = 3, l2 = 5; unsigned long q1 = 3, q2 = 5;
asm("shldw %1, %0" : "+r"(w1) : "r"(w2)); asm("shldl %1, %0" : "+r"(l1) : "r"(l2)); asm("shldq %1, %0" : "+r"(q1) : "r"(q2));
return w1 + l1 + q1;
}
Quoted 15 lines
arch/x86/kvm/x86_emulate.c +14
-0+#define __emulate_2op_cl (_op,_src,_src2,_dst,_eflags,_wx,_wy) \ + do { \ + unsigned long _tmp; \ + \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op" %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _wy ((_src).val) , _wy ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + } while (0)
Quoted 2 lines
I tested the code and it seems to work.
That's actually better and could be used for the other emulations. Please disassemble x86_emulate.o and verify that there are three different shld instructions, one for each register size.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Patch 4/5] x86_emulator: add the assembler code for three operands
Quoted 17 lines · On Tue, 25 Nov 2008 16:59:00 +0200 Avi Kivity <[email protected]> wrote:
Quoted 17 lines
arch/x86/kvm/x86_emulate.c +14
-0+#define __emulate_2op_cl (_op,_src,_src2,_dst,_eflags,_wx,_wy) \ + do { \ + unsigned long _tmp; \ + \ + __asm__ __volatile__ ( \ + _PRE_EFLAGS("0", "5", "2") \ + "mov %4, %%rcx \n\t" \ + _op" %%cl,%3,%1; \n\t" \ + _POST_EFLAGS("0", "5", "2") \ + : "=m" (_eflags), "=m" ((_dst).val), \ + "=&r" (_tmp) \ + : _wy ((_src).val) , _wy ((_src2).val), "i" (EFLAGS_MASK) \ + : "%rcx" ); \ + } while (0)
Quoted 7 lines
Quoted 2 lines
I tested the code and it seems to work.
That's actually better and could be used for the other emulations. Please disassemble x86_emulate.o and verify that there are three different shld instructions, one for each register size.
I tried with the following code (it's nearly the same as above):
+ __asm__ __volatile__ ( \
+ _PRE_EFLAGS("0", "5", "2") \
+ "mov %4, %%rcx \n\t" \
+ _op" %3,%1; \n\t" \
+ _POST_EFLAGS("0", "5", "2") \
+ : "=m" (_eflags), "+r" ((_dst).val), \
+ "=&r" (_tmp) \+ : _x ((_src).val) , _y ((_src2).val), "i" (EFLAGS_MASK) \
+ : "%rcx" ); \
When I disassemble x86_emulate.o I can see the following produced code:
4787: ...
4788: 41 8f 44 24 08 popq 0x8(%r12)
478d: 48 89 d1 mov %rdx,%rcx
4790: 48 0f a5 f0 shld %cl,%rsi,%rax
4794: 9c pushfq
4795: ... It's the only code with shld instruction. I don't see how you can have three different shld instructions here. I'm sure that I'm missing something here because for me, when we emulate the shld instruction, the code produced is the same. I mean that src.val and dst.val are always unsigned long and I don't see why register size are important here. In fact I don't understand why we need to use the switch ((_dst).bytes) for the other emulations.
Guillaume
Re: [Patch 4/5] x86_emulator: add the assembler code for three operands
Quoted 8 lines · Guillaume Thouvenin
It's the only code with shld instruction. I don't see how you can have three different shld instructions here. I'm sure that I'm missing something here because for me, when we emulate the shld instruction, the code produced is the same. I mean that src.val and dst.val are always unsigned long and I don't see why register size are important here. In fact I don't understand why we need to use the switch ((_dst).bytes) for the other emulations.
The flags vary according to operand size. For example, shld $1, %bx, %ax where %ax == 0x8000 will set eflags.cf, but shld $1, %ebx, %eax , with the same arguments, will not.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [Patch 4/5] x86_emulator: add the assembler code for three operands
In reply to Avi KivityQuoted 3 lines · On Tue, 25 Nov 2008 16:59:00 +0200 Avi Kivity <[email protected]> wrote:
That's actually better and could be used for the other emulations. Please disassemble x86_emulate.o and verify that there are three different shld instructions, one for each register size.
For generating the three shld instructions I need to do the following:
+/* Instruction has three operands like shld */
+#define __emulate_2op_cl(_op,_shift, _src, _dst,_eflags,_suffix) \
+ do { \
+ unsigned long _tmp; \
+ __asm__ __volatile__ ( \
+ _PRE_EFLAGS("0", "5", "2") \
+ _op _suffix" %4,%1 \n\t" \
+ _POST_EFLAGS("0", "5", "2") \
+ : "=m" (_eflags), "+r" (_dst), \
+ "=&r" (_tmp) \
+ : "c" (_shift) , "r" (_src), "i" (EFLAGS_MASK) \
+ ); \
+ } while (0)
+
+#define emulate_2op_cl(_op, _shift, _src, _dst, _eflags) \
+ do { \
+ switch ((_dst).bytes) { \
+ case 2: { \
+ unsigned short shift = (_shift).val; \ + unsigned short src = (_src).val; \ + unsigned short dst = (_dst).val; \
+ __emulate_2op_cl(_op,shift, src,dst,_eflags,"w"); \
+ break; \
+ } \
+ case 4: { \
+ unsigned int shift = (_shift).val; \ + unsigned int src = (_src).val; \ + unsigned int dst = (_dst).val; \
+ __emulate_2op_cl(_op,shift, src,dst,_eflags,"l"); \
+ break; \
+ } \
+ case 8: { \
+ unsigned long shift = (_shift).val; \ + unsigned long src = (_src).val; \ + unsigned long dst = (_dst).val; \
+ ON64(__emulate_2op_cl(_op,shift, src,dst,_eflags,"q")); \
+ break; \
+ } \
+ } \
+ } while (0)
+
Otherwise the code for "case 4:" cannot be generated. I've got:
Error: Incorrect register %rax' used with l' suffix
Is it correct? If yes I will repost patches that emulate shld/shrd instructions.
Guillaume
PATCH 5/5 x86_emulator: add the emulation of shld and shrd instructions
In reply to Guillaume ThouveninAdd emulation of shld and shrd instructions
--- arch/x86/kvm/x86_emulate.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-)
arch/x86/kvm/x86_emulate.c +15 -2
@@ -237,9 +237,14 @@ static u32 twobyte_table[256] = {/* 0x90 - 0x9F */ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,/* 0xA0 - 0xA7 */ -0 ,0 ,0 , DstMem | SrcReg | ModRM | BitOp,0 ,0 ,0 ,0 , +0 ,0 ,0 , DstMem | SrcReg | ModRM | BitOp, + DstMem | SrcReg | Src2ImmByte | ModRM, + DstMem | SrcReg | Src2CL | ModRM,0 ,0 ,/* 0xA8 - 0xAF */ -0 ,0 ,0 , DstMem | SrcReg | ModRM | BitOp,0 ,0 , ModRM,0 , +0 ,0 ,0 , DstMem | SrcReg | ModRM | BitOp, + DstMem | SrcReg | Src2ImmByte | ModRM, + DstMem | SrcReg | Src2CL | ModRM, + ModRM,0 ,/* 0xB0 - 0xB7 */ ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,0 , DstMem | SrcReg | ModRM | BitOp,
@@ -2056,12 +2061,20 @@ twobyte_insn: c->src.val &= (c->dst.bytes <<3 ) -1 ;emulate_2op_SrcV_nobyte ("bt" , c->src, c->dst, ctxt->eflags);break ; +case 0xa4 :/* shld imm8, r, r/m */ +case 0xa5 :/* shld cl, r, r/m */ +emulate_3op ("shld" , c->src, c->src2, c->dst, ctxt->eflags); +break ;case 0xab : bts:/* bts */ /* only subword offset */ c->src.val &= (c->dst.bytes <<3 ) -1 ;emulate_2op_SrcV_nobyte ("bts" , c->src, c->dst, ctxt->eflags);break ; +case 0xac :/* shrd imm8, r, r/m */ +case 0xad :/* shrd cl, r, r/m */ +emulate_3op ("shrd" , c->src, c->src2, c->dst, ctxt->eflags); +break ;case 0xae :/* clflush */ break ; case 0xb0 ... 0xb1: /* cmpxchg */
Signature · 1 line
1.6.0.3.514.g2f91b
Quoted 5 lines · Guillaume Thouvenin
This series of patches emulate instructions shld and shrd. As those instructions have three operands we introduce a decode set for the Src2 operand. By doing this, the opcode descriptor needs to be extend to 32 bit.
Other than the missing operand sizes, looks good.
Signature · 1 line
error compiling committee.c: too many arguments to function