From a781322552d9fb52b7b5e51641f49f12678f682f Mon Sep 17 00:00:00 2001 From: iximeow Date: Thu, 1 Jul 2021 23:54:06 -0700 Subject: reallocate OperandCode, convert disparate registers to array also remove redundant assignments of operand_count and some OperandSpec, bulk-assign all registers and operands on entry to `read_instr`. this all, taken together, shaves off about 7 cycles per decode. --- src/protected_mode/vex.rs | 210 +++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 105 deletions(-) (limited to 'src/protected_mode/vex.rs') diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index 2f871c6..235d160 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -117,7 +117,7 @@ pub(crate) fn three_byte_vex::Address, > 3) & 0b1111) ^ 0b1111, }; @@ -125,7 +125,7 @@ pub(crate) fn three_byte_vex::Address, ::Address, VEXOpcodePrefix::PrefixF2, _ => { unreachable!("p is two bits"); } }; - instruction.vex_reg = RegSpec { + instruction.regs[3] = RegSpec { bank: RegisterBank::X, num: ((vex_byte >> 3) & 0b1111) ^ 0b1111, }; @@ -146,7 +146,7 @@ pub(crate) fn two_byte_vex::Address, ::Address, ::Address, ::Address, ::Address, ::Address, ::Address, ::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -362,7 +362,7 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } @@ -380,7 +380,7 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[2] = OperandSpec::RegRRR; @@ -391,7 +391,7 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } @@ -415,7 +415,7 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::X); instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -431,7 +431,7 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::X); instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -444,12 +444,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E(words, instruction, modrm, 4)?; instruction.operands[0] = mem_oper; @@ -477,12 +477,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E(words, instruction, modrm, 4)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -494,12 +494,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E(words, instruction, modrm, 4)?; instruction.operands[0] = mem_oper; @@ -511,16 +511,16 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); - let mem_oper = read_E(words instruction, modrm, 4)?; + let mem_oper = read_E(words, instruction, modrm, 4)?; if let OperandSpec::RegMMM = mem_oper { - instruction.modrm_mmm.bank = RegisterBank::X; + instruction.regs[1].bank = RegisterBank::X; } else { instruction.mem_size = 4; } @@ -530,16 +530,16 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); let mem_oper = read_E(words, instruction, modrm, 4)?; if let OperandSpec::RegMMM = mem_oper { - instruction.modrm_mmm.bank = RegisterBank::X; + instruction.regs[1].bank = RegisterBank::X; } else { instruction.mem_size = 8; } @@ -550,12 +550,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; match (op, mem_oper) { @@ -583,12 +583,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); let mem_oper = read_E_xmm(words, instruction, modrm)?; if mem_oper != OperandSpec::RegMMM { @@ -600,12 +600,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); let mem_oper = read_E_ymm(words, instruction, modrm)?; if mem_oper != OperandSpec::RegMMM { @@ -617,12 +617,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); let mem_oper = read_E_xmm(words, instruction, modrm)?; if mem_oper != OperandSpec::RegMMM { @@ -636,12 +636,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = mem_oper; @@ -655,12 +655,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = mem_oper; @@ -675,12 +675,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); let mem_oper = read_E_xmm(words, instruction, modrm)?; if mem_oper != OperandSpec::RegMMM { @@ -692,12 +692,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D); let mem_oper = read_E_ymm(words, instruction, modrm)?; if mem_oper != OperandSpec::RegMMM { @@ -712,7 +712,7 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } @@ -730,7 +730,7 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -748,12 +748,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -765,12 +765,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -783,7 +783,7 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } @@ -793,7 +793,7 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::Y); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -811,12 +811,12 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y); let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -830,7 +830,7 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } @@ -844,7 +844,7 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::Y); let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = mem_oper; @@ -858,7 +858,7 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { instruction.opcode = Opcode::Invalid; return Err(DecodeError::InvalidOperand); } @@ -872,7 +872,7 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::Y); let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -891,9 +891,9 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::Y); - instruction.vex_reg.bank = RegisterBank::Y; + instruction.regs[3].bank = RegisterBank::Y; let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -906,9 +906,9 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y); - instruction.vex_reg.bank = RegisterBank::Y; + instruction.regs[3].bank = RegisterBank::Y; let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -926,9 +926,9 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::Y); - instruction.vex_reg.bank = RegisterBank::Y; + instruction.regs[3].bank = RegisterBank::Y; let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = mem_oper; instruction.operands[1] = OperandSpec::RegVex; @@ -944,7 +944,7 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -962,7 +962,7 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -982,7 +982,7 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E(words, instruction, modrm, 4)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -996,7 +996,7 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1012,9 +1012,9 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y); - instruction.vex_reg.bank = RegisterBank::Y; + instruction.regs[3].bank = RegisterBank::Y; let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -1033,7 +1033,7 @@ fn read_vex_operands::Address, > 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = mem_oper; @@ -1048,10 +1048,10 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; - instruction.sib_index.bank = RegisterBank::X; + instruction.regs[2].bank = RegisterBank::X; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; instruction.operands[2] = OperandSpec::RegVex; @@ -1063,11 +1063,11 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_ymm(words, instruction, modrm)?; - instruction.vex_reg.bank = RegisterBank::X; - instruction.sib_index.bank = RegisterBank::Y; + instruction.regs[3].bank = RegisterBank::X; + instruction.regs[2].bank = RegisterBank::Y; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; instruction.operands[2] = OperandSpec::RegVex; @@ -1079,11 +1079,11 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y); let mem_oper = read_E_ymm(words, instruction, modrm)?; - instruction.vex_reg.bank = RegisterBank::Y; - instruction.sib_index.bank = RegisterBank::Y; + instruction.regs[3].bank = RegisterBank::Y; + instruction.regs[2].bank = RegisterBank::Y; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; instruction.operands[2] = OperandSpec::RegVex; @@ -1100,9 +1100,9 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; let (opwidth, bank) = (4, RegisterBank::D); - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, bank); - instruction.vex_reg.bank = bank; + instruction.regs[3].bank = bank; let mem_oper = read_E(words, instruction, modrm, opwidth)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -1116,9 +1116,9 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; let (opwidth, bank) = (4, RegisterBank::D); - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, bank); - instruction.vex_reg.bank = bank; + instruction.regs[3].bank = bank; let mem_oper = read_E(words, instruction, modrm, opwidth)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = mem_oper; @@ -1132,7 +1132,7 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; let (opwidth, bank) = (4, RegisterBank::D); - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, bank); let mem_oper = read_E(words, instruction, modrm, opwidth)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1163,7 +1163,7 @@ fn read_vex_operands::Address, > 3) & 7, bank); let mem_oper = read_E(words, instruction, modrm, opwidth)?; instruction.operands[0] = OperandSpec::RegVex; @@ -1172,7 +1172,7 @@ fn read_vex_operands::Address, { @@ -1201,11 +1201,11 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1219,11 +1219,11 @@ fn read_vex_operands::Address, { - if instruction.vex_reg.num != 0 { + if instruction.regs[3].num != 0 { return Err(DecodeError::InvalidOperand); } let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y); let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; @@ -1238,9 +1238,9 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y); - instruction.vex_reg.bank = RegisterBank::Y; + instruction.regs[3].bank = RegisterBank::Y; let mem_oper = read_E_ymm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -1255,9 +1255,9 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); - instruction.vex_reg.bank = RegisterBank::X; + instruction.regs[3].bank = RegisterBank::X; let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -1272,9 +1272,9 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y); - instruction.vex_reg.bank = RegisterBank::Y; + instruction.regs[3].bank = RegisterBank::Y; let mem_oper = read_E_xmm(words, instruction, modrm)?; instruction.operands[0] = OperandSpec::RegRRR; instruction.operands[1] = OperandSpec::RegVex; @@ -1287,9 +1287,9 @@ fn read_vex_operands::Address, { let modrm = read_modrm(words)?; - instruction.modrm_rrr = + instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X); - instruction.vex_reg.bank = RegisterBank::X; + instruction.regs[3].bank = RegisterBank::X; // TODO: but the memory access is word-sized let mem_oper = read_E(words, instruction, modrm, 4)?; instruction.operands[0] = OperandSpec::RegRRR; -- cgit v1.1