Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/56492 )
Change subject: arch-x86: Move load/store microops into python.
......................................................................
arch-x86: Move load/store microops into python.
Change-Id: I0fd3d1193b42c90b5ae74c2fe52ef5a95aa9636e
---
M src/arch/x86/isa/microops/ldstop.isa
M src/arch/x86/ucasmlib/arch/x86/microops/__init__.py
A src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py
3 files changed, 425 insertions(+), 379 deletions(-)
diff --git a/src/arch/x86/isa/microops/ldstop.isa
b/src/arch/x86/isa/microops/ldstop.isa
index 99a381a..2e15b71 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -217,10 +217,6 @@
%(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
Trace::InstRecord *traceData) const
{
- %(op_decl)s;
- %(op_rd)s;
- %(complete_code)s;
- %(op_wb)s;
return NoFault;
}
}};
@@ -293,153 +289,6 @@
}};
let {{
- class LdStOp(X86Microop):
- def __init__(self, data, segment, addr, disp,
- dataSize, addressSize, baseFlags, atCPL0, prefetch,
nonSpec,
- uncacheable):
- self.data = data
- [self.scale, self.index, self.base] = addr
- self.disp = disp
- self.segment = segment
- self.dataSize = dataSize
- self.addressSize = addressSize
- self.memFlags = baseFlags
- if atCPL0:
- self.memFlags += " | CPL0FlagBit"
- self.instFlags = ""
- if prefetch:
- self.memFlags += " | Request::PREFETCH"
- self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
- if nonSpec:
- self.instFlags += " | (1ULL <<
StaticInst::IsNonSpeculative)"
- if uncacheable:
- self.instFlags += " | Request::UNCACHEABLE"
- self.memFlags += \
- " | ((log2i(%s) & AddrSizeFlagMask) <<
AddrSizeFlagShift)" % \
- addressSize
-
- def getAllocator(self, microFlags):
- allocator = '''new %(class_name)s(machInst, macrocodeBlock,
- %(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,
- "base" : self.base,
- "disp" : self.disp,
- "segment" : self.segment, "data" : self.data,
- "dataSize" : self.dataSize, "addressSize" :
self.addressSize,
- "memFlags" : self.memFlags}
- return allocator
-
- class BigLdStOp(X86Microop):
- def __init__(self, data, segment, addr, disp,
- dataSize, addressSize, baseFlags, atCPL0, prefetch,
nonSpec,
- uncacheable):
- self.data = data
- [self.scale, self.index, self.base] = addr
- self.disp = disp
- self.segment = segment
- self.dataSize = dataSize
- self.addressSize = addressSize
- self.memFlags = baseFlags
- if atCPL0:
- self.memFlags += " | CPL0FlagBit"
- self.instFlags = ""
- if prefetch:
- self.memFlags += " | Request::PREFETCH"
- self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
- if nonSpec:
- self.instFlags += " | (1ULL <<
StaticInst::IsNonSpeculative)"
- if uncacheable:
- self.instFlags += " | Request::UNCACHEABLE"
- self.memFlags += \
- " | ((log2i(%s) & AddrSizeFlagMask) <<
AddrSizeFlagShift)" % \
- addressSize
-
- def getAllocator(self, microFlags):
- allocString = '''
- (%(dataSize)s >= 4) ?
- (StaticInstPtr)(new %(class_name)sBig(machInst,
- 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, %(dataSize)s,
- %(addressSize)s, %(memFlags)s, %(data)s, %(scale)s,
- %(index)s, %(base)s, %(disp)s, %(segment)s))
- '''
- allocator = allocString % {
- "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, "data" : self.data,
- "dataSize" : self.dataSize, "addressSize" :
self.addressSize,
- "memFlags" : self.memFlags}
- return allocator
-
- class LdStSplitOp(LdStOp):
- def __init__(self, data, segment, addr, disp,
- dataSize, addressSize, baseFlags, atCPL0, prefetch,
nonSpec,
- uncacheable):
- super().__init__(0, segment, addr, disp,
- dataSize, addressSize, baseFlags, atCPL0, prefetch,
nonSpec,
- uncacheable)
- (self.dataLow, self.dataHi) = data
-
- def getAllocator(self, microFlags):
- allocString = '''(StaticInstPtr)(new %(class_name)s(machInst,
- 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 % {
- "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,
- "dataLow" : self.dataLow, "dataHi" : self.dataHi,
- "dataSize" : self.dataSize, "addressSize" :
self.addressSize,
- "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 + \
- " | ((log2i(%s) & AddrSizeFlagMask) <<
AddrSizeFlagShift)" % \
- addressSize
-
- 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 {{
# Make these empty strings so that concatenating onto
# them will always work.
@@ -452,29 +301,20 @@
calculateEA = 'EA = SegBase + ' + segmentEAExpr
- def defineMicroLoadOp(mnemonic, code, bigCode='',
- mem_flags="0", big=True, nonSpec=False,
- is_float=False):
- global header_output
- global decoder_output
- global exec_output
- global microopClasses
- Name = mnemonic
- name = mnemonic.lower()
-
- if is_float:
+ for cls in microopClasses.loadops:
+ if cls.is_float:
base = 'X86ISA::LdStFpOp'
else:
base = 'X86ISA::LdStOp'
# Build up the all register version of this micro op
- iops = [InstObjParams(name, Name, base,
- { "code": code,
+ iops = [InstObjParams(cls.mnemonic, cls.className, base,
+ { "code": cls.code,
"ea_code": calculateEA,
"memDataSize": "dataSize" })]
- if big:
- iops += [InstObjParams(name, Name + "Big", base,
- { "code": bigCode,
+ if cls.big:
+ iops += [InstObjParams(cls.mnemonic, cls.className + "Big",
base,
+ { "code": cls.bigCode,
"ea_code": calculateEA,
"memDataSize": "dataSize" })]
for iop in iops:
@@ -483,78 +323,13 @@
exec_output += MicroLoadInitiateAcc.subst(iop)
exec_output += MicroLoadCompleteAcc.subst(iop)
- base = LdStOp
- if big:
- base = BigLdStOp
- class LoadOp(base):
- def __init__(self, data, segment, addr, disp = 0,
- dataSize="env.dataSize",
- addressSize="env.addressSize",
- atCPL0=False, prefetch=False, nonSpec=nonSpec,
- uncacheable=False):
- super().__init__(data, segment, addr,
- disp, dataSize, addressSize, mem_flags,
- atCPL0, prefetch, nonSpec, uncacheable)
- self.className = Name
- self.mnemonic = name
+ for cls in microopClasses.splitloadops:
+ code = '''
+ DataLow = Mem_u2qw[0];
+ DataHi = Mem_u2qw[1];
+ '''
- microopClasses[name] = LoadOp
-
- defineMicroLoadOp('Ld', 'Data = merge(Data, data, Mem, dataSize);',
- 'Data = Mem & mask(dataSize * 8);')
- defineMicroLoadOp('Ldst', 'Data = merge(Data, data, Mem, dataSize);',
- 'Data = Mem & mask(dataSize * 8);',
- 'Request::READ_MODIFY_WRITE')
- defineMicroLoadOp('Ldstl', 'Data = merge(Data, data, Mem, dataSize);',
- 'Data = Mem & mask(dataSize * 8);',
- 'Request::READ_MODIFY_WRITE | Request::LOCKED_RMW',
- nonSpec=True)
-
- defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big=False,
- is_float=True)
-
- defineMicroLoadOp('Ldfp87', code='''
- switch (dataSize)
- {
- case 4:
- FpData_df = *(float *)&Mem;
- break;
- case 8:
- FpData_df = *(double *)&Mem;
- break;
- default:
- panic("Unhandled data size in LdFp87.\\n");
- }
- ''', big=False, is_float=True)
-
- # Load integer from memory into x87 top-of-stack register.
- # Used to implement fild instruction.
- defineMicroLoadOp('Ldifp87', code='''
- switch (dataSize)
- {
- case 2:
- FpData_df = (int64_t)sext<16>(Mem);
- break;
- case 4:
- FpData_df = (int64_t)sext<32>(Mem);
- break;
- case 8:
- FpData_df = (int64_t)Mem;
- break;
- default:
- panic("Unhandled data size in LdIFp87.\\n");
- }
- ''', big=False, is_float=True)
-
- def defineMicroLoadSplitOp(mnemonic, code, mem_flags="0",
nonSpec=False):
- global header_output
- global decoder_output
- global exec_output
- global microopClasses
- Name = mnemonic
- name = mnemonic.lower()
-
- iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp',
+ iop = InstObjParams(cls.mnemonic,
cls.className, 'X86ISA::LdStSplitOp',
{ "code": code,
"ea_code": calculateEA,
"memDataSize": "2 * dataSize" })
@@ -565,52 +340,17 @@
exec_output += MicroLoadInitiateAcc.subst(iop)
exec_output += MicroLoadCompleteAcc.subst(iop)
- class LoadOp(LdStSplitOp):
- def __init__(self, data, segment, addr, disp = 0,
- dataSize="env.dataSize",
- addressSize="env.addressSize",
- atCPL0=False, prefetch=False, nonSpec=nonSpec,
- uncacheable=False):
- super().__init__(data, segment, addr,
- disp, dataSize, addressSize, mem_flags,
- atCPL0, prefetch, nonSpec, uncacheable)
- self.className = Name
- self.mnemonic = name
-
- microopClasses[name] = LoadOp
-
- code = '''
- DataLow = Mem_u2qw[0];
- DataHi = Mem_u2qw[1];
- '''
-
- defineMicroLoadSplitOp('LdSplit', code,
- 'Request::READ_MODIFY_WRITE')
-
- defineMicroLoadSplitOp('LdSplitl', code,
- 'Request::READ_MODIFY_WRITE |
Request::LOCKED_RMW',
- nonSpec=True)
-
- def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0",
- is_float=False, has_data=True):
- global header_output
- global decoder_output
- global exec_output
- global microopClasses
- Name = mnemonic
- name = mnemonic.lower()
-
- if not has_data:
+ for cls in microopClasses.storeops:
+ if not cls.has_data:
base = 'X86ISA::MemNoDataOp'
- elif is_float:
+ elif cls.is_float:
base = 'X86ISA::LdStFpOp'
else:
base = 'X86ISA::LdStOp'
# Build up the all register version of this micro op
- iop = InstObjParams(name, Name, base,
- { "code": code,
- "complete_code": completeCode,
+ iop = InstObjParams(cls.mnemonic, cls.className, base,
+ { "code": cls.code,
"ea_code": calculateEA,
"memDataSize": "dataSize" })
header_output += MicroLdStOpDeclare.subst(iop)
@@ -618,70 +358,14 @@
exec_output += MicroStoreInitiateAcc.subst(iop)
exec_output += MicroStoreCompleteAcc.subst(iop)
+ for cls in microopClasses.splitstoreops:
+ code = '''
+ Mem_u2qw[0] = DataLow;
+ Mem_u2qw[1] = DataHi;
+ '''
- if has_data:
- class StoreOp(LdStOp):
- def __init__(self, data, segment, addr, disp=0,
- dataSize="env.dataSize",
addressSize="env.addressSize",
- atCPL0=False, nonSpec=False, uncacheable=False):
- super().__init__(data, segment, addr, disp,
- dataSize, addressSize, mem_flags, atCPL0,
False,
- nonSpec, uncacheable)
- self.className = Name
- self.mnemonic = name
- else:
- class StoreOp(MemNoDataOp):
- def __init__(self, segment, addr, disp=0,
- dataSize="env.dataSize",
- addressSize="env.addressSize"):
- super().__init__(segment, addr, disp,
- dataSize, addressSize, mem_flags)
- self.className = Name
- self.mnemonic = name
-
- microopClasses[name] = StoreOp
-
- defineMicroStoreOp('St', 'Mem = PData;')
- defineMicroStoreOp('Stis', 'Mem = PData;')
- defineMicroStoreOp('Stul', 'Mem = PData;',
mem_flags="Request::LOCKED_RMW")
-
- defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;', is_float=True)
-
- defineMicroStoreOp('Stfp87', code='''
- switch (dataSize)
- {
- case 4: {
- float single(FpData_df);
- Mem = *(uint32_t *)&single;
- } break;
- case 8:
- Mem = *(uint64_t *)&FpData_df;
- break;
- default:
- panic("Unhandled data size in StFp87.\\n");
- }
- ''', is_float=True)
-
- 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", has_data=False)
- defineMicroStoreOp('Clwb', 'Mem = 0;', has_data=False,
- mem_flags="Request::CLEAN | Request::DST_POC")
-
- def defineMicroStoreSplitOp(mnemonic, code,
- completeCode="", mem_flags="0"):
- global header_output
- global decoder_output
- global exec_output
- global microopClasses
- Name = mnemonic
- name = mnemonic.lower()
-
- iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp',
+ iop = InstObjParams(cls.mnemonic,
cls.className, 'X86ISA::LdStSplitOp',
{ "code": code,
- "complete_code": completeCode,
"ea_code": calculateEA,
"memDataSize": "2 * dataSize" })
@@ -691,29 +375,6 @@
exec_output += MicroStoreInitiateAcc.subst(iop)
exec_output += MicroStoreCompleteAcc.subst(iop)
- class StoreOp(LdStSplitOp):
- def __init__(self, data, segment, addr, disp = 0,
- dataSize="env.dataSize",
- addressSize="env.addressSize",
- atCPL0=False, nonSpec=False, uncacheable=False):
- super().__init__(data, segment, addr, disp,
- dataSize, addressSize, mem_flags, atCPL0, False,
- nonSpec, uncacheable)
- self.className = Name
- self.mnemonic = name
-
- microopClasses[name] = StoreOp
-
- code = '''
- Mem_u2qw[0] = DataLow;
- Mem_u2qw[1] = DataHi;
- '''
-
- defineMicroStoreSplitOp('StSplit', code);
-
- defineMicroStoreSplitOp('StSplitul', code,
- mem_flags='Request::LOCKED_RMW')
-
iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
{ "code": "Data = merge(Data, data, EA,
dataSize);",
"ea_code": "EA = " + segmentEAExpr,
@@ -721,17 +382,6 @@
header_output += MicroLeaDeclare.subst(iop)
exec_output += MicroLeaExecute.subst(iop)
- class LeaOp(LdStOp):
- def __init__(self, data, segment, addr, disp = 0,
- dataSize="env.dataSize", addressSize="env.addressSize"):
- super().__init__(data, segment, addr, disp,
- dataSize, addressSize, "0",
- False, False, False, False)
- self.className = "Lea"
- self.mnemonic = "lea"
-
- microopClasses["lea"] = LeaOp
-
iop = InstObjParams("tia", "Tia", 'X86ISA::MemNoDataOp',
{ "code": "xc->demapPage(EA, 0);",
@@ -739,9 +389,4 @@
"memDataSize": "dataSize" })
header_output += MicroLeaDeclare.subst(iop)
exec_output += MicroLeaExecute.subst(iop)
-
- class TiaOp(MemNoDataOp):
- className = "Tia"
- mnemonic = "tia"
- microopClasses["tia"] = TiaOp
}};
diff --git a/src/arch/x86/ucasmlib/arch/x86/microops/__init__.py
b/src/arch/x86/ucasmlib/arch/x86/microops/__init__.py
index 90f0c9e..3afee2a 100644
--- a/src/arch/x86/ucasmlib/arch/x86/microops/__init__.py
+++ b/src/arch/x86/ucasmlib/arch/x86/microops/__init__.py
@@ -50,3 +50,11 @@
# Add the load immediate microops.
from . import limmop
microops.update(limmop.microops)
+
+# Add the load/store microops.
+from . import ldstop
+microops.update(ldstop.microops)
+microops.loadops = ldstop.loadops
+microops.splitloadops = ldstop.splitloadops
+microops.storeops = ldstop.storeops
+microops.splitstoreops = ldstop.splitstoreops
diff --git a/src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py
b/src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py
new file mode 100644
index 0000000..c2a5828
--- /dev/null
+++ b/src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py
@@ -0,0 +1,384 @@
+# Copyright 2007-2008 The Hewlett-Packard Development Company
+# Copyright 2015 Advanced Micro Devices, Inc.
+#
+# 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.
+#
+# Copyright (c) 2008 The Regents of The University of Michigan
+# All rights reserved.
+#
+# 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.
+
+from .base import X86Microop
+
+microops = {}
+
+class LdStOp(X86Microop):
+ def __init__(self, data, segment, addr, disp,
+ dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
+ uncacheable):
+ self.data = data
+ [self.scale, self.index, self.base] = addr
+ self.disp = disp
+ self.segment = segment
+ self.dataSize = dataSize
+ self.addressSize = addressSize
+ self.memFlags = baseFlags
+ if atCPL0:
+ self.memFlags += " | CPL0FlagBit"
+ self.instFlags = ""
+ if prefetch:
+ self.memFlags += " | Request::PREFETCH"
+ self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
+ if nonSpec:
+ self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
+ if uncacheable:
+ self.instFlags += " | Request::UNCACHEABLE"
+ self.memFlags += \
+ " | ((log2i(%s) & AddrSizeFlagMask) << AddrSizeFlagShift)" % \
+ addressSize
+
+ def getAllocator(self, microFlags):
+ allocator = '''new %(class_name)s(machInst, macrocodeBlock,
+ %(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,
+ "base" : self.base,
+ "disp" : self.disp,
+ "segment" : self.segment, "data" : self.data,
+ "dataSize" : self.dataSize, "addressSize" : self.addressSize,
+ "memFlags" : self.memFlags}
+ return allocator
+
+class BigLdStOp(X86Microop):
+ def __init__(self, data, segment, addr, disp,
+ dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
+ uncacheable):
+ self.data = data
+ [self.scale, self.index, self.base] = addr
+ self.disp = disp
+ self.segment = segment
+ self.dataSize = dataSize
+ self.addressSize = addressSize
+ self.memFlags = baseFlags
+ if atCPL0:
+ self.memFlags += " | CPL0FlagBit"
+ self.instFlags = ""
+ if prefetch:
+ self.memFlags += " | Request::PREFETCH"
+ self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
+ if nonSpec:
+ self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
+ if uncacheable:
+ self.instFlags += " | Request::UNCACHEABLE"
+ self.memFlags += \
+ " | ((log2i(%s) & AddrSizeFlagMask) << AddrSizeFlagShift)" % \
+ addressSize
+
+ def getAllocator(self, microFlags):
+ allocString = '''
+ (%(dataSize)s >= 4) ?
+ (StaticInstPtr)(new %(class_name)sBig(machInst,
+ 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, %(dataSize)s,
+ %(addressSize)s, %(memFlags)s, %(data)s, %(scale)s,
+ %(index)s, %(base)s, %(disp)s, %(segment)s))
+ '''
+ allocator = allocString % {
+ "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, "data" : self.data,
+ "dataSize" : self.dataSize, "addressSize" : self.addressSize,
+ "memFlags" : self.memFlags}
+ return allocator
+
+class LdStSplitOp(LdStOp):
+ def __init__(self, data, segment, addr, disp,
+ dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
+ uncacheable):
+ super().__init__(0, segment, addr, disp,
+ dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
+ uncacheable)
+ (self.dataLow, self.dataHi) = data
+
+ def getAllocator(self, microFlags):
+ allocString = '''(StaticInstPtr)(new %(class_name)s(machInst,
+ 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 % {
+ "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,
+ "dataLow" : self.dataLow, "dataHi" : self.dataHi,
+ "dataSize" : self.dataSize, "addressSize" : self.addressSize,
+ "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 + \
+ " | ((log2i(%s) & AddrSizeFlagMask) << AddrSizeFlagShift)" % \
+ addressSize
+
+ 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
+
+loadops = []
+
+def defineMicroLoadOp(Name, code, bigCode='',
+ mem_flags="0", big=True, nonSpec=False,
+ is_float=False):
+
+ _code = code
+ _big_code = bigCode
+ _big = big
+ _is_float = is_float
+ class LoadOp(BigLdStOp if big else LdStOp):
+ className = Name
+ mnemonic = Name.lower()
+ code = _code
+ bigCode = _big_code
+ big = _big
+ is_float = _is_float
+
+ def __init__(self, data, segment, addr, disp=0,
+ dataSize="env.dataSize", addressSize="env.addressSize",
+ atCPL0=False, prefetch=False, nonSpec=nonSpec,
+ uncacheable=False):
+ super().__init__(data, segment, addr,
+ disp, dataSize, addressSize, mem_flags,
+ atCPL0, prefetch, nonSpec, uncacheable)
+
+ microops[LoadOp.mnemonic] = LoadOp
+ loadops.append(LoadOp)
+
+defineMicroLoadOp('Ld', 'Data = merge(Data, data, Mem, dataSize);',
+ 'Data = Mem & mask(dataSize * 8);')
+defineMicroLoadOp('Ldst', 'Data = merge(Data, data, Mem, dataSize);',
+ 'Data = Mem & mask(dataSize * 8);',
+ 'Request::READ_MODIFY_WRITE')
+defineMicroLoadOp('Ldstl', 'Data = merge(Data, data, Mem, dataSize);',
+ 'Data = Mem & mask(dataSize * 8);',
+ 'Request::READ_MODIFY_WRITE | Request::LOCKED_RMW',
+ nonSpec=True)
+
+defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big=False,
+ is_float=True)
+
+defineMicroLoadOp('Ldfp87', code='''
+ switch (dataSize)
+ {
+ case 4:
+ FpData_df = *(float *)&Mem;
+ break;
+ case 8:
+ FpData_df = *(double *)&Mem;
+ break;
+ default:
+ panic("Unhandled data size in LdFp87.\\n");
+ }
+''', big=False, is_float=True)
+
+# Load integer from memory into x87 top-of-stack register.
+# Used to implement fild instruction.
+defineMicroLoadOp('Ldifp87', code='''
+ switch (dataSize)
+ {
+ case 2:
+ FpData_df = (int64_t)sext<16>(Mem);
+ break;
+ case 4:
+ FpData_df = (int64_t)sext<32>(Mem);
+ break;
+ case 8:
+ FpData_df = (int64_t)Mem;
+ break;
+ default:
+ panic("Unhandled data size in LdIFp87.\\n");
+ }
+''', big=False, is_float=True)
+
+splitloadops = []
+
+def defineMicroLoadSplitOp(Name, mem_flags="0", nonSpec=False):
+ class LoadOp(LdStSplitOp):
+ className = Name
+ mnemonic = Name.lower()
+ def __init__(self, data, segment, addr, disp=0,
+ dataSize="env.dataSize", addressSize="env.addressSize",
+ atCPL0=False, prefetch=False, nonSpec=nonSpec,
+ uncacheable=False):
+ super().__init__(data, segment, addr,
+ disp, dataSize, addressSize, mem_flags,
+ atCPL0, prefetch, nonSpec, uncacheable)
+
+ microops[LoadOp.mnemonic] = LoadOp
+ splitloadops.append(LoadOp)
+
+defineMicroLoadSplitOp('LdSplit', 'Request::READ_MODIFY_WRITE')
+
+defineMicroLoadSplitOp('LdSplitl',
+ 'Request::READ_MODIFY_WRITE | Request::LOCKED_RMW',
+ nonSpec=True)
+
+storeops = []
+
+def defineMicroStoreOp(Name, code, mem_flags="0",
+ is_float=False, has_data=True):
+
+ _is_float = is_float
+ _has_data = has_data
+ _code = code
+ if has_data:
+ class StoreOp(LdStOp):
+ className = Name
+ mnemonic = Name.lower()
+ is_float = _is_float
+ has_data = _has_data
+ code = _code
+ def __init__(self, data, segment, addr, disp=0,
+ dataSize="env.dataSize", addressSize="env.addressSize",
+ atCPL0=False, nonSpec=False, uncacheable=False):
+ super().__init__(data, segment, addr, disp,
+ dataSize, addressSize, mem_flags, atCPL0, False,
+ nonSpec, uncacheable)
+ else:
+ class StoreOp(MemNoDataOp):
+ className = Name
+ mnemonic = Name.lower()
+ is_float = _is_float
+ has_data = _has_data
+ code = _code
+ def __init__(self, segment, addr, disp=0,
+ dataSize="env.dataSize",
addressSize="env.addressSize"):
+ super().__init__(segment, addr, disp,
+ dataSize, addressSize, mem_flags)
+
+ microops[StoreOp.mnemonic] = StoreOp
+ storeops.append(StoreOp)
+
+defineMicroStoreOp('St', 'Mem = PData;')
+defineMicroStoreOp('Stis', 'Mem = PData;')
+defineMicroStoreOp('Stul', 'Mem = PData;', mem_flags="Request::LOCKED_RMW")
+
+defineMicroStoreOp('Stfp', 'Mem = FpData_uqw;', is_float=True)
+
+defineMicroStoreOp('Stfp87', '''
+ switch (dataSize)
+ {
+ case 4: {
+ float single(FpData_df);
+ Mem = *(uint32_t *)&single;
+ } break;
+ case 8:
+ Mem = *(uint64_t *)&FpData_df;
+ break;
+ default:
+ panic("Unhandled data size in StFp87.\\n");
+ }
+''', is_float=True)
+
+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", has_data=False)
+defineMicroStoreOp('Clwb', 'Mem = 0;', has_data=False,
+ mem_flags="Request::CLEAN | Request::DST_POC")
+
+splitstoreops = []
+
+def defineMicroStoreSplitOp(Name, mem_flags="0"):
+ class StoreOp(LdStSplitOp):
+ className = Name
+ mnemonic = Name.lower()
+ def __init__(self, data, segment, addr, disp=0,
+ dataSize="env.dataSize", addressSize="env.addressSize",
+ atCPL0=False, nonSpec=False, uncacheable=False):
+ super().__init__(data, segment, addr, disp,
+ dataSize, addressSize, mem_flags, atCPL0, False,
+ nonSpec, uncacheable)
+
+ microops[StoreOp.mnemonic] = StoreOp
+ splitstoreops.append(StoreOp)
+
+defineMicroStoreSplitOp('StSplit');
+defineMicroStoreSplitOp('StSplitul', mem_flags='Request::LOCKED_RMW')
+
+class LeaOp(LdStOp):
+ def __init__(self, data, segment, addr, disp = 0,
+ dataSize="env.dataSize", addressSize="env.addressSize"):
+ super().__init__(data, segment, addr, disp,
+ dataSize, addressSize, "0",
+ False, False, False, False)
+ self.className = "Lea"
+ self.mnemonic = "lea"
+
+microops["lea"] = LeaOp
+
+class TiaOp(MemNoDataOp):
+ className = "Tia"
+ mnemonic = "tia"
+
+microops["tia"] = TiaOp
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/56492
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I0fd3d1193b42c90b5ae74c2fe52ef5a95aa9636e
Gerrit-Change-Number: 56492
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s