Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/56488 )
Change subject: arch-x86: Refactor fp uops to separate out C++ generation.
......................................................................
arch-x86: Refactor fp uops to separate out C++ generation.
With the C++ generation handled separately, it can be done at a
different time and in a different body of code from where the microops
themselves are defined. One can stay in the ISA description, while the
other moves to the microcode asm library.
Change-Id: I468d78b82e689c92d07a92abd0c26f44da0c9e2f
---
M src/arch/x86/isa/microops/fpop.isa
M src/arch/x86/ucasmlib/arch/x86/microops.py
2 files changed, 92 insertions(+), 87 deletions(-)
diff --git a/src/arch/x86/isa/microops/fpop.isa
b/src/arch/x86/isa/microops/fpop.isa
index 6fda08c..f73f181 100644
--- a/src/arch/x86/isa/microops/fpop.isa
+++ b/src/arch/x86/isa/microops/fpop.isa
@@ -100,100 +100,21 @@
}};
let {{
-
- # Make these empty strings so that concatenating onto
- # them will always work.
- header_output = ""
- decoder_output = ""
- exec_output = ""
+ microopClasses.fpops = []
class FpOpMeta(type):
- def buildCppClasses(self, name, Name, suffix, code, flag_code,
- cond_check, else_code, op_class, operand_types):
-
- # Globals to stick the output in
- global header_output
- global decoder_output
- global exec_output
-
- # Stick all the code together so it can be searched at once
- allCode = "|".join((code, flag_code, cond_check, else_code))
-
- # If there's something optional to do with flags, generate
- # a version without it and fix up this version to use it.
- if flag_code != "" or cond_check != "true":
- self.buildCppClasses(name, Name, suffix,
- code, "", "true", else_code, op_class,
operand_types)
- suffix = "Flags" + suffix
-
- base = "X86ISA::InstOperands<" + \
- ", ".join(["X86ISA::FpOp"] +
- [op.cxx_class() for op in operand_types]) + ">"
-
- # Get everything ready for the substitution
- iop_tag = InstObjParams(name, Name + suffix + "TopTag", base,
- {"code" : code,
- "flag_code" : flag_code,
- "cond_check" : cond_check,
- "else_code" : else_code,
- "tag_code" : "FTW = genX87Tags(FTW, TOP, spm);",
- "top_code" : "TOP = (TOP + spm + 8) % 8;",
- "op_class" : op_class})
- iop_top = InstObjParams(name, Name + suffix + "Top", base,
- {"code" : code,
- "flag_code" : flag_code,
- "cond_check" : cond_check,
- "else_code" : else_code,
- "tag_code" : ";",
- "top_code" : "TOP = (TOP + spm + 8) % 8;",
- "op_class" : op_class})
- iop = InstObjParams(name, Name + suffix, base,
- {"code" : code,
- "flag_code" : flag_code,
- "cond_check" : cond_check,
- "else_code" : else_code,
- "tag_code" : ";",
- "top_code" : ";",
- "op_class" : op_class})
-
- # Generate the actual code (finally!)
- header_output += MicroFpOpDeclare.subst(iop_tag)
- decoder_output += MicroFpOpConstructor.subst(iop_tag)
- exec_output += MicroFpOpExecute.subst(iop_tag)
- header_output += MicroFpOpDeclare.subst(iop_top)
- decoder_output += MicroFpOpConstructor.subst(iop_top)
- exec_output += MicroFpOpExecute.subst(iop_top)
- header_output += MicroFpOpDeclare.subst(iop)
- decoder_output += MicroFpOpConstructor.subst(iop)
- exec_output += MicroFpOpExecute.subst(iop)
-
-
def __new__(mcls, Name, bases, dict):
- abstract = False
- name = Name.lower()
- if "abstract" in dict:
- abstract = dict['abstract']
- del dict['abstract']
+ dict.setdefault('abstract', False)
+ dict['className'] = Name
+ dict['mnemonic'] = Name.lower()
cls = super().__new__(mcls, Name, bases, dict)
- if not abstract:
- cls.className = Name
- cls.mnemonic = name
- code = cls.code
- flag_code = cls.flag_code
- cond_check = cls.cond_check
- else_code = cls.else_code
- op_class = cls.op_class
- operand_types = cls.operand_types
- # Set up the C++ classes
- mcls.buildCppClasses(cls, name, Name, "",
- code, flag_code, cond_check, else_code, op_class,
- operand_types)
-
+ if not cls.abstract:
# Hook into the microassembler dict
global microopClasses
- microopClasses[name] = cls
+ microopClasses[cls.mnemonic] = cls
+ microopClasses.fpops.append(cls)
return cls
@@ -430,4 +351,72 @@
class Pop87(Fp0Op):
code = ''
op_class = 'IntAluOp'
+
+ def buildCppClasses(cls, suffix="", flag_code=None, cond_check=None):
+
+ if flag_code is None:
+ flag_code = cls.flag_code
+ if cond_check is None:
+ cond_check = cls.cond_check
+
+ # Stick all the code together so it can be searched at once
+ allCode = "|".join((cls.code, flag_code, cond_check,
cls.else_code))
+
+ # If there's something optional to do with flags, generate
+ # a version without it and fix up this version to use it.
+ if flag_code != "" or cond_check != "true":
+ buildCppClasses(cls, suffix, "", "true")
+ suffix = "Flags" + suffix
+
+ base = "X86ISA::InstOperands<" + \
+ ", ".join(["X86ISA::FpOp"] +
+ [op.cxx_class() for op in cls.operand_types]) + ">"
+
+ # Get everything ready for the substitution
+ iop_tag = InstObjParams(cls.mnemonic,
+ cls.className + suffix + "TopTag", base,
+ {"code" : cls.code,
+ "flag_code" : flag_code,
+ "cond_check" : cond_check,
+ "else_code" : cls.else_code,
+ "tag_code" : "FTW = genX87Tags(FTW, TOP, spm);",
+ "top_code" : "TOP = (TOP + spm + 8) % 8;",
+ "op_class" : cls.op_class})
+ iop_top = InstObjParams(cls.mnemonic,
+ cls.className + suffix + "Top", base,
+ {"code" : cls.code,
+ "flag_code" : flag_code,
+ "cond_check" : cond_check,
+ "else_code" : cls.else_code,
+ "tag_code" : ";",
+ "top_code" : "TOP = (TOP + spm + 8) % 8;",
+ "op_class" : cls.op_class})
+ iop = InstObjParams(cls.mnemonic,
+ cls.className + suffix, base,
+ {"code" : cls.code,
+ "flag_code" : flag_code,
+ "cond_check" : cond_check,
+ "else_code" : cls.else_code,
+ "tag_code" : ";",
+ "top_code" : ";",
+ "op_class" : cls.op_class})
+
+ # Globals to stick the output in
+ global header_output
+ global decoder_output
+ global exec_output
+
+ # Generate the actual code (finally!)
+ header_output += MicroFpOpDeclare.subst(iop_tag)
+ decoder_output += MicroFpOpConstructor.subst(iop_tag)
+ exec_output += MicroFpOpExecute.subst(iop_tag)
+ header_output += MicroFpOpDeclare.subst(iop_top)
+ decoder_output += MicroFpOpConstructor.subst(iop_top)
+ exec_output += MicroFpOpExecute.subst(iop_top)
+ header_output += MicroFpOpDeclare.subst(iop)
+ decoder_output += MicroFpOpConstructor.subst(iop)
+ exec_output += MicroFpOpExecute.subst(iop)
+
+ for cls in microopClasses.fpops:
+ buildCppClasses(cls)
}};
diff --git a/src/arch/x86/ucasmlib/arch/x86/microops.py
b/src/arch/x86/ucasmlib/arch/x86/microops.py
index ab6a14b..bcc432d 100644
--- a/src/arch/x86/ucasmlib/arch/x86/microops.py
+++ b/src/arch/x86/ucasmlib/arch/x86/microops.py
@@ -32,7 +32,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-classes = {}
+class ExpandableDict(dict):
+ pass
+classes = ExpandableDict()
class X86Microop(object):
def __init__(self, name):
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/56488
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: I468d78b82e689c92d07a92abd0c26f44da0c9e2f
Gerrit-Change-Number: 56488
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