Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/56470 )
Change subject: arch-x86: Move the macroop type into pure python.
......................................................................
arch-x86: Move the macroop type into pure python.
Also expose it to the microcode assembler directly by making it part of
the ucasmlib namespace package.
Change-Id: I86e5193a35fc770363e6dbc6e2386880af312a1f
---
M src/arch/x86/isa/macroop.isa
M src/arch/x86/isa/microasm.isa
M src/arch/x86/ucasmlib/arch/x86/__init__.py
A src/arch/x86/ucasmlib/arch/x86/macroop.py
4 files changed, 228 insertions(+), 198 deletions(-)
diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa
index bc5effc..8331d94 100644
--- a/src/arch/x86/isa/macroop.isa
+++ b/src/arch/x86/isa/macroop.isa
@@ -35,202 +35,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Basic instruction class declaration template.
-def template MacroDeclare {{
- GEM5_DEPRECATED_NAMESPACE(X86Macroop, x86_macroop);
- namespace x86_macroop
- {
- /**
- * Static instruction class for "%(mnemonic)s".
- */
- class %(class_name)s : public %(base_class)s
- {
- private:
- %(declareLabels)s
- public:
- // Constructor.
- %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv _env);
-
- std::string generateDisassembly(
- Addr pc, const loader::SymbolTable *symtab) const
override;
- };
- }
-}};
-
-def template MacroDisassembly {{
- std::string
- x86_macroop::%(class_name)s::generateDisassembly(
- Addr pc, const loader::SymbolTable *symtab) const
- {
- std::stringstream out;
- out << mnemonic << "\t";
-
- int regSize = %(regSize)s;
- %(disassembly)s
- // Shut up gcc.
- regSize = regSize;
- return out.str();
- }
-}};
-
-// Basic instruction class constructor template.
-def template MacroConstructor {{
- x86_macroop::%(class_name)s::%(class_name)s(
- ExtMachInst machInst, EmulEnv _env)
- : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s,
_env)
- {
- %(adjust_env)s;
- %(adjust_imm)s;
- %(adjust_disp)s;
- %(init_env)s;
- %(constructor)s;
- const char *macrocodeBlock = "%(class_name)s";
- //alloc_microops is the code that sets up the microops
- //array in the parent class.
- %(alloc_microops)s;
- }
-}};
-
-let {{
- from ucasmlib.containers import Macroop
- class X86Macroop(Macroop):
- def setAdjustEnv(self, val):
- self.adjust_env = val
- def adjustImm(self, val):
- self.adjust_imm += val
- def adjustDisp(self, val):
- self.adjust_disp += val
- def serializeBefore(self):
- self.serialize_before = True
- def serializeAfter(self):
- self.serialize_after = True
-
- def function_call(self):
- self.function_call = True
- def function_return(self):
- self.function_return = True
- def control_direct(self):
- self.control_direct = True
- def control_indirect(self):
- self.control_indirect = True
-
- def __init__(self, name):
- super().__init__(name)
- self.directives = {
- "adjust_env" : self.setAdjustEnv,
- "adjust_imm" : self.adjustImm,
- "adjust_disp" : self.adjustDisp,
- "serialize_before" : self.serializeBefore,
- "serialize_after" : self.serializeAfter,
- "function_call" : self.function_call,
- "function_return" : self.function_return,
- "control_direct" : self.control_direct,
- "control_indirect" : self.control_indirect
- }
- self.declared = False
- self.adjust_env = ""
- self.init_env = ""
- self.adjust_imm = '''
- uint64_t adjustedImm = IMMEDIATE;
- //This is to pacify gcc in case the immediate isn't used.
- adjustedImm = adjustedImm;
- '''
- self.adjust_disp = '''
- uint64_t adjustedDisp = DISPLACEMENT;
- //This is to pacify gcc in case the displacement isn't
used.
- adjustedDisp = adjustedDisp;
- '''
- self.serialize_before = False
- self.serialize_after = False
- self.function_call = False
- self.function_return = False
- self.control_direct = False
- self.control_indirect = False
-
- def getAllocator(self, env):
- return "new x86_macroop::%s(machInst, %s)" % \
- (self.name, env.getAllocator())
- def getMnemonic(self):
- mnemonic = self.name.lower()
- mnemonic = re.match(r'[^_]*', mnemonic).group(0)
- return mnemonic
- def getDeclaration(self):
- #FIXME This first parameter should be the mnemonic. I need to
- #write some code which pulls that out
- declareLabels = ""
- for (label, micropc) in self.labels.items():
- declareLabels += "const static uint64_t label_%s = %d;\n" \
- % (label, micropc)
- iop = InstObjParams(self.getMnemonic(), self.name,
- "X86ISA::MacroopBase",
- {"code" : "",
- "declareLabels" : declareLabels
- })
- return MacroDeclare.subst(iop);
- def getDefinition(self, env):
- #FIXME This first parameter should be the mnemonic. I need to
- #write some code which pulls that out
- numMicroops = len(self.microops)
- allocMicroops = ''
- micropc = 0
- for op in self.microops:
- flags = ["IsMicroop"]
- if micropc == 0:
- flags.append("IsFirstMicroop")
-
- if self.serialize_before:
- flags.append("IsSerializing")
- flags.append("IsSerializeBefore")
-
- if micropc == numMicroops - 1:
- flags.append("IsLastMicroop")
-
- if self.serialize_after:
- flags.append("IsSerializing")
- flags.append("IsSerializeAfter")
-
- if self.function_call:
- flags.append("IsCall")
- flags.append("IsUncondControl")
- if self.function_return:
- flags.append("IsReturn")
- flags.append("IsUncondControl")
- if self.control_direct:
- flags.append("IsDirectControl")
- if self.control_indirect:
- flags.append("IsIndirectControl")
- else:
- flags.append("IsDelayedCommit")
-
- allocMicroops += \
- "microops[%d] = %s;\n" % \
- (micropc, op.getAllocator(flags))
- micropc += 1
- if env.useStackSize:
- useStackSize = "true"
- else:
- useStackSize = "false"
- if env.memoryInst:
- memoryInst = "true"
- else:
- memoryInst = "false"
- regSize = '''(%s || (env.base == INTREG_RSP && %s) ?
- env.stackSize :
- env.dataSize)''' % (useStackSize, memoryInst)
- iop = InstObjParams(self.getMnemonic(), self.name,
- "X86ISA::MacroopBase",
- {"code" : "", "num_microops" : numMicroops,
- "alloc_microops" : allocMicroops,
- "adjust_env" : self.adjust_env,
- "adjust_imm" : self.adjust_imm,
- "adjust_disp" : self.adjust_disp,
- "disassembly" : env.disassembly,
- "regSize" : regSize,
- "init_env" : self.initEnv})
- return MacroConstructor.subst(iop) + \
- MacroDisassembly.subst(iop);
-}};
-
let {{
class EmulEnv(object):
def __init__(self):
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa
index 5293410..cb16e4a 100644
--- a/src/arch/x86/isa/microasm.isa
+++ b/src/arch/x86/isa/microasm.isa
@@ -52,11 +52,11 @@
from insts import microcode
sys.path[0:0] = ["src/arch/x86/"]
from ucasmlib.assembler import MicroAssembler
- from ucasmlib.arch.x86 import Rom
+ from ucasmlib.arch.x86 import Rom, Macroop
sys.path = old_path
mainRom = Rom('main ROM')
- assembler = MicroAssembler(X86Macroop, microopClasses, mainRom)
+ assembler = MicroAssembler(Macroop, microopClasses, mainRom)
def gpRegIdx(idx):
return "X86ISA::GpRegIndex(%s)" % idx
diff --git a/src/arch/x86/ucasmlib/arch/x86/__init__.py
b/src/arch/x86/ucasmlib/arch/x86/__init__.py
index 6a1bdd7..d4cb77c 100644
--- a/src/arch/x86/ucasmlib/arch/x86/__init__.py
+++ b/src/arch/x86/ucasmlib/arch/x86/__init__.py
@@ -24,3 +24,4 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from .rom import Rom
+from .macroop import Macroop
diff --git a/src/arch/x86/ucasmlib/arch/x86/macroop.py
b/src/arch/x86/ucasmlib/arch/x86/macroop.py
new file mode 100644
index 0000000..249d47e
--- /dev/null
+++ b/src/arch/x86/ucasmlib/arch/x86/macroop.py
@@ -0,0 +1,213 @@
+# Copyright (c) 2007 The Hewlett-Packard Development Company
+# 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.
+
+import re
+
+# Basic instruction class declaration template.
+MacroDeclare = """
+ GEM5_DEPRECATED_NAMESPACE(X86Macroop, x86_macroop);
+ namespace x86_macroop
+ {{
+ /**
+ * Static instruction class for "{mnemonic}".
+ */
+ class {class_name} : public X86ISA::MacroopBase
+ {{
+ private:
+ {declare_labels}
+ public:
+ // Constructor.
+ {class_name}(ExtMachInst machInst, X86ISA::EmulEnv _env);
+
+ std::string generateDisassembly(
+ Addr pc, const loader::SymbolTable *symtab) const
override;
+ }};
+ }}
+"""
+
+MacroDisassembly = """
+ std::string
+ x86_macroop::{class_name}::generateDisassembly(
+ Addr pc, const loader::SymbolTable *symtab) const
+ {{
+ std::stringstream out;
+ out << mnemonic << "\\t";
+
+ [[maybe_unused]] int regSize = {reg_size};
+ {disassembly}
+ return out.str();
+ }}
+"""
+
+# Basic instruction class constructor template.
+MacroConstructor = """
+ x86_macroop::{class_name}::{class_name}(
+ ExtMachInst machInst, EmulEnv _env) :
+ X86ISA::MacroopBase("{mnemonic}", machInst, {num_microops}, _env)
+ {{
+ {adjust_env};
+ {adjust_imm};
+ {adjust_disp};
+ {init_env};
+ const char *macrocodeBlock = "{class_name}";
+ //alloc_microops is the code that sets up the microops
+ //array in the parent class.
+ {alloc_microops};
+ }}
+"""
+
+from ucasmlib.containers import Macroop
+class Macroop(Macroop):
+ def setAdjustEnv(self, val):
+ self.adjust_env = val
+ def adjustImm(self, val):
+ self.adjust_imm += val
+ def adjustDisp(self, val):
+ self.adjust_disp += val
+ def serializeBefore(self):
+ self.serialize_before = True
+ def serializeAfter(self):
+ self.serialize_after = True
+
+ def function_call(self):
+ self.function_call = True
+ def function_return(self):
+ self.function_return = True
+ def control_direct(self):
+ self.control_direct = True
+ def control_indirect(self):
+ self.control_indirect = True
+
+ def __init__(self, name):
+ super().__init__(name)
+ self.directives = {
+ "adjust_env" : self.setAdjustEnv,
+ "adjust_imm" : self.adjustImm,
+ "adjust_disp" : self.adjustDisp,
+ "serialize_before" : self.serializeBefore,
+ "serialize_after" : self.serializeAfter,
+ "function_call" : self.function_call,
+ "function_return" : self.function_return,
+ "control_direct" : self.control_direct,
+ "control_indirect" : self.control_indirect
+ }
+ self.declared = False
+ self.adjust_env = ""
+ self.init_env = ""
+ self.adjust_imm = '[[maybe_unused]] uint64_t adjustedImm =
IMMEDIATE;'
+ self.adjust_disp = \
+ '[[maybe_unused]] uint64_t adjustedDisp = DISPLACEMENT;'
+ self.serialize_before = False
+ self.serialize_after = False
+ self.function_call = False
+ self.function_return = False
+ self.control_direct = False
+ self.control_indirect = False
+
+ def getAllocator(self, env):
+ return f"new x86_macroop::{self.name}(machInst,
{env.getAllocator()})"
+ def getMnemonic(self):
+ return re.split(r'_', self.name)[0].lower()
+ def getDeclaration(self):
+ declare_labels = '\n'.join(
+ f"const static uint64_t label_{label} = {micropc};" for
+ (label, micropc) in self.labels.items())
+ return MacroDeclare.format(
+ class_name = self.name,
+ mnemonic = self.getMnemonic(),
+ declare_labels = declare_labels
+ )
+ def getDefinition(self, env):
+ num_microops = len(self.microops)
+ alloc_microops = ''
+ micropc = 0
+ for op in self.microops:
+ flags = ["IsMicroop"]
+ if micropc == 0:
+ flags.append("IsFirstMicroop")
+
+ if self.serialize_before:
+ flags.append("IsSerializing")
+ flags.append("IsSerializeBefore")
+
+ if micropc == num_microops - 1:
+ flags.append("IsLastMicroop")
+
+ if self.serialize_after:
+ flags.append("IsSerializing")
+ flags.append("IsSerializeAfter")
+
+ if self.function_call:
+ flags.append("IsCall")
+ flags.append("IsUncondControl")
+ if self.function_return:
+ flags.append("IsReturn")
+ flags.append("IsUncondControl")
+ if self.control_direct:
+ flags.append("IsDirectControl")
+ if self.control_indirect:
+ flags.append("IsIndirectControl")
+ else:
+ flags.append("IsDelayedCommit")
+
+ alloc_microops += \
+ f"microops[{micropc}] = {op.getAllocator(flags)};\n"
+ micropc += 1
+ if env.useStackSize:
+ use_stack_size = "true"
+ else:
+ use_stack_size = "false"
+ if env.memoryInst:
+ memory_inst = "true"
+ else:
+ memory_inst = "false"
+ reg_size = f'''({use_stack_size} ||
+ (env.base == INTREG_RSP && {memory_inst}) ?
+ env.stackSize : env.dataSize)'''
+
+ subst = {
+ 'class_name': self.name,
+ 'mnemonic': self.getMnemonic(),
+ 'num_microops' : num_microops,
+ 'alloc_microops' : alloc_microops,
+ 'adjust_env' : self.adjust_env,
+ 'adjust_imm' : self.adjust_imm,
+ 'adjust_disp' : self.adjust_disp,
+ 'disassembly' : env.disassembly,
+ 'reg_size' : reg_size,
+ 'init_env' : self.initEnv
+ }
+ return MacroConstructor.format(**subst) + \
+ MacroDisassembly.format(**subst)
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/56470
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: I86e5193a35fc770363e6dbc6e2386880af312a1f
Gerrit-Change-Number: 56470
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