Important bugfix: passing the instruction cache entry pointer
does not account for arrays of instructions provided by one virtual instruction trace cache entry -> passing the current instruction directly. ALUInstr not yet completely tested. git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1704 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -1,39 +1,34 @@
|
||||
#ifndef __L4SYS_ALUINSTR_HPP__
|
||||
#define __L4SYS_ALUINSTR_HPP__
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Forward declaration of the Bochs instruction decode table.
|
||||
* This is necessary because, inconveniently, it is not declared in a header file.
|
||||
*/
|
||||
#include "cpu/fetchdecode.h"
|
||||
static const BxOpcodeInfo_t *BxOpcodeInfo32;
|
||||
#endif
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
#include "cpu/instr.h"
|
||||
|
||||
/**
|
||||
* Trying to order X86 ALU instructions.
|
||||
* Each instruction class contains instructions
|
||||
* of roughly equal length and operands, so that
|
||||
* all the bxInstruction_c structures residing within
|
||||
* one class contain the same member fields.
|
||||
* one class contain the same member fields (except for
|
||||
* b1, rm and the execute pointers).
|
||||
*/
|
||||
enum X86AluClass {
|
||||
ALU_UNDEF = 0,
|
||||
ALU_GENERIC,
|
||||
ALU_RM8,
|
||||
ALU_RM16,
|
||||
ALU_RM32,
|
||||
ALU_REG,
|
||||
ALU_IMM8_REG,
|
||||
ALU_IMM16_REG,
|
||||
ALU_IMM32_REG,
|
||||
ALU_IMM8,
|
||||
ALU_IMM16,
|
||||
ALU_IMM32,
|
||||
ALU_IMM8_RM8,
|
||||
ALU_IMM8_RM16,
|
||||
ALU_IMM8_RM32,
|
||||
ALU_IMM16_RM16,
|
||||
ALU_IMM32_RM32,
|
||||
ALU_REG_RM8,
|
||||
ALU_REG_RM16,
|
||||
ALU_REG_RM32
|
||||
ALU_IMM32_RM32
|
||||
};
|
||||
|
||||
/**
|
||||
@ -48,28 +43,32 @@ struct BochsALUInstr {
|
||||
*/
|
||||
Bit16u bochs_operation;
|
||||
/**
|
||||
* the x86 opcode (known as b1 in bxInstruction_c)
|
||||
* the x86 opcode, as stored by Bochs (known as b1 in bxInstruction_c)
|
||||
*/
|
||||
Bit8u opcode;
|
||||
/**
|
||||
* the reg part of the modr/m field (known as "nnn" in bxInstruction_c)
|
||||
* it is used to
|
||||
* a) further subdivide the functionality of a given opcode
|
||||
* b) specify a register the instruction is supposed to use
|
||||
* In this class, a value of 8 or higher marks this field unused.
|
||||
* a) further subdivide the functionality of a given opcode (reg < REG_COUNT)
|
||||
* b) specify a register the instruction is supposed to use (reg = REG_COUNT)
|
||||
* In this class, a value greater than REG_COUNT marks this field unused.
|
||||
*/
|
||||
Bit8u reg;
|
||||
/**
|
||||
* the register offset of the instruction byte of this instruction
|
||||
* Some x86 instructions, like INC register, add a register offset
|
||||
* to their opcode. This offset is stored as "rm" in bxInstruction_c.
|
||||
* In this class, a value of 8 or higher marks this field unused.
|
||||
* In this class, a value greater than REG_COUNT marks this field unused.
|
||||
*/
|
||||
Bit8u opcodeRegisterOffset;
|
||||
/**
|
||||
* the ALU class this instruction belongs to
|
||||
*/
|
||||
X86AluClass aluClass;
|
||||
/**
|
||||
* the count of registers
|
||||
*/
|
||||
static const unsigned REG_COUNT = 8;
|
||||
};
|
||||
|
||||
|
||||
@ -86,43 +85,54 @@ const BochsALUInstr aluInstructions [] = {
|
||||
/* --- /// UNARY OPERATIONS \\\ --- */
|
||||
|
||||
// 8-bit
|
||||
{ BX_IA_INC_Eb, 0xFE, 0, 8, ALU_RM8},
|
||||
{ BX_IA_DEC_Eb, 0xFE, 1, 8, ALU_RM8},
|
||||
{ BX_IA_NOT_Eb, 0xF6, 2, 8, ALU_RM8},
|
||||
{ BX_IA_NEG_Eb, 0xF6, 3, 8, ALU_RM8},
|
||||
{ BX_IA_INC_Eb, 0xFE, 0, BochsALUInstr::REG_COUNT + 1, ALU_RM8},
|
||||
{ BX_IA_DEC_Eb, 0xFE, 1, BochsALUInstr::REG_COUNT + 1, ALU_RM8},
|
||||
{ BX_IA_NOT_Eb, 0xF6, 2, BochsALUInstr::REG_COUNT + 1, ALU_RM8},
|
||||
{ BX_IA_NEG_Eb, 0xF6, 3, BochsALUInstr::REG_COUNT + 1, ALU_RM8},
|
||||
|
||||
// 16-bit
|
||||
{ BX_IA_INC_Ew, 0xFF, 0, 8, ALU_RM16},
|
||||
{ BX_IA_DEC_Ew, 0xFF, 1, 8, ALU_RM16},
|
||||
{ BX_IA_NOT_Ew, 0xF7, 2, 8, ALU_RM16},
|
||||
{ BX_IA_NEG_Ew, 0xF7, 3, 8, ALU_RM16},
|
||||
{ BX_IA_INC_Ew, 0xFF, 0, BochsALUInstr::REG_COUNT + 1, ALU_RM16},
|
||||
{ BX_IA_DEC_Ew, 0xFF, 1, BochsALUInstr::REG_COUNT + 1, ALU_RM16},
|
||||
{ BX_IA_NOT_Ew, 0xF7, 2, BochsALUInstr::REG_COUNT + 1, ALU_RM16},
|
||||
{ BX_IA_NEG_Ew, 0xF7, 3, BochsALUInstr::REG_COUNT + 1, ALU_RM16},
|
||||
|
||||
// 32-bit
|
||||
{ BX_IA_INC_Ed, 0xFF, 0, 8, ALU_RM32},
|
||||
{ BX_IA_DEC_Ed, 0xFF, 1, 8, ALU_RM32},
|
||||
{ BX_IA_NOT_Ed, 0xF7, 2, 8, ALU_RM32},
|
||||
{ BX_IA_NEG_Ed, 0xF7, 3, 8, ALU_RM32},
|
||||
{ BX_IA_INC_Ed, 0xFF, 0, BochsALUInstr::REG_COUNT + 1, ALU_RM32},
|
||||
{ BX_IA_DEC_Ed, 0xFF, 1, BochsALUInstr::REG_COUNT + 1, ALU_RM32},
|
||||
{ BX_IA_NOT_Ed, 0xF7, 2, BochsALUInstr::REG_COUNT + 1, ALU_RM32},
|
||||
{ BX_IA_NEG_Ed, 0xF7, 3, BochsALUInstr::REG_COUNT + 1, ALU_RM32},
|
||||
|
||||
// register
|
||||
{ BX_IA_INC_RX, 0x40, 8, 7, ALU_REG},
|
||||
{ BX_IA_DEC_RX, 0x48, 8, 7, ALU_REG},
|
||||
{ BX_IA_INC_ERX, 0x40, 8, 7, ALU_REG},
|
||||
{ BX_IA_DEC_ERX, 0x48, 8, 7, ALU_REG},
|
||||
{ BX_IA_INC_RX, 0x40, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT, ALU_GENERIC},
|
||||
{ BX_IA_DEC_RX, 0x48, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT, ALU_GENERIC},
|
||||
{ BX_IA_INC_ERX, 0x40, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT, ALU_GENERIC},
|
||||
{ BX_IA_DEC_ERX, 0x48, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT, ALU_GENERIC},
|
||||
|
||||
/* --- \\\ UNARY OPERATIONS /// --- */
|
||||
|
||||
/* --- /// BCD ADJUSTMENT \\\ --- */
|
||||
|
||||
{ BX_IA_DAA, 0x27, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_GENERIC},
|
||||
{ BX_IA_DAS, 0x2F, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_GENERIC},
|
||||
{ BX_IA_AAA, 0x37, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_GENERIC},
|
||||
{ BX_IA_AAS, 0x3F, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_GENERIC},
|
||||
{ BX_IA_AAM, 0xD4, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM8 },
|
||||
{ BX_IA_AAD, 0xD5, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM8 },
|
||||
|
||||
/* --- \\\ BCD ADJUSTMENT /// --- */
|
||||
|
||||
/* --- /// SHIFT OPERATIONS \\\ --- */
|
||||
|
||||
// a macro to reduce copy-paste overhead
|
||||
#define SHIFTOPS(OPCODE, WD, CLASS) \
|
||||
{ BX_IA_RCL_E##WD, OPCODE, 2, 8, CLASS }, \
|
||||
{ BX_IA_RCR_E##WD, OPCODE, 3, 8, CLASS }, \
|
||||
{ BX_IA_ROL_E##WD, OPCODE, 0, 8, CLASS }, \
|
||||
{ BX_IA_ROR_E##WD, OPCODE, 1, 8, CLASS }, \
|
||||
{ BX_IA_SHL_E##WD, OPCODE, 4, 8, CLASS }, \
|
||||
{ BX_IA_SAR_E##WD, OPCODE, 7, 8, CLASS }, \
|
||||
{ BX_IA_SHL_E##WD, OPCODE, 6, 8, CLASS }, \
|
||||
{ BX_IA_SHR_E##WD, OPCODE, 5, 8, CLASS }
|
||||
{ BX_IA_RCL_E##WD, OPCODE, 2, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_RCR_E##WD, OPCODE, 3, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_ROL_E##WD, OPCODE, 0, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_ROR_E##WD, OPCODE, 1, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_SHL_E##WD, OPCODE, 4, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_SAR_E##WD, OPCODE, 7, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_SHL_E##WD, OPCODE, 6, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_SHR_E##WD, OPCODE, 5, BochsALUInstr::REG_COUNT + 1, CLASS }
|
||||
|
||||
// first shifting by one bit
|
||||
SHIFTOPS(0xD0, b, ALU_RM8),
|
||||
@ -130,24 +140,35 @@ const BochsALUInstr aluInstructions [] = {
|
||||
SHIFTOPS(0xD1, d, ALU_RM32),
|
||||
|
||||
// then shifting by CL bits
|
||||
SHIFTOPS(0xD2, b, ALU_REG_RM8),
|
||||
SHIFTOPS(0xD3, w, ALU_REG_RM16),
|
||||
SHIFTOPS(0xD3, d, ALU_REG_RM32),
|
||||
SHIFTOPS(0xD2, b, ALU_RM8),
|
||||
SHIFTOPS(0xD3, w, ALU_RM16),
|
||||
SHIFTOPS(0xD3, d, ALU_RM32),
|
||||
|
||||
// then shifting by a number of bits given via an immediate value
|
||||
SHIFTOPS(0xC0, b, ALU_IMM8_RM8),
|
||||
SHIFTOPS(0xC1, w, ALU_IMM8_RM16),
|
||||
SHIFTOPS(0xC1, d, ALU_IMM8_RM32),
|
||||
|
||||
#undef SHIFTOPS
|
||||
// SHLD / SHRD (Note: Bochs Opcode; normally 0x0F...)
|
||||
{ BX_IA_SHLD_EwGw, 0xA4, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_IMM8_RM16 },
|
||||
{ BX_IA_SHLD_EdGd, 0xA4, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_IMM8_RM32 },
|
||||
{ BX_IA_SHLD_EwGw, 0xA5, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM16 },
|
||||
{ BX_IA_SHLD_EdGd, 0xA5, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM32 },
|
||||
{ BX_IA_SHRD_EwGw, 0xAC, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_IMM8_RM16 },
|
||||
{ BX_IA_SHRD_EdGd, 0xAC, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_IMM8_RM32 },
|
||||
{ BX_IA_SHRD_EwGw, 0xAD, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM16 },
|
||||
{ BX_IA_SHRD_EdGd, 0xAD, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM32 },
|
||||
|
||||
/* --- \\\ SHIFT OPERATIONS /// --- */
|
||||
|
||||
/* --- /// BINARY OPERATIONS \\\ --- */
|
||||
|
||||
// register ax, immediate
|
||||
#define BINOPS(IACODE, OPCODE8, OPCODE16) \
|
||||
{ BX_IA_##IACODE##_ALIb, OPCODE8, 8, 8, ALU_IMM8_REG }, \
|
||||
{ BX_IA_##IACODE##_AXIw, OPCODE16, 8, 8, ALU_IMM16_REG }, \
|
||||
{ BX_IA_##IACODE##_EAXId, OPCODE16, 8, 8, ALU_IMM32_REG }
|
||||
{ BX_IA_##IACODE##_ALIb, OPCODE8, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM8 }, \
|
||||
{ BX_IA_##IACODE##_AXIw, OPCODE16, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM16 }, \
|
||||
{ BX_IA_##IACODE##_EAXId, OPCODE16, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM32 }
|
||||
|
||||
BINOPS(ADC, 0x14, 0x15),
|
||||
BINOPS(ADD, 0x04, 0x05),
|
||||
@ -161,27 +182,28 @@ const BochsALUInstr aluInstructions [] = {
|
||||
|
||||
// r/m, immediate
|
||||
#define BINOPS(OPCODE, WDE, WDI, CLASS) \
|
||||
{ BX_IA_ADC_E##WDE##I##WDI, OPCODE, 2, 8, CLASS }, \
|
||||
{ BX_IA_ADD_E##WDE##I##WDI, OPCODE, 0, 8, CLASS }, \
|
||||
{ BX_IA_AND_E##WDE##I##WDI, OPCODE, 4, 8, CLASS }, \
|
||||
{ BX_IA_CMP_E##WDE##I##WDI, OPCODE, 7, 8, CLASS }, \
|
||||
{ BX_IA_OR_E##WDE##I##WDI, OPCODE, 1, 8, CLASS }, \
|
||||
{ BX_IA_SBB_E##WDE##I##WDI, OPCODE, 3, 8, CLASS }, \
|
||||
{ BX_IA_SUB_E##WDE##I##WDI, OPCODE, 5, 8, CLASS }, \
|
||||
{ BX_IA_XOR_E##WDE##I##WDI, OPCODE, 6, 8, CLASS }
|
||||
{ BX_IA_ADC_E##WDE##I##WDI, OPCODE, 2, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_ADD_E##WDE##I##WDI, OPCODE, 0, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_AND_E##WDE##I##WDI, OPCODE, 4, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_CMP_E##WDE##I##WDI, OPCODE, 7, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_OR_E##WDE##I##WDI, OPCODE, 1, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_SBB_E##WDE##I##WDI, OPCODE, 3, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_SUB_E##WDE##I##WDI, OPCODE, 5, BochsALUInstr::REG_COUNT + 1, CLASS }, \
|
||||
{ BX_IA_XOR_E##WDE##I##WDI, OPCODE, 6, BochsALUInstr::REG_COUNT + 1, CLASS }
|
||||
|
||||
BINOPS(0x80, b, b, ALU_IMM8_RM8),
|
||||
BINOPS(0x81, w, w, ALU_IMM16_RM16),
|
||||
BINOPS(0x81, d, d, ALU_IMM32_RM32),
|
||||
BINOPS(0x82, b, b, ALU_IMM8_RM8),
|
||||
BINOPS(0x83, w, w, ALU_IMM8_RM16),
|
||||
BINOPS(0x83, d, d, ALU_IMM8_RM32),
|
||||
#undef BINOPS
|
||||
|
||||
// r/m, arbitrary register
|
||||
#define BINOPS(IACODE, OPCODE8, OPCODE16) \
|
||||
{ BX_IA_##IACODE##_EbGb, OPCODE8, 7, 8, ALU_REG_RM8 }, \
|
||||
{ BX_IA_##IACODE##_EwGw, OPCODE16, 7, 8, ALU_REG_RM16 }, \
|
||||
{ BX_IA_##IACODE##_EdGd, OPCODE16, 7, 8, ALU_REG_RM32 }
|
||||
{ BX_IA_##IACODE##_EbGb, OPCODE8, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM8 }, \
|
||||
{ BX_IA_##IACODE##_EwGw, OPCODE16, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM16 }, \
|
||||
{ BX_IA_##IACODE##_EdGd, OPCODE16, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM32 }
|
||||
|
||||
BINOPS(ADC, 0x10, 0x11),
|
||||
BINOPS(ADD, 0x00, 0x01),
|
||||
@ -195,21 +217,83 @@ const BochsALUInstr aluInstructions [] = {
|
||||
|
||||
// arbitrary register, r/m
|
||||
#define BINOPS(IACODE, OPCODE8, OPCODE16) \
|
||||
{ BX_IA_##IACODE##_GbEb, OPCODE8, 7, 8, ALU_REG_RM8 }, \
|
||||
{ BX_IA_##IACODE##_GwEw, OPCODE16, 7, 8, ALU_REG_RM16 }, \
|
||||
{ BX_IA_##IACODE##_GdEd, OPCODE16, 7, 8, ALU_REG_RM32 }
|
||||
{ BX_IA_##IACODE##_GbEb, OPCODE8, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM8 }, \
|
||||
{ BX_IA_##IACODE##_GwEw, OPCODE16, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM16 }, \
|
||||
{ BX_IA_##IACODE##_GdEd, OPCODE16, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM32 }
|
||||
|
||||
BINOPS(ADC, 0x12, 0x13),
|
||||
BINOPS(ADD, 0x02, 0x03),
|
||||
BINOPS(AND, 0x22, 0x23),
|
||||
BINOPS(CMP, 0x3a, 0x3b),
|
||||
BINOPS(OR, 0x0a, 0x0b),
|
||||
BINOPS(SBB, 0x1a, 0x1b),
|
||||
BINOPS(SUB, 0x2a, 0x2b),
|
||||
BINOPS(CMP, 0x3A, 0x3B),
|
||||
BINOPS(OR, 0x0A, 0x0B),
|
||||
BINOPS(SBB, 0x1A, 0x1B),
|
||||
BINOPS(SUB, 0x2A, 0x2B),
|
||||
BINOPS(XOR, 0x32, 0x33),
|
||||
#undef BINOPS
|
||||
|
||||
// TEST instruction
|
||||
{ BX_IA_TEST_ALIb, 0xA8, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM8},
|
||||
{ BX_IA_TEST_AXIw, 0xA9, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM16},
|
||||
{ BX_IA_TEST_EAXId, 0xA9, BochsALUInstr::REG_COUNT + 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM32},
|
||||
{ BX_IA_TEST_EbIb, 0xF6, 0, BochsALUInstr::REG_COUNT + 1, ALU_IMM8_RM8 },
|
||||
{ BX_IA_TEST_EbIb, 0xF6, 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM8_RM8 },
|
||||
{ BX_IA_TEST_EwIw, 0xF7, 0, BochsALUInstr::REG_COUNT + 1, ALU_IMM16_RM16 },
|
||||
{ BX_IA_TEST_EwIw, 0xF7, 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM16_RM16 },
|
||||
{ BX_IA_TEST_EdId, 0xF7, 0, BochsALUInstr::REG_COUNT + 1, ALU_IMM32_RM32 },
|
||||
{ BX_IA_TEST_EdId, 0xF7, 1, BochsALUInstr::REG_COUNT + 1, ALU_IMM32_RM32 },
|
||||
{ BX_IA_TEST_EbGb, 0x84, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM8},
|
||||
{ BX_IA_TEST_EwGw, 0x85, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM16},
|
||||
{ BX_IA_TEST_EdGd, 0x85, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM32},
|
||||
|
||||
// MUL and DIV
|
||||
#define BINOPS(IACODE, OPCODE8, OPCODE16, REG) \
|
||||
{ BX_IA_##IACODE##_ALEb, OPCODE8, REG, BochsALUInstr::REG_COUNT + 1, ALU_IMM8 }, \
|
||||
{ BX_IA_##IACODE##_AXEw, OPCODE16, REG, BochsALUInstr::REG_COUNT + 1, ALU_IMM16 }, \
|
||||
{ BX_IA_##IACODE##_EAXEd, OPCODE16, REG, BochsALUInstr::REG_COUNT + 1, ALU_IMM32 }
|
||||
BINOPS(MUL, 0xF6, 0xF7, 4),
|
||||
BINOPS(IMUL, 0xF6, 0xF7, 5),
|
||||
BINOPS(DIV, 0xF6, 0xF7, 6),
|
||||
BINOPS(IDIV, 0xF6, 0xF7, 7),
|
||||
#undef BINOPS
|
||||
{ BX_IA_IMUL_GwEwIw, 0x69, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_IMM16_RM16 },
|
||||
{ BX_IA_IMUL_GwEwIw, 0x69, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_IMM32_RM32 },
|
||||
{ BX_IA_IMUL_GwEwIw, 0x6B, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_IMM8_RM16 },
|
||||
{ BX_IA_IMUL_GwEwIw, 0x6B, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_IMM8_RM32 },
|
||||
// two-byte opcode, see above
|
||||
{ BX_IA_IMUL_GwEw, 0xAF, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM16},
|
||||
{ BX_IA_IMUL_GdEd, 0xAF, BochsALUInstr::REG_COUNT, BochsALUInstr::REG_COUNT + 1, ALU_RM32},
|
||||
|
||||
/* --- \\\ BINARY OPERATIONS /// --- */
|
||||
};
|
||||
|
||||
const size_t aluInstructionsSize = sizeof(aluInstructions);
|
||||
|
||||
class BochsALUInstructions {
|
||||
public:
|
||||
/**
|
||||
*
|
||||
*/
|
||||
typedef std::vector<BochsALUInstr> InstrList;
|
||||
typedef std::map<X86AluClass, InstrList> EquivClassMap;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
BochsALUInstructions(const BochsALUInstr *initial_array, size_t array_size);
|
||||
~BochsALUInstructions() { free(allInstr); }
|
||||
bool isALUInstruction(const bxInstruction_c *src);
|
||||
bxInstruction_c randomEquivalent() const;
|
||||
protected:
|
||||
void bochsInstrToInstrStruct(const bxInstruction_c *src, BochsALUInstr *dest) const;
|
||||
private:
|
||||
BochsALUInstr *allInstr;
|
||||
BochsALUInstr lastInstr;
|
||||
const bxInstruction_c *lastOrigInstr;
|
||||
size_t allInstrSize;
|
||||
EquivClassMap equivalenceClasses;
|
||||
void buildEquivalenceClasses();
|
||||
#ifdef DEBUG
|
||||
void printNestedMap();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // __L4SYS_ALUINSTR_HPP__
|
||||
|
||||
Reference in New Issue
Block a user