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:
Gabe Black 2007-07-20 23:16:03 -07:00
parent 009df5ff1e
commit fc1b7d62b7
7 changed files with 245 additions and 65 deletions

View file

@ -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();
}
}
}
}

View file

@ -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 {{

View file

@ -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
};
'''

View file

@ -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):

View file

@ -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}"
#}};

View file

@ -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):

View file

@ -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);