Skip to contentSkip to conversation

KVM: x86 emulator: add bsf/bsr instruction emulation

PATCH Superseded Wei Yongjun 2 participants 4 messages Aug 9, 2010 – Aug 10, 2010

Subsystems (3)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 KVM: x86 emulator: add bsf/bsr instruction emulation

Add bsf/bsr instruction emulation (opcode 0x0f 0xbc~0xbd)

---
 arch/x86/kvm/emulate.c |   28 ++++++++++++++++++++++++++--
 1 files changed, 26 insertions(+), 2 deletions(-)
arch/x86/kvm/emulate.c +26 -2
index fb4ac8c..831aa6e 100644
@@ -2342,8 +2342,8 @@ static struct opcode twobyte_table[256] = {
 	/* 0xB8 - 0xBF */
 	N, N,
 	G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
-	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
-	    D(DstReg | SrcMem16 | ModRM | Mov),
+	D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xC0 - 0xCF */
 	N, N, N, D(DstMem | SrcReg | ModRM | Mov),
 	N, N, N, GD(0, &group9),
@@ -3464,6 +3464,30 @@ twobyte_insn:
 	      btc:		/* btc */
 		emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags);
 		break;
+	case 0xbc: {		/* bsf */
+		int zf;
+		__asm__ ("bsf %2, %0; setz %b1"
+			 : "=r"(c->dst.val), "=q"(zf)
+			 : "r"(c->src.val), "1" (0));
+		ctxt->eflags &= ~X86_EFLAGS_ZF;
+		if (zf) {
+			ctxt->eflags |= X86_EFLAGS_ZF;
+			c->dst.type = OP_NONE;	/* Disable writeback. */
+		}
+		break;
+	}
+	case 0xbd: {		/* bsr */
+		int zf;
+		__asm__ ("bsr %2, %0; setz %b1"
+			 : "=r"(c->dst.val), "=q"(zf)
+			 : "r"(c->src.val), "1" (0));
+		ctxt->eflags &= ~X86_EFLAGS_ZF;
+		if (zf) {
+			ctxt->eflags |= X86_EFLAGS_ZF;
+			c->dst.type = OP_NONE;	/* Disable writeback. */
+		}
+		break;
+	}
 	case 0xbe ... 0xbf:	/* movsx */
 		c->dst.bytes = c->op_bytes;
 		c->dst.val = (c->d & ByteOp) ? (s8) c->src.val :
Signature · 1 line
1.7.0.4
#1 lore raw

arch/x86/kvm/emulate.c twobyte_insn: · line 3471

Quoted 11 lines · Wei Yongjun

Add bsf/bsr instruction emulation (opcode 0x0f 0xbc~0xbd)

arch/x86/kvm/emulate.c +5 -0
@@ -3464,6 +3464,30 @@ twobyte_insn:
 	      btc:		/* btc */
 		emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags);
 		break;
+	case 0xbc: {		/* bsf */
+		int zf;
+		__asm__ ("bsf %2, %0; setz %b1"
+			 : "=r"(c->dst.val), "=q"(zf)
+			 : "r"(c->src.val), "1" (0));

Won't the high bytes of zf remain clear? Please examine the assembly.

Declaring it u8 is probably better.

Signature · 2 lines
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
#2 lore raw

PATCH v2 1/1 KVM: x86 emulator: add bsf/bsr instruction emulation

Add bsf/bsr instruction emulation (opcode 0x0f 0xbc~0xbd)

---
v1 -> v2: use 'u8 zf' instead of int.

---
 arch/x86/kvm/emulate.c |   28 ++++++++++++++++++++++++++--
 1 files changed, 26 insertions(+), 2 deletions(-)
arch/x86/kvm/emulate.c +26 -2
index 66139ad..7cbcb66 100644
@@ -2381,8 +2381,8 @@ static struct opcode twobyte_table[256] = {
 	/* 0xB8 - 0xBF */
 	N, N,
 	G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
-	N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov),
-	    D(DstReg | SrcMem16 | ModRM | Mov),
+	D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM),
+	D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
 	/* 0xC0 - 0xCF */
 	N, N, N, D(DstMem | SrcReg | ModRM | Mov),
 	N, N, N, GD(0, &group9),
@@ -3500,6 +3500,30 @@ twobyte_insn:
 	      btc:		/* btc */
 		emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags);
 		break;
+	case 0xbc: {		/* bsf */
+		u8 zf;
+		__asm__ ("bsf %2, %0; setz %1"
+			 : "=r"(c->dst.val), "=q"(zf)
+			 : "r"(c->src.val));
+		ctxt->eflags &= ~X86_EFLAGS_ZF;
+		if (zf) {
+			ctxt->eflags |= X86_EFLAGS_ZF;
+			c->dst.type = OP_NONE;	/* Disable writeback. */
+		}
+		break;
+	}
+	case 0xbd: {		/* bsr */
+		u8 zf;
+		__asm__ ("bsr %2, %0; setz %1"
+			 : "=r"(c->dst.val), "=q"(zf)
+			 : "r"(c->src.val));
+		ctxt->eflags &= ~X86_EFLAGS_ZF;
+		if (zf) {
+			ctxt->eflags |= X86_EFLAGS_ZF;
+			c->dst.type = OP_NONE;	/* Disable writeback. */
+		}
+		break;
+	}
 	case 0xbe ... 0xbf:	/* movsx */
 		c->dst.bytes = c->op_bytes;
 		c->dst.val = (c->d & ByteOp) ? (s8) c->src.val :
Signature · 1 line
1.7.0.4
Applied
#3 lore raw
Quoted 2 lines · Wei Yongjun

Add bsf/bsr instruction emulation (opcode 0x0f 0xbc~0xbd)

Applied, thanks.

Signature · 2 lines
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.