CVS: htdocs/cgi-bin disassemble.py,1.8,1.9 test-disassemble.py,1.1,1.2
Chris Liechti <[email protected]>
| Newsgroups | gmane.comp.hardware.texas-instruments.msp430.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/mspgcc/htdocs/cgi-bin
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19021/htdocs/cgi-bin
Modified Files:
disassemble.py test-disassemble.py
Log Message:
disassembler update:
- support for emulated instructions
- make labels for jump targets
- build code blocks by inserting newlines after unconditional jumps (jmp, be, ret, reti)
- support for symbol file (definitions for peripheral register names and their bits)
Index: disassemble.py
===================================================================
RCS file: /cvsroot/mspgcc/htdocs/cgi-bin/disassemble.py,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -w -d -r1.8 -r1.9
--- disassemble.py 3 Aug 2004 13:17:12 -0000 1.8
+++ disassemble.py 3 May 2005 16:40:20 -0000 1.9
@@ -52,15 +52,15 @@
#x = RegisterArgument(core,reg=core.R[src], bytemode=bytemode, am=as)
elif as == 1: #pc rel
if src == 0:
- x = '%(x)s'
+ x = '0x%(x)04x'
#x = IndexedRegisterArgument(core, reg=core.PC, offset=pc.next(), bytemode=bytemode)
c = c + 2 #fetch+read
elif src == 2: #abs
- x = '&%(x)s'
+ x = '&0x%(x)04x'
#x = MemoryArgument(core, address=pc.next(), bytemode=bytemode)
c = c + 2 #fetch+read
else: #indexed
- x = '%%(x)s(%s)' % regnames[src]
+ x = '0x%%(x)04x(%s)' % regnames[src]
#x = IndexedRegisterArgument(core, reg=core.R[src], offset=pc.next(), bytemode=bytemode)
c = c + 2 #fetch+read
elif as == 2: #indirect
@@ -69,7 +69,7 @@
c = c + 1 #target mem read
elif as == 3:
if src == 0: #immediate
- x = '#%(x)s'
+ x = bytemode and '#0x%(x)02x' or '#0x%(x)04x'
#x = ImmediateArgument(core, value=pc.next(), bytemode=bytemode)
c = c + 1 #fetch
else: #indirect autoincrement
@@ -87,15 +87,15 @@
c = c + 1 #modifying PC gives one cycle penalty
else:
if dest == 0: #PC relative
- y = '%(y)s'
+ y = '0x%(y)04x'
#y = IndexedRegisterArgument(core, reg=core.PC, offset=pc.next(), bytemode=bytemode)
c = c + 3 #fetch + read modify write
elif dest == 2: #abs
- y = '&%(y)s'
+ y = '&0x%(y)04x'
#y = MemoryArgument(core, address=pc.next(), bytemode=bytemode)
c = c + 3 #fetch + read modify write
else: #indexed
- y = '%%(y)s(%s)' % regnames[dest]
+ y = '0x%%(y)04x(%s)' % regnames[dest]
#y = IndexedRegisterArgument(core, reg=core.R[dest], offset=pc.next(), bytemode=bytemode)
c = c + 3 #fetch + read modify write
@@ -138,7 +138,195 @@
0x7: ('jmp', 1),
}
+INSN_WIDTH = 7 #instruction width (args follow)
+symbols = {} #address -> label
+bits = {} #label -> list of (bits, shift, width)
+bits_speacial = {} #label -> dict: value -> name
+
+def symbol_from_adr(opt):
+ """try to find a symbolname if the argument points to an absolute address"""
+ if opt[0:1] == '&':
+ adr = int(opt[1:], 0)
+ if adr in symbols:
+ return '&%s' % (symbols[adr], )
+ return opt
+
+def symbols_for_bits(arg, opt):
+ """for known targets, convert immediate values to a list of or'ed bits"""
+ if opt[0:1] == '&':
+ reg = opt[1:]
+ if arg[0:1] == '#' and reg in bits:
+ value = int(arg[1:], 0)
+ result = []
+ for names, shift, width in bits[reg]:
+ mask = ((1<<width) - 1) << shift
+ x = (value & mask) >> shift
+ if x and names[x]:
+ value &= ~mask #clear these bits
+ result.append(names[x])
+ #if there are bits left, append them to the result, so that nothing gets lost
+ if value:
+ if value in bits_speacial[reg]:
+ result.append(bits_speacial[reg][value])
+ else:
+ result.append('0x%x' % value)
+ return '#%s' % '|'.join(result)
+ return arg
+
+class Instruction:
+ """this class s used to represent an MSP430 assembler instruction.
+ emulated instructions are handled on class instantiation."""
+ def __init__(self, name, bytemode=0, src=None, dst=None, usedwords=0, cycles=0):
+ self.name = name
+ self.bytemode = bytemode
+ self.src = src
+ self.dst = dst
+ self.usedwords = usedwords
+ self.cycles = cycles
+
+ #transformations of emulated instructions
+ new_name = None
+ if self.name == 'add':
+ if self.src == '#1':
+ new_name = 'inc'
+ elif self.src == '#2':
+ new_name = 'incd'
+ elif self.src == self.dst:
+ new_name = 'rla'
+ elif self.name == 'addc':
+ if self.src == '#0':
+ new_name = 'adc'
+ elif self.src == self.dst:
+ new_name = 'rlc'
+ elif self.name == 'dadd' and self.src == '#0':
+ new_name = 'dadc'
+ elif self.name == 'sub':
+ if self.src == '#1':
+ new_name = 'dec'
+ elif self.src == '#2':
+ new_name = 'decd'
+ elif self.name == 'subc' and self.src == '#0':
+ new_name = 'sbc'
+ elif self.name == 'xor' and self.src == '#-1':
+ new_name = 'inv'
+ elif self.name == 'mov':
+ if self.src == '#0':
+ if self.dst == 'CG2':
+ new_name = 'nop'
+ self.dst = None
+ else:
+ new_name = 'clr'
+ elif self.src == '@SP+':
+ if self.dst == 'PC':
+ new_name = 'ret'
+ self.dst = None
+ else:
+ new_name = 'pop'
+ elif self.dst == 'PC':
+ new_name = 'br'
+ self.dst = self.src
+ elif self.name == 'bic' and self.dst == 'SR':
+ if self.src == '#8':
+ new_name = 'dint'
+ self.dst = None
+ elif self.src == '#1':
+ new_name = 'clrc'
+ self.dst = None
+ elif self.src == '#4':
+ new_name = 'clrn'
+ self.dst = None
+ elif self.src == '#2':
+ new_name = 'clrz'
+ self.dst = None
+ elif self.name == 'bis' and self.dst == 'SR':
+ if self.src == '#8':
+ new_name = 'eint'
+ self.dst = None
+ elif self.src == '#1':
+ new_name = 'setc'
+ self.dst = None
+ elif self.src == '#4':
+ new_name = 'setn'
+ self.dst = None
+ elif self.src == '#2':
+ new_name = 'setz'
+ self.dst = None
+ elif self.name == 'cmp' and self.src == '#0':
+ new_name = 'tst'
+ #emulated insns have no src
+ if new_name is not None:
+ self.name = new_name
+ self.src = None
+
+ #try to replace values by symbols
+ if self.dst: self.dst = symbol_from_adr(self.dst)
+ if self.src:
+ self.src = symbol_from_adr(self.src)
+ self.src = symbols_for_bits(self.src, self.dst)
+
+ def __str__(self):
+ if self.src is not None and self.dst is not None:
+ return ("%%-%ds %%s, %%s" % INSN_WIDTH) % ("%s%s" % (self.name, (self.bytemode and '.b' or '')), self.src, self.dst)
+ elif self.dst is not None:
+ return ("%%-%ds %%s" % INSN_WIDTH) % ( "%s%s" % (self.name, (self.bytemode and '.b' or '')), self.dst)
+ else:
+ return ("%%-%ds" % INSN_WIDTH) % (self.name,)
+
+ def str_width_label(self, label):
+ if not self.jumps(): raise ValueError('only possible with jump insns')
+ if self.dst is not None and self.dst[0:1] == '#' and self.src is None:
+ return ("%%-%ds #%%s" % INSN_WIDTH) % (self.name, label)
+ raise ValueError('only possible with dst only insns')
+
+ def jumps(self):
+ """return true if this instructions jumps (modifies the PC)"""
+ return (self.name == 'call' or self.dst == 'PC') and (self.dst[0] == '#') #XXX relative address mode missing
+
+ def targetAddress(self, address):
+ """only valid for instructions that jump; return the target address of the jump"""
+ if self.name == 'call' or self.name == 'br':
+ if self.dst[0] == '#':
+ return int(self.dst[1:], 0)
+ else:
+ return address + int(self.dst, 0)
+ else:
+ raise ValueError('not a branching instruction')
+
+ def ends_a_block(self):
+ """helper for a nice output. return true if execution does not continue
+ after this instruction."""
+ return self.name in ('ret', 'reti', 'br')
+
+
+class JumpInstruction(Instruction):
+ """represent jump instructions"""
+ def __init__(self, name, offset, usedwords=0, cycles=0):
+ Instruction.__init__(self, name, 0, None, None, usedwords, cycles)
+ self.offset = offset
+
+ def jumps(self):
+ """return true because this instructions jumps (modifies the PC)"""
+ return 1
+
+ def targetAddress(self, address):
+ """return the target address of the jump"""
+ return address + self.offset
+
+ def __str__(self):
+ return ("%%-%ds %%+d" % INSN_WIDTH) % (self.name, self.offset)
+
+ def str_width_label(self, label):
+ return ("%%-%ds %%s" % INSN_WIDTH) % (self.name, label)
+
+ def ends_a_block(self):
+ """helper for a nice output. return true if execution does not continue
+ after this instruction."""
+ return self.name == 'jmp'
+
def disassemble(words):
+ """disassembler one instruction from a stream of words. returns an
+ instance of Instruction. that class has informationa bout how many
+ wwords have been consumed and more."""
cycles = 1 #count cycles, start with insn fetch
usedwords = 1
x = y = None
@@ -172,10 +360,10 @@
if '%' in x:
x = x % {'x':words[0]}
usedwords = usedwords + 1
- if name != 'reti':
- return "%s%s %s" % (name, (bytemode and '.b' or ''), x), usedwords, cycles
+ if name == 'reti':
+ return Instruction(name, usedwords=usedwords, cycles=cycles)
else:
- return "reti", usedwords, cycles
+ return Instruction(name, bytemode, dst=x, usedwords=usedwords, cycles=cycles)
#double operand
elif (opcode>>12)&0xf in doubleOperandInstructions.keys():
@@ -195,7 +383,7 @@
if '%' in y:
y = y % {'y':words[0]}
usedwords = usedwords + 1
- return "%s%s %s, %s" % (name, (bytemode and '.b' or ''), x, y), usedwords, cycles
+ return Instruction(name, bytemode, src=x, dst=y, usedwords=usedwords, cycles=cycles)
#jump instructions
elif ((opcode & 0xe000) == 0x2000 and
@@ -206,11 +394,11 @@
if offset & 0x400: #negative?
offset = -((~offset + 1) & 0x7ff)
cycles = cycles + addcyles #jumps allways have 2 cycles
- return "%s %s" % (name, offset), usedwords, cycles
+ return JumpInstruction(name, offset, usedwords=usedwords, cycles=cycles)
#unkown instruction
else:
- return 'illegal insn 0x%04x' % opcode, usedwords, cycles
+ return Instruction('illegal-insn-0x%04x' % opcode, usedwords=usedwords, cycles=cycles)
if __name__ == '__main__':
if len(sys.argv) > 1:
@@ -234,6 +422,8 @@
parser = OptionParser(option_class=MyOption)
parser.add_option("-b", "--bin", dest="binary",
help="read data from a binary file", metavar="FILE")
+ parser.add_option("", "--symbols", dest="symbols",
+ help="read symbol addresses from a text file", metavar="FILE")
parser.add_option("-s", "--startadr", dest="startadr",
help="startoffset for binary input", type="intautobase", default=0)
@@ -244,37 +434,103 @@
sys.stdout.write("Parameter disassemble: %s (%d words %d cycles)\n" % (insn, words, cycles))
if options.binary is not None:
+ #symbol file provided?
+ if options.symbols is not None:
+ #parse symbol file
+ for line in file(options.symbols):
+ #skip comment lines
+ if line.strip()[0:1] == '#': continue
+ #break the line in elements (whitespace separated)
+ els = line.split()
+ if len(els) >= 2:
+ adr = els.pop(0) #1st column -> address
+ name = els.pop(0) #2nd column -> name
+ symbols[int(adr, 0)] = name
+ #the optional third column defines names for the bits
+ if els:
+ bitstring = els.pop(0)
+ bits[name] = []
+ b = bitstring.split('|')
+ b.reverse()
+ for n, bit in enumerate(b):
+ if bit != '?':
+ bits[name].append((['', bit], n, 1)) #name, shift, width
+ bits[name].reverse()
+ #the optional fourth column defines names for special values
+ if els:
+ bits_speacial[name] = {}
+ consts = els.pop(0).split(',')
+ for const in consts:
+ cname, cvalue = const.split('=')
+ bits_speacial[name][int(cvalue, 0)] = cname
sys.stderr.write("---- file: %s ----\n" % options.binary)
- if options.binary:
import msp430, msp430.memory, msp430.elf
data = msp430.memory.Memory()
try:
+ #try to load elf, IntelHex or TI-Text
data.loadFile(options.binary)
except msp430.elf.ELFException:
+ #failed, treat it as binary file
sys.stderr.write("Attention: parsing binary file\n")
memory = file(options.binary, 'rb').read()
if len(memory) & 1:
sys.stderr.write("odd length!!, cutting off last byte\n")
memory = memory[:-1]
- memwords = [struct.unpack("<H", memory[x:x+2])[0] for x in range(0, len(memory), 2) ]
- offset = 0
- while offset < len(memwords):
- insn, words, cycles = disassemble(memwords[offset:])
- bytes = ' '.join(['%04x' % x for x in memwords[offset:offset+words]])
- sys.stdout.write("0x%04x: %-16s %-36s (%d cycles)\n" % (options.startadr+offset*2, bytes, insn, cycles))
- offset += words
- else:
+ #can't know startaddress, use cmdline option
+ data.append(msp430.memory.Segment(options.startadr, memory))
+ #disassemble memory
memwords = []
+ labels = {}
+ label_num = 1
for seg in data:
memwords = [struct.unpack("<H", seg.data[x:x+2])[0] for x in range(0, len(seg.data), 2) ]
- sys.stdout.write("----- Address 0x%04x:\n" % seg.startaddress)
+ sys.stdout.write("; Address 0x%04x:\n" % seg.startaddress)
options.startadr = seg.startaddress
offset = 0
+ lines = []
while offset < len(memwords):
- insn, words, cycles = disassemble(memwords[offset:])
- bytes = ' '.join(['%04x' % x for x in memwords[offset:offset+words]])
- sys.stdout.write("0x%04x: %-16s %-36s (%d cycles)\n" % (options.startadr+offset*2, bytes, insn, cycles))
- offset += words
+ address = options.startadr+offset*2
+ insn = disassemble(memwords[offset:])
+ bytes = ' '.join(['%04x' % x for x in memwords[offset:offset+insn.usedwords]])
+ instext = str(insn)
+ #does this instruction jump? if so, get a label for the jump target
+ if insn.jumps():
+ l_adr = insn.targetAddress(options.startadr+offset*2+2)
+ if l_adr not in labels:
+ #create a new label
+ label = '.L%04d' % label_num
+ label_num = label_num + 1
+ labels[l_adr] = label
+ #update note with information about the values
+ if isinstance(insn, JumpInstruction):
+ instext = insn.str_width_label(labels[l_adr])
+ note = ' %+d --> 0x%04x' % (insn.offset, l_adr)
+ else:
+ instext = insn.str_width_label(labels[l_adr])
+ note = ' --> 0x%04x' % (l_adr, )
+ else:
+ note = ''
+ #save generated line
+ lines.append((address, "0x%04x: %-16s" % (address, bytes), "%-36s ;%d cycles%s\n" % (instext, insn.cycles, note)))
+ #after unconditional jumps, make an empty line
+ if insn.ends_a_block():
+ lines.append((None, '', '\n'))
+ offset += insn.usedwords
+ #now output all the lines, put the labels where they belong
+ unused_labels = dict(labels) #work on a copy
+ for address, prefix, suffix in lines:
+ if address in labels:
+ label = "%s:" % labels[address]
+ del unused_labels[address] #remove used label
+ else:
+ label = ''
+ #render lines with labels
+ sys.stdout.write("%s %-7s %s" % (prefix, label, suffix))
+ #if there are labels left, print them in a list
+ if unused_labels:
+ sys.stdout.write("\nLabels that could not be placed:\n")
+ for address, label in unused_labels.items():
+ sys.stdout.write(" %s = 0x%04x\n" % (label, address))
else:
import cgi, os
#cgitb is not available in py 1.5.2
@@ -291,7 +547,8 @@
print "<pre>", values, "</pre>"
print "<H3>Results in the following assembler instruction:</H3>"
print "<pre>"
- insn, words, cycles = disassemble(map(myint, string.split(values)))
+ insn = disassemble(map(myint, string.split(values)))
+ words, cycles = insn.usedwords, insn.cycles
print "%s (%d cycles, %d words)" % (insn, cycles, words)
print "</pre>"
else:
Index: test-disassemble.py
===================================================================
RCS file: /cvsroot/mspgcc/htdocs/cgi-bin/test-disassemble.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -d -r1.1 -r1.2
--- test-disassemble.py 13 Jun 2003 02:23:31 -0000 1.1
+++ test-disassemble.py 3 May 2005 16:40:20 -0000 1.2
@@ -1,76 +1,70 @@
import unittest
import disassemble
+
formatItests = [
#input, iop, cycles
('mov R5, R8', [['OPC', 0x4508]], 1),
- #~ ('br R9', [['OPC', 0x4900]], 2), #emulated insn see next line
- ('mov R9, PC', [['OPC', 0x4900]], 2),
- ('add R5, 3(R6)', [['OPC', 0x5586], ['DW', 0x0003]], 4),
- ('xor R8, 1234', [['OPC', 0xe880], ['PCREL', 0x04d2]], 4),
- ('mov R5, &1234', [['OPC', 0x4582], ['DW', 0x04d2]], 4),
+ ('br R9', [['OPC', 0x4900]], 2), #emulated insn see next line
+ ('add R5, 0x0003(R6)', [['OPC', 0x5586], ['DW', 0x0003]], 4),
+ ('xor R8, 0x04d2', [['OPC', 0xe880], ['PCREL', 0x04d2]], 4),
+ ('mov R5, &0x04d2', [['OPC', 0x4582], ['DW', 0x04d2]], 4),
('and @R4, R5', [['OPC', 0xf425]], 2),
- #~ ('br @R8', [['OPC', 0x4820]], 3), #emulated insn see next line
- ('mov @R8, PC', [['OPC', 0x4820]], 3),
- ('xor @R5, 8(R6)', [['OPC', 0xe5a6], ['DW', 0x0008]], 5),
- ('mov @R5, 1234', [['OPC', 0x45a0], ['PCREL', 0x04d2]], 5),
- ('xor @R5, &1234', [['OPC', 0xe5a2], ['DW', 0x04d2]], 5),
+ ('br @R8', [['OPC', 0x4820]], 3), #emulated insn see next line
+ ('xor @R5, 0x0008(R6)', [['OPC', 0xe5a6], ['DW', 0x0008]], 5),
+ ('mov @R5, 0x04d2', [['OPC', 0x45a0], ['PCREL', 0x04d2]], 5),
+ ('xor @R5, &0x04d2', [['OPC', 0xe5a2], ['DW', 0x04d2]], 5),
('add @R5+, R6', [['OPC', 0x5536]], 2),
- #~ ('br @R9+', [['OPC', 0x4930]], 3), #emulated insn see next line
- ('mov @R9+, PC', [['OPC', 0x4930]], 3),
- ('xor @R5+, 8(R6)', [['OPC', 0xe5b6], ['DW', 0x0008]], 5),
- ('mov @R9+, 1234', [['OPC', 0x49b0], ['PCREL', 0x04d2]], 5),
- ('mov @R9+, &1234', [['OPC', 0x49b2], ['DW', 0x04d2]], 5),
+ ('br @R9+', [['OPC', 0x4930]], 3), #emulated insn see next line
+ ('xor @R5+, 0x0008(R6)', [['OPC', 0xe5b6], ['DW', 0x0008]], 5),
+ ('mov @R9+, 0x04d2', [['OPC', 0x49b0], ['PCREL', 0x04d2]], 5),
+ ('mov @R9+, &0x04d2', [['OPC', 0x49b2], ['DW', 0x04d2]], 5),
- ('mov #20, R9', [['OPC', 0x4039], ['DW', 0x0014]], 2),
- #~ ('br #0x02ae', [['OPC', 0x4030], ['DW', 0x02ae]], 3), #emulated insn see next line
- #~ ('mov #0x02ae, PC', [['OPC', 0x4030], ['DW', 0x02ae]], 3),
- ('mov #686, PC', [['OPC', 0x4030], ['DW', 0x02ae]], 3),
- ('mov #768, 0(SP)', [['OPC', 0x40b1], ['DW', 0x0300], ['DW', 0x0000]], 5),
- ('add #33, 1234', [['OPC', 0x50b0], ['DW', 0x0021], ['PCREL', 0x04d2]], 5),
- ('add #33, &1234', [['OPC', 0x50b2], ['DW', 0x0021], ['DW', 0x04d2]], 5),
+ ('mov #0x0014, R9', [['OPC', 0x4039], ['DW', 0x0014]], 2),
+ ('br #0x02ae', [['OPC', 0x4030], ['DW', 0x02ae]], 3), #emulated insn see next line
+ ('mov #0x0300, 0x0000(SP)', [['OPC', 0x40b1], ['DW', 0x0300], ['DW', 0x0000]], 5),
+ ('add #0x0021, 0x04d2', [['OPC', 0x50b0], ['DW', 0x0021], ['PCREL', 0x04d2]], 5),
+ ('add #0x0021, &0x04d2', [['OPC', 0x50b2], ['DW', 0x0021], ['DW', 0x04d2]], 5),
- ('mov 2(R5), R7', [['OPC', 0x4517], ['DW', 0x0002]], 3),
- #~ ('br 2(R6)', [['OPC', 0x4610], ['DW', 0x0002]], 3), #emulated insn see next line
- ('mov 2(R6), PC', [['OPC', 0x4610], ['DW', 0x0002]], 3),
- ('mov 4(R7), 1234', [['OPC', 0x4790], ['DW', 0x0004], ['PCREL', 0x04d2]], 6),
- ('add 3(R4), 6(R9)',[['OPC', 0x5499], ['DW', 0x0003], ['DW', 0x0006]], 6),
- ('mov 2(R5), &1234',[['OPC', 0x4592], ['DW', 0x0002], ['DW', 0x04d2]], 6),
+ ('mov 0x0002(R5), R7', [['OPC', 0x4517], ['DW', 0x0002]], 3),
+ ('br 0x0002(R6)', [['OPC', 0x4610], ['DW', 0x0002]], 3), #emulated insn see next line
+ ('mov 0x0004(R7), 0x04d2', [['OPC', 0x4790], ['DW', 0x0004], ['PCREL', 0x04d2]], 6),
+ ('add 0x0003(R4), 0x0006(R9)',[['OPC', 0x5499], ['DW', 0x0003], ['DW', 0x0006]], 6),
+ ('mov 0x0002(R5), &0x04d2', [['OPC', 0x4592], ['DW', 0x0002], ['DW', 0x04d2]], 6),
- ('and 1234, R6', [['OPC', 0xf016], ['PCREL', 0x04d2]], 3),
- #~ ('br 1234', [['OPC', 0x4010], ['PCREL', 0x04d2]], 3), #emulated insn see next line
- ('mov 1234, PC', [['OPC', 0x4010], ['PCREL', 0x04d2]], 3),
- ('cmp 1234, 5678', [['OPC', 0x9090], ['PCREL', 0x04d2], ['PCREL', 0x162e]], 6),
- ('mov 1234, 0(SP)', [['OPC', 0x4091], ['PCREL', 0x04d2], ['DW', 0x0000]], 6),
- ('mov 1234, &5678', [['OPC', 0x4092], ['PCREL', 0x04d2], ['DW', 0x162e]], 6),
+ ('and 0x04d2, R6', [['OPC', 0xf016], ['PCREL', 0x04d2]], 3),
+ ('br 0x04d2', [['OPC', 0x4010], ['PCREL', 0x04d2]], 3), #emulated insn see next line
+ ('cmp 0x04d2, 0x162e', [['OPC', 0x9090], ['PCREL', 0x04d2], ['PCREL', 0x162e]], 6),
+ ('mov 0x04d2, 0x0000(SP)', [['OPC', 0x4091], ['PCREL', 0x04d2], ['DW', 0x0000]], 6),
+ ('mov 0x04d2, &0x162e', [['OPC', 0x4092], ['PCREL', 0x04d2], ['DW', 0x162e]], 6),
- ('mov &1234, R8', [['OPC', 0x4218], ['DW', 0x04d2]], 3),
- #~ ('br &1234', [['OPC', 0x4210], ['DW', 0x04d2]], 3),
- ('mov &1234, PC', [['OPC', 0x4210], ['DW', 0x04d2]], 3),
- ('mov &1234, 5678', [['OPC', 0x4290], ['DW', 0x04d2], ['PCREL', 0x162e]], 6),
- ('mov &1234, 0(SP)',[['OPC', 0x4291], ['DW', 0x04d2], ['DW', 0x0000]], 6),
- ('mov &1234, &5678',[['OPC', 0x4292], ['DW', 0x04d2], ['DW', 0x162e]], 6),
+ ('mov &0x04d2, R8', [['OPC', 0x4218], ['DW', 0x04d2]], 3),
+ ('br &0x04d2', [['OPC', 0x4210], ['DW', 0x04d2]], 3),
+ ('mov &0x04d2, 0x162e', [['OPC', 0x4290], ['DW', 0x04d2], ['PCREL', 0x162e]], 6),
+ ('mov &0x04d2, 0x0000(SP)', [['OPC', 0x4291], ['DW', 0x04d2], ['DW', 0x0000]], 6),
+ ('mov &0x04d2, &0x162e', [['OPC', 0x4292], ['DW', 0x04d2], ['DW', 0x162e]], 6),
]
class TestFormatI(unittest.TestCase):
def testFormatI(self):
for line, iop, desired_cylces in formatItests:
- insn, words, cycles = disassemble.disassemble([w for m,w in iop])
+ insn = disassemble.disassemble([w for m,w in iop])
+ words, cycles = insn.usedwords, insn.cycles
#~ print
#~ print iop, cycles
#~ print desired_iop, desired_cylces
- self.failUnless(insn == line, '%r failed, wrong output (%r)' % (line, insn))
+ self.failUnless(str(insn).split() == line.split(), '%r failed, wrong output (%s)' % (line, insn))
self.failUnless(desired_cylces == cycles, '%r failed, wrong number of cycles' % line)
formatIItests = [
#input, iop, cycles
- ('push #8', [['OPC', 0x1230], ['DW', 0x0008]], 4),
- ('push #7', [['OPC', 0x1230], ['DW', 0x0007]], 4),
- ('push #4', [['OPC', 0x1230], ['DW', 0x0004]], 4),
+ ('push #0x0008', [['OPC', 0x1230], ['DW', 0x0008]], 4),
+ ('push #0x0007', [['OPC', 0x1230], ['DW', 0x0007]], 4),
+ ('push #0x0004', [['OPC', 0x1230], ['DW', 0x0004]], 4),
('push #0', [['OPC', 0x1203]], 3),
('push #1', [['OPC', 0x1213]], 3),
('push #2', [['OPC', 0x1223]], 3),
@@ -79,57 +73,59 @@
('push @R4', [['OPC', 0x1224]], 4),
('push @R4+', [['OPC', 0x1234]], 4),
- ('push 0(R4)', [['OPC', 0x1214], ['DW', 0x0000]], 5),
- ('push 1234', [['OPC', 0x1210], ['PCREL', 0x04d2]], 5),
- ('push &1234', [['OPC', 0x1212], ['DW', 0x04d2]], 5),
+ ('push 0x0000(R4)', [['OPC', 0x1214], ['DW', 0x0000]], 5),
+ ('push 0x04d2', [['OPC', 0x1210], ['PCREL', 0x04d2]], 5),
+ ('push &0x04d2', [['OPC', 0x1212], ['DW', 0x04d2]], 5),
('call R4', [['OPC', 0x1284]], 4),
- ('call 1234', [['OPC', 0x1290], ['PCREL', 0x04d2]], 5),
+ ('call 0x04d2', [['OPC', 0x1290], ['PCREL', 0x04d2]], 5),
('call @R4', [['OPC', 0x12a4]], 4),
- ('call #1234', [['OPC', 0x12b0], ['DW', 0x04d2]], 5),
+ ('call #0x04d2', [['OPC', 0x12b0], ['DW', 0x04d2]], 5),
('swpb R4', [['OPC', 0x1084]], 1),
- ('rra 1234', [['OPC', 0x1110], ['PCREL', 0x04d2]], 4),
+ ('rra 0x04d2', [['OPC', 0x1110], ['PCREL', 0x04d2]], 4),
('rrc @R4', [['OPC', 0x1024]], 3),
- ('rra #1234', [['OPC', 0x1130], ['DW', 0x04d2]], 3),
+ ('rra #0x04d2', [['OPC', 0x1130], ['DW', 0x04d2]], 3),
]
class TestFormatII(unittest.TestCase):
def testFormatII(self):
for line, iop, desired_cylces in formatIItests:
- insn, words, cycles = disassemble.disassemble([w for m,w in iop])
+ insn = disassemble.disassemble([w for m,w in iop])
+ words, cycles = insn.usedwords, insn.cycles
#~ print
#~ print insn, words, cycles
#~ print line, desired_cylces
- self.failUnless(insn == line, '%r failed, wrong output (%r)' % (line, insn))
+ self.failUnless(str(insn).split() == line.split(), '%r failed, wrong output (%s)' % (line, insn))
self.failUnless(desired_cylces == cycles, '%r failed, wrong number of cycles' % line)
formatIIItests = [
#input, iop, cycles
- ('jnz 8', [['OPC', 0x2004]], 2),
- ('jz 4', [['OPC', 0x2402]], 2),
- ('jnc 4', [['OPC', 0x2802]], 2),
- ('jc 4', [['OPC', 0x2c02]], 2),
+ ('jnz +8', [['OPC', 0x2004]], 2),
+ ('jz +4', [['OPC', 0x2402]], 2),
+ ('jnc +4', [['OPC', 0x2802]], 2),
+ ('jc +4', [['OPC', 0x2c02]], 2),
#~ ('jhs -8', [['OPC', 0x2ffc]], 2), #alias for jc
- ('jn 4', [['OPC', 0x3002]], 2),
- ('jge 4', [['OPC', 0x3402]], 2),
- ('jl 4', [['OPC', 0x3802]], 2),
- ('jmp 4', [['OPC', 0x3c02]], 2),
+ ('jn +4', [['OPC', 0x3002]], 2),
+ ('jge +4', [['OPC', 0x3402]], 2),
+ ('jl +4', [['OPC', 0x3802]], 2),
+ ('jmp +4', [['OPC', 0x3c02]], 2),
('jmp -2', [['OPC', 0x3fff]], 2),
#~ ('jmp $', [['OPC', 0x3fff]], 2), #alias for -2
#~ ('jmp .', [['OPC', 0x3fff]], 2), #alias for -2
('jmp -1024', [['OPC', 0x3e00]], 2),
- ('jmp 1022', [['OPC', 0x3dff]], 2),
+ ('jmp +1022', [['OPC', 0x3dff]], 2),
]
class TestFormatIII(unittest.TestCase):
def testFormatIII(self):
for line, iop, desired_cylces in formatIIItests:
- insn, words, cycles = disassemble.disassemble([w for m,w in iop])
+ insn = disassemble.disassemble([w for m,w in iop])
+ words, cycles = insn.usedwords, insn.cycles
#~ print
#~ print insn, words, cycles
#~ print line, desired_cylces
- self.failUnless(insn == line, '%r failed, wrong output (%r)' % (line, insn))
+ self.failUnless(str(insn).split() == line.split(), '%r failed, wrong output (%s)' % (line, insn))
self.failUnless(desired_cylces == cycles, '%r failed, wrong number of cycles' % line)
#~ def testOutOfRangeError(self):
@@ -142,8 +138,9 @@
class TestFormatMisc(unittest.TestCase):
def testMiscInsns(self):
- insn, words, cycles = disassemble.disassemble([0x1300])
- self.failUnless(insn == 'reti')
+ insn = disassemble.disassemble([0x1300])
+ words, cycles = insn.usedwords, insn.cycles
+ self.failUnless(str(insn).strip() == 'reti')
self.failUnless(cycles == 5)
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.
Get your fingers limbered up and give it your best shot. 4 great events, 4
opportunities to win big! Highest score wins.NEC IT Guy Games. Play to
win an NEC 61 plasma display. Visit http://www.necitguy.com/?r=20