Fixed the distinction between far and near versions of jmp, call and ret. Implemented some shifts, rotates, and pushes.
--HG-- extra : convert_revision : fcb06189ff213e82da16ac43231feb308cb3a285
This commit is contained in:
parent
009df5ff1e
commit
fc1b7d62b7
7 changed files with 245 additions and 65 deletions
|
@ -306,7 +306,7 @@
|
|||
0x1: cwd_or_cdq_or_cqo_rAX_rDX();
|
||||
0x2: decode MODE_SUBMODE {
|
||||
0x0: Inst::UD2();
|
||||
default: call_Ap();
|
||||
default: call_far_Ap();
|
||||
}
|
||||
0x3: fwait(); //aka wait
|
||||
0x4: pushf_Fv();
|
||||
|
@ -356,25 +356,25 @@
|
|||
0x18: decode OPCODE_OP_BOTTOM3 {
|
||||
//0x0: group2_Eb_Ib();
|
||||
0x0: decode MODRM_REG {
|
||||
0x0: rol_Eb_Ib();
|
||||
0x1: ror_Eb_Ib();
|
||||
0x0: Inst::ROL(Eb,Ib);
|
||||
0x1: Inst::ROR(Eb,Ib);
|
||||
0x2: rcl_Eb_Ib();
|
||||
0x3: rcr_Eb_Ib();
|
||||
0x4: Inst::SAL(Eb,Ib);
|
||||
0x5: shr_Eb_Ib();
|
||||
0x5: Inst::SHR(Eb,Ib);
|
||||
0x6: Inst::SAL(Eb,Ib);
|
||||
0x7: sar_Eb_Ib();
|
||||
0x7: Inst::SAR(Eb,Ib);
|
||||
}
|
||||
//0x1: group2_Ev_Ib();
|
||||
0x1: decode MODRM_REG {
|
||||
0x0: rol_Ev_Ib();
|
||||
0x1: ror_Ev_Ib();
|
||||
0x0: Inst::ROL(Ev,Ib);
|
||||
0x1: Inst::ROR(Ev,Ib);
|
||||
0x2: rcl_Ev_Ib();
|
||||
0x3: rcr_Ev_Ib();
|
||||
0x4: Inst::SAL(Ev,Ib);
|
||||
0x5: shr_Ev_Ib();
|
||||
0x5: Inst::SHR(Ev,Ib);
|
||||
0x6: Inst::SAL(Ev,Ib);
|
||||
0x7: sar_Ev_Ib();
|
||||
0x7: Inst::SAR(Ev,Ib);
|
||||
}
|
||||
0x2: ret_near_Iw();
|
||||
0x3: Inst::RET_NEAR();
|
||||
|
@ -452,7 +452,7 @@
|
|||
0x1: Inst::JMP(Jz);
|
||||
0x2: decode MODE_SUBMODE {
|
||||
0x0: Inst::UD2();
|
||||
default: jmp_Ap();
|
||||
default: jmp_far_Ap();
|
||||
}
|
||||
0x3: Inst::JMP(Jb);
|
||||
0x4: in_Al_Dx();
|
||||
|
@ -480,22 +480,24 @@
|
|||
0x3: sti();
|
||||
0x4: cld();
|
||||
0x5: std();
|
||||
//0x6: group4();
|
||||
0x6: decode MODRM_REG {
|
||||
0x0: Inst::INC(Eb);
|
||||
0x1: Inst::DEC(Eb);
|
||||
default: Inst::UD2();
|
||||
}
|
||||
//0x7: group5();
|
||||
0x7: decode MODRM_REG {
|
||||
0x0: Inst::INC(Ev);
|
||||
0x1: Inst::DEC(Ev);
|
||||
0x2: call_Ev();
|
||||
0x3: call_Mp();
|
||||
0x4: jmp_Ev();
|
||||
0x5: jmp_Mp();
|
||||
0x6: push_Ev();
|
||||
0x7: Inst::UD2();
|
||||
format Inst {
|
||||
//0x6: group4();
|
||||
0x6: decode MODRM_REG {
|
||||
0x0: INC(Eb);
|
||||
0x1: DEC(Eb);
|
||||
default: UD2();
|
||||
}
|
||||
//0x7: group5();
|
||||
0x7: decode MODRM_REG {
|
||||
0x0: INC(Ev);
|
||||
0x1: DEC(Ev);
|
||||
0x2: CALL_NEAR(Ev);
|
||||
0x3: WarnUnimpl::call_far_Mp();
|
||||
0x4: JMP(Ev);
|
||||
0x5: WarnUnimpl::jmp_far_Mp();
|
||||
0x6: PUSH(Ev);
|
||||
0x7: UD2();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,11 +59,46 @@ def macroop CALL_NEAR_I
|
|||
# Make the default data size of calls 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
limm t2, imm
|
||||
limm t1, imm
|
||||
rdip t7
|
||||
subi rsp, rsp, dsz
|
||||
st t7, ss, [0, t0, rsp]
|
||||
wrip t7, t1
|
||||
};
|
||||
|
||||
def macroop CALL_NEAR_R
|
||||
{
|
||||
# Make the default data size of calls 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t1
|
||||
subi rsp, rsp, dsz
|
||||
st t1, ss, [0, t0, rsp]
|
||||
wrip t1, t2
|
||||
wripi reg, 0
|
||||
};
|
||||
|
||||
def macroop CALL_NEAR_M
|
||||
{
|
||||
# Make the default data size of calls 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t7
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
subi rsp, rsp, dsz
|
||||
st t7, ss, [0, t0, rsp]
|
||||
wripi t1, 0
|
||||
};
|
||||
|
||||
def macroop CALL_NEAR_P
|
||||
{
|
||||
# Make the default data size of calls 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
subi rsp, rsp, dsz
|
||||
st t7, ss, [0, t0, rsp]
|
||||
wripi t1, 0
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
|
|
|
@ -235,4 +235,10 @@ def macroop JMP_M
|
|||
wripi t1, 0
|
||||
};
|
||||
|
||||
def macroop JMP_P
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
wripi t1, 0
|
||||
};
|
||||
'''
|
||||
|
|
|
@ -69,6 +69,25 @@ def macroop PUSH_R {
|
|||
subi rsp, rsp, dsz
|
||||
st reg, ss, [0, t0, rsp]
|
||||
};
|
||||
|
||||
def macroop PUSH_M {
|
||||
# Make the default data size of pops 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
subi rsp, rsp, dsz
|
||||
st t1, ss, [0, t0, rsp]
|
||||
};
|
||||
|
||||
def macroop PUSH_P {
|
||||
# Make the default data size of pops 64 bits in 64 bit mode
|
||||
.adjust_env oszIn64Override
|
||||
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
subi rsp, rsp, dsz
|
||||
st t1, ss, [0, t0, rsp]
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class POPA(Inst):
|
||||
|
|
|
@ -53,14 +53,50 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
microcode = '''
|
||||
def macroop ROL_R_I
|
||||
{
|
||||
rol reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop ROL_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
rol t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ROL_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
rol t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop ROR_R_I
|
||||
{
|
||||
ror reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop ROR_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
ror t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop ROR_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
ror t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class RCL(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class RCR(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class ROL(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class ROR(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
#}};
|
||||
|
|
|
@ -73,6 +73,46 @@ def macroop SAL_P_I
|
|||
sll t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop SHR_R_I
|
||||
{
|
||||
srl reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop SHR_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
srl t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SHR_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
srl t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
|
||||
def macroop SAR_R_I
|
||||
{
|
||||
sra reg, reg, imm
|
||||
};
|
||||
|
||||
def macroop SAR_M_I
|
||||
{
|
||||
ld t1, ds, [scale, index, base], disp
|
||||
sra t1, t1, imm
|
||||
st t1, ds, [scale, index, base], disp
|
||||
};
|
||||
|
||||
def macroop SAR_P_I
|
||||
{
|
||||
rdip t7
|
||||
ld t1, ds, [0, t0, t7], disp
|
||||
sra t1, t1, imm
|
||||
st t1, ds, [0, t0, t7], disp
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class SAL(Inst):
|
||||
|
|
|
@ -381,34 +381,6 @@ let {{
|
|||
setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
|
||||
flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
|
||||
|
||||
defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
|
||||
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
|
||||
defineMicroRegOp('Adc', '''
|
||||
CCFlagBits flags = ccFlagBits;
|
||||
DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Sbb', '''
|
||||
CCFlagBits flags = ccFlagBits;
|
||||
DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
|
||||
''', True)
|
||||
defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
|
||||
defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
|
||||
defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
|
||||
# defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
|
||||
defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
|
||||
defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
|
||||
elseCode='DestReg=DestReg;', cc=True)
|
||||
|
||||
# Shift instructions
|
||||
defineMicroRegOp('Sll', '''
|
||||
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
|
||||
''')
|
||||
# There are special rules for the flag for a single bit shift
|
||||
defineMicroRegOp('Bll', '''
|
||||
DestReg = merge(DestReg, SrcReg1 << 1, dataSize);
|
||||
''')
|
||||
|
||||
# This has it's own function because Wr ops have implicit destinations
|
||||
def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
|
||||
Name = mnemonic
|
||||
|
@ -445,8 +417,6 @@ let {{
|
|||
setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
|
||||
condCheck = checkCCFlagBits, elseCode = elseCode);
|
||||
|
||||
defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
|
||||
|
||||
# This has it's own function because Rd ops don't always have two parameters
|
||||
def defineMicroRegOpRd(mnemonic, code):
|
||||
Name = mnemonic
|
||||
|
@ -462,8 +432,6 @@ let {{
|
|||
|
||||
setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
|
||||
|
||||
defineMicroRegOpRd('Rdip', 'DestReg = RIP')
|
||||
|
||||
def defineMicroRegOpImm(mnemonic, code):
|
||||
Name = mnemonic
|
||||
name = mnemonic.lower()
|
||||
|
@ -478,6 +446,80 @@ let {{
|
|||
|
||||
setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
|
||||
|
||||
defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
|
||||
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
|
||||
defineMicroRegOp('Adc', '''
|
||||
CCFlagBits flags = ccFlagBits;
|
||||
DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Sbb', '''
|
||||
CCFlagBits flags = ccFlagBits;
|
||||
DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
|
||||
''', True)
|
||||
defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
|
||||
defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
|
||||
defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
|
||||
# defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
|
||||
defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
|
||||
defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
|
||||
elseCode='DestReg=DestReg;', cc=True)
|
||||
|
||||
# Shift instructions
|
||||
defineMicroRegOp('Sll', '''
|
||||
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Srl', '''
|
||||
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
// Because what happens to the bits shift -in- on a right shift
|
||||
// is not defined in the C/C++ standard, we have to mask them out
|
||||
// to be sure they're zero.
|
||||
uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
|
||||
DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) & logicalMask, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Sra', '''
|
||||
uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
// Because what happens to the bits shift -in- on a right shift
|
||||
// is not defined in the C/C++ standard, we have to sign extend
|
||||
// them manually to be sure.
|
||||
uint64_t arithMask =
|
||||
-bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
|
||||
DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
|
||||
''')
|
||||
defineMicroRegOp('Ror', '''
|
||||
uint8_t shiftAmt =
|
||||
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
if(shiftAmt)
|
||||
{
|
||||
uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
|
||||
uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
|
||||
DestReg = merge(DestReg, top | bottom, dataSize);
|
||||
}
|
||||
else
|
||||
DestReg = DestReg;
|
||||
''')
|
||||
defineMicroRegOp('Rcr', '''
|
||||
''')
|
||||
defineMicroRegOp('Rol', '''
|
||||
uint8_t shiftAmt =
|
||||
(op2 & ((dataSize == 8) ? mask(4) : mask(3)));
|
||||
if(shiftAmt)
|
||||
{
|
||||
uint64_t top = SrcReg1 << shiftAmt;
|
||||
uint64_t bottom =
|
||||
bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
|
||||
DestReg = merge(DestReg, top | bottom, dataSize);
|
||||
}
|
||||
else
|
||||
DestReg = DestReg;
|
||||
''')
|
||||
defineMicroRegOp('Rcl', '''
|
||||
''')
|
||||
|
||||
defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
|
||||
|
||||
defineMicroRegOpRd('Rdip', 'DestReg = RIP')
|
||||
|
||||
defineMicroRegOpImm('Sext', '''
|
||||
IntReg val = SrcReg1;
|
||||
int sign_bit = bits(val, imm8-1, imm8-1);
|
||||
|
|
Loading…
Reference in a new issue