Commit 0253aaae authored by Benoit Perrot's avatar Benoit Perrot
Browse files

Index: ChangeLog

--- ChangeLog Thu, 08 Jan 2004 15:27:18 +0100 noe (mipsy/2_ChangeLog 1.54 604)
+++ ChangeLog Sat, 10 Jan 2004 22:21:15 +0100 noe (mipsy/2_ChangeLog 1.54 604)
@@ -1,3 +1,13 @@
+2004-01-10  Benoît Perrot  <benoit@lrde.epita.fr>
+
+	* dev/mipsy.xml: Use a better DTD.
+	* dev/mipsy.py: Use new DTD.
+	* dev/inst-builder-gen.py,
+	* dev/inst-nodes-gen.py,
+	* dev/parse-asm-parse-gen.py,
+	* dev/parse-asm-scan-gen.py:
+	Use new mipsy.py package.	
+
parent 07584f19
2004-01-10 Benot Perrot <benoit@lrde.epita.fr>
* dev/mipsy.xml: Use a better DTD.
* dev/mipsy.py: Use new DTD.
* dev/inst-builder-gen.py,
* dev/inst-nodes-gen.py,
* dev/parse-asm-parse-gen.py,
* dev/parse-asm-scan-gen.py:
Use new mipsy.py package.
2004-01-08 Benot Perrot <benoit@lrde.epita.fr>
* dev/parse-asm-scan.py: Simplify scanner register generation.
......
......@@ -111,9 +111,8 @@ for inst in instructions:
if syntax.level == "native":
proto = ""
call = ""
for attribute in inst.format.params:
proto = proto + type_map[attribute.kind] + " " + \
attribute.name + ", "
for attribute in inst.format.attributes:
proto = proto + attribute.type + "& " + attribute.name + ", "
call = call + attribute.name + ", "
proto = string.rstrip(proto, ", ")
call = string.rstrip(call, ", ")
......@@ -133,10 +132,10 @@ for inst in instructions:
else: # syntax.level == "complex"
proto = ""
for param in syntax.params:
proto = proto + type_map[param.kind]
if param.name:
proto = proto + " " + param.name
for token in syntax.tokens:
proto = proto + type_map[token.kind]
if token.name:
proto = proto + " " + token.name
proto = proto + ", "
proto = string.rstrip(proto, ", ")
print " void\tadd_" + inst.opcode + "(" + proto + ");"
......
......@@ -59,8 +59,8 @@ namespace inst
print " public:"
proto = ""
init = ""
for attribute in format.params:
proto = proto + type_map[attribute.kind] + " " + attribute.name + ", "
for attribute in format.attributes:
proto = proto + attribute.type + "& " + attribute.name + ", "
init = init + attribute.name + "(" + attribute.name + "), "
proto = string.rstrip(proto, ", ")
init = string.rstrip(init, ", ")
......@@ -81,14 +81,14 @@ namespace inst
## Methods: accessors
print """
public:"""
for attribute in format.params:
type = type_map[attribute.kind]
print " const " + type + "\t\tget_" + attribute.name + " () const"
for attribute in format.attributes:
type = attribute.type
print " const " + type + "&\t\tget_" + attribute.name + " () const"
print " {"
print " return " + attribute.name + ";"
print " }"
if type != "int":
print " " + type + "\t\tget_" + attribute.name + " ()"
print " " + type + "&\t\tget_" + attribute.name + " ()"
print " {"
print " return " + attribute.name + ";"
print " }"
......@@ -113,15 +113,15 @@ namespace inst
{"""
s = ""
i = 0
while i < len(format.params):
if (i < len(format.params) - 1) and \
(format.params[i].kind == "immediate") and \
(format.params[i + 1].kind == "register"):
s = s + " << " + format.params[i].name + \
" << '(' << " + format.params[i + 1].name + " << ')' "
while i < len(format.attributes):
if (i < len(format.attributes) - 1) and \
(format.attributes[i].type == "Exp") and \
(format.attributes[i + 1].type == "Register"):
s = s + " << " + format.attributes[i].name + \
" << '(' << " + format.attributes[i + 1].name + " << ')' "
i = i + 1
else:
s = s + " << " + format.params[i].name + " << \", \""
s = s + " << " + format.attributes[i].name + " << \", \""
i = i + 1
s = string.rstrip(s, "<< \", \"")
print " ostr << \"" + inst.opcode + "\\t\"" + s + ";"
......@@ -130,8 +130,8 @@ namespace inst
## Print attributes
print " protected:"
for attribute in format.params:
print " " + type_map[attribute.kind] + "\t\t" + attribute.name + ";"
for attribute in format.attributes:
print " " + attribute.type + "&\t\t" + attribute.name + ";"
print " };"
print """
} // namespace inst
......
......@@ -19,7 +19,7 @@
##
import string
import os.path, filecmp, shutil
import sys, os.path, filecmp, shutil
from xml.sax import ContentHandler, make_parser
## ---------------------------------------------------------------------------
......@@ -90,148 +90,192 @@ def file_id(s):
return string.lower(s)
## -------------------------------------
class Param:
def __init__(self, kind, name, value, default):
self.kind = kind
class Attribute:
def __init__(self, type, name, value):
self.type = type
self.name = name
self.value = value
self.default = default
def display(self):
print self.kind + " " + self.name + " = " + self.value
class ParamBuilder:
self.value = value # FIXME: useless
def __str__(self):
return "<attribute type=\"" + self.type + "\" name=\"" + self.name +"\" />"
class AttributeBuilder:
def reset(self):
self.kind = ""
self.type = ""
self.name = ""
self.value = ""
self.default = ""
self.value = ""# FIXME: useless
def __init__(self):
self.reset()
def get(self):
return Param(self.kind, self.name, self.value, self.default)
assert(self.type != "" and self.name != "")
return Attribute(self.type, self.name, self.value)
## -------------------------------------
class Format:
def __init__(self, params):
self.params = params
def display(self):
for p in self.params:
p.display()
def __init__(self, attributes):
self.attributes = attributes
def __str__(self):
res = " <format>"
for p in self.attributes:
res = res + "\n " + str(p)
return res + "\n </format>"
class FormatBuilder:
def reset(self):
self.params = []
self.attributes = []
def __init__(self):
self.reset()
def get(self):
return Format(self.attributes)
## -------------------------------------
class Token:
def __init__(self, kind, name, value, default):
self.kind = kind
self.name = name
self.value = value
self.default = default
def __str__(self):
res = "<token kind=\"" + self.kind + "\" "
if self.name != "":
res = res + "name=\"" + self.name + "\" "
if self.value != "":
res = res + "value=\"" + self.value + "\" "
if self.default != "":
res = res + "default=\"" + self.default + "\" "
return res + "/>"
class TokenBuilder:
def reset(self):
self.kind = ""
self.name = ""
self.value = ""
self.default = ""
def __init__(self):
self.reset()
def get(self):
return Format(self.params)
assert(self.kind != "")
return Token(self.kind, self.name, self.value, self.default)
## -------------------------------------
class Syntax:
def __init__(self, params, alias, level):
self.params = params
def __init__(self, tokens, alias, level):
self.tokens = tokens
self.alias = alias
self.level = level
def display(self):
def __str__(self):
res = " <syntax"
if self.alias != "":
print self.alias
for p in self.params:
p.display()
res = res + " alias=\"" + self.alias + "\""
res = res + ">"
for t in self.tokens:
res = res + "\n " + str(t)
return res + "\n </syntax>"
class SyntaxBuilder:
def reset(self):
self.params = []
self.tokens = []
self.alias = ""
def __init__(self):
self.reset()
def get(self):
return Syntax(self.params, self.alias, self.level)
return Syntax(self.tokens, self.alias, self.level)
## -------------------------------------
class Instruction:
def __init__(self, opcode, level, kind, format, syntaxes):
def __init__(self, opcode, level, kind, desc, format, syntaxes):
self.opcode = opcode
self.level = level
self.kind = kind
self.desc = desc
self.format = format
self.syntaxes = syntaxes
def display(self):
print self.opcode + " >>"
self.format.display()
def __str__(self):
res = "<instruction opcode=\"" + self.opcode + \
"\" level=\"" + self.level + \
"\" kind=\"" + self.kind + ">\n" + \
" <description>" + self.desc + "</description>\n" + \
str(self.format) + "\n"
for s in self.syntaxes:
print "<syntax>"
s.display()
print "</syntax>"
res = res + str(s) + "\n"
return res + "</instruction>"
class InstructionBuilder:
def reset(self):
self.opcode = ""
self.level = ""
self.kind = ""
self.desc = ""
self.format = Format("")
self.syntaxes = []
def __init__(self):
self.reset()
def get(self):
return Instruction(self.opcode, self.level, self.kind,
assert(self.opcode != "" and self.level != "" and self.kind != "")
return Instruction(self.opcode, self.level, self.kind, self.desc,
self.format, self.syntaxes)
## -------------------------------------
## -------------------------------------
class InstructionSetHandler(ContentHandler):
pb = ParamBuilder()
sb = SyntaxBuilder()
fb = None
ib = InstructionBuilder()
instructions = []
def reset(self):
self.attr_b = AttributeBuilder()
self.format_b = None
self.token_b = TokenBuilder()
self.syntax_b = SyntaxBuilder()
self.inst_b = InstructionBuilder()
self.instructions = []
self.content = ""
def __init__(self):
self.reset()
def startElement(self, name, attrs):
if name == "instruction":
self.ib.reset()
self.ib.opcode = attrs["opcode"]
self.ib.level = attrs["level"]
self.ib.kind = attrs["kind"]
self.inst_b.reset()
self.inst_b.opcode = attrs["opcode"]
self.inst_b.level = attrs["level"]
self.inst_b.kind = attrs["kind"]
elif name == "description":
self.content = ""
elif name == "format":
self.fb = FormatBuilder()
self.format_b = FormatBuilder()
elif name == "attribute":
self.attr_b.reset()
self.attr_b.type = attrs["type"]
self.attr_b.name = attrs["name"]
# if attrs.has_key("default"):
# self.attr_b.default = attrs["default"]
# if attrs.has_key("value"):
# self.attr_b.value = attrs["value"]
elif name == "syntax":
self.sb.reset()
self.syntax_b.reset()
if attrs.has_key("alias"):
self.sb.alias = attrs["alias"]
self.syntax_b.alias = attrs["alias"]
if attrs.has_key("level"):
self.sb.level = attrs["level"]
self.syntax_b.level = attrs["level"]
else:
self.sb.level = self.ib.level
elif name in ["register", "immediate", "label", "address", "hidden"]:
self.pb.reset()
self.pb.kind = name
self.syntax_b.level = self.inst_b.level
elif name == "token":
self.token_b.reset()
self.token_b.kind = attrs["kind"]
if attrs.has_key("name"):
self.pb.name = attrs["name"]
self.token_b.name = attrs["name"]
if attrs.has_key("default"):
self.pb.default = attrs["default"]
self.token_b.default = attrs["default"]
if attrs.has_key("value"):
self.pb.value = attrs["value"]
self.token_b.value = attrs["value"]
def endElement(self, name):
if name in ["register", "immediate", "label", "address", "hidden"]:
if self.fb != None:
self.fb.params.append(self.pb.get())
else:
self.sb.params.append(self.pb.get())
if name == "token":
self.syntax_b.tokens.append(self.token_b.get())
elif name == "syntax":
self.ib.syntaxes.append(self.sb.get())
self.inst_b.syntaxes.append(self.syntax_b.get())
if name == "attribute":
self.format_b.attributes.append(self.attr_b.get())
elif name == "format":
self.ib.format = self.fb.get()
self.fb = None
self.inst_b.format = self.format_b.get()
elif name == "description":
self.inst_b.desc = self.content
elif name == "instruction":
self.instructions.append(self.ib.get())
self.instructions.append(self.inst_b.get())
def characters (self, content):
self.content = self.content + content
class InstructionSetParser:
......
<!--
This file is part of Mipsy, a tiny MIPS simulator
Copyright (C) 2003 Benoit Perrot (benoit@lrde.epita.fr)
Mipsy is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Mipsy is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!-- This file is part of Mipsy, a tiny MIPS simulator -->
<!-- Copyright (C) 2003 Benoit Perrot (benoit@lrde.epita.fr) -->
<!-- Mipsy is free software; you can redistribute it and/or modify -->
<!-- it under the terms of the GNU General Public License as published by -->
<!-- the Free Software Foundation; either version 2 of the License, or -->
<!-- (at your option) any later version. -->
<!-- Mipsy is distributed in the hope that it will be useful, -->
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
<!-- GNU General Public License for more details. -->
<!-- You should have received a copy of the GNU General Public License -->
<!-- along with this program; if not, write to the Free Software -->
<!-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
<instructions>
<!-- Arithmetic instructions -->
<!-- Arithmetic instructions -->
<instruction opcode="add" level="native" kind="arithmetic">
<description>To add 32-bit integers. If an overflow occurs, then trap.</description>
<format>
<register name="dest" />
<register name="src1" />
<register name="src2" />
<attribute type="Register" name="dest" />
<attribute type="Register" name="src1" />
<attribute type="Register" name="src2" />
</format>
<syntax>
<register />
<register default="@0"/>
<register />
<token kind="register" name="dest" />
<token kind="register" default="@0" />
<token kind="register" />
</syntax>
<syntax alias="addi">
<register />
<register default="@0" />
<immediate />
<token kind="register" name="dest" />
<token kind="register" default="@0" />
<token kind="immediate" />
</syntax>
</instruction>
<instruction opcode="addi" level="native" kind="arithmetic">
<instruction opcode="addu" level="native" kind="arithmetic">
<description>To add 32-bit integers.</description>
<format>
<register name="dest" />
<register name="src" />
<immediate name="imm" />
<attribute type="Register" name="dest" />
<attribute type="Register" name="src1" />
<attribute type="Register" name="src2" />
</format>
<syntax>
<register />
<register default="@0" />
<immediate />
<token kind="register" name="dest" />
<token kind="register" default="@0"/>
<token kind="register" />
</syntax>
<syntax alias="addiu">
<token kind="register" name="dest" />
<token kind="register" default="@0" />
<token kind="immediate" />
</syntax>
</instruction>
<instruction opcode="addu" level="native" kind="arithmetic">
<instruction opcode="addi" level="native" kind="arithmetic">
<description>To add a constant to a 32-bit integer. If overflow occurs, then trap.</description>
<format>
<register name="dest" />
<register name="src1" />
<register name="src2" />
<attribute type="Register" name="dest" />
<attribute type="Register" name="src" />
<attribute type="Exp" name="imm" />
</format>
<syntax>
<register />
<register default="@0"/>
<register />
</syntax>
<syntax alias="addiu">
<register />
<register default="@0" />
<immediate />
<token kind="register" name="dest" />
<token kind="register" default="@0" />
<token kind="immediate" />
</syntax>
</instruction>
<instruction opcode="addiu" level="native" kind="arithmetic">
<description>To add a constant to a 32-bit integer.</description>
<format>
<register name="dest" />
<register name="src" />
<immediate name="imm" />
<attribute type="Register" name="dest" />
<attribute type="Register" name="src" />
<attribute type="Exp" name="imm" />
</format>
<syntax>
<register />
<register default="@0" />
<immediate />
<token kind="register" name="dest" />
<token kind="register" default="@0" />
<token kind="immediate" />
</syntax>
</instruction>
<instruction opcode="sub" level="native" kind="arithmetic">
<description>To subtract 32-bit integers. If overflow occurs, then trap.</description>
<format>
<register name="dest" />
<register name="src1" />
<register name="src2" />
<attribute type="Register" name="dest" />
<attribute type="Register" name="src1" />
<attribute type="Register" name="src2" />
</format>
<syntax>
<register />
<register />
<register />
<token kind="register" />
<token kind="register" />
<token kind="register" />
</syntax>
<syntax alias="addi">
<register />
<register />
<immediate value="*new OpExp(*new IntExp(0), OpExp::sub, @2)" />
<token kind="register" />
<token kind="register" />
<token kind="immediate" name="imm" value="*new OpExp(*new IntExp(0), OpExp::sub, @2)" />
</syntax>
</instruction>
<instruction opcode="subu" level="native" kind="arithmetic">
<description>To subtract 32-bit integers.</description>
<format>
<register name="dest" />
<register name="src1" />
<register name="src2" />
<attribute type="Register" name="dest" />
<attribute type="Register" name="src1" />
<attribute type="Register" name="src2" />
</format>
<syntax>
<register />
<register />
<register />
<token kind="register" />
<token kind="register" />
<token kind="register" />
</syntax>
<syntax alias="addiu">
<register />
<register />
<immediate value="*new OpExp(*new IntExp(0), OpExp::sub, @2)" />
<token kind="register" />
<token kind="register" />
<token kind="immediate" name="imm" value="*new OpExp(*new IntExp(0), OpExp::sub, @2)" />
</syntax>
</instruction>
<instruction opcode="neg" level="pseudo" kind="arithmetic">
<description>FIXME</description>
<syntax alias="sub">
<register />
<hidden value="* new Register(Register::general, Cpu::zero)" />
<register default="@0" />
<token kind="register" name="dest" />
<token kind="hidden" value="* new Register(Register::general, Cpu::zero)" />
<token kind="register" default="@0" />
</syntax>
</instruction>
<instruction opcode="negu" level="pseudo" kind="arithmetic">
<description>FIXME</description>
<syntax alias="subu">
<register />
<hidden value="* new Register(Register::general, Cpu::zero)" />
<register default="@0" />
<token kind="register" name="dest" />
<token kind="hidden" value="* new Register(Register::general, Cpu::zero)" />
<token kind="register" default="@0" />
</syntax>
</instruction>
<instruction opcode="abs" level="complex" kind="arithmetic">
<description>FIXME</description>
<syntax>
<register />
<register default="@0" />