All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: Will Deacon <will.deacon@arm.com>
Cc: Christoffer Dall <c.dall@virtualopensystems.com>,
	"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	dave.martin@linaro.org, Rusty Russell <rusty.russell@linaro.org>
Subject: [PATCH 01/10] kvm: split out instruction structure from decoding method.
Date: Wed, 24 Oct 2012 21:55:14 +1030	[thread overview]
Message-ID: <1351077923-17977-2-git-send-email-rusty@rustcorp.com.au> (raw)
In-Reply-To: <1351077923-17977-1-git-send-email-rusty@rustcorp.com.au>

From: Rusty Russell <rusty.russell@linaro.org>

Add a new 'struct arm_insn' to represent the decoded instruction; the
decoding logic belong in a separate structure (arm_decode).

Signed-off-by: Rusty Russell <rusty.russell@linaro.org>
---
 arch/arm/kvm/emulate.c |  120 +++++++++++++++++++++++++++---------------------
 1 file changed, 68 insertions(+), 52 deletions(-)

diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c
index 30124cb..e4fc12b 100644
--- a/arch/arm/kvm/emulate.c
+++ b/arch/arm/kvm/emulate.c
@@ -288,34 +288,37 @@ out:
 /******************************************************************************
  * Load-Store instruction emulation
  *****************************************************************************/
+enum SRType {
+	SRType_LSL,
+	SRType_LSR,
+	SRType_ASR,
+	SRType_ROR,
+	SRType_RRX
+};
 
-struct arm_instr {
-	/* Instruction decoding */
-	u32 opc;
-	u32 opc_mask;
-
+struct arm_insn {
 	/* Decoding for the register write back */
 	bool register_form;
 	u32 imm;
-	u8 Rm;
 	u8 type;
+	u8 Rt, Rn, Rm;
 	u8 shift_n;
 
 	/* Common decoding */
 	u8 len;
 	bool sign_extend;
 	bool w;
+};
+
+struct arm_decode {
+	/* Instruction decoding */
+	u32 opc;
+	u32 opc_mask;
 
 	bool (*decode)(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
-		       unsigned long instr, struct arm_instr *ai);
-};
+		       unsigned long instr, struct arm_insn *ai);
 
-enum SRType {
-	SRType_LSL,
-	SRType_LSR,
-	SRType_ASR,
-	SRType_ROR,
-	SRType_RRX
+	struct arm_insn template;
 };
 
 /* Modelled after DecodeImmShift() in the ARM ARM */
@@ -383,7 +386,7 @@ u32 shift(u32 value, u8 N, enum SRType type, u8 amount, bool carry_in)
 }
 
 static bool decode_arm_wb(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
-			  unsigned long instr, const struct arm_instr *ai)
+			  unsigned long instr, const struct arm_insn *ai)
 {
 	u8 Rt = (instr >> 12) & 0xf;
 	u8 Rn = (instr >> 16) & 0xf;
@@ -431,7 +434,7 @@ static bool decode_arm_wb(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
 }
 
 static bool decode_arm_ls(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
-			  unsigned long instr, struct arm_instr *ai)
+			  unsigned long instr, struct arm_insn *ai)
 {
 	u8 A = (instr >> 25) & 1;
 
@@ -449,7 +452,7 @@ static bool decode_arm_ls(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
 }
 
 static bool decode_arm_extra(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
-			     unsigned long instr, struct arm_instr *ai)
+			     unsigned long instr, struct arm_insn *ai)
 {
 	mmio->is_write = ai->w;
 	mmio->len = ai->len;
@@ -476,56 +479,69 @@ static bool decode_arm_extra(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
  * loads and stores as their encodings mandate the W bit set and the P bit
  * clear.
  */
-static const struct arm_instr arm_instr[] = {
+static const struct arm_decode arm_decode[] = {
 	/**************** Load/Store Word and Byte **********************/
 	/* Store word with writeback */
-	{ .opc = 0x04000000, .opc_mask = 0x0c500000, .len = 4, .w = true,
-		.sign_extend = false, .decode = decode_arm_ls },
+	{ .opc = 0x04000000, .opc_mask = 0x0c500000,
+	  .decode = decode_arm_ls,
+	  .template =  { .len = 4, .w = true, .sign_extend = false, }, },
 	/* Store byte with writeback */
-	{ .opc = 0x04400000, .opc_mask = 0x0c500000, .len = 1, .w = true,
-		.sign_extend = false, .decode = decode_arm_ls },
+	{ .opc = 0x04400000, .opc_mask = 0x0c500000,
+	  .decode = decode_arm_ls,
+	  .template = {  .len = 1, .w = true, .sign_extend = false, }, },
 	/* Load word with writeback */
-	{ .opc = 0x04100000, .opc_mask = 0x0c500000, .len = 4, .w = false,
-		.sign_extend = false, .decode = decode_arm_ls },
+	{ .opc = 0x04100000, .opc_mask = 0x0c500000,
+	  .decode = decode_arm_ls,
+	  .template = {  .len = 4, .w = false, .sign_extend = false, }, },
 	/* Load byte with writeback */
-	{ .opc = 0x04500000, .opc_mask = 0x0c500000, .len = 1, .w = false,
-		.sign_extend = false, .decode = decode_arm_ls },
+	{ .opc = 0x04500000, .opc_mask = 0x0c500000,
+	  .decode = decode_arm_ls,
+	  .template = { .len = 1, .w = false, .sign_extend = false, }, },
 
 	/*************** Extra load/store instructions ******************/
 
 	/* Store halfword with writeback */
-	{ .opc = 0x000000b0, .opc_mask = 0x0c1000f0, .len = 2, .w = true,
-		.sign_extend = false, .decode = decode_arm_extra },
+	{ .opc = 0x000000b0, .opc_mask = 0x0c1000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 2, .w = true, .sign_extend = false, }, },
 	/* Load halfword with writeback */
-	{ .opc = 0x001000b0, .opc_mask = 0x0c1000f0, .len = 2, .w = false,
-		.sign_extend = false, .decode = decode_arm_extra },
-
+	{ .opc = 0x001000b0, .opc_mask = 0x0c1000f0, 
+	  .decode = decode_arm_extra,
+	  .template = { .len = 2, .w = false, .sign_extend = false, }, },
 	/* Load dual with writeback */
-	{ .opc = 0x000000d0, .opc_mask = 0x0c1000f0, .len = 8, .w = false,
-		.sign_extend = false, .decode = decode_arm_extra },
+	{ .opc = 0x000000d0, .opc_mask = 0x0c1000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 8, .w = false, .sign_extend = false, }, },
 	/* Load signed byte with writeback */
-	{ .opc = 0x001000d0, .opc_mask = 0x0c1000f0, .len = 1, .w = false,
-		.sign_extend = true,  .decode = decode_arm_extra },
+	{ .opc = 0x001000d0, .opc_mask = 0x0c1000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 1, .w = false, .sign_extend = true, }, },
 
 	/* Store dual with writeback */
-	{ .opc = 0x000000f0, .opc_mask = 0x0c1000f0, .len = 8, .w = true,
-		.sign_extend = false, .decode = decode_arm_extra },
+	{ .opc = 0x000000f0, .opc_mask = 0x0c1000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 8, .w = true, .sign_extend = false, }, },
 	/* Load signed halfword with writeback */
-	{ .opc = 0x001000f0, .opc_mask = 0x0c1000f0, .len = 2, .w = false,
-		.sign_extend = true,  .decode = decode_arm_extra },
+	{ .opc = 0x001000f0, .opc_mask = 0x0c1000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 2, .w = false, .sign_extend = true, }, },
 
 	/* Store halfword unprivileged */
-	{ .opc = 0x002000b0, .opc_mask = 0x0f3000f0, .len = 2, .w = true,
-		.sign_extend = false, .decode = decode_arm_extra },
+	{ .opc = 0x002000b0, .opc_mask = 0x0f3000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 2, .w = true, .sign_extend = false, }, },
 	/* Load halfword unprivileged */
-	{ .opc = 0x003000b0, .opc_mask = 0x0f3000f0, .len = 2, .w = false,
-		.sign_extend = false, .decode = decode_arm_extra },
+	{ .opc = 0x003000b0, .opc_mask = 0x0f3000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 2, .w = false, .sign_extend = false, }, },
 	/* Load signed byte unprivileged */
-	{ .opc = 0x003000d0, .opc_mask = 0x0f3000f0, .len = 1, .w = false,
-		.sign_extend = true , .decode = decode_arm_extra },
+	{ .opc = 0x003000d0, .opc_mask = 0x0f3000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 1, .w = false, .sign_extend = true, }, },
 	/* Load signed halfword unprivileged */
-	{ .opc = 0x003000d0, .opc_mask = 0x0f3000f0, .len = 2, .w = false,
-		.sign_extend = true , .decode = decode_arm_extra },
+	{ .opc = 0x003000d0, .opc_mask = 0x0f3000f0,
+	  .decode = decode_arm_extra,
+	  .template = { .len = 2, .w = false, .sign_extend = true, }, },
 };
 
 static bool kvm_decode_arm_ls(struct kvm_vcpu *vcpu, unsigned long instr,
@@ -533,11 +549,11 @@ static bool kvm_decode_arm_ls(struct kvm_vcpu *vcpu, unsigned long instr,
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(arm_instr); i++) {
-		const struct arm_instr *ai = &arm_instr[i];
-		if ((instr & ai->opc_mask) == ai->opc) {
-			struct arm_instr ai_copy = *ai;
-			return ai->decode(vcpu, mmio, instr, &ai_copy);
+	for (i = 0; i < ARRAY_SIZE(arm_decode); i++) {
+		const struct arm_decode *d = &arm_decode[i];
+		if ((instr & d->opc_mask) == d->opc) {
+			struct arm_insn ai = d->template;
+			return d->decode(vcpu, mmio, instr, &ai);
 		}
 	}
 	return false;
-- 
1.7.10.4


  reply	other threads:[~2012-10-24 11:29 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-05  7:58 [PATCH 0/3] KVM_VCPU_GET_REG_LIST API Rusty Russell
2012-09-05  7:58 ` [PATCH 1/3] KVM: Move KVM_SET_ONE_REG/KVM_GET_ONE_REG to generic code Rusty Russell
2012-09-19 14:17   ` Alexander Graf
2012-09-05  7:58 ` [PATCH 2/3] KVM: Add KVM_REG_SIZE() helper Rusty Russell
2012-09-19 14:18   ` Alexander Graf
2012-09-05  7:58 ` [PATCH 3/3] KVM: Add KVM_VCPU_GET_REG_LIST/KVM_CAP_REG_LIST Rusty Russell
2012-09-19 14:22   ` Alexander Graf
2012-10-10 18:12   ` Marcelo Tosatti
2012-10-11  8:11     ` Rusty Russell
2012-10-18 14:45 ` [PATCH 0/3] KVM_VCPU_GET_REG_LIST API Avi Kivity
2012-10-19  0:36   ` Rusty Russell
2012-10-19  6:19     ` Rusty Russell
2012-10-19 16:06       ` Christoffer Dall
2012-10-22  3:09         ` Rusty Russell
2012-10-22 17:45           ` Will Deacon
2012-10-22 18:11             ` Christoffer Dall
2012-10-24 11:25             ` RFC: Move kvm's instruction decoding into generic code Rusty Russell
2012-10-24 11:25               ` Rusty Russell [this message]
2012-10-24 11:25               ` [PATCH 02/10] kvm: split out instruction decode from emulation Rusty Russell
2012-10-24 11:25               ` [PATCH 03/10] kvm: split out instruction decode from emulation (thumb instructions) Rusty Russell
2012-10-24 11:25               ` [PATCH 04/10] kvm: completely separate decoding from execution Rusty Russell
2012-10-24 11:25               ` [PATCH 05/10] kvm: move instruction copying inside kvm_decode() Rusty Russell
2012-10-24 11:25               ` [PATCH 06/10] kvm: cleanup use of instr Rusty Russell
2012-10-24 11:25               ` [PATCH 07/10] kvm: clean up use of is_wide_instruction() Rusty Russell
2012-10-24 11:25               ` [PATCH 08/10] kvm: avoid using vcpu_cpsr() by passing down PSR Rusty Russell
2012-10-24 11:25               ` [PATCH 09/10] kvm: avoid reference vcpu->arch.hxfar by making thumb offset_addr relative Rusty Russell
2012-10-24 11:25               ` [PATCH 10/10] opcode: move generic instruction decode out of KVM Rusty Russell
2012-10-24 16:27               ` RFC: Move kvm's instruction decoding into generic code Dave Martin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1351077923-17977-2-git-send-email-rusty@rustcorp.com.au \
    --to=rusty@rustcorp.com.au \
    --cc=c.dall@virtualopensystems.com \
    --cc=dave.martin@linaro.org \
    --cc=kvm@vger.kernel.org \
    --cc=rusty.russell@linaro.org \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.