arch-x86: Specialize the remaining operand types for uops.
Change-Id: Ibe49b7fa020d3c722fe6f41cf83786dcfaf16819 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42355 Reviewed-by: Gabe Black <gabe.black@gmail.com> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -82,9 +82,9 @@ class LdStOp : public InstOperands<MemOp, FoldedDataOp, AddrOp>
|
||||
{
|
||||
protected:
|
||||
LdStOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem,
|
||||
uint64_t set_flags, InstRegIndex _data,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
uint64_t set_flags, GpRegIndex _data,
|
||||
uint8_t _scale, GpRegIndex _index, GpRegIndex _base,
|
||||
uint64_t _disp, SegRegIndex _segment,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, OpClass op_class) :
|
||||
InstOperands<MemOp, FoldedDataOp, AddrOp>(
|
||||
@@ -102,8 +102,8 @@ class LdStFpOp : public InstOperands<MemOp, FloatDataOp, AddrOp>
|
||||
protected:
|
||||
LdStFpOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem,
|
||||
uint64_t set_flags, FpRegIndex _data,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
uint8_t _scale, GpRegIndex _index, GpRegIndex _base,
|
||||
uint64_t _disp, SegRegIndex _segment,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, OpClass op_class) :
|
||||
InstOperands<MemOp, FloatDataOp, AddrOp>(
|
||||
@@ -120,8 +120,8 @@ class MemNoDataOp : public InstOperands<MemOp, AddrOp>
|
||||
{
|
||||
protected:
|
||||
MemNoDataOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem,
|
||||
uint64_t set_flags, uint8_t _scale, InstRegIndex _index,
|
||||
InstRegIndex _base, uint64_t _disp, InstRegIndex _segment,
|
||||
uint64_t set_flags, uint8_t _scale, GpRegIndex _index,
|
||||
GpRegIndex _base, uint64_t _disp, SegRegIndex _segment,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, OpClass op_class) :
|
||||
InstOperands<MemOp, AddrOp>(
|
||||
@@ -141,9 +141,9 @@ class LdStSplitOp :
|
||||
{
|
||||
protected:
|
||||
LdStSplitOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem,
|
||||
uint64_t set_flags, InstRegIndex data_low, InstRegIndex data_hi,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
uint64_t set_flags, GpRegIndex data_low, GpRegIndex data_hi,
|
||||
uint8_t _scale, GpRegIndex _index, GpRegIndex _base,
|
||||
uint64_t _disp, SegRegIndex _segment,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, OpClass op_class) :
|
||||
InstOperands<MemOp, FoldedDataLowOp, FoldedDataHiOp, AddrOp>(
|
||||
|
||||
@@ -44,7 +44,6 @@ namespace X86ISA
|
||||
|
||||
struct DestOp
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex dest;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return dest; }
|
||||
@@ -54,7 +53,6 @@ struct DestOp
|
||||
|
||||
struct Src1Op
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex src1;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return src1; }
|
||||
@@ -64,7 +62,6 @@ struct Src1Op
|
||||
|
||||
struct Src2Op
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex src2;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return src2; }
|
||||
@@ -74,7 +71,6 @@ struct Src2Op
|
||||
|
||||
struct DataOp
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex data;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return data; }
|
||||
@@ -84,7 +80,6 @@ struct DataOp
|
||||
|
||||
struct DataHiOp
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex dataHi;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return dataHi; }
|
||||
@@ -94,7 +89,6 @@ struct DataHiOp
|
||||
|
||||
struct DataLowOp
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex dataLow;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return dataLow; }
|
||||
@@ -106,10 +100,10 @@ struct DataLowOp
|
||||
template <class Base>
|
||||
struct IntOp : public Base
|
||||
{
|
||||
using ArgType = GpRegIndex;
|
||||
|
||||
template <class InstType>
|
||||
IntOp(InstType *inst, typename Base::ArgType idx) :
|
||||
Base(idx.index, inst->dataSize)
|
||||
{}
|
||||
IntOp(InstType *inst, ArgType idx) : Base(idx.index, inst->dataSize) {}
|
||||
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
@@ -122,8 +116,10 @@ struct IntOp : public Base
|
||||
template <class Base>
|
||||
struct FoldedOp : public Base
|
||||
{
|
||||
using ArgType = GpRegIndex;
|
||||
|
||||
template <class InstType>
|
||||
FoldedOp(InstType *inst, typename Base::ArgType idx) :
|
||||
FoldedOp(InstType *inst, ArgType idx) :
|
||||
Base(INTREG_FOLDED(idx.index, inst->foldOBit), inst->dataSize)
|
||||
{}
|
||||
|
||||
@@ -138,8 +134,10 @@ struct FoldedOp : public Base
|
||||
template <class Base>
|
||||
struct CrOp : public Base
|
||||
{
|
||||
using ArgType = CrRegIndex;
|
||||
|
||||
template <class InstType>
|
||||
CrOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index, 0) {}
|
||||
CrOp(InstType *inst, ArgType idx) : Base(idx.index, 0) {}
|
||||
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
@@ -151,8 +149,10 @@ struct CrOp : public Base
|
||||
template <class Base>
|
||||
struct DbgOp : public Base
|
||||
{
|
||||
using ArgType = DbgRegIndex;
|
||||
|
||||
template <class InstType>
|
||||
DbgOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index, 0) {}
|
||||
DbgOp(InstType *inst, ArgType idx) : Base(idx.index, 0) {}
|
||||
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
@@ -165,8 +165,10 @@ struct DbgOp : public Base
|
||||
template <class Base>
|
||||
struct SegOp : public Base
|
||||
{
|
||||
using ArgType = SegRegIndex;
|
||||
|
||||
template <class InstType>
|
||||
SegOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index, 0) {}
|
||||
SegOp(InstType *inst, ArgType idx) : Base(idx.index, 0) {}
|
||||
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
@@ -178,10 +180,10 @@ struct SegOp : public Base
|
||||
template <class Base>
|
||||
struct MiscOp : public Base
|
||||
{
|
||||
using ArgType = CtrlRegIndex;
|
||||
|
||||
template <class InstType>
|
||||
MiscOp(InstType *inst, typename Base::ArgType idx) :
|
||||
Base(idx.index, inst->dataSize)
|
||||
{}
|
||||
MiscOp(InstType *inst, ArgType idx) : Base(idx.index, inst->dataSize) {}
|
||||
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
@@ -301,10 +303,10 @@ struct AddrOp
|
||||
struct ArgType
|
||||
{
|
||||
uint8_t scale;
|
||||
InstRegIndex index;
|
||||
InstRegIndex base;
|
||||
GpRegIndex index;
|
||||
GpRegIndex base;
|
||||
uint64_t disp;
|
||||
InstRegIndex segment;
|
||||
SegRegIndex segment;
|
||||
};
|
||||
|
||||
const uint8_t scale;
|
||||
|
||||
@@ -50,10 +50,10 @@ namespace X86ISA
|
||||
* wrapper struct for these lets take advantage of the compiler's type
|
||||
* checking.
|
||||
*/
|
||||
struct InstRegIndex
|
||||
struct GpRegIndex
|
||||
{
|
||||
RegIndex index;
|
||||
explicit InstRegIndex(RegIndex idx) : index(idx) {}
|
||||
explicit GpRegIndex(RegIndex idx) : index(idx) {}
|
||||
};
|
||||
|
||||
struct FpRegIndex
|
||||
@@ -62,6 +62,30 @@ struct FpRegIndex
|
||||
explicit FpRegIndex(RegIndex idx) : index(idx) {}
|
||||
};
|
||||
|
||||
struct CtrlRegIndex
|
||||
{
|
||||
RegIndex index;
|
||||
explicit CtrlRegIndex(RegIndex idx) : index(idx) {}
|
||||
};
|
||||
|
||||
struct CrRegIndex
|
||||
{
|
||||
RegIndex index;
|
||||
explicit CrRegIndex(RegIndex idx) : index(idx) {}
|
||||
};
|
||||
|
||||
struct DbgRegIndex
|
||||
{
|
||||
RegIndex index;
|
||||
explicit DbgRegIndex(RegIndex idx) : index(idx) {}
|
||||
};
|
||||
|
||||
struct SegRegIndex
|
||||
{
|
||||
RegIndex index;
|
||||
explicit SegRegIndex(RegIndex idx) : index(idx) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for all X86 static instructions.
|
||||
*/
|
||||
|
||||
@@ -69,8 +69,12 @@ output header {{
|
||||
#include "mem/packet.hh"
|
||||
#include "sim/faults.hh"
|
||||
|
||||
using X86ISA::InstRegIndex;
|
||||
using X86ISA::GpRegIndex;
|
||||
using X86ISA::FpRegIndex;
|
||||
using X86ISA::CtrlRegIndex;
|
||||
using X86ISA::CrRegIndex;
|
||||
using X86ISA::DbgRegIndex;
|
||||
using X86ISA::SegRegIndex;
|
||||
|
||||
}};
|
||||
|
||||
|
||||
@@ -174,54 +174,54 @@ def macroop MOVZX_W_R_P {
|
||||
def macroop MOV_C_R {
|
||||
.serialize_after
|
||||
.adjust_env maxOsz
|
||||
wrcr reg, regm
|
||||
wrcr cr, regm
|
||||
};
|
||||
|
||||
def macroop MOV_R_C {
|
||||
.serialize_after
|
||||
.adjust_env maxOsz
|
||||
rdcr reg, regm
|
||||
rdcr reg, crm
|
||||
};
|
||||
|
||||
def macroop MOV_D_R {
|
||||
.serialize_after
|
||||
.adjust_env maxOsz
|
||||
wrdr reg, regm
|
||||
wrdr dr, regm
|
||||
};
|
||||
|
||||
def macroop MOV_R_D {
|
||||
.adjust_env maxOsz
|
||||
rddr reg, regm
|
||||
rddr reg, drm
|
||||
};
|
||||
|
||||
def macroop MOV_R_S {
|
||||
rdsel reg, regm
|
||||
rdsel reg, srm
|
||||
};
|
||||
|
||||
def macroop MOV_M_S {
|
||||
rdsel t1, reg
|
||||
rdsel t1, sr
|
||||
st t1, seg, sib, disp, dataSize=2
|
||||
};
|
||||
|
||||
def macroop MOV_P_S {
|
||||
rdip t7
|
||||
rdsel t1, reg
|
||||
rdsel t1, sr
|
||||
st t1, seg, riprel, disp, dataSize=2
|
||||
};
|
||||
|
||||
def macroop MOV_REAL_S_R {
|
||||
zexti t2, regm, 15, dataSize=8
|
||||
slli t3, t2, 4, dataSize=8
|
||||
wrsel reg, regm
|
||||
wrbase reg, t3, dataSize=8
|
||||
wrsel sr, regm
|
||||
wrbase sr, t3, dataSize=8
|
||||
};
|
||||
|
||||
def macroop MOV_REAL_S_M {
|
||||
ld t1, seg, sib, disp, dataSize=2
|
||||
zexti t2, t1, 15, dataSize=8
|
||||
slli t3, t2, 4, dataSize=8
|
||||
wrsel reg, t1
|
||||
wrbase reg, t3, dataSize=8
|
||||
wrsel sr, t1
|
||||
wrbase sr, t3, dataSize=8
|
||||
};
|
||||
|
||||
def macroop MOV_REAL_S_P {
|
||||
@@ -240,8 +240,8 @@ globalDescriptor:
|
||||
ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
|
||||
processDescriptor:
|
||||
chks regm, t3, dataSize=8
|
||||
wrdl reg, t3, regm
|
||||
wrsel reg, regm
|
||||
wrdl sr, t3, regm
|
||||
wrsel sr, regm
|
||||
};
|
||||
|
||||
def macroop MOV_S_M {
|
||||
@@ -257,8 +257,8 @@ globalDescriptor:
|
||||
ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
|
||||
processDescriptor:
|
||||
chks t1, t3, dataSize=8
|
||||
wrdl reg, t3, t1
|
||||
wrsel reg, t1
|
||||
wrdl sr, t3, t1
|
||||
wrsel sr, t1
|
||||
};
|
||||
|
||||
def macroop MOV_S_P {
|
||||
@@ -275,8 +275,8 @@ globalDescriptor:
|
||||
ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
|
||||
processDescriptor:
|
||||
chks t1, t3, dataSize=8
|
||||
wrdl reg, t3, t1
|
||||
wrsel reg, t1
|
||||
wrdl sr, t3, t1
|
||||
wrsel sr, t1
|
||||
};
|
||||
|
||||
def macroop MOVSS_S_R {
|
||||
@@ -291,8 +291,8 @@ globalDescriptor:
|
||||
ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
|
||||
processDescriptor:
|
||||
chks regm, t3, SSCheck, dataSize=8
|
||||
wrdl reg, t3, regm
|
||||
wrsel reg, regm
|
||||
wrdl sr, t3, regm
|
||||
wrsel sr, regm
|
||||
};
|
||||
|
||||
def macroop MOVSS_S_M {
|
||||
@@ -308,8 +308,8 @@ globalDescriptor:
|
||||
ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
|
||||
processDescriptor:
|
||||
chks t1, t3, SSCheck, dataSize=8
|
||||
wrdl reg, t3, t1
|
||||
wrsel reg, t1
|
||||
wrdl sr, t3, t1
|
||||
wrsel sr, t1
|
||||
};
|
||||
|
||||
def macroop MOVSS_S_P {
|
||||
@@ -326,8 +326,8 @@ globalDescriptor:
|
||||
ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8
|
||||
processDescriptor:
|
||||
chks t1, t3, SSCheck, dataSize=8
|
||||
wrdl reg, t3, t1
|
||||
wrsel reg, t1
|
||||
wrdl sr, t3, t1
|
||||
wrsel sr, t1
|
||||
};
|
||||
|
||||
def macroop MOVNTI_M_R {
|
||||
|
||||
@@ -35,24 +35,24 @@
|
||||
|
||||
microcode = '''
|
||||
def macroop STMXCSR_M {
|
||||
rdval t1, regIdx("MISCREG_MXCSR")
|
||||
rdval t1, ctrlRegIdx("MISCREG_MXCSR")
|
||||
st t1, seg, sib, disp
|
||||
};
|
||||
|
||||
def macroop STMXCSR_P {
|
||||
rdval t1, regIdx("MISCREG_MXCSR")
|
||||
rdval t1, ctrlRegIdx("MISCREG_MXCSR")
|
||||
rdip t7
|
||||
st t1, seg, riprel, disp
|
||||
};
|
||||
|
||||
def macroop LDMXCSR_M {
|
||||
ld t1, seg, sib, disp
|
||||
wrval regIdx("MISCREG_MXCSR"), t1
|
||||
wrval ctrlRegIdx("MISCREG_MXCSR"), t1
|
||||
};
|
||||
|
||||
def macroop LDMXCSR_P {
|
||||
rdip t7
|
||||
ld t1, seg, riprel, disp
|
||||
wrval regIdx("MISCREG_MXCSR"), t1
|
||||
wrval ctrlRegIdx("MISCREG_MXCSR"), t1
|
||||
};
|
||||
'''
|
||||
|
||||
@@ -80,10 +80,10 @@ fxsaveCommonTemplate = """
|
||||
rdxftw t1
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 4", dataSize=1
|
||||
|
||||
rdval t1, regIdx("MISCREG_FOP")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FOP")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 6", dataSize=2
|
||||
|
||||
rdval t1, regIdx("MISCREG_MXCSR")
|
||||
rdval t1, ctrlRegIdx("MISCREG_MXCSR")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 8", dataSize=4
|
||||
|
||||
# MXCSR_MASK, software assumes the default (0xFFBF) if 0.
|
||||
@@ -92,24 +92,24 @@ fxsaveCommonTemplate = """
|
||||
""" + storeAllDataRegs
|
||||
|
||||
fxsave32Template = """
|
||||
rdval t1, regIdx("MISCREG_FIOFF")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FIOFF")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=4
|
||||
|
||||
rdval t1, regIdx("MISCREG_FISEG")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FISEG")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 12", dataSize=2
|
||||
|
||||
rdval t1, regIdx("MISCREG_FOOFF")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FOOFF")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=4
|
||||
|
||||
rdval t1, regIdx("MISCREG_FOSEG")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FOSEG")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 4", dataSize=2
|
||||
""" + fxsaveCommonTemplate
|
||||
|
||||
fxsave64Template = """
|
||||
rdval t1, regIdx("MISCREG_FIOFF")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FIOFF")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=8
|
||||
|
||||
rdval t1, regIdx("MISCREG_FOOFF")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FOOFF")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=8
|
||||
""" + fxsaveCommonTemplate
|
||||
|
||||
@@ -126,36 +126,36 @@ fxrstorCommonTemplate = """
|
||||
wrxftw t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 6", dataSize=2
|
||||
wrval regIdx("MISCREG_FOP"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FOP"), t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 8", dataSize=4
|
||||
wrval regIdx("MISCREG_MXCSR"), t1
|
||||
wrval ctrlRegIdx("MISCREG_MXCSR"), t1
|
||||
""" + loadAllDataRegs
|
||||
|
||||
fxrstor32Template = """
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=4
|
||||
wrval regIdx("MISCREG_FIOFF"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FIOFF"), t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 12", dataSize=2
|
||||
wrval regIdx("MISCREG_FISEG"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FISEG"), t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=4
|
||||
wrval regIdx("MISCREG_FOOFF"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FOOFF"), t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 4", dataSize=2
|
||||
wrval regIdx("MISCREG_FOSEG"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FOSEG"), t1
|
||||
""" + fxrstorCommonTemplate
|
||||
|
||||
fxrstor64Template = """
|
||||
limm t2, 0, dataSize=8
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=8
|
||||
wrval regIdx("MISCREG_FIOFF"), t1
|
||||
wrval regIdx("MISCREG_FISEG"), t2
|
||||
wrval ctrlRegIdx("MISCREG_FIOFF"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FISEG"), t2
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=8
|
||||
wrval regIdx("MISCREG_FOOFF"), t1
|
||||
wrval regIdx("MISCREG_FOSEG"), t2
|
||||
wrval ctrlRegIdx("MISCREG_FOOFF"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FOSEG"), t2
|
||||
""" + fxrstorCommonTemplate
|
||||
|
||||
microcode = '''
|
||||
|
||||
@@ -26,58 +26,58 @@
|
||||
|
||||
microcode = '''
|
||||
def macroop CLTS {
|
||||
rdcr t1, regIdx(0), dataSize=8
|
||||
rdcr t1, cr0, dataSize=8
|
||||
andi t1, t1, 0xF7, dataSize=1
|
||||
wrcr regIdx(0), t1, dataSize=8
|
||||
wrcr cr0, t1, dataSize=8
|
||||
};
|
||||
|
||||
def macroop LMSW_R {
|
||||
rdcr t1, regIdx(0), dataSize=8
|
||||
rdcr t1, cr0, dataSize=8
|
||||
# This logic sets MP, EM, and TS to whatever is in the operand. It will
|
||||
# set PE but not clear it.
|
||||
limm t2, "~0xeULL", dataSize=8
|
||||
and t1, t1, t2, dataSize=8
|
||||
andi t2, reg, 0xf, dataSize=8
|
||||
or t1, t1, t2, dataSize=8
|
||||
wrcr regIdx(0), t1, dataSize=8
|
||||
wrcr cr0, t1, dataSize=8
|
||||
};
|
||||
|
||||
def macroop LMSW_M {
|
||||
ld t3, seg, sib, disp, dataSize=2
|
||||
rdcr t1, regIdx(0), dataSize=8
|
||||
rdcr t1, cr0, dataSize=8
|
||||
# This logic sets MP, EM, and TS to whatever is in the operand. It will
|
||||
# set PE but not clear it.
|
||||
limm t2, "~0xeULL", dataSize=8
|
||||
and t1, t1, t2, dataSize=8
|
||||
andi t2, t3, 0xf, dataSize=8
|
||||
or t1, t1, t2, dataSize=8
|
||||
wrcr regIdx(0), t1, dataSize=8
|
||||
wrcr cr0, t1, dataSize=8
|
||||
};
|
||||
|
||||
def macroop LMSW_P {
|
||||
rdip t7, dataSize=asz
|
||||
ld t3, seg, riprel, disp, dataSize=2
|
||||
rdcr t1, regIdx(0), dataSize=8
|
||||
rdcr t1, cr0, dataSize=8
|
||||
# This logic sets MP, EM, and TS to whatever is in the operand. It will
|
||||
# set PE but not clear it.
|
||||
limm t2, "~0xeULL", dataSize=8
|
||||
and t1, t1, t2, dataSize=8
|
||||
andi t2, t3, 0xf, dataSize=8
|
||||
or t1, t1, t2, dataSize=8
|
||||
wrcr regIdx(0), t1, dataSize=8
|
||||
wrcr cr0, t1, dataSize=8
|
||||
};
|
||||
|
||||
def macroop SMSW_R {
|
||||
rdcr reg, regIdx(0)
|
||||
rdcr reg, cr0
|
||||
};
|
||||
|
||||
def macroop SMSW_M {
|
||||
rdcr t1, regIdx(0)
|
||||
rdcr t1, cr0
|
||||
st t1, seg, sib, disp, dataSize=2
|
||||
};
|
||||
|
||||
def macroop SMSW_P {
|
||||
rdcr t1, regIdx(0)
|
||||
rdcr t1, cr0
|
||||
rdip t7, dataSize=asz
|
||||
st t1, seg, riprel, disp, dataSize=2
|
||||
};
|
||||
|
||||
@@ -71,6 +71,6 @@ def macroop RDTSCP
|
||||
rdtsc t1
|
||||
mov rax, rax, t1, dataSize=4
|
||||
srli rdx, t1, 32, dataSize=8
|
||||
rdval rcx, regIdx("MISCREG_TSC_AUX"), dataSize=4
|
||||
rdval rcx, ctrlRegIdx("MISCREG_TSC_AUX"), dataSize=4
|
||||
};
|
||||
'''
|
||||
|
||||
@@ -39,19 +39,19 @@ fldenvTemplate = """
|
||||
wrval ftw, t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 12", dataSize=4
|
||||
wrval regIdx("MISCREG_FIOFF"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FIOFF"), t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=2
|
||||
wrval regIdx("MISCREG_FISEG"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FISEG"), t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 2", dataSize=2
|
||||
wrval regIdx("MISCREG_FOP"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FOP"), t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 20", dataSize=4
|
||||
wrval regIdx("MISCREG_FOOFF"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FOOFF"), t1
|
||||
|
||||
ld t1, seg, %(mode)s, "DISPLACEMENT + 24", dataSize=2
|
||||
wrval regIdx("MISCREG_FOSEG"), t1
|
||||
wrval ctrlRegIdx("MISCREG_FOSEG"), t1
|
||||
"""
|
||||
|
||||
fnstenvTemplate = """
|
||||
@@ -63,24 +63,24 @@ fnstenvTemplate = """
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 4", dataSize=2
|
||||
srli t1, t1, 11, dataSize=2
|
||||
andi t1, t1, 0x7, dataSize=2
|
||||
wrval regIdx("MISCREG_X87_TOP"), t1
|
||||
wrval ctrlRegIdx("MISCREG_X87_TOP"), t1
|
||||
|
||||
rdval t1, ftw
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=2
|
||||
|
||||
rdval t1, regIdx("MISCREG_FIOFF")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FIOFF")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 12", dataSize=4
|
||||
|
||||
rdval t1, regIdx("MISCREG_FISEG")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FISEG")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=2
|
||||
|
||||
rdval t1, regIdx("MISCREG_FOP")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FOP")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 2", dataSize=2
|
||||
|
||||
rdval t1, regIdx("MISCREG_FOOFF")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FOOFF")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 20", dataSize=4
|
||||
|
||||
rdval t1, regIdx("MISCREG_FOSEG")
|
||||
rdval t1, ctrlRegIdx("MISCREG_FOSEG")
|
||||
st t1, seg, %(mode)s, "DISPLACEMENT + 24", dataSize=2
|
||||
|
||||
# Mask exceptions
|
||||
|
||||
@@ -56,24 +56,36 @@ let {{
|
||||
mainRom = X86MicrocodeRom('main ROM')
|
||||
assembler = MicroAssembler(X86Macroop, microopClasses, mainRom, Rom_Macroop)
|
||||
|
||||
def regIdx(idx):
|
||||
return "X86ISA::InstRegIndex(%s)" % idx
|
||||
def gpRegIdx(idx):
|
||||
return "X86ISA::GpRegIndex(%s)" % idx
|
||||
def fpRegIdx(idx):
|
||||
return "X86ISA::FpRegIndex(%s)" % idx
|
||||
def ctrlRegIdx(idx):
|
||||
return "X86ISA::CtrlRegIndex(%s)" % idx
|
||||
def crRegIdx(idx):
|
||||
return "X86ISA::CrRegIndex(%s)" % idx
|
||||
def drRegIdx(idx):
|
||||
return "X86ISA::DbgRegIndex(%s)" % idx
|
||||
def segRegIdx(idx):
|
||||
return "X86ISA::SegRegIndex(%s)" % idx
|
||||
|
||||
assembler.symbols["regIdx"] = regIdx
|
||||
assembler.symbols["gpRegIdx"] = gpRegIdx
|
||||
assembler.symbols["fpRegIdx"] = fpRegIdx
|
||||
assembler.symbols["ctrlRegIdx"] = ctrlRegIdx
|
||||
assembler.symbols["crRegIdx"] = crRegIdx
|
||||
assembler.symbols["drRegIdx"] = drRegIdx
|
||||
assembler.symbols["segRegIdx"] = segRegIdx
|
||||
|
||||
# Add in symbols for the microcode registers
|
||||
for num in range(16):
|
||||
assembler.symbols["t%d" % num] = regIdx("NUM_INTREGS+%d" % num)
|
||||
assembler.symbols["t%d" % num] = gpRegIdx("NUM_INTREGS+%d" % num)
|
||||
for num in range(8):
|
||||
assembler.symbols["ufp%d" % num] = \
|
||||
fpRegIdx("FLOATREG_MICROFP(%d)" % num)
|
||||
# Add in symbols for the segment descriptor registers
|
||||
for letter in ("C", "D", "E", "F", "G", "H", "S"):
|
||||
assembler.symbols["%ss" % letter.lower()] = \
|
||||
regIdx("SEGMENT_REG_%sS" % letter)
|
||||
segRegIdx("SEGMENT_REG_%sS" % letter)
|
||||
|
||||
# Add in symbols for the various checks of segment selectors.
|
||||
for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck",
|
||||
@@ -82,27 +94,33 @@ let {{
|
||||
assembler.symbols[check] = "Seg%s" % check
|
||||
|
||||
for reg in ("TR", "IDTR"):
|
||||
assembler.symbols[reg.lower()] = regIdx("SYS_SEGMENT_REG_%s" % reg)
|
||||
assembler.symbols[reg.lower()] = segRegIdx("SYS_SEGMENT_REG_%s" % reg)
|
||||
|
||||
for reg in ("TSL", "TSG"):
|
||||
assembler.symbols[reg.lower()] = regIdx("SEGMENT_REG_%s" % reg)
|
||||
assembler.symbols[reg.lower()] = segRegIdx("SEGMENT_REG_%s" % reg)
|
||||
|
||||
# Miscellaneous symbols
|
||||
symbols = {
|
||||
"reg" : regIdx("env.reg"),
|
||||
"reg" : gpRegIdx("env.reg"),
|
||||
"cr" : crRegIdx("env.reg"),
|
||||
"dr" : drRegIdx("env.reg"),
|
||||
"sr" : segRegIdx("env.reg"),
|
||||
"xmml" : fpRegIdx("FLOATREG_XMM_LOW(env.reg)"),
|
||||
"xmmh" : fpRegIdx("FLOATREG_XMM_HIGH(env.reg)"),
|
||||
"regm" : regIdx("env.regm"),
|
||||
"regm" : gpRegIdx("env.regm"),
|
||||
"crm" : crRegIdx("env.regm"),
|
||||
"drm" : drRegIdx("env.regm"),
|
||||
"srm" : segRegIdx("env.regm"),
|
||||
"xmmlm" : fpRegIdx("FLOATREG_XMM_LOW(env.regm)"),
|
||||
"xmmhm" : fpRegIdx("FLOATREG_XMM_HIGH(env.regm)"),
|
||||
"mmx" : fpRegIdx("FLOATREG_MMX(env.reg)"),
|
||||
"mmxm" : fpRegIdx("FLOATREG_MMX(env.regm)"),
|
||||
"imm" : "adjustedImm",
|
||||
"disp" : "adjustedDisp",
|
||||
"seg" : regIdx("env.seg"),
|
||||
"seg" : segRegIdx("env.seg"),
|
||||
"scale" : "env.scale",
|
||||
"index" : regIdx("env.index"),
|
||||
"base" : regIdx("env.base"),
|
||||
"index" : gpRegIdx("env.index"),
|
||||
"base" : gpRegIdx("env.base"),
|
||||
"dsz" : "env.dataSize",
|
||||
"asz" : "env.addressSize",
|
||||
"ssz" : "env.stackSize"
|
||||
@@ -126,23 +144,23 @@ let {{
|
||||
|
||||
# This segment selects an internal address space mapped to MSRs,
|
||||
# CPUID info, etc.
|
||||
assembler.symbols["intseg"] = regIdx("SEGMENT_REG_MS")
|
||||
assembler.symbols["intseg"] = segRegIdx("SEGMENT_REG_MS")
|
||||
# This segment always has base 0, and doesn't imply any special handling
|
||||
# like the internal segment above
|
||||
assembler.symbols["flatseg"] = regIdx("SEGMENT_REG_LS")
|
||||
assembler.symbols["flatseg"] = segRegIdx("SEGMENT_REG_LS")
|
||||
|
||||
for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di', \
|
||||
'8', '9', '10', '11', '12', '13', '14', '15'):
|
||||
assembler.symbols["r%s" % reg] = \
|
||||
regIdx("INTREG_R%s" % reg.upper())
|
||||
gpRegIdx("INTREG_R%s" % reg.upper())
|
||||
|
||||
for reg in ('ah', 'bh', 'ch', 'dh'):
|
||||
assembler.symbols[reg] = \
|
||||
regIdx("X86ISA::INTREG_FOLDED(INTREG_%s, IntFoldBit)" %
|
||||
gpRegIdx("X86ISA::INTREG_FOLDED(INTREG_%s, IntFoldBit)" %
|
||||
reg.upper())
|
||||
|
||||
for reg in range(16):
|
||||
assembler.symbols["cr%d" % reg] = regIdx("MISCREG_CR%d" % reg)
|
||||
assembler.symbols["cr%d" % reg] = crRegIdx("%d" % reg)
|
||||
|
||||
for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF', \
|
||||
'TF', 'IF', 'NT', 'RF', 'VM', 'AC', 'VIF', 'VIP', 'ID'):
|
||||
@@ -163,7 +181,7 @@ let {{
|
||||
for reg in ('sysenter_cs', 'sysenter_esp', 'sysenter_eip',
|
||||
'star', 'lstar', 'cstar', 'sf_mask',
|
||||
'kernel_gs_base'):
|
||||
assembler.symbols[reg] = regIdx("MISCREG_%s" % reg.upper())
|
||||
assembler.symbols[reg] = ctrlRegIdx("MISCREG_%s" % reg.upper())
|
||||
|
||||
for flag in ('Scalar', 'MultHi', 'Signed'):
|
||||
assembler.symbols[flag] = 'Media%sOp' % flag
|
||||
@@ -214,12 +232,9 @@ let {{
|
||||
assembler.symbols["sti"] = stack_index("env.reg")
|
||||
assembler.symbols["stim"] = stack_index("env.regm")
|
||||
|
||||
def readFpReg(reg_name):
|
||||
return regIdx("MISCREG_%s" % reg_name)
|
||||
|
||||
assembler.symbols["fsw"] = readFpReg("FSW")
|
||||
assembler.symbols["fcw"] = readFpReg("FCW")
|
||||
assembler.symbols["ftw"] = readFpReg("FTW")
|
||||
assembler.symbols["fsw"] = ctrlRegIdx("MISCREG_FSW")
|
||||
assembler.symbols["fcw"] = ctrlRegIdx("MISCREG_FCW")
|
||||
assembler.symbols["ftw"] = ctrlRegIdx("MISCREG_FTW")
|
||||
|
||||
macroopDict = assembler.assemble(microcode)
|
||||
|
||||
|
||||
@@ -63,11 +63,8 @@ let {{
|
||||
Macroop * macroop = dynamic_cast<Macroop *>(curMacroop.get());
|
||||
const ExtMachInst &machInst =
|
||||
macroop ? macroop->getExtMachInst() : dummyExtMachInst;
|
||||
const EmulEnv &env =
|
||||
M5_VAR_USED const EmulEnv &env =
|
||||
macroop ? macroop->getEmulEnv() : dummyEmulEnv;
|
||||
// env may not be used in the microop's constructor.
|
||||
InstRegIndex reg(env.reg);
|
||||
reg = reg;
|
||||
using namespace RomLabels;
|
||||
return %s;
|
||||
}
|
||||
|
||||
@@ -262,9 +262,9 @@ def template MicroLdStSplitOpDeclare {{
|
||||
public:
|
||||
%(class_name)s(ExtMachInst mach_inst, const char *inst_mnem,
|
||||
uint64_t set_flags,
|
||||
InstRegIndex data_low, InstRegIndex data_hi,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
GpRegIndex data_low, GpRegIndex data_hi,
|
||||
uint8_t _scale, GpRegIndex _index, GpRegIndex _base,
|
||||
uint64_t _disp, SegRegIndex _segment,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags);
|
||||
|
||||
@@ -278,9 +278,9 @@ def template MicroLdStSplitOpDeclare {{
|
||||
def template MicroLdStSplitOpConstructor {{
|
||||
%(class_name)s::%(class_name)s(ExtMachInst mach_inst,
|
||||
const char *inst_mnem, uint64_t set_flags,
|
||||
InstRegIndex data_low, InstRegIndex data_hi,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
GpRegIndex data_low, GpRegIndex data_hi,
|
||||
uint8_t _scale, GpRegIndex _index, GpRegIndex _base,
|
||||
uint64_t _disp, SegRegIndex _segment,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags) :
|
||||
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
|
||||
|
||||
Reference in New Issue
Block a user