summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/tms57002/tmsmake.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/tms57002/tmsmake.py')
-rwxr-xr-xsrc/devices/cpu/tms57002/tmsmake.py435
1 files changed, 435 insertions, 0 deletions
diff --git a/src/devices/cpu/tms57002/tmsmake.py b/src/devices/cpu/tms57002/tmsmake.py
new file mode 100755
index 00000000000..c822599e7d2
--- /dev/null
+++ b/src/devices/cpu/tms57002/tmsmake.py
@@ -0,0 +1,435 @@
+#!/usr/bin/python
+
+import sys
+import re
+
+
+DASM_ARGS = {
+ "c": ("%s", "get_memadr(opcode, 'c')"),
+ "d": ("%s", "get_memadr(opcode, 'd')"),
+ "i": ("%02x", "opcode & 0xff"),
+}
+
+TYPES = {
+ "": None,
+ "d": None,
+ "b": " cs->branch = BR_UB;",
+ "cb": " cs->branch = BR_CB;",
+ "i": " cs->branch = BR_IDLE;",
+ "f": None,
+}
+
+def expand_c(v):
+ fmt = ["%s", "(%s & 0xffff0000)", "(%s << 16)"][v["crm"]]
+ param = ["cmem[i->param]", "cmem[ca]"][v["cmode"]]
+ return fmt % param
+
+def expand_d(v):
+ index = ["(i->param + ", "(id + "][v["dmode"]]
+ mask = ["ba0) & 0xff] << 8)", "ba1) & 0x1f] << 8)"][v["dbp"]]
+ return "(dmem%d[" % v["dbp"] + index + mask
+
+def expand_d24(v):
+ index = ["(i->param + ", "(id + "][v["dmode"]]
+ mask = ["ba0) & 0xff]", "ba1) & 0x1f]"][v["dbp"]]
+ return "dmem%d[" % v["dbp"] + index + mask
+
+EXPAND_ML = ["macc", "(macc << 2)", "(macc << 4)", "(macc >> 16)" ]
+
+def expand_mv(v):
+ c = ["", "s"][v["movm"]]
+ return "check_macc_overflow_%d%s()" % (v["sfmo"], c)
+
+EXPAND_WC = ["cmem[i->param] =", "cmem[ca] ="]
+
+
+ROUNDING = [ 0, 1 << (48-32-1), 1 << (48-24-1), 1 << (48-30-1),
+ 1 << (48-16-1)]
+
+A = (1 << 64) - 1
+RMASK= [A,
+ A - (1 << (48-32)) + 1,
+ A - (1 << (48-24)) + 1,
+ A - (1 << (48-30)) + 1,
+ A - (1 << (48-16)) + 1,
+ ]
+
+def expand_mo(v):
+ c = ["", "s"][v["movm"]]
+ return "macc_to_output_%d%s(0x%016xULL, 0x%016xULL)" % (
+ v["sfmo"], c, ROUNDING[v["rnd"]], RMASK[v["rnd"]])
+
+
+def expand_wd1(v):
+ index = ["(i->param + ", "(id + "][v["dmode"]]
+ mask = ["ba0) & 0xff] =", "ba1) & 0x1f] ="][v["dbp"]]
+ return "dmem%d[" % v["dbp"] + index + mask
+
+WA2 = (
+" if(r < -0x80000000 || r > 0x7fffffff)\n"
+" st1 |= ST1_AOV;\n"
+" aacc = r;")
+
+
+PDESC_EXPAND = {
+ "a": lambda v: ["aacc", "(aacc << 7)"][v["sfao"]],
+ "c": expand_c,
+ "d": expand_d,
+ "d24": expand_d24,
+ "i": lambda v: "i->param",
+
+ "ml": lambda v: EXPAND_ML[v["sfma"]],
+ "mo": expand_mo,
+ "mv": expand_mv,
+ "wa1": lambda v: "r =",
+ "wa2": lambda v: WA2,
+ "wc1": lambda v: EXPAND_WC[v["cmode"]],
+ "wd1": expand_wd1,
+ "b1": lambda v: "pc = ",
+ "b2": lambda v: " sti |= S_BRANCH;",
+ "sfai1": lambda v: ["", "((INT32)("][v["sfai"]],
+ "sfai2": lambda v: ["", ")) >> 1"][v["sfai"]],
+}
+
+PDESC = {
+ "a": (0, ["sfao"]),
+ "c": (0, ["cmode", "crm"]),
+ "d": (0, ["dmode", "dbp"]),
+ "d24": (0, ["dmode", "dbp"]),
+ "i": (0, []),
+ "ml": (0, ["sfma"]),
+ "mo": (0, ["sfmo", "rnd", "movm"]),
+ "mv": (0, ["sfmo", "movm"]),
+ "wa": (1, []),
+ "wc": (1, ["cmode"]),
+ "wd": (1, ["dmode", "dbp"]),
+ "b": (1, []),
+ "sfai": (2, ["sfai"]),
+}
+
+VARIANTS = {
+ "cmode": (2, "xmode(opcode, 'c', cs)" ),
+ "dmode": (2, "xmode(opcode, 'd', cs)" ),
+ "sfai": (2, "sfai(st1)"),
+ "crm": (3, "crm(st1)"),
+ "dbp": (2, "dbp(st1)"),
+ "sfao": (2, "sfao(st1)"),
+ "sfmo": (4, "sfmo(st1)"),
+ "rnd": (5, "rnd(st1)"),
+ "movm": (2, "movm(st1)"),
+ "sfma": (4, "sfma(st1)"),
+ # dummy
+ "post": (1, None),
+
+}
+
+VARIANT_CANONICAL_ORDER = [
+ "cmode",
+ "dmode",
+ "sfai",
+ "crm",
+ "dbp",
+ "sfao",
+ "sfmo",
+ "rnd",
+ "movm",
+ "sfma",
+]
+
+def EmitWithPrefix(f, out, prefix):
+ for o in out:
+ print >>f, prefix + o
+
+class Instruction:
+
+ def __init__(self, line):
+ token = line.split()
+ if len(token) == 5:
+ token.append("")
+ assert len(token) == 6
+
+ self._name = token[0]
+ self._cat = token[1]
+ self._id = int(token[2], 16)
+ self._cyc = int(token[3])
+ self._rep = token[4]
+ self._type = token[5]
+ self._flags = set()
+ if self._cat == "2b":
+ self._flags.add("post")
+ self._dasm = None
+ self._run = []
+ self._variants = 1
+ # sanity checks
+ assert 0 <= self._id
+ if self._cat == "1":
+ assert self._id < 0x40
+ else:
+ assert self._id < 0x80
+ assert self._type in TYPES
+
+ def __str__(self):
+ return repr([self._name, self._cat, self._id, self._variants, self._flags])
+
+
+ def GetDasmInfo(self):
+ lst = []
+ def extract(match):
+ s = match.group()[1:]
+ assert s in DASM_ARGS
+ fmt, val = DASM_ARGS[s]
+ lst.append(val)
+ return fmt
+ s = re.sub("%.", extract, self._dasm)
+ return s, lst
+
+
+ def GetCdecSum(self):
+ lst = []
+ n = 1
+ for f in VARIANT_CANONICAL_ORDER:
+ if f in self._flags:
+ c, s = VARIANTS[f]
+ lst.append(" + ")
+ if n != 1:
+ lst.append("%d*" % n)
+ lst.append(s)
+ n *=c
+ return "".join(lst)
+
+
+ def EmitDasm(self, f, prefix):
+ opcode, args = self.GetDasmInfo()
+ args = [", " + a for a in args]
+ print >>f, "%scase 0x%02x:" % (prefix, self._id)
+ print >>f, "%s sprintf(buf, \"%s\"%s);" % (prefix, opcode, "".join(args))
+ print >>f, "%s break;" % prefix
+
+
+ def EmitCdec(self, f, prefix, no, empty):
+ print >>f, "%scase 0x%02x: // %s" % (prefix, self._id, self._name)
+ if not empty:
+ print >>f, "%s *op = %s%s;" % (prefix, no, self.GetCdecSum())
+ if self._type == "f":
+ for l in self._run:
+ print >>f, prefix + l
+ else:
+ l = TYPES[self._type]
+ if l:
+ print >>f, prefix + l
+ print >>f, "%s break;" % prefix
+
+
+ def ExpandCintrp(self, line, values):
+ def extract(match):
+ s = match.group()[1:]
+ assert s in PDESC_EXPAND
+ # call the right expand_XXX function
+ return PDESC_EXPAND[s](values)
+
+
+ return re.sub("%[a-z0-9]+", extract, line)
+
+
+ def PreprocessRunString(self):
+ out = []
+ for r in self._run:
+ if "%wa(" in r:
+ assert r.endswith(");")
+ r = r[0:-2].replace("%wa(", "%wa1 ") + ";"
+ out.append(r)
+ out.append("%wa2")
+ elif "%wd(" in r:
+ assert r.endswith(");")
+ r = r[0:-2].replace("%wd(", "%wd1 ") + ";"
+ out.append(r)
+ elif "%wc(" in r:
+ assert r.endswith(");")
+ r = r[0:-2].replace("%wc(", "%wc1 ") + ";"
+ out.append(r)
+ elif "%b(" in r:
+ assert r.endswith(");")
+ r = r[0:-2].replace("%b(", "%b1") + ";"
+ out.append(r)
+ out.append("%b2")
+ elif "%sfai(" in r:
+ assert r.endswith(");")
+ r = r[0:-2].replace("%sfai(", "")
+ r = r.replace(",", " = %sfai1", 1)
+ out.append(r + "%sfai2;")
+ else:
+ out.append(r)
+ return out
+
+
+ def EmitCintrpRecurse(self, f, prefix, no, flags_fixed, flags_unfixed):
+ if not flags_unfixed:
+ vals = []
+ for v in VARIANT_CANONICAL_ORDER:
+ if v in flags_fixed:
+ #print "@@@@", f
+ vals.append("%s=%d" % (v, flags_fixed[v]))
+ out = ["case %d: // %s %s" % (no, self._name, " ".join(vals))]
+ for line in self.PreprocessRunString():
+ exp = self.ExpandCintrp(line, flags_fixed)
+ # ensure we're not outputing a = a;
+ if not CheckSelfAssign(exp):
+ out.append(exp)
+ out.append(" break;")
+ out.append("")
+ EmitWithPrefix(f, out, prefix)
+ return no + 1
+ x = flags_unfixed.pop(-1)
+ n = VARIANTS[x][0]
+ for i in range(n):
+ flags_fixed[x] = i
+ no = self.EmitCintrpRecurse(f, prefix, no, flags_fixed, flags_unfixed)
+ flags_unfixed.append(x)
+ return no
+
+
+ def EmitCintrp(self, f, prefix, no):
+ if not self._run:
+ return no
+ flags = [fn for fn in VARIANT_CANONICAL_ORDER
+ if fn in self._flags]
+ return self.EmitCintrpRecurse(f, prefix, no, {}, flags)
+
+
+ def Finalize(self):
+ def extract(match):
+ s = match.group()[1:]
+ assert s in PDESC
+ self._flags.update(PDESC[s][1])
+ # result does not matter
+ return "X"
+ for line in self._run:
+ # ignore result of substitution
+ re.sub("%[a-z0-9]+", extract, line)
+ for f in self._flags:
+ self._variants *= VARIANTS[f][0]
+
+
+ def AddInfo(self, line):
+ if self._dasm is None:
+ self._dasm = line.lstrip()
+ else:
+ self._run.append(line)
+
+
+def ins_cmp_dasm(a, b):
+ if a._cat[0] != b._cat[0]:
+ return cmp(a._cat[0], b._cat[0])
+ else:
+ return cmp(a._id, b._id)
+
+
+def LoadLst(filename):
+ instructions = []
+ ins = None
+ for n, line in enumerate(open(filename, "rU")):
+ line = line.rstrip()
+ if not line and ins:
+ # new lines separate intructions
+ ins.Finalize()
+ ins = None
+ elif line[0] in [" ", "\t"]:
+ assert ins
+ ins.AddInfo(line)
+ else:
+ ins = Instruction(line)
+ instructions.append(ins)
+ if ins:
+ ins.Finalize()
+ return instructions
+
+
+def EmitDasm(f, ins_list):
+ ins_list.sort(cmp=ins_cmp_dasm)
+ last_cat = ""
+ for i in ins_list:
+ cat = i._cat[0]
+ if cat != last_cat:
+ if last_cat:
+ print >>f, "#endif"
+ print >>f
+ print >>f, "#ifdef DASM" + cat
+ last_cat = cat
+ i.EmitDasm(f, " ")
+ print >>f
+ print >>f, "#endif"
+ print >>f
+
+
+def EmitCdec(f, ins_list):
+ ins_list.sort(cmp=ins_cmp_dasm)
+ no = 4
+ last_cat = ""
+ for i in ins_list:
+ if not i._run: continue
+ cat = i._cat.upper()
+ if cat == "2B": cat = "2A"
+ if cat == "3": continue
+
+ if cat != last_cat:
+ if last_cat:
+ print >>f, "#endif"
+ print >>f
+ print >>f, "#ifdef CDEC" + cat
+ last_cat = cat
+
+ i.EmitCdec(f, "", no, i._cat == "2b")
+ no += i._variants
+ print >>f
+
+ no = 4
+ for i in ins_list:
+ if not i._run: continue
+ cat = i._cat.upper()
+ if cat == "2A": cat = "2B"
+
+ if cat == "1":
+ no += i._variants
+ continue
+
+ if cat != last_cat:
+ if last_cat:
+ print >>f, "#endif"
+ print >>f
+ print >>f, "#ifdef CDEC" + cat
+ last_cat = cat
+
+ i.EmitCdec(f, "", no, i._cat == "2a")
+ no += i._variants
+ print >>f
+ print >>f, "#endif"
+ print >>f
+
+def EmitCintrp(f, ins_list):
+ ins_list.sort(cmp=ins_cmp_dasm)
+ print >>f, "#ifdef CINTRP"
+ no = 4
+ for i in ins_list:
+ no = i.EmitCintrp(f, "", no)
+ print >>f, "#endif"
+
+
+def CheckSelfAssign(line):
+ ls = line.split('=')
+ if len(ls) != 2:
+ return False
+ lhs = ls[0].strip()
+ rhs = ls[1].strip().rstrip(';')
+ return lhs == rhs
+
+ins_list = LoadLst(sys.argv[1])
+try:
+ f = open(sys.argv[2], "w")
+except Exception:
+ err = sys.exc_info()[1]
+ sys.stderr.write("cannot write file %s [%s]\n" % (sys.argv[2], err))
+ sys.exit(1)
+
+EmitDasm(f, ins_list)
+EmitCdec(f, ins_list)
+EmitCintrp(f, ins_list)