api: Store index register in operand struct
Combined with some reordering of the struct fields, this reduces the size of an FdInstr from 56 bytes to 48 bytes.
This commit is contained in:
5
decode.c
5
decode.c
@@ -249,8 +249,7 @@ decode_modrm(const uint8_t* buffer, int len, DecodeMode mode, FdInstr* instr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out_o1->type = FD_OT_MEM;
|
out_o1->type = FD_OT_MEM;
|
||||||
instr->idx_scale = scale;
|
out_o1->misc = (scale << 6) | (!vsib && idx == 4 ? FD_REG_NONE : idx);
|
||||||
instr->idx_reg = !vsib && idx == 4 ? FD_REG_NONE : idx;
|
|
||||||
|
|
||||||
// RIP-relative addressing only if SIB-byte is absent
|
// RIP-relative addressing only if SIB-byte is absent
|
||||||
if (mod == 0 && rm == 5 && mode == DECODE_64)
|
if (mod == 0 && rm == 5 && mode == DECODE_64)
|
||||||
@@ -521,7 +520,7 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
|
|||||||
FdOp* operand = &instr->operands[DESC_IMM_IDX(desc)];
|
FdOp* operand = &instr->operands[DESC_IMM_IDX(desc)];
|
||||||
operand->type = FD_OT_MEM;
|
operand->type = FD_OT_MEM;
|
||||||
operand->reg = FD_REG_NONE;
|
operand->reg = FD_REG_NONE;
|
||||||
instr->idx_reg = FD_REG_NONE;
|
operand->misc = FD_REG_NONE;
|
||||||
|
|
||||||
if (UNLIKELY(off + addr_size > len))
|
if (UNLIKELY(off + addr_size > len))
|
||||||
return FD_ERR_PARTIAL;
|
return FD_ERR_PARTIAL;
|
||||||
|
|||||||
17
fadec.h
17
fadec.h
@@ -82,7 +82,7 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t size;
|
uint8_t size;
|
||||||
int8_t reg;
|
uint8_t reg;
|
||||||
uint8_t misc;
|
uint8_t misc;
|
||||||
} FdOp;
|
} FdOp;
|
||||||
|
|
||||||
@@ -92,12 +92,13 @@ typedef struct {
|
|||||||
uint8_t segment;
|
uint8_t segment;
|
||||||
uint8_t addrsz;
|
uint8_t addrsz;
|
||||||
uint8_t operandsz;
|
uint8_t operandsz;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t _pad0;
|
||||||
|
|
||||||
FdOp operands[4];
|
FdOp operands[4];
|
||||||
|
|
||||||
uint8_t idx_reg;
|
int32_t disp;
|
||||||
uint8_t idx_scale;
|
uint32_t _pad1;
|
||||||
uint8_t size;
|
|
||||||
intptr_t disp;
|
|
||||||
intptr_t imm;
|
intptr_t imm;
|
||||||
|
|
||||||
uintptr_t address;
|
uintptr_t address;
|
||||||
@@ -192,16 +193,16 @@ void fd_format(const FdInstr* instr, char* buf, size_t len);
|
|||||||
/** Gets the index of the index register from a memory operand, or FD_REG_NONE,
|
/** Gets the index of the index register from a memory operand, or FD_REG_NONE,
|
||||||
* if the memory operand has no scaled index register.
|
* if the memory operand has no scaled index register.
|
||||||
* Only valid if FD_OP_TYPE == FD_OT_MEM **/
|
* Only valid if FD_OP_TYPE == FD_OT_MEM **/
|
||||||
#define FD_OP_INDEX(instr,idx) ((FdReg) (instr)->idx_reg)
|
#define FD_OP_INDEX(instr,idx) ((FdReg) (instr)->operands[idx].misc & 0x3f)
|
||||||
/** Gets the scale of the index register from a memory operand when existent.
|
/** Gets the scale of the index register from a memory operand when existent.
|
||||||
* This does /not/ return the scale in an absolute value but returns the amount
|
* This does /not/ return the scale in an absolute value but returns the amount
|
||||||
* of bits the index register is shifted to the left (i.e. the value in in the
|
* of bits the index register is shifted to the left (i.e. the value in in the
|
||||||
* range 0-3). The actual scale can be computed easily using 1<<FD_OP_SCALE.
|
* range 0-3). The actual scale can be computed easily using 1<<FD_OP_SCALE.
|
||||||
* Only valid if FD_OP_TYPE == FD_OT_MEM and FD_OP_INDEX != FD_REG_NONE **/
|
* Only valid if FD_OP_TYPE == FD_OT_MEM and FD_OP_INDEX != FD_REG_NONE **/
|
||||||
#define FD_OP_SCALE(instr,idx) ((instr)->idx_scale)
|
#define FD_OP_SCALE(instr,idx) ((instr)->operands[idx].misc >> 6)
|
||||||
/** Gets the sign-extended displacement of a memory operand.
|
/** Gets the sign-extended displacement of a memory operand.
|
||||||
* Only valid if FD_OP_TYPE == FD_OT_MEM **/
|
* Only valid if FD_OP_TYPE == FD_OT_MEM **/
|
||||||
#define FD_OP_DISP(instr,idx) ((instr)->disp)
|
#define FD_OP_DISP(instr,idx) ((int64_t) (instr)->disp)
|
||||||
/** Gets the (sign-extended) encoded constant for an immediate operand.
|
/** Gets the (sign-extended) encoded constant for an immediate operand.
|
||||||
* Only valid if FD_OP_TYPE == FD_OT_IMM **/
|
* Only valid if FD_OP_TYPE == FD_OT_IMM **/
|
||||||
#define FD_OP_IMM(instr,idx) ((instr)->imm)
|
#define FD_OP_IMM(instr,idx) ((instr)->imm)
|
||||||
|
|||||||
Reference in New Issue
Block a user