Skip to content

Commit

Permalink
Fixes for enc2 & testing
Browse files Browse the repository at this point in the history
  * vpermil2ps (XOP) has a imm8 value and a reg encoded in the imm8
    upper bits. I had to support merging the values from the imm8 and
    the register encoding and only emit one imm8. For now, I 'OR' the
    two values together. If the test generator generates a large imm8
    value for this instr, then the register bits will likely get
    corrupted.

  * RCL and ROR with implicit one operands were getting imm8's appended
    their output. Had to improve test for gpr8_imm8 and gprv_imm8.

  * Bad luck cased the test for XCHG to use EAX,EAX and it decoded as
    a NOP and failed. I excluded EAX from the test register list for
    gpr32 in 32b mode.

Change-Id: If62f212f1bbc6e929b7cb12f8210da2fc28a81ce
(cherry picked from commit 45bedfe2a0306b52156e3b16bff5e4c77f417335)
  • Loading branch information
mjcharne authored and markcharney committed Mar 23, 2020
1 parent 77a4255 commit 2b44713
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 15 deletions.
6 changes: 6 additions & 0 deletions include/private/xed-enc2-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,12 @@ void enc_imm8_reg_xmm(xed_enc2_req_t* r,
xed_reg_enum_t dst);
void enc_imm8_reg_ymm(xed_enc2_req_t* r,
xed_reg_enum_t dst);
void enc_imm8_reg_xmm_and_imm(xed_enc2_req_t* r,
xed_reg_enum_t dst,
xed_uint_t imm);
void enc_imm8_reg_ymm_and_imm(xed_enc2_req_t* r,
xed_reg_enum_t dst,
xed_uint_t imm);


// CRs and DRs, SEG regs
Expand Down
31 changes: 24 additions & 7 deletions pysrc/enc2gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@ def two_scalable_regs(ii): # allow optional imm8, immz, allow one implicit GPR
return n==2 and i <= 1 and implicit <= 1
def op_implicit(op):
return op.visibility == 'IMPLICIT'
def op_implicit_or_suppressed(op):
return op.visibility in ['IMPLICIT','SUPPRESSED']

def one_x87_reg(ii):
n = 0
Expand Down Expand Up @@ -657,8 +659,11 @@ def op_immv(op):
def op_imm8(op):
if op.name == 'IMM0':
if op.oc2 == 'b':
if op_implicit_or_suppressed(op):
return False
return True
return False

def op_imm16(op):
if op.name == 'IMM0':
if op.oc2 == 'w':
Expand Down Expand Up @@ -2073,36 +2078,42 @@ def create_legacy_one_x87_reg(env,ii):


def gpr8_imm8(ii):
reg,imm=0,0
for i,op in enumerate(_gen_opnds(ii)):
if i == 0:
if op.name == 'REG0' and op_luf_start(op,'GPR8'):
continue
reg = reg + 1
else:
return False
elif i == 1:
if op.name == 'IMM0' and op.oc2 == 'b':
continue
if op_implicit_or_suppressed(op):
return False
imm = imm + 1
else:
return False
else:
return False
return True
return reg == 1 and imm == 1

def gprv_imm8(ii):
reg,imm=0,0
for i,op in enumerate(_gen_opnds(ii)):
if i == 0:
if op.name == 'REG0' and op_luf_start(op,'GPRv'):
continue
reg = reg + 1
else:
return False
elif i == 1:
if op.name == 'IMM0' and op.oc2 == 'b':
continue
if op_implicit_or_suppressed(op):
return False
imm = imm + 1
else:
return False
else:
return False
return True
return reg == 1 and imm == 1

def gprv_immz(ii):
for i,op in enumerate(_gen_opnds(ii)):
Expand Down Expand Up @@ -3925,10 +3936,16 @@ def create_vex_regs_mem(env,ii):
fo.add_code_eol('set_rm(r,{})'.format(ii.rm_required))

if var_se:
fo.add_code_eol('enc_imm8_reg_{}(r,{})'.format(sz_se, var_se))
if immw:
immw=0
fo.add_code_eol('enc_imm8_reg_{}_and_imm(r,{},{})'.format(sz_se, var_se, var_imm8))
else:
fo.add_code_eol('enc_imm8_reg_{}(r,{})'.format(sz_se, var_se))

encode_mem_operand(env, ii, fo, use_index, dispsz)
emit_vex_prefix(env, ii,fo,register_only=False)


finish_memop(env, ii, fo, dispsz, immw, space='vex')
if var_se:
fo.add_code_eol('emit_se_imm8_reg(r)')
Expand Down
1 change: 1 addition & 0 deletions pysrc/enc2test.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def _add_test_function(ii,fo):
gpr64_index = "RAX RCX RDX RBX RSI RDI RBP R8 R9 R10 R11 R12 R13 R14 R15".split()

gpr32_not64 = "EAX ECX EDX EBX ESI EDI EBP ESP".split()
gpr32_not64 = "ECX EDX EBX ESI EDI EBP ESP".split() # omit EAX for XCHG EAX,EAX vs NOP issue
gpr32_index_not64 = "EAX ECX EDX EBX ESI EDI EBP".split()

gpr16_not64 = "AX CX DX BX SI DI BP SP".split()
Expand Down
13 changes: 13 additions & 0 deletions src/enc2/xed-encode-direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,19 @@ void enc_imm8_reg_ymm(xed_enc2_req_t* r, // _SE imm8 reg
set_imm8_reg(r, offset<<4);
}

void enc_imm8_reg_xmm_and_imm(xed_enc2_req_t* r, // _SE imm8 reg
xed_reg_enum_t dst,
xed_uint_t imm) {
xed_uint_t offset = dst-XED_REG_XMM_FIRST;
set_imm8_reg(r, (offset<<4)|imm);
}
void enc_imm8_reg_ymm_and_imm(xed_enc2_req_t* r, // _SE imm8 reg
xed_reg_enum_t dst,
xed_uint_t imm) {
xed_uint_t offset = dst-XED_REG_YMM_FIRST;
set_imm8_reg(r, (offset<<4)|imm);
}

// CRs and DRs, SEG regs

void enc_modrm_reg_cr(xed_enc2_req_t* r,
Expand Down
26 changes: 18 additions & 8 deletions src/enc2test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,18 @@ static void dump(xed_uint8_t* buf, xed_uint32_t len) {
printf("%02x ",buf[i]);
}
}
static void dump_comment(xed_uint8_t* buf, xed_uint32_t len) {
xed_uint_t i;
printf("// ");
for(i=0;i<len;i++) {
printf("%02x",buf[i]);
}
printf("\n");
}

static void dump_emit_byte(xed_uint8_t* buf, xed_uint32_t len) {
xed_uint_t i;
dump_comment(buf,len);
printf(".byte ");
for(i=0;i<len;i++) {
if (i>0)
Expand All @@ -67,6 +76,7 @@ static void dump_emit_byte(xed_uint8_t* buf, xed_uint32_t len) {

static void dump_emit(xed_uint8_t* buf, xed_uint32_t len) {
xed_uint_t i;
dump_comment(buf,len);
for(i=0;i<len;i++) {
printf("__emit 0x%02x\n", buf[i]);
}
Expand Down Expand Up @@ -167,12 +177,12 @@ int test_all(test_func_t* base, const char** str_table, const xed_iclass_enum_t*
delta = t2-t1;


printf("Tests: %6d\n", test_id);
printf("Repeats: %6d\n", reps);
printf("Errors: %6d\n", errors);
printf("Cycles: " XED_FMT_LU "\n", delta);
printf("Cycles/(enc+dec) : %7.1lf\n", 1.0*delta/(reps*test_id));
printf("Cycles/encode : %7.1lf\n", 1.0*total/(reps*test_id));
printf("//Tests: %6d\n", test_id);
printf("//Repeats: %6d\n", reps);
printf("//Errors: %6d\n", errors);
printf("//Cycles: " XED_FMT_LU "\n", delta);
printf("//Cycles/(enc+dec) : %7.1lf\n", 1.0*delta/(reps*test_id));
printf("//Cycles/encode : %7.1lf\n", 1.0*total/(reps*test_id));
return errors;
}

Expand Down Expand Up @@ -211,7 +221,7 @@ int main(int argc, char** argv) {


m = i;
printf("Total tests %d\n",m);
printf("//Total tests %d\n",m);
for(i=1;i<argc;i++) {
if (strcmp(argv[i],"--reps")==0) {
assert( i+1 < argc );
Expand Down Expand Up @@ -258,7 +268,7 @@ int main(int argc, char** argv) {
exit(1);
}
if (specific_tests==0) {
printf("Testing all...\n");
printf("//Testing all...\n");
errors = test_all(base, str_table, iclass_table);
}
if (enable_histogram)
Expand Down

0 comments on commit 2b44713

Please sign in to comment.