Skip to content

Commit a06a520

Browse files
committed
fix msp430 decoder and formatter
1 parent 5acf6c9 commit a06a520

File tree

3 files changed

+98
-60
lines changed

3 files changed

+98
-60
lines changed

amoco/arch/msp430/cpu.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
instruction_msp430 = type('instruction_msp430',(instruction,),{})
1111
instruction_msp430.set_uarch(uarch)
1212

13-
from amoco.arch.msp430.formats import MSP430_synthetic
13+
from amoco.arch.msp430.formats import MSP430_full,MSP430_synthetic
1414
instruction_msp430.set_formatter(MSP430_synthetic)
1515

1616
#define disassembler:

amoco/arch/msp430/formats.py

Lines changed: 81 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
# -*- coding: utf-8 -*-
2-
32
from .env import *
43
from amoco.arch.core import Formatter
4+
from amoco.ui.render import Token, TokenListJoin, highlight
5+
6+
def mn(m,pad=8):
7+
return [(Token.Mnemonic, m.lower().ljust(pad))]
58

69
def mnemo(i,pad=8):
710
m = i.mnemonic
811
if i.BW: m+='.B'
9-
return m.lower().ljust(pad)
12+
return mn(m)
1013

11-
def mnemo_cond(i):
12-
m = mnemo(i,pad=0).replace('jcc','j')
14+
def jump(i):
15+
m = i.mnemonic.lower().replace('jcc','j')
1316
s = COND[i.cond][0].split('/')[0]
14-
return (m+s).lower().ljust(8)
17+
l = mn(m+s)
18+
adr = i.operands[0].value
19+
if i.address is None:
20+
l.append((Token.Constant,'.%+'%adr))
21+
else:
22+
l.append((Token.Address,'*%s'%(i.address+adr+2)))
23+
return l
1524

1625
def ops(i):
1726
s = []
@@ -20,72 +29,94 @@ def ops(i):
2029
assert i.BW
2130
o = o.x
2231
if o._is_reg:
23-
s.append(str(o))
32+
s.append((Token.Register,str(o)))
2433
elif o._is_cst:
25-
s.append('#%s'%o)
34+
s.append((Token.Constant,'#%s'%o))
2635
else:
2736
assert o._is_mem
2837
a = o.a.base
29-
if a._is_reg:
38+
disp = o.a.disp
39+
if disp==0 and a._is_reg:
3040
if i.misc['autoinc'] is a:
31-
s.append('@%s+'%a)
41+
s.append((Token.Memory,'@%s+'%a))
3242
else:
33-
s.append('@%s'%a)
43+
s.append((Token.Memory,'@%s'%a))
3444
elif a._is_cst:
35-
s.append('&%s'%a)
45+
a.sf = False
46+
s.append((Token.Memory,'&%s'%a))
3647
else:
37-
assert a._is_eqn
38-
l,r = a.l,a.r
48+
if a._is_eqn:
49+
l,r = a.l,a.r
50+
else:
51+
l,r = a,disp
3952
if l==pc and i.address:
40-
s.append('*%s'%(i.address+r))
53+
s.append((Token.Address,'*%s'%(i.address+r)))
4154
else:
42-
s.append('%s(%s)'%(r,l))
43-
return ', '.join(s)
55+
s.append((Token.Memory,'%s(%s)'%(r,l)))
56+
return TokenListJoin(', ',s)
4457

4558
MSP430_full_formats = {
4659
'msp430_doubleop' : [mnemo, ops],
4760
'msp430_singleop' : [mnemo, ops],
48-
'msp430_jumps' : [mnemo_cond, ops],
61+
'msp430_jumps' : [jump],
4962
}
5063

5164
MSP430_full = Formatter(MSP430_full_formats)
5265

53-
def MSP430_synthetic(null,i):
54-
s = MSP430_full(i)
66+
def MSP430_synthetic(null,i,toks=False):
67+
s = MSP430_full(i,True)
5568
if i.mnemonic == 'ADDC' and i.operands[0]==0:
56-
return s.replace('addc','adc').replace('#0x0,','')
57-
if i.mnemonic == 'DADD' and i.operands[0]==0:
58-
return s.replace('dadd','dadc').replace('#0x0,','')
59-
if i.mnemonic == 'CMP' and i.operands[0]==0:
60-
return s.replace('cmp','tst').replace('#0x0,','')
61-
if i.mnemonic == 'MOV':
69+
s[0] = mn('adc')[0]
70+
del s[1:3]
71+
elif i.mnemonic == 'DADD' and i.operands[0]==0:
72+
s[0] = mn('dadc')[0]
73+
del s[1:3]
74+
elif i.mnemonic == 'CMP' and i.operands[0]==0:
75+
s[0] = mn('tst')[0]
76+
del s[1:3]
77+
elif i.mnemonic == 'MOV':
6278
if i.operands[1] is pc:
63-
return s.replace('mov','br').replace(',pc','')
79+
s[0] = mn('br')[0]
80+
del s[2:4]
6481
elif i.operands[0]==0:
65-
return s.replace('mov','clr').replace('#0x0,','')
82+
s[0] = mn('clr')[0]
83+
del s[1:3]
6684
elif i.misc['autoinc'] is sp:
67-
if i.operands[1] is pc: return 'ret'
68-
return s.replace('mov','pop').replace('@sp+,','')
69-
if i.mnemonic == 'BIC':
85+
if i.operands[1] is pc:
86+
s = mn('ret')
87+
else:
88+
s[0] = mn('pop')[0]
89+
del s[1:3]
90+
elif i.mnemonic == 'BIC':
7091
if i.operands[1] is sr:
71-
if i.operands[0]==1: return 'clrc'
72-
if i.operands[0]==4: return 'clrn'
73-
if i.operands[0]==2: return 'clrz'
74-
if i.operands[0]==8: return 'dint'
75-
if i.mnemonic == 'BIS':
92+
m = None
93+
if i.operands[0]==1: m = 'clrc'
94+
elif i.operands[0]==4: m = 'clrn'
95+
elif i.operands[0]==2: m = 'clrz'
96+
elif i.operands[0]==8: m = 'dint'
97+
if m: s = mn(m)
98+
elif i.mnemonic == 'BIS':
7699
if i.operands[1] is sr:
77-
if i.operands[0]==1: return 'setc'
78-
if i.operands[0]==4: return 'setn'
79-
if i.operands[0]==2: return 'setz'
80-
if i.operands[0]==8: return 'eint'
81-
if i.mnemonic == 'SUB' and i.operands[0]==1:
82-
return s.replace('sub','dec').replace('#0x1,','')
83-
if i.mnemonic == 'SUB' and i.operands[0]==2:
84-
return s.replace('sub','decd').replace('#0x2,','')
85-
if i.mnemonic == 'ADD' and i.operands[0]==1:
86-
return s.replace('add','inc').replace('#0x1,','')
87-
if i.mnemonic == 'ADD' and i.operands[0]==2:
88-
return s.replace('add','incd').replace('#0x2,','')
89-
if i.mnemonic == 'XOR' and i.operands[0].signextend(16).value==-1:
90-
return 'inv '+ops(i).split(',')[-1].strip()
91-
return s
100+
m = None
101+
if i.operands[0]==1: m = 'setc'
102+
elif i.operands[0]==4: m = 'setn'
103+
elif i.operands[0]==2: m = 'setz'
104+
elif i.operands[0]==8: m = 'eint'
105+
if m: s = mn(m)
106+
elif i.mnemonic == 'SUB' and i.operands[0]==1:
107+
s[0] = mn('dec')[0]
108+
del s[1:3]
109+
elif i.mnemonic == 'SUB' and i.operands[0]==2:
110+
s[0] = mn('decd')[0]
111+
del s[1:3]
112+
elif i.mnemonic == 'ADD' and i.operands[0]==1:
113+
s[0] = mn('inc')[0]
114+
del s[1:3]
115+
elif i.mnemonic == 'ADD' and i.operands[0]==2:
116+
s[0] = mn('incd')[0]
117+
del s[1:3]
118+
elif i.mnemonic == 'XOR' and i.operands[0].signextend(16).value==-1:
119+
s[0] = mn('inv')[0]
120+
del s[1:-1]
121+
if toks: return s
122+
return highlight(s)

amoco/arch/msp430/spec_msp430.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
# get operand type/value based on addressing mode:
1919
def getopd(obj,mode,reg,data,CGR=False):
2020
r = env.R[reg]
21-
size = 8 if obj.BW else 16
22-
if CGR and reg==2:
23-
r = [r,0,env.cst(0x4,16),env.cst(0x8,16)][mode]
24-
return r[0:size],data
25-
if CGR and reg==3:
26-
r = env.cst([0,1,2,-1][mode],16)
27-
return r[0:size],data
21+
if obj.BW: size=8
22+
else : size=16
23+
if CGR:
24+
if reg==2:
25+
r = [r,env.cst(0,16),env.cst(0x4,16),env.cst(0x8,16)][mode]
26+
elif reg==3:
27+
r = env.cst([0,1,2,-1][mode],16)
2828
if mode==0: # register mode
2929
return r[0:size],data
3030
if mode==1: # indexed/symbolic/absolute modes
@@ -36,10 +36,13 @@ def getopd(obj,mode,reg,data,CGR=False):
3636
return env.mem(imm,size),data
3737
if r is env.pc:
3838
return env.mem(env.pc+imm,size),data
39+
if r._is_cst: imm.sf = False
3940
return env.mem(r+imm,size),data
4041
if mode==2: # indirect register mode
42+
if r._is_cst: return r[0:size],data
4143
return env.mem(r,size),data
4244
if mode==3: # immediate & indirect autoincrement
45+
if r._is_cst: return r[0:size],data
4346
if r is env.pc:
4447
addr,data = data[0:16],data[16:]
4548
imm = env.cst(addr.int(),16)
@@ -71,7 +74,10 @@ def msp430_doubleop(obj,data,Sreg,Ad,As,Dreg):
7174
src,data = getopd(obj,As,Sreg,data,CGR=True)
7275
dst,data = getopd(obj,Ad,Dreg,data)
7376
obj.operands = [src,dst]
74-
obj.type = type_data_processing
77+
if dst is env.pc:
78+
obj.type = type_control_flow
79+
else:
80+
obj.type = type_data_processing
7581

7682
# single-operand format
7783
#----------------------
@@ -99,6 +105,7 @@ def msp430_singleop(obj,data,Ad,DSreg):
99105
@ispec("16<[ 001 .cond(3) offset(10) ]", mnemonic="Jcc", BW=0)
100106
def msp430_jumps(obj,offset):
101107
if obj.cond == 0b111: obj.mnemonic = "JMP"
102-
obj.operands = [env.cst(offset,10).signextend(16)]
108+
off = env.cst(offset*2,11).signextend(16)
109+
obj.operands = [off]
103110
obj.type = type_control_flow
104111

0 commit comments

Comments
 (0)