diff options
Diffstat (limited to 'src/devices/cpu/dsp563xx/dsp563xx-make.py')
| -rwxr-xr-x | src/devices/cpu/dsp563xx/dsp563xx-make.py | 124 |
1 files changed, 96 insertions, 28 deletions
diff --git a/src/devices/cpu/dsp563xx/dsp563xx-make.py b/src/devices/cpu/dsp563xx/dsp563xx-make.py index 00cef22f74e..e2a1041dc85 100755 --- a/src/devices/cpu/dsp563xx/dsp563xx-make.py +++ b/src/devices/cpu/dsp563xx/dsp563xx-make.py @@ -26,6 +26,11 @@ class SlotMode: write = 1 memory = 2 +class SlotChange: + none = 0 + sel1 = 1 + bus24 = 2 + functions = {} class Function: @@ -296,11 +301,11 @@ class Function: mode = self.values[3 if self.values[0] == "split-range" else 2] if mode == 'imm': return '0x%%0%dx' % ((self.bcount + 3) // 4) - elif mode == 'bit': + elif mode == 'bit' or mode == 'shift': return '%d' - elif mode == 'asap' or mode == 'asaq' or mode == 'pcrel': + elif mode == 'asap' or mode == 'asaq' or mode == 'pcrel' or mode == 'abs': return '0x%06x' - if self.name == 'exabs' or self.name == 'expcrel' or self.name == 'eximm' or self.name == 'eam1a' or self.name == 'eam1i': + if self.name == 'exabs' or self.name == 'expcrel' or self.name == 'eximm' or self.name == 'exoff' or self.name == 'eam1a' or self.name == 'eam1i': return '0x%06x' return '[' + self.name + ']' @@ -324,30 +329,32 @@ class Function: b1 = self.bcount - b2 return 'bitswap<%d>(opcode, %d%s%s)' % (self.bcount+1, params[2], self.brange(params[0], b1), self.brange(params[1], b2)) elif self.values[0] == 'range': - mode = self.values[3 if self.values[0] == "split-range" else 2] - if mode == 'imm' or mode == 'bit' or mode == 'abs': + mode = self.values[2] + if mode == 'imm' or mode == 'bit' or mode == 'shift' or mode == 'abs': return 'BIT(opcode, %d, %d)' % (params[0], self.bcount) elif mode == 'asap': return '0xffffc0 + BIT(opcode, %d, %d)' % (params[0], self.bcount) elif mode == 'asaq': return '0xffff80 + BIT(opcode, %d, %d)' % (params[0], self.bcount) + elif mode == 'pcrel': + return 'm_pc + util::sext(BIT(opcode, %d, %d), %d)' % (params[0], self.bcount, self.bcount) else: print('unsupported range on %s %s' % (mode, self.name)) elif self.values[0] == 'split-range': b2 = self.values[1] b1 = self.bcount - b2 - mode = self.values[3 if self.values[0] == "split-range" else 2] - if mode == 'imm' or mode == 'bit': + mode = self.values[3] + if mode == 'imm' or mode == 'bit' or mode == 'shift': return 'bitswap<%d>(opcode%s%s)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2)) elif mode == 'asap': return '0xffffc0 + bitswap<%d>(opcode%s%s)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2)) elif mode == 'asaq': return '0xffff80 + bitswap<%d>(opcode%s%s)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2)) elif mode == 'pcrel': - return 'm_pc + bitswap<%d>(opcode%s%s)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2)) + return 'm_pc + util::sext(bitswap<%d>(opcode%s%s), %d)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2), self.bcount) else: print('unsupported split-range on %s %s' % (mode, self.name)) - elif self.name == 'exabs' or self.name == 'eximm' or self.name == 'eam1a' or self.name == 'eam1i': + elif self.name == 'exabs' or self.name == 'eximm' or self.name == 'exoff' or self.name == 'eam1a' or self.name == 'eam1i': return 'exv' elif self.name == 'expcrel': return '(m_pc+exv) & 0xffffff' @@ -369,26 +376,28 @@ class Function: b1 = self.bcount - b2 return ', ts_%s[bitswap<%d>(opcode, %d%s%s)]' % (self.name, self.bcount+1, params[2], self.brange(params[0], b1), self.brange(params[1], b2)) elif self.values[0] == 'range': - mode = self.values[3 if self.values[0] == "split-range" else 2] - if mode == 'imm' or mode == 'bit': + mode = self.values[2] + if mode == 'imm' or mode == 'bit' or mode == 'shift' or mode == 'abs': return ', BIT(opcode, %d, %d)' % (params[0], self.bcount) elif mode == 'asap': return ', 0xffffc0 + BIT(opcode, %d, %d)' % (params[0], self.bcount) elif mode == 'asaq': return ', 0xffff80 + BIT(opcode, %d, %d)' % (params[0], self.bcount) + elif mode == 'pcrel': + return ', pc + util::sext(BIT(opcode, %d, %d), %d)' % (params[0], self.bcount, self.bcount) elif self.values[0] == 'split-range': b2 = self.values[1] b1 = self.bcount - b2 - mode = self.values[3 if self.values[0] == "split-range" else 2] - if mode == 'imm' or mode == 'bit': + mode = self.values[3] + if mode == 'imm' or mode == 'bit' or mode == 'shift': return ', bitswap<%d>(opcode%s%s)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2)) elif mode == 'asap': return ', 0xffffc0 + bitswap<%d>(opcode%s%s)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2)) elif mode == 'asaq': return ', 0xffff80 + bitswap<%d>(opcode%s%s)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2)) elif mode == 'pcrel': - return ', pc + bitswap<%d>(opcode%s%s)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2)) - elif self.name == 'exabs' or self.name == 'eximm' or self.name == 'eam1a' or self.name == 'eam1i': + return ', pc + util::sext(bitswap<%d>(opcode%s%s), %d)' % (self.bcount, self.brange(params[0], b1), self.brange(params[1], b2), self.bcount) + elif self.name == 'exabs' or self.name == 'eximm' or self.name == 'exoff' or self.name == 'eam1a' or self.name == 'eam1i': return ', exv' elif self.name == 'expcrel': return ', (pc+exv) & 0xffffff' @@ -414,12 +423,13 @@ Function("imm4", 1, ["range", 16, "imm"]) Function("imm1", 1, ["range", 2, "imm"]) Function("bit5", 1, ["range", 24, "bit"]) Function("shift5", 1, ["range", 17, "shift"]) +Function("shift6", 1, ["range", 41, "shift"]) Function("actrl", 1, ["single", [None, None, 'a1', 'b1', 'x0', 'y0', 'x1', 'y1']]) Function("eam4", 1, ["single", ['(r)-n', '(r)+n', '(r)-', '(r)+']]) Function("eam1", 1, ["single", ['(r)-n', '(r)+n', '(r)-', '(r)+', '(r)', '(r+n)', None, None, None, None, None, None, None, None, '-(r)']]) Function("eam1a", 1, ["val", 0x30, "abs"]) Function("eam1i", 1, ["val", 0x34, "imm"]) -Function("asa6", 1, ["range", 64, "asa"]) +Function("asa6", 1, ["range", 64, "abs"]) Function("asa6p", 1, ["range", 64, "asap"]) Function("asa6q", 1, ["range", 64, "asaq"]) Function("asa6qs", 2, ["split-range", 5, 64, "asaq"]) @@ -439,7 +449,6 @@ Function("exco", 0, ["pass"]) Function("pcrel", 2, ["split-range", 5, 512, "pcrel"]) Function("sda7", 2, ["split-range", 1, 128, "imm"]) Function("sda7b", 2, ["split-range", 4, 128, "imm"]) -Function("pcrel12", 1, ["range", 4096, "pcrel"]) Function("abs12", 1, ["range", 4096, "abs"]) Function("fobr", 1, ["single", [None, None, None, None, 'x0', 'x1', 'y0', 'y1', 'a0', 'b0', 'a2', 'b2', 'a1', 'b1', 'a', 'b']]) @@ -471,6 +480,7 @@ Function("damo2", 1, ["single", ['y1', 'x0', 'y0', 'x1']]) NormalRegs = ['a', 'a0', 'a1', 'a2', 'b', 'b0', 'b1', 'b2', 'x0', 'x1', 'y0', 'y1', 'ep', 'vba', 'sc', 'sz', 'sr', 'omr', 'sp', 'ssh', 'ssl', 'la', 'lc', 'mr', 'ccr', 'com', 'eom'] ArrayRegs = ['r', 'n', 'm'] IndirectRegs = ['(r)-n', '(r)+n', '(r)-', '(r)+', '(r)', '(r+n)', '-(r)'] +DasmFlags = ['over', 'cond', 'out'] class Slot: def __init__(self, name, func): @@ -578,10 +588,11 @@ class Source: while pos != len(line) and isa(line[pos]): pos += 1 smode = line[spos:pos] - if smode != '' and smode != 'w' and smode != 'm': + if smode != '' and smode != 'w' and smode != 'm' and smode != '1' and smode != 'w1' and smode != 'h' and smode != 'wh': print("Unexpected slot mode %s" % smode) sys.exit(1) - smode_id = SlotMode.read if smode == '' else SlotMode.write if smode == 'w' else SlotMode.memory + smode_id = SlotMode.memory if smode == 'm' else SlotMode.write if 'w' in smode else SlotMode.read + schange_id = SlotChange.sel1 if '1' in smode else SlotChange.bus24 if 'h' in smode else SlotChange.none if sname not in self.slots: self.slots[sname] = [False]*3 self.slots[sname][smode_id] = True @@ -600,7 +611,7 @@ class Source: print("Unbalanced parenthesis") sys.exit(1) sub = self.parse(line[spos:pos-1]) - r.append([sname, smode_id, sub]) + r.append([sname, smode_id, schange_id, sub]) return r def add(self, line): @@ -614,17 +625,37 @@ class Source: s += e continue if e[1] == SlotMode.read: - s += e[0] + if e[0] in slots: + slot = slots[e[0]] + if slot == 'a' or slot == 'b': + if e[2] == SlotChange.sel1: + s += e[0] + '_1' + elif e[2] == SlotChange.bus24: + s += e[0] + '_h' + else: + s += e[0] + else: + s += e[0] + else: + s += e[0] elif e[1] == SlotMode.memory: if e[0] not in slots: print("uninstanciated slot (memory)", e) s += 'm_' + slots[e[0]] else: - sub = self.expand(e[2], slots, islots) + sub = self.expand(e[3], slots, islots) if e[0] in slots: slot = slots[e[0]] if slot in NormalRegs: - s += 'set_%s(%s)' % (slot, sub) + if slot == 'a' or slot == 'b': + if e[2] == SlotChange.sel1: + s += 'set_%s1(%s)' % (slot, sub) + elif e[2] == SlotChange.bus24: + s += 'set_%sh(%s)' % (slot, sub) + else: + s += 'set_%s(%s)' % (slot, sub) + else: + s += 'set_%s(%s)' % (slot, sub) elif slot in ArrayRegs: si = islots[e[0]].get_value_expression() + ' & 7' s += 'set_%s(%s, %s)' % (slot, si, sub) @@ -635,6 +666,22 @@ class Source: sys.exit(1) return s + def ab_scan_gen(self, f, slot, inst, line, changes): + for e in line: + if type(e) == list and e[0] == slot and e[1] == SlotMode.read: + if e[2] not in changes: + changes.append(e[2]) + if e[2] == SlotChange.none: + print('\t\tu64 %s = get_%s();' % (slot, inst), file=f) + elif e[2] == SlotChange.sel1: + print('\t\tu32 %s_1 = get_%s1();' % (slot, inst), file=f) + elif e[2] == SlotChange.bus24: + print('\t\tu32 %s_h = get_%sh();' % (slot, inst), file=f) + else: + print("unhandled SlotChange %d" % e[2]) + if type(e) == list: + self.ab_scan_gen(f, slot, inst, e[3], changes) + def gen(self, f, slots, islots): for slot, sinfo in self.slots.items(): if sinfo[SlotMode.read]: @@ -642,7 +689,9 @@ class Source: inst = slots[slot] if inst in NormalRegs: if inst == 'a' or inst == 'b': - print('\t\tu64 %s = get_%s();' % (slot, inst), file=f) + changes = [] + for line in self.text: + self.ab_scan_gen(f, slot, inst, line, changes) else: print('\t\tu32 %s = get_%s();' % (slot, inst), file=f) elif inst in ArrayRegs: @@ -672,6 +721,8 @@ class Source: else: print("Unimplemented IndirectRegs %s" % inst) sys.exit(1) + elif islots[slot].func.name == 'cc': + print('\t\tbool %s = test_%s();' % (slot, inst), file=f) else: print("instanciated slot (read)", slot, inst) else: @@ -716,7 +767,7 @@ class Instruction: def parse_slots(self, head, pos): self.slots = {} - self.keywords = [] + self.flags = [] while pos != len(head): while pos != len(head) and head[pos] == ' ': pos += 1 @@ -726,8 +777,11 @@ class Instruction: while pos != len(head) and head[pos] != ':' and head[pos] != '(' and head[pos] != ' ': sname += head[pos] pos += 1 - if pos != len(head) and head[pos] == ' ': - self.keyword.append(sname) + if pos == len(head) or head[pos] == ' ': + if sname not in DasmFlags: + print("Unknown dasm flag %s" % sname) + sys.exit(1) + self.flags.append(sname) continue if pos == len(head) or head[pos] != ':': print("Missing : after slot name %s [%s]" % (sname, head[0])) @@ -985,6 +1039,16 @@ class ISA: s += "%d," % array[i+j] print(s, file=f) + def gen_flags_array(self, f, array): + for i in range(0, 256, 16): + s = '\t' + for j in range(16): + if i+j < len(array) and array[i+j] and len(array[i+j].flags) > 0: + s += '|'.join(['STEP_' + flag.upper() for flag in array[i+j].flags]) + ',' + else: + s += '0,' + print(s, file=f) + def gen_ex_array(self, f, insts): s = '\t' total = 64*((len(insts) + 63) // 64) @@ -1054,6 +1118,10 @@ class ISA: self.gen_ex_array(f, self.dnpars) print("};", file=f) print("", file=f) + print("const u32 dsp563xx_disassembler::t_npar_flags[0x100] = {", file=f) + self.gen_flags_array(f, self.dnpars) + print("};", file=f) + print("", file=f) for _,ff in functions.items(): if ff.need_array(): ff.gen_array(f) @@ -1104,7 +1172,7 @@ class ISA: self.gen_index_array(f, self.cnpar[:0x100000]) print("};", file=f) print("", file=f) - print("const u64 dsp563xx_device::t_move_ex[39] = {", file=f) + print("const u64 dsp563xx_device::t_move_ex[40] = {", file=f) self.gen_ex_array(f, self.cmoves) print("};", file=f) print("", file=f) |
