arch-x86: Use the new op bases for memory microops.
Change-Id: I73538b547093e6f872e085686ea164ef89527321 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42346 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:
@@ -51,7 +51,6 @@ Source('faults.cc')
|
||||
Source('fs_workload.cc')
|
||||
Source('insts/badmicroop.cc')
|
||||
Source('insts/microfpop.cc')
|
||||
Source('insts/microldstop.cc')
|
||||
Source('insts/micromediaop.cc')
|
||||
Source('insts/microop.cc')
|
||||
Source('insts/microregop.cc')
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* Copyright (c) 2015 Advanced Micro Devices, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "arch/x86/insts/microldstop.hh"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
|
||||
std::string
|
||||
LdStOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
if (flags[IsLoad])
|
||||
printDestReg(response, 0, dataSize);
|
||||
else
|
||||
printSrcReg(response, 2, dataSize);
|
||||
response << ", ";
|
||||
printMem(response, segment, scale, index, base, disp, addressSize, false);
|
||||
return response.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
LdStSplitOp::generateDisassembly(
|
||||
Addr pc, const Loader::SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, instMnem, mnemonic);
|
||||
int baseRegIdx = flags[IsLoad] ? 0 : 2;
|
||||
response << "[";
|
||||
printDestReg(response, baseRegIdx, dataSize);
|
||||
response << ", ";
|
||||
printDestReg(response, baseRegIdx+1, dataSize);
|
||||
response << "], ";
|
||||
printMem(response, segment, scale, index, base, disp, addressSize, false);
|
||||
return response.str();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,6 +40,7 @@
|
||||
#define __ARCH_X86_INSTS_MICROLDSTOP_HH__
|
||||
|
||||
#include "arch/x86/insts/microop.hh"
|
||||
#include "arch/x86/insts/microop_args.hh"
|
||||
#include "arch/x86/ldstflags.hh"
|
||||
#include "mem/packet.hh"
|
||||
#include "mem/request.hh"
|
||||
@@ -54,65 +55,80 @@ namespace X86ISA
|
||||
class MemOp : public X86MicroopBase
|
||||
{
|
||||
protected:
|
||||
const uint8_t scale;
|
||||
const RegIndex index;
|
||||
const RegIndex base;
|
||||
const uint64_t disp;
|
||||
const uint8_t segment;
|
||||
const uint8_t dataSize;
|
||||
const uint8_t addressSize;
|
||||
const Request::FlagsType memFlags;
|
||||
RegIndex foldOBit, foldABit;
|
||||
|
||||
//Constructor
|
||||
MemOp(ExtMachInst _machInst,
|
||||
const char * mnem, const char * _instMnem,
|
||||
uint64_t setFlags,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
Request::FlagsType _memFlags,
|
||||
OpClass __opClass) :
|
||||
X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass),
|
||||
scale(_scale), index(_index.index()), base(_base.index()),
|
||||
disp(_disp), segment(_segment.index()),
|
||||
dataSize(_dataSize), addressSize(_addressSize),
|
||||
memFlags(_memFlags | _segment.index())
|
||||
{
|
||||
assert(_segment.index() < NUM_SEGMENTREGS);
|
||||
foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
|
||||
foldABit = (addressSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
|
||||
}
|
||||
MemOp(ExtMachInst mach_inst, const char *mnem, const char *inst_mnem,
|
||||
uint64_t set_flags, OpClass op_class,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags) :
|
||||
X86MicroopBase(mach_inst, mnem, inst_mnem, set_flags, op_class),
|
||||
memFlags(mem_flags),
|
||||
dataSize(data_size), addressSize(address_size),
|
||||
foldOBit((dataSize == 1 && !mach_inst.rex.present) ? 1 << 6 : 0),
|
||||
foldABit((addressSize == 1 && !mach_inst.rex.present) ? 1 << 6 : 0)
|
||||
{}
|
||||
|
||||
public:
|
||||
const uint8_t dataSize;
|
||||
const uint8_t addressSize;
|
||||
const RegIndex foldOBit, foldABit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for load and store ops using one register
|
||||
* Base class for load ops using one integer register.
|
||||
*/
|
||||
class LdStOp : public MemOp
|
||||
class LdStOp : public InstOperands<MemOp, FoldedDataOp, AddrOp>
|
||||
{
|
||||
protected:
|
||||
const RegIndex data;
|
||||
|
||||
//Constructor
|
||||
LdStOp(ExtMachInst _machInst,
|
||||
const char * mnem, const char * _instMnem,
|
||||
uint64_t setFlags,
|
||||
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,
|
||||
InstRegIndex _data,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
Request::FlagsType _memFlags,
|
||||
OpClass __opClass) :
|
||||
MemOp(_machInst, mnem, _instMnem, setFlags,
|
||||
_scale, _index, _base, _disp, _segment,
|
||||
_dataSize, _addressSize, _memFlags,
|
||||
__opClass),
|
||||
data(_data.index())
|
||||
{
|
||||
}
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, OpClass op_class) :
|
||||
InstOperands<MemOp, FoldedDataOp, AddrOp>(
|
||||
mach_inst, mnem, inst_mnem, set_flags, op_class,
|
||||
_data, { _scale, _index, _base, _disp, _segment },
|
||||
data_size, address_size, mem_flags | _segment.index())
|
||||
{}
|
||||
};
|
||||
|
||||
std::string generateDisassembly(
|
||||
Addr pc, const Loader::SymbolTable *symtab) const override;
|
||||
/**
|
||||
* Base class for load ops using one FP register.
|
||||
*/
|
||||
class LdStFpOp : public InstOperands<MemOp, FloatDataOp, AddrOp>
|
||||
{
|
||||
protected:
|
||||
LdStFpOp(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,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, OpClass op_class) :
|
||||
InstOperands<MemOp, FloatDataOp, AddrOp>(
|
||||
mach_inst, mnem, inst_mnem, set_flags, op_class,
|
||||
_data, { _scale, _index, _base, _disp, _segment },
|
||||
data_size, address_size, mem_flags | _segment.index())
|
||||
{}
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for the tia microop which has no destination register.
|
||||
*/
|
||||
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,
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, OpClass op_class) :
|
||||
InstOperands<MemOp, AddrOp>(
|
||||
mach_inst, mnem, inst_mnem, set_flags, op_class,
|
||||
{ _scale, _index, _base, _disp, _segment },
|
||||
data_size, address_size, mem_flags | _segment.index())
|
||||
{}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -120,33 +136,21 @@ class LdStOp : public MemOp
|
||||
* call them split ops for this reason. These are mainly used to
|
||||
* implement cmpxchg8b and cmpxchg16b.
|
||||
*/
|
||||
class LdStSplitOp : public MemOp
|
||||
class LdStSplitOp :
|
||||
public InstOperands<MemOp, FoldedDataLowOp, FoldedDataHiOp, AddrOp>
|
||||
{
|
||||
protected:
|
||||
const RegIndex dataLow;
|
||||
const RegIndex dataHi;
|
||||
|
||||
//Constructor
|
||||
LdStSplitOp(ExtMachInst _machInst,
|
||||
const char * mnem, const char * _instMnem,
|
||||
uint64_t setFlags,
|
||||
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,
|
||||
InstRegIndex _dataLow, InstRegIndex _dataHi,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
Request::FlagsType _memFlags,
|
||||
OpClass __opClass) :
|
||||
MemOp(_machInst, mnem, _instMnem, setFlags,
|
||||
_scale, _index, _base, _disp, _segment,
|
||||
_dataSize, _addressSize, _memFlags,
|
||||
__opClass),
|
||||
dataLow(_dataLow.index()),
|
||||
dataHi(_dataHi.index())
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(
|
||||
Addr pc, const Loader::SymbolTable *symtab) const override;
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, OpClass op_class) :
|
||||
InstOperands<MemOp, FoldedDataLowOp, FoldedDataHiOp, AddrOp>(
|
||||
mach_inst, mnem, inst_mnem, set_flags, op_class,
|
||||
data_low, data_hi, { _scale, _index, _base, _disp, _segment },
|
||||
data_size, address_size, mem_flags | _segment.index())
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ struct DestOp
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex dest;
|
||||
const size_t size;
|
||||
RegIndex index() const { return dest; }
|
||||
RegIndex opIndex() const { return dest; }
|
||||
|
||||
DestOp(RegIndex _dest, size_t _size) : dest(_dest), size(_size) {}
|
||||
};
|
||||
@@ -56,7 +56,7 @@ struct Src1Op
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex src1;
|
||||
const size_t size;
|
||||
RegIndex index() const { return src1; }
|
||||
RegIndex opIndex() const { return src1; }
|
||||
|
||||
Src1Op(RegIndex _src1, size_t _size) : src1(_src1), size(_size) {}
|
||||
};
|
||||
@@ -66,11 +66,42 @@ struct Src2Op
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex src2;
|
||||
const size_t size;
|
||||
RegIndex index() const { return src2; }
|
||||
RegIndex opIndex() const { return src2; }
|
||||
|
||||
Src2Op(RegIndex _src2, size_t _size) : src2(_src2), size(_size) {}
|
||||
};
|
||||
|
||||
struct DataOp
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex data;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return data; }
|
||||
|
||||
DataOp(RegIndex _data, size_t _size) : data(_data), size(_size) {}
|
||||
};
|
||||
|
||||
struct DataHiOp
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex dataHi;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return dataHi; }
|
||||
|
||||
DataHiOp(RegIndex data_hi, size_t _size) : dataHi(data_hi), size(_size) {}
|
||||
};
|
||||
|
||||
struct DataLowOp
|
||||
{
|
||||
using ArgType = InstRegIndex;
|
||||
const RegIndex dataLow;
|
||||
const size_t size;
|
||||
RegIndex opIndex() const { return dataLow; }
|
||||
|
||||
DataLowOp(RegIndex data_low, size_t _size) : dataLow(data_low), size(_size)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class Base>
|
||||
struct FoldedOp : public Base
|
||||
{
|
||||
@@ -82,7 +113,7 @@ struct FoldedOp : public Base
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
{
|
||||
X86StaticInst::printReg(os, RegId(IntRegClass, this->index()),
|
||||
X86StaticInst::printReg(os, RegId(IntRegClass, this->opIndex()),
|
||||
this->size);
|
||||
}
|
||||
};
|
||||
@@ -96,7 +127,7 @@ struct CrOp : public Base
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
{
|
||||
ccprintf(os, "cr%d", this->index());
|
||||
ccprintf(os, "cr%d", this->opIndex());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -109,7 +140,7 @@ struct DbgOp : public Base
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
{
|
||||
ccprintf(os, "dr%d", this->index());
|
||||
ccprintf(os, "dr%d", this->opIndex());
|
||||
}
|
||||
|
||||
};
|
||||
@@ -123,7 +154,7 @@ struct SegOp : public Base
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
{
|
||||
X86StaticInst::printSegment(os, this->index());
|
||||
X86StaticInst::printSegment(os, this->opIndex());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -138,7 +169,23 @@ struct MiscOp : public Base
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
{
|
||||
X86StaticInst::printReg(os, RegId(MiscRegClass, this->index()),
|
||||
X86StaticInst::printReg(os, RegId(MiscRegClass, this->opIndex()),
|
||||
this->size);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Base>
|
||||
struct FloatOp : public Base
|
||||
{
|
||||
template <class InstType>
|
||||
FloatOp(InstType *inst, typename Base::ArgType idx) :
|
||||
Base(idx.index(), inst->dataSize)
|
||||
{}
|
||||
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
{
|
||||
X86StaticInst::printReg(os, RegId(FloatRegClass, this->opIndex()),
|
||||
this->size);
|
||||
}
|
||||
};
|
||||
@@ -157,6 +204,11 @@ using MiscSrc1Op = MiscOp<Src1Op>;
|
||||
|
||||
using FoldedSrc2Op = FoldedOp<Src2Op>;
|
||||
|
||||
using FoldedDataOp = FoldedOp<DataOp>;
|
||||
using FloatDataOp = FloatOp<DataOp>;
|
||||
using FoldedDataHiOp = FoldedOp<DataHiOp>;
|
||||
using FoldedDataLowOp = FoldedOp<DataLowOp>;
|
||||
|
||||
struct Imm8Op
|
||||
{
|
||||
using ArgType = uint8_t;
|
||||
@@ -173,6 +225,42 @@ struct Imm8Op
|
||||
}
|
||||
};
|
||||
|
||||
struct AddrOp
|
||||
{
|
||||
struct ArgType
|
||||
{
|
||||
uint8_t scale;
|
||||
InstRegIndex index;
|
||||
InstRegIndex base;
|
||||
uint64_t disp;
|
||||
InstRegIndex segment;
|
||||
};
|
||||
|
||||
const uint8_t scale;
|
||||
const RegIndex index;
|
||||
const RegIndex base;
|
||||
const uint64_t disp;
|
||||
const uint8_t segment;
|
||||
const size_t size;
|
||||
|
||||
template <class InstType>
|
||||
AddrOp(InstType *inst, const ArgType &args) : scale(args.scale),
|
||||
index(INTREG_FOLDED(args.index.index(), inst->foldABit)),
|
||||
base(INTREG_FOLDED(args.base.index(), inst->foldABit)),
|
||||
disp(args.disp), segment(args.segment.index()),
|
||||
size(inst->addressSize)
|
||||
{
|
||||
assert(segment < NUM_SEGMENTREGS);
|
||||
}
|
||||
|
||||
void
|
||||
print(std::ostream &os) const
|
||||
{
|
||||
X86StaticInst::printMem(
|
||||
os, segment, scale, index, base, disp, size, false);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base, typename ...Operands>
|
||||
class InstOperands : public Base, public Operands...
|
||||
{
|
||||
|
||||
@@ -58,37 +58,37 @@ def macroop PREFETCH_T0_P
|
||||
|
||||
def macroop CLFLUSH_M
|
||||
{
|
||||
clflushopt t0, seg, sib, disp, dataSize=1
|
||||
clflushopt seg, sib, disp, dataSize=1
|
||||
mfence
|
||||
};
|
||||
|
||||
def macroop CLFLUSH_P
|
||||
{
|
||||
rdip t7
|
||||
clflushopt t0, seg, riprel, disp, dataSize=1
|
||||
clflushopt seg, riprel, disp, dataSize=1
|
||||
mfence
|
||||
};
|
||||
|
||||
def macroop CLFLUSHOPT_M
|
||||
{
|
||||
clflushopt t0, seg, sib, disp, dataSize=1
|
||||
clflushopt seg, sib, disp, dataSize=1
|
||||
};
|
||||
|
||||
def macroop CLFLUSHOPT_P
|
||||
{
|
||||
rdip t7
|
||||
clflushopt t0, seg, riprel, disp, dataSize=1
|
||||
clflushopt seg, riprel, disp, dataSize=1
|
||||
};
|
||||
|
||||
def macroop CLWB_M
|
||||
{
|
||||
clwb t1, seg, sib, disp, dataSize=1
|
||||
clwb seg, sib, disp, dataSize=1
|
||||
};
|
||||
|
||||
def macroop CLWB_P
|
||||
{
|
||||
rdip t7
|
||||
clwb t1, seg, riprel, disp, dataSize=1
|
||||
clwb seg, riprel, disp, dataSize=1
|
||||
};
|
||||
|
||||
'''
|
||||
|
||||
@@ -58,8 +58,7 @@ def template MicroLeaExecute {{
|
||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||
|
||||
%(code)s;
|
||||
if(fault == NoFault)
|
||||
{
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
@@ -74,13 +73,16 @@ def template MicroLeaDeclare {{
|
||||
%(reg_idx_arr_decl)s;
|
||||
|
||||
public:
|
||||
%(class_name)s(ExtMachInst _machInst,
|
||||
const char * instMnem, uint64_t setFlags,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
InstRegIndex _data,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
Request::FlagsType _memFlags);
|
||||
template <typename ...Args>
|
||||
%(class_name)s(ExtMachInst mach_inst, const char *inst_mnem,
|
||||
uint64_t set_flags, uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, Args ...args) :
|
||||
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
|
||||
args..., data_size, address_size, mem_flags, %(op_class)s)
|
||||
{
|
||||
%(set_reg_idx_arr)s;
|
||||
%(constructor)s;
|
||||
}
|
||||
|
||||
Fault execute(ExecContext *, Trace::InstRecord *) const override;
|
||||
};
|
||||
@@ -89,8 +91,9 @@ def template MicroLeaDeclare {{
|
||||
// Load templates
|
||||
|
||||
def template MicroLoadExecute {{
|
||||
Fault %(class_name)s::execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
Fault
|
||||
%(class_name)s::execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
Addr EA;
|
||||
@@ -108,8 +111,7 @@ def template MicroLoadExecute {{
|
||||
// For prefetches, ignore any faults/exceptions.
|
||||
return NoFault;
|
||||
}
|
||||
if(fault == NoFault)
|
||||
{
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
@@ -118,8 +120,9 @@ def template MicroLoadExecute {{
|
||||
}};
|
||||
|
||||
def template MicroLoadInitiateAcc {{
|
||||
Fault %(class_name)s::initiateAcc(ExecContext * xc,
|
||||
Trace::InstRecord * traceData) const
|
||||
Fault
|
||||
%(class_name)s::initiateAcc(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
Addr EA;
|
||||
@@ -129,16 +132,16 @@ def template MicroLoadInitiateAcc {{
|
||||
%(ea_code)s;
|
||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||
|
||||
fault = initiateMemRead(xc, traceData, EA,
|
||||
%(memDataSize)s, memFlags);
|
||||
fault = initiateMemRead(xc, traceData, EA, %(memDataSize)s, memFlags);
|
||||
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template MicroLoadCompleteAcc {{
|
||||
Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext * xc,
|
||||
Trace::InstRecord * traceData) const
|
||||
Fault
|
||||
%(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
@@ -149,8 +152,7 @@ def template MicroLoadCompleteAcc {{
|
||||
|
||||
%(code)s;
|
||||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
|
||||
@@ -161,7 +163,8 @@ def template MicroLoadCompleteAcc {{
|
||||
// Store templates
|
||||
|
||||
def template MicroStoreExecute {{
|
||||
Fault %(class_name)s::execute(ExecContext * xc,
|
||||
Fault
|
||||
%(class_name)s::execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
@@ -176,7 +179,7 @@ def template MicroStoreExecute {{
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA,
|
||||
memFlags, NULL);
|
||||
memFlags, NULL);
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
@@ -187,8 +190,9 @@ def template MicroStoreExecute {{
|
||||
}};
|
||||
|
||||
def template MicroStoreInitiateAcc {{
|
||||
Fault %(class_name)s::initiateAcc(ExecContext * xc,
|
||||
Trace::InstRecord * traceData) const
|
||||
Fault
|
||||
%(class_name)s::initiateAcc(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
|
||||
@@ -202,15 +206,16 @@ def template MicroStoreInitiateAcc {{
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = writeMemTiming(xc, traceData, Mem, dataSize, EA,
|
||||
memFlags, NULL);
|
||||
memFlags, NULL);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
def template MicroStoreCompleteAcc {{
|
||||
Fault %(class_name)s::completeAcc(PacketPtr pkt,
|
||||
ExecContext * xc, Trace::InstRecord * traceData) const
|
||||
Fault
|
||||
%(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
@@ -227,13 +232,17 @@ def template MicroLdStOpDeclare {{
|
||||
%(reg_idx_arr_decl)s;
|
||||
|
||||
public:
|
||||
%(class_name)s(ExtMachInst _machInst,
|
||||
const char * instMnem, uint64_t setFlags,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
InstRegIndex _data,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
Request::FlagsType _memFlags);
|
||||
template <typename ...Args>
|
||||
%(class_name)s(ExtMachInst mach_inst, const char *inst_mnem,
|
||||
uint64_t set_flags, uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags, Args ...args) :
|
||||
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
|
||||
args..., data_size, address_size, mem_flags, %(op_class)s)
|
||||
{
|
||||
%(set_reg_idx_arr)s;
|
||||
%(constructor)s;
|
||||
}
|
||||
|
||||
|
||||
Fault execute(ExecContext *, Trace::InstRecord *) const override;
|
||||
Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
|
||||
@@ -251,13 +260,13 @@ def template MicroLdStSplitOpDeclare {{
|
||||
%(reg_idx_arr_decl)s;
|
||||
|
||||
public:
|
||||
%(class_name)s(ExtMachInst _machInst,
|
||||
const char * instMnem, uint64_t setFlags,
|
||||
%(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,
|
||||
InstRegIndex _dataLow, InstRegIndex _dataHi,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
Request::FlagsType _memFlags);
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags);
|
||||
|
||||
Fault execute(ExecContext *, Trace::InstRecord *) const override;
|
||||
Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
|
||||
@@ -266,36 +275,17 @@ def template MicroLdStSplitOpDeclare {{
|
||||
};
|
||||
}};
|
||||
|
||||
def template MicroLdStOpConstructor {{
|
||||
%(class_name)s::%(class_name)s(
|
||||
ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
|
||||
uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
|
||||
uint64_t _disp, InstRegIndex _segment,
|
||||
InstRegIndex _data,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
Request::FlagsType _memFlags) :
|
||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
|
||||
_scale, _index, _base,
|
||||
_disp, _segment, _data,
|
||||
_dataSize, _addressSize, _memFlags, %(op_class)s)
|
||||
{
|
||||
%(set_reg_idx_arr)s;
|
||||
%(constructor)s;
|
||||
}
|
||||
}};
|
||||
|
||||
def template MicroLdStSplitOpConstructor {{
|
||||
%(class_name)s::%(class_name)s(
|
||||
ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
|
||||
%(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,
|
||||
InstRegIndex _dataLow, InstRegIndex _dataHi,
|
||||
uint8_t _dataSize, uint8_t _addressSize,
|
||||
Request::FlagsType _memFlags) :
|
||||
%(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
|
||||
_scale, _index, _base,
|
||||
_disp, _segment, _dataLow, _dataHi,
|
||||
_dataSize, _addressSize, _memFlags, %(op_class)s)
|
||||
uint8_t data_size, uint8_t address_size,
|
||||
Request::FlagsType mem_flags) :
|
||||
%(base_class)s(mach_inst, "%(mnemonic)s", inst_mnem, set_flags,
|
||||
data_low, data_hi, _scale, _index, _base, _disp, _segment,
|
||||
data_size, address_size, mem_flags, %(op_class)s)
|
||||
{
|
||||
%(set_reg_idx_arr)s;
|
||||
%(constructor)s;
|
||||
@@ -332,9 +322,9 @@ let {{
|
||||
|
||||
def getAllocator(self, microFlags):
|
||||
allocator = '''new %(class_name)s(machInst, macrocodeBlock,
|
||||
%(flags)s, %(scale)s, %(index)s, %(base)s,
|
||||
%(disp)s, %(segment)s, %(data)s,
|
||||
%(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
|
||||
%(flags)s, %(dataSize)s, %(addressSize)s, %(memFlags)s,
|
||||
%(data)s, %(scale)s, %(index)s, %(base)s,
|
||||
%(disp)s, %(segment)s)''' % {
|
||||
"class_name" : self.className,
|
||||
"flags" : self.microFlagsText(microFlags) + self.instFlags,
|
||||
"scale" : self.scale, "index" : self.index,
|
||||
@@ -376,13 +366,13 @@ let {{
|
||||
allocString = '''
|
||||
(%(dataSize)s >= 4) ?
|
||||
(StaticInstPtr)(new %(class_name)sBig(machInst,
|
||||
macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
|
||||
%(base)s, %(disp)s, %(segment)s, %(data)s,
|
||||
%(dataSize)s, %(addressSize)s, %(memFlags)s)) :
|
||||
macrocodeBlock, %(flags)s, %(dataSize)s,
|
||||
%(addressSize)s, %(memFlags)s, %(data)s, %(scale)s,
|
||||
%(index)s, %(base)s, %(disp)s, %(segment)s)) :
|
||||
(StaticInstPtr)(new %(class_name)s(machInst,
|
||||
macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
|
||||
%(base)s, %(disp)s, %(segment)s, %(data)s,
|
||||
%(dataSize)s, %(addressSize)s, %(memFlags)s))
|
||||
macrocodeBlock, %(flags)s, %(dataSize)s,
|
||||
%(addressSize)s, %(memFlags)s, %(data)s, %(scale)s,
|
||||
%(index)s, %(base)s, %(disp)s, %(segment)s))
|
||||
'''
|
||||
allocator = allocString % {
|
||||
"class_name" : self.className,
|
||||
@@ -406,9 +396,8 @@ let {{
|
||||
|
||||
def getAllocator(self, microFlags):
|
||||
allocString = '''(StaticInstPtr)(new %(class_name)s(machInst,
|
||||
macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
|
||||
%(base)s, %(disp)s, %(segment)s,
|
||||
%(dataLow)s, %(dataHi)s,
|
||||
macrocodeBlock, %(flags)s, %(dataLow)s, %(dataHi)s,
|
||||
%(scale)s, %(index)s, %(base)s, %(disp)s, %(segment)s,
|
||||
%(dataSize)s, %(addressSize)s, %(memFlags)s))
|
||||
'''
|
||||
allocator = allocString % {
|
||||
@@ -423,6 +412,34 @@ let {{
|
||||
"memFlags" : self.memFlags}
|
||||
return allocator
|
||||
|
||||
class MemNoDataOp(X86Microop):
|
||||
def __init__(self, segment, addr, disp=0,
|
||||
dataSize="env.dataSize", addressSize="env.addressSize",
|
||||
baseFlags="0"):
|
||||
[self.scale, self.index, self.base] = addr
|
||||
self.disp = disp
|
||||
self.segment = segment
|
||||
self.dataSize = dataSize
|
||||
self.addressSize = addressSize
|
||||
self.instFlags = ""
|
||||
self.memFlags = baseFlags + "| " \
|
||||
"(machInst.legacy.addr ? (AddrSizeFlagBit << FlagShift) : 0)"
|
||||
|
||||
def getAllocator(self, microFlags):
|
||||
allocator = '''new %(class_name)s(machInst, macrocodeBlock,
|
||||
%(flags)s, %(dataSize)s, %(addressSize)s, %(memFlags)s,
|
||||
%(scale)s, %(index)s, %(base)s, %(disp)s,
|
||||
%(segment)s)''' % {
|
||||
"class_name" : self.className,
|
||||
"flags" : self.microFlagsText(microFlags) + self.instFlags,
|
||||
"scale" : self.scale, "index" : self.index,
|
||||
"base" : self.base,
|
||||
"disp" : self.disp,
|
||||
"segment" : self.segment,
|
||||
"dataSize" : self.dataSize, "addressSize" : self.addressSize,
|
||||
"memFlags" : self.memFlags}
|
||||
return allocator
|
||||
|
||||
}};
|
||||
|
||||
let {{
|
||||
@@ -440,7 +457,7 @@ let {{
|
||||
|
||||
def defineMicroLoadOp(mnemonic, code, bigCode='',
|
||||
mem_flags="0", big=True, nonSpec=False,
|
||||
implicitStack=False):
|
||||
implicitStack=False, is_float=False):
|
||||
global header_output
|
||||
global decoder_output
|
||||
global exec_output
|
||||
@@ -448,19 +465,23 @@ let {{
|
||||
Name = mnemonic
|
||||
name = mnemonic.lower()
|
||||
|
||||
if is_float:
|
||||
base = 'X86ISA::LdStFpOp'
|
||||
else:
|
||||
base = 'X86ISA::LdStOp'
|
||||
|
||||
# Build up the all register version of this micro op
|
||||
iops = [InstObjParams(name, Name, 'X86ISA::LdStOp',
|
||||
iops = [InstObjParams(name, Name, base,
|
||||
{ "code": code,
|
||||
"ea_code": calculateEA,
|
||||
"memDataSize": "dataSize" })]
|
||||
if big:
|
||||
iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
|
||||
iops += [InstObjParams(name, Name + "Big", base,
|
||||
{ "code": bigCode,
|
||||
"ea_code": calculateEA,
|
||||
"memDataSize": "dataSize" })]
|
||||
for iop in iops:
|
||||
header_output += MicroLdStOpDeclare.subst(iop)
|
||||
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||
exec_output += MicroLoadExecute.subst(iop)
|
||||
exec_output += MicroLoadInitiateAcc.subst(iop)
|
||||
exec_output += MicroLoadCompleteAcc.subst(iop)
|
||||
@@ -503,7 +524,8 @@ let {{
|
||||
'(StoreCheck << FlagShift) | Request::LOCKED_RMW',
|
||||
nonSpec=True)
|
||||
|
||||
defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False)
|
||||
defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big=False,
|
||||
is_float=True)
|
||||
|
||||
defineMicroLoadOp('Ldfp87', code='''
|
||||
switch (dataSize)
|
||||
@@ -517,7 +539,7 @@ let {{
|
||||
default:
|
||||
panic("Unhandled data size in LdFp87.\\n");
|
||||
}
|
||||
''', big = False)
|
||||
''', big=False, is_float=True)
|
||||
|
||||
# Load integer from memory into x87 top-of-stack register.
|
||||
# Used to implement fild instruction.
|
||||
@@ -536,7 +558,7 @@ let {{
|
||||
default:
|
||||
panic("Unhandled data size in LdIFp87.\\n");
|
||||
}
|
||||
''', big = False)
|
||||
''', big=False, is_float=True)
|
||||
|
||||
def defineMicroLoadSplitOp(mnemonic, code, mem_flags="0", nonSpec=False):
|
||||
global header_output
|
||||
@@ -584,7 +606,7 @@ let {{
|
||||
nonSpec=True)
|
||||
|
||||
def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0",
|
||||
implicitStack=False):
|
||||
implicitStack=False, is_float=False, has_data=True):
|
||||
global header_output
|
||||
global decoder_output
|
||||
global exec_output
|
||||
@@ -592,14 +614,20 @@ let {{
|
||||
Name = mnemonic
|
||||
name = mnemonic.lower()
|
||||
|
||||
if not has_data:
|
||||
base = 'X86ISA::MemNoDataOp'
|
||||
elif is_float:
|
||||
base = 'X86ISA::LdStFpOp'
|
||||
else:
|
||||
base = 'X86ISA::LdStOp'
|
||||
|
||||
# Build up the all register version of this micro op
|
||||
iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
|
||||
iop = InstObjParams(name, Name, base,
|
||||
{ "code": code,
|
||||
"complete_code": completeCode,
|
||||
"ea_code": calculateEA,
|
||||
"memDataSize": "dataSize" })
|
||||
header_output += MicroLdStOpDeclare.subst(iop)
|
||||
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||
exec_output += MicroStoreExecute.subst(iop)
|
||||
exec_output += MicroStoreInitiateAcc.subst(iop)
|
||||
exec_output += MicroStoreCompleteAcc.subst(iop)
|
||||
@@ -612,17 +640,25 @@ let {{
|
||||
else:
|
||||
addressSize = "env.addressSize"
|
||||
|
||||
class StoreOp(LdStOp):
|
||||
def __init__(self, data, segment, addr, disp = 0,
|
||||
dataSize="env.dataSize",
|
||||
addressSize=addressSize,
|
||||
atCPL0=False, nonSpec=False, implicitStack=implicitStack,
|
||||
uncacheable=False):
|
||||
super(StoreOp, self).__init__(data, segment, addr, disp,
|
||||
dataSize, addressSize, mem_flags, atCPL0, False,
|
||||
nonSpec, implicitStack, uncacheable)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
if has_data:
|
||||
class StoreOp(LdStOp):
|
||||
def __init__(self, data, segment, addr, disp=0,
|
||||
dataSize="env.dataSize", addressSize=addressSize,
|
||||
atCPL0=False, nonSpec=False,
|
||||
implicitStack=implicitStack, uncacheable=False):
|
||||
super(StoreOp, self).__init__(data, segment, addr, disp,
|
||||
dataSize, addressSize, mem_flags, atCPL0, False,
|
||||
nonSpec, implicitStack, uncacheable)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
else:
|
||||
class StoreOp(MemNoDataOp):
|
||||
def __init__(self, segment, addr, disp=0,
|
||||
dataSize="env.dataSize", addressSize=addressSize):
|
||||
super(StoreOp, self).__init__(segment, addr, disp,
|
||||
dataSize, addressSize, mem_flags)
|
||||
self.className = Name
|
||||
self.mnemonic = name
|
||||
|
||||
microopClasses[name] = StoreOp
|
||||
|
||||
@@ -632,7 +668,7 @@ let {{
|
||||
defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
|
||||
mem_flags="Request::LOCKED_RMW")
|
||||
|
||||
defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;')
|
||||
defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;', is_float=True)
|
||||
|
||||
defineMicroStoreOp('Stfp87', code='''
|
||||
switch (dataSize)
|
||||
@@ -647,13 +683,14 @@ let {{
|
||||
default:
|
||||
panic("Unhandled data size in StFp87.\\n");
|
||||
}
|
||||
''')
|
||||
''', is_float=True)
|
||||
|
||||
defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
|
||||
defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS",
|
||||
has_data=False)
|
||||
defineMicroStoreOp('Clflushopt', 'Mem = 0;',
|
||||
mem_flags="Request::CLEAN | Request::INVALIDATE" +
|
||||
" | Request::DST_POC")
|
||||
defineMicroStoreOp('Clwb', 'Mem = 0;',
|
||||
" | Request::DST_POC", has_data=False)
|
||||
defineMicroStoreOp('Clwb', 'Mem = 0;', has_data=False,
|
||||
mem_flags="Request::CLEAN | Request::DST_POC")
|
||||
|
||||
def defineMicroStoreSplitOp(mnemonic, code,
|
||||
@@ -706,7 +743,6 @@ let {{
|
||||
"ea_code": "EA = " + segmentEAExpr,
|
||||
"memDataSize": "dataSize" })
|
||||
header_output += MicroLeaDeclare.subst(iop)
|
||||
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||
exec_output += MicroLeaExecute.subst(iop)
|
||||
|
||||
class LeaOp(LdStOp):
|
||||
@@ -721,35 +757,15 @@ let {{
|
||||
microopClasses["lea"] = LeaOp
|
||||
|
||||
|
||||
iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
|
||||
iop = InstObjParams("tia", "Tia", 'X86ISA::MemNoDataOp',
|
||||
{ "code": "xc->demapPage(EA, 0);",
|
||||
"ea_code": calculateEA,
|
||||
"memDataSize": "dataSize" })
|
||||
header_output += MicroLeaDeclare.subst(iop)
|
||||
decoder_output += MicroLdStOpConstructor.subst(iop)
|
||||
exec_output += MicroLeaExecute.subst(iop)
|
||||
|
||||
class TiaOp(LdStOp):
|
||||
def __init__(self, segment, addr, disp = 0,
|
||||
dataSize="env.dataSize",
|
||||
addressSize="env.addressSize"):
|
||||
super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
|
||||
addr, disp, dataSize, addressSize, "0", False, False,
|
||||
False, False, False)
|
||||
self.className = "Tia"
|
||||
self.mnemonic = "tia"
|
||||
|
||||
class TiaOp(MemNoDataOp):
|
||||
className = "Tia"
|
||||
mnemonic = "tia"
|
||||
microopClasses["tia"] = TiaOp
|
||||
|
||||
class CdaOp(LdStOp):
|
||||
def __init__(self, segment, addr, disp = 0,
|
||||
dataSize="env.dataSize",
|
||||
addressSize="env.addressSize", atCPL0=False):
|
||||
super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
|
||||
addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
|
||||
atCPL0, False, False, False, False)
|
||||
self.className = "Cda"
|
||||
self.mnemonic = "cda"
|
||||
|
||||
microopClasses["cda"] = CdaOp
|
||||
}};
|
||||
|
||||
@@ -93,13 +93,13 @@ def operands {{
|
||||
'SSrcReg1': intReg('src1', 1),
|
||||
'SrcReg2': foldInt('src2', 'foldOBit', 2),
|
||||
'SSrcReg2': intReg('src2', 2),
|
||||
'Index': foldInt('index', 'foldABit', 3),
|
||||
'Base': foldInt('base', 'foldABit', 4),
|
||||
'Index': intReg('index', 3),
|
||||
'Base': intReg('base', 4),
|
||||
'DestReg': foldInt('dest', 'foldOBit', 5),
|
||||
'SDestReg': intReg('dest', 5),
|
||||
'Data': foldInt('data', 'foldOBit', 6),
|
||||
'DataLow': foldInt('dataLow', 'foldOBit', 6),
|
||||
'DataHi': foldInt('dataHi', 'foldOBit', 6),
|
||||
'Data': intReg('data', 6),
|
||||
'DataLow': intReg('dataLow', 6),
|
||||
'DataHi': intReg('dataHi', 6),
|
||||
'ProdLow': impIntReg(0, 7),
|
||||
'ProdHi': impIntReg(1, 8),
|
||||
'Quotient': impIntReg(2, 9),
|
||||
|
||||
Reference in New Issue
Block a user