xref: /aosp_15_r20/external/capstone/contrib/objdump/objdump-m68k.py (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1*9a0e4156SSadaf Ebrahimi#!/usr/bin/env python
2*9a0e4156SSadaf Ebrahimi
3*9a0e4156SSadaf Ebrahimifrom __future__ import print_function
4*9a0e4156SSadaf Ebrahimiimport sys
5*9a0e4156SSadaf Ebrahimiimport bitstring
6*9a0e4156SSadaf Ebrahimifrom capstone import *
7*9a0e4156SSadaf Ebrahimifrom capstone.m68k import *
8*9a0e4156SSadaf Ebrahimi
9*9a0e4156SSadaf Ebrahimi#
10*9a0e4156SSadaf Ebrahimi# Objdump with the same output as his binary cousin
11*9a0e4156SSadaf Ebrahimi#
12*9a0e4156SSadaf Ebrahimi
13*9a0e4156SSadaf EbrahimiTODO = """
14*9a0e4156SSadaf EbrahimiTODO :
15*9a0e4156SSadaf Ebrahimi
16*9a0e4156SSadaf Ebrahimi  o need more testing on M68K_AM_*_DISP
17*9a0e4156SSadaf Ebrahimi  o cleanup, etc ...
18*9a0e4156SSadaf Ebrahimi
19*9a0e4156SSadaf Ebrahimi"""
20*9a0e4156SSadaf Ebrahimi
21*9a0e4156SSadaf Ebrahimiobjdump_cmd_example = 'm68k-atari-mint-objdump -b binary -D -mm68k --adjust-vma 0x30664 u/m68k.bin'
22*9a0e4156SSadaf Ebrahimiobjdump_dumpheader_fmt = """
23*9a0e4156SSadaf Ebrahimi%s:     file format binary
24*9a0e4156SSadaf Ebrahimi
25*9a0e4156SSadaf Ebrahimi
26*9a0e4156SSadaf EbrahimiDisassembly of section .data:
27*9a0e4156SSadaf Ebrahimi
28*9a0e4156SSadaf Ebrahimi%08x <.data>:"""
29*9a0e4156SSadaf Ebrahimi
30*9a0e4156SSadaf Ebrahimi
31*9a0e4156SSadaf EbrahimiM68000_CODE = b"\x04\x40\x00\x40"
32*9a0e4156SSadaf Ebrahimi
33*9a0e4156SSadaf Ebrahimiall_tests = (
34*9a0e4156SSadaf Ebrahimi        (CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_060, M68000_CODE, "M68060-32 (Big-endian)"),
35*9a0e4156SSadaf Ebrahimi)
36*9a0e4156SSadaf Ebrahimi
37*9a0e4156SSadaf Ebrahimi
38*9a0e4156SSadaf Ebrahimidef dump_bytes(b, len):
39*9a0e4156SSadaf Ebrahimi    str = ''
40*9a0e4156SSadaf Ebrahimi    i = 0
41*9a0e4156SSadaf Ebrahimi    while i < len:
42*9a0e4156SSadaf Ebrahimi        str += format("%02x%02x " % (b[i], b[i+1]))
43*9a0e4156SSadaf Ebrahimi        i += 2
44*9a0e4156SSadaf Ebrahimi    return str[:-1]
45*9a0e4156SSadaf Ebrahimi
46*9a0e4156SSadaf Ebrahimidef dump_op_reg(insn, op_reg):
47*9a0e4156SSadaf Ebrahimi    if op_reg == M68K_REG_A7:
48*9a0e4156SSadaf Ebrahimi        return "%sp"
49*9a0e4156SSadaf Ebrahimi    if op_reg == M68K_REG_A6:
50*9a0e4156SSadaf Ebrahimi        return "%fp"
51*9a0e4156SSadaf Ebrahimi    return '%' + insn.reg_name(op_reg)
52*9a0e4156SSadaf Ebrahimi
53*9a0e4156SSadaf Ebrahimidef s8(value):
54*9a0e4156SSadaf Ebrahimi    return bitstring.Bits(uint=value, length=8).unpack('int')[0]
55*9a0e4156SSadaf Ebrahimi
56*9a0e4156SSadaf Ebrahimidef s16(value):
57*9a0e4156SSadaf Ebrahimi    return bitstring.Bits(uint=value, length=16).unpack('int')[0]
58*9a0e4156SSadaf Ebrahimi
59*9a0e4156SSadaf Ebrahimidef extsign8(value):
60*9a0e4156SSadaf Ebrahimi    if value & 0x80:
61*9a0e4156SSadaf Ebrahimi        return 0xffffffffffffff00 + value
62*9a0e4156SSadaf Ebrahimi    return value
63*9a0e4156SSadaf Ebrahimi
64*9a0e4156SSadaf Ebrahimidef extsign1616(value):
65*9a0e4156SSadaf Ebrahimi    if value & 0x8000:
66*9a0e4156SSadaf Ebrahimi        return 0xffff0000 + value
67*9a0e4156SSadaf Ebrahimi    return value
68*9a0e4156SSadaf Ebrahimi
69*9a0e4156SSadaf Ebrahimidef extsign1632(value):
70*9a0e4156SSadaf Ebrahimi    if value & 0x8000:
71*9a0e4156SSadaf Ebrahimi        return 0xffffffffffff0000 + value
72*9a0e4156SSadaf Ebrahimi    return value
73*9a0e4156SSadaf Ebrahimi
74*9a0e4156SSadaf Ebrahimi
75*9a0e4156SSadaf Ebrahimidef printRegbitsRange(buffer, data, prefix):
76*9a0e4156SSadaf Ebrahimi    str = ''
77*9a0e4156SSadaf Ebrahimi    first = 0
78*9a0e4156SSadaf Ebrahimi    run_length = 0
79*9a0e4156SSadaf Ebrahimi
80*9a0e4156SSadaf Ebrahimi    i = 0
81*9a0e4156SSadaf Ebrahimi    while i < 8:
82*9a0e4156SSadaf Ebrahimi        if (data & (1 << i)):
83*9a0e4156SSadaf Ebrahimi            first = i
84*9a0e4156SSadaf Ebrahimi            run_length = 0
85*9a0e4156SSadaf Ebrahimi
86*9a0e4156SSadaf Ebrahimi            while (i < 7 and (data & (1 << (i + 1)))):
87*9a0e4156SSadaf Ebrahimi                i += 1
88*9a0e4156SSadaf Ebrahimi                run_length += 1
89*9a0e4156SSadaf Ebrahimi
90*9a0e4156SSadaf Ebrahimi            if len(buffer) or len(str):
91*9a0e4156SSadaf Ebrahimi                str += "/"
92*9a0e4156SSadaf Ebrahimi
93*9a0e4156SSadaf Ebrahimi            str += format("%%%s%d" % (prefix, first))
94*9a0e4156SSadaf Ebrahimi            if run_length > 0:
95*9a0e4156SSadaf Ebrahimi                str += format("-%%%s%d" % (prefix, first + run_length))
96*9a0e4156SSadaf Ebrahimi        i += 1
97*9a0e4156SSadaf Ebrahimi    return str
98*9a0e4156SSadaf Ebrahimi
99*9a0e4156SSadaf Ebrahimidef registerBits(op):
100*9a0e4156SSadaf Ebrahimi    str = ''
101*9a0e4156SSadaf Ebrahimi    data = op.register_bits
102*9a0e4156SSadaf Ebrahimi
103*9a0e4156SSadaf Ebrahimi    str += printRegbitsRange(str, data & 0xff, "d")
104*9a0e4156SSadaf Ebrahimi    str += printRegbitsRange(str, (data >> 8) & 0xff, "a")
105*9a0e4156SSadaf Ebrahimi    str += printRegbitsRange(str, (data >> 16) & 0xff, "fp")
106*9a0e4156SSadaf Ebrahimi    return str
107*9a0e4156SSadaf Ebrahimi
108*9a0e4156SSadaf Ebrahimidef dump_op_ea(insn, op):
109*9a0e4156SSadaf Ebrahimi    s_spacing = " "
110*9a0e4156SSadaf Ebrahimi    map_index_size_str = { 0: 'w', 1 : 'l' }
111*9a0e4156SSadaf Ebrahimi    str = ''
112*9a0e4156SSadaf Ebrahimi
113*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_NONE:
114*9a0e4156SSadaf Ebrahimi        if op.type == M68K_OP_REG_BITS:
115*9a0e4156SSadaf Ebrahimi            return registerBits(op)
116*9a0e4156SSadaf Ebrahimi        if op.type == M68K_OP_REG_PAIR:
117*9a0e4156SSadaf Ebrahimi            return registerPair(op)
118*9a0e4156SSadaf Ebrahimi        if op.type == M68K_OP_REG:
119*9a0e4156SSadaf Ebrahimi            return dump_op_reg(insn, op.reg)
120*9a0e4156SSadaf Ebrahimi
121*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_REG_DIRECT_DATA:
122*9a0e4156SSadaf Ebrahimi        return dump_op_reg(insn, op.reg)
123*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_REG_DIRECT_ADDR:
124*9a0e4156SSadaf Ebrahimi        return dump_op_reg(insn, op.reg) + "@"
125*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_REGI_ADDR:
126*9a0e4156SSadaf Ebrahimi        return dump_op_reg(insn, op.reg) + "@"
127*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_REGI_ADDR_POST_INC:
128*9a0e4156SSadaf Ebrahimi        return dump_op_reg(insn, op.reg) + "@+"
129*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_REGI_ADDR_PRE_DEC:
130*9a0e4156SSadaf Ebrahimi        return dump_op_reg(insn, op.reg) + "@-"
131*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_REGI_ADDR_DISP:
132*9a0e4156SSadaf Ebrahimi#        str = dump_op_reg(insn, op.mem.base_reg - M68K_REG_A0 + 1) #double check and fixme '+1' : 02af 899f 2622
133*9a0e4156SSadaf Ebrahimi        str = dump_op_reg(insn, op.mem.base_reg)
134*9a0e4156SSadaf Ebrahimi        if op.mem.disp:
135*9a0e4156SSadaf Ebrahimi            str += format("@(%d)" % s16(op.mem.disp))
136*9a0e4156SSadaf Ebrahimi        return str
137*9a0e4156SSadaf Ebrahimi
138*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_PCI_DISP:
139*9a0e4156SSadaf Ebrahimi        return format("%%pc@(0x%x)" % ( extsign1616(op.mem.disp + 2)))
140*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_ABSOLUTE_DATA_SHORT:
141*9a0e4156SSadaf Ebrahimi        return format("0x%x" % (extsign1616(op.imm & 0xffff)))
142*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_ABSOLUTE_DATA_LONG:
143*9a0e4156SSadaf Ebrahimi        return format("0x%x" % (op.imm & 0xffffffff))
144*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_IMMEDIATE:
145*9a0e4156SSadaf Ebrahimi        if insn.op_size.type == M68K_SIZE_TYPE_FPU:
146*9a0e4156SSadaf Ebrahimi            map_fpu_size_str = { M68K_FPU_SIZE_SINGLE : op.simm, M68K_FPU_SIZE_DOUBLE : op.dimm }
147*9a0e4156SSadaf Ebrahimi            return format("#%f" % (insn.op_size.fpu_size[map_fpu_size_str]))
148*9a0e4156SSadaf Ebrahimi        return format("#$%x" % (op.imm))
149*9a0e4156SSadaf Ebrahimi
150*9a0e4156SSadaf Ebrahimi    if op.address_mode in [ M68K_AM_PCI_INDEX_8_BIT_DISP, M68K_AM_AREGI_INDEX_8_BIT_DISP ]:
151*9a0e4156SSadaf Ebrahimi        disp = op.mem.disp
152*9a0e4156SSadaf Ebrahimi        if op.register_bits == 2:
153*9a0e4156SSadaf Ebrahimi            disp = extsign8(op.mem.disp)
154*9a0e4156SSadaf Ebrahimi        if op.register_bits == 4:
155*9a0e4156SSadaf Ebrahimi            disp = extsign1632(op.mem.disp)
156*9a0e4156SSadaf Ebrahimi
157*9a0e4156SSadaf Ebrahimi        str = dump_op_reg(insn, op.mem.base_reg) + "@(" + "{0:016x}".format(disp) + "," + dump_op_reg(insn, op.mem.index_reg) + ":" + map_index_size_str[op.mem.index_size]
158*9a0e4156SSadaf Ebrahimi        if op.register_bits:
159*9a0e4156SSadaf Ebrahimi            str += format(":%u" % (op.register_bits))
160*9a0e4156SSadaf Ebrahimi        return str + ")"
161*9a0e4156SSadaf Ebrahimi
162*9a0e4156SSadaf Ebrahimi
163*9a0e4156SSadaf Ebrahimi    if op.address_mode in [ M68K_AM_PCI_INDEX_BASE_DISP, M68K_AM_AREGI_INDEX_BASE_DISP ]:
164*9a0e4156SSadaf Ebrahimi        str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg) ))
165*9a0e4156SSadaf Ebrahimi        str += format("@(%016x)@(%016x" % (extsign1632(op.mem.in_disp), extsign1632(op.mem.out_disp)))
166*9a0e4156SSadaf Ebrahimi        if op.mem.index_reg:
167*9a0e4156SSadaf Ebrahimi            str += "," + dump_op_reg(insn, op.mem.index_reg) + ":" + map_index_size_str[op.mem.index_size]
168*9a0e4156SSadaf Ebrahimi        if op.register_bits:
169*9a0e4156SSadaf Ebrahimi            str += format(":%u" % (op.register_bits))
170*9a0e4156SSadaf Ebrahimi        str += ")"
171*9a0e4156SSadaf Ebrahimi        return str
172*9a0e4156SSadaf Ebrahimi
173*9a0e4156SSadaf Ebrahimi        if op.mem.in_disp > 0:
174*9a0e4156SSadaf Ebrahimi            str += format("$%x" % ( op.mem.in_disp))
175*9a0e4156SSadaf Ebrahimi
176*9a0e4156SSadaf Ebrahimi        str += format("(")
177*9a0e4156SSadaf Ebrahimi
178*9a0e4156SSadaf Ebrahimi        if op.address_mode == M68K_AM_PCI_INDEX_BASE_DISP:
179*9a0e4156SSadaf Ebrahimi            str_size = ''
180*9a0e4156SSadaf Ebrahimi            if op.mem.index_size:
181*9a0e4156SSadaf Ebrahimi                str_size = "l"
182*9a0e4156SSadaf Ebrahimi            else:
183*9a0e4156SSadaf Ebrahimi                str_size = "w"
184*9a0e4156SSadaf Ebrahimi            str += format("pc,%s%s.%s" % ( dump_op_reg(insn, op.mem.index_reg)), s_spacing, str_size)
185*9a0e4156SSadaf Ebrahimi        else:
186*9a0e4156SSadaf Ebrahimi            if op.mem.base_reg != M68K_REG_INVALID:
187*9a0e4156SSadaf Ebrahimi                str += format("a%d,%s" % ( op.mem.base_reg - M68K_REG_A0, s_spacing))
188*9a0e4156SSadaf Ebrahimi            str_size = ''
189*9a0e4156SSadaf Ebrahimi            if op.mem.index_size:
190*9a0e4156SSadaf Ebrahimi                str_size = "l"
191*9a0e4156SSadaf Ebrahimi            else:
192*9a0e4156SSadaf Ebrahimi                str_size = "w"
193*9a0e4156SSadaf Ebrahimi            str += format("%s.%s" % ( dump_op_reg(insn, op.mem.index_reg), str_size))
194*9a0e4156SSadaf Ebrahimi
195*9a0e4156SSadaf Ebrahimi        if op.mem.scale > 0:
196*9a0e4156SSadaf Ebrahimi            str += format("%s*%s%d)" % ( s_spacing, s_spacing, op.mem.scale))
197*9a0e4156SSadaf Ebrahimi        else:
198*9a0e4156SSadaf Ebrahimi            str += ")"
199*9a0e4156SSadaf Ebrahimi        return str
200*9a0e4156SSadaf Ebrahimi
201*9a0e4156SSadaf Ebrahimi    # It's ok to just use PCMI here as is as we set base_reg to PC in the disassembler.
202*9a0e4156SSadaf Ebrahimi    # While this is not strictly correct it makes the code
203*9a0e4156SSadaf Ebrahimi    # easier and that is what actually happens when the code is executed anyway.
204*9a0e4156SSadaf Ebrahimi
205*9a0e4156SSadaf Ebrahimi    if op.address_mode in [ M68K_AM_PC_MEMI_POST_INDEX, M68K_AM_PC_MEMI_PRE_INDEX, M68K_AM_MEMI_PRE_INDEX, M68K_AM_MEMI_POST_INDEX]:
206*9a0e4156SSadaf Ebrahimi        if op.mem.base_reg:
207*9a0e4156SSadaf Ebrahimi            str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg) ))
208*9a0e4156SSadaf Ebrahimi        if op.mem.in_disp:
209*9a0e4156SSadaf Ebrahimi            value = op.mem.in_disp
210*9a0e4156SSadaf Ebrahimi            if op.mem.in_disp & 0x8000:
211*9a0e4156SSadaf Ebrahimi                value = 0xffffffffffff0000 + op.mem.in_disp
212*9a0e4156SSadaf Ebrahimi            str += format("@(%016x)@(%016x)" % (value, op.mem.out_disp))
213*9a0e4156SSadaf Ebrahimi        return str
214*9a0e4156SSadaf Ebrahimi
215*9a0e4156SSadaf Ebrahimi        str += format("([")
216*9a0e4156SSadaf Ebrahimi        if op.mem.in_disp > 0:
217*9a0e4156SSadaf Ebrahimi            str += format("$%x" % ( op.mem.in_disp))
218*9a0e4156SSadaf Ebrahimi
219*9a0e4156SSadaf Ebrahimi        if op.mem.base_reg != M68K_REG_INVALID:
220*9a0e4156SSadaf Ebrahimi            if op.mem.in_disp > 0:
221*9a0e4156SSadaf Ebrahimi                str += format(",%s%s" % ( s_spacing, dump_op_reg(insn, op.mem.base_reg)))
222*9a0e4156SSadaf Ebrahimi            else:
223*9a0e4156SSadaf Ebrahimi                str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg)))
224*9a0e4156SSadaf Ebrahimi
225*9a0e4156SSadaf Ebrahimi        if op.address_mode in [ M68K_AM_MEMI_POST_INDEX, M68K_AM_PC_MEMI_POST_INDEX]:
226*9a0e4156SSadaf Ebrahimi            str += format("]")
227*9a0e4156SSadaf Ebrahimi
228*9a0e4156SSadaf Ebrahimi        if op.mem.index_reg != M68K_REG_INVALID:
229*9a0e4156SSadaf Ebrahimi            str_size = ''
230*9a0e4156SSadaf Ebrahimi            if op.mem.index_size:
231*9a0e4156SSadaf Ebrahimi                str_size = "l"
232*9a0e4156SSadaf Ebrahimi            else:
233*9a0e4156SSadaf Ebrahimi                str_size = "w"
234*9a0e4156SSadaf Ebrahimi            str += format(",%s%s.%s" % ( s_spacing, dump_op_reg(insn, op.mem.index_reg), str_size))
235*9a0e4156SSadaf Ebrahimi        if op.mem.scale > 0:
236*9a0e4156SSadaf Ebrahimi            str += format("%s*%s%d" % ( s_spacing, s_spacing, op.mem.scale))
237*9a0e4156SSadaf Ebrahimi        if op.address_mode in [ M68K_AM_MEMI_PRE_INDEX, M68K_AM_PC_MEMI_PRE_INDEX]:
238*9a0e4156SSadaf Ebrahimi            str += format("]")
239*9a0e4156SSadaf Ebrahimi        if op.mem.out_disp > 0:
240*9a0e4156SSadaf Ebrahimi            str += format(",%s$%x" % ( s_spacing, op.mem.out_disp))
241*9a0e4156SSadaf Ebrahimi        str += format(")")
242*9a0e4156SSadaf Ebrahimi        return str
243*9a0e4156SSadaf Ebrahimi
244*9a0e4156SSadaf Ebrahimi
245*9a0e4156SSadaf Ebrahimi    if op.mem.bitfield:
246*9a0e4156SSadaf Ebrahimi        return format("%d:%d" % ( op.mem.offset, op.mem.width))
247*9a0e4156SSadaf Ebrahimi
248*9a0e4156SSadaf Ebrahimi        ############# OK
249*9a0e4156SSadaf Ebrahimi    if op.address_mode == M68K_AM_AREGI_INDEX_BASE_DISP:
250*9a0e4156SSadaf Ebrahimi        if op.mem.index_size:
251*9a0e4156SSadaf Ebrahimi            str_size = "l"
252*9a0e4156SSadaf Ebrahimi        else:
253*9a0e4156SSadaf Ebrahimi            str_size = "w"
254*9a0e4156SSadaf Ebrahimi        bits = op.mem.disp
255*9a0e4156SSadaf Ebrahimi        return dump_op_reg(insn, op.mem.base_reg) + "@(" + "{0:016b}".format(bits) + "," + dump_op_reg(insn, op.mem.index_reg) + ":" + str_size + ")"
256*9a0e4156SSadaf Ebrahimi    return ''
257*9a0e4156SSadaf Ebrahimi
258*9a0e4156SSadaf Ebrahimi
259*9a0e4156SSadaf Ebrahimi
260*9a0e4156SSadaf Ebrahimi# M68K Addressing Modes
261*9a0e4156SSadaf Ebrahimi
262*9a0e4156SSadaf Ebrahimimap_address_mode_str = {
263*9a0e4156SSadaf Ebrahimi    0 : "M68K_AM_NONE",
264*9a0e4156SSadaf Ebrahimi    1 : "M68K_AM_REG_DIRECT_DATA",
265*9a0e4156SSadaf Ebrahimi    2 : "M68K_AM_REG_DIRECT_ADDR",
266*9a0e4156SSadaf Ebrahimi    3 : "M68K_AM_REGI_ADDR",
267*9a0e4156SSadaf Ebrahimi    4 : "M68K_AM_REGI_ADDR_POST_INC",
268*9a0e4156SSadaf Ebrahimi    5 : "M68K_AM_REGI_ADDR_PRE_DEC",
269*9a0e4156SSadaf Ebrahimi    6 : "M68K_AM_REGI_ADDR_DISP",
270*9a0e4156SSadaf Ebrahimi    7 : "M68K_AM_AREGI_INDEX_8_BIT_DISP",
271*9a0e4156SSadaf Ebrahimi    8 : "M68K_AM_AREGI_INDEX_BASE_DISP",
272*9a0e4156SSadaf Ebrahimi    9 : "M68K_AM_MEMI_POST_INDEX",
273*9a0e4156SSadaf Ebrahimi    10 : "M68K_AM_MEMI_PRE_INDEX",
274*9a0e4156SSadaf Ebrahimi    11 : "M68K_AM_PCI_DISP",
275*9a0e4156SSadaf Ebrahimi    12 : "M68K_AM_PCI_INDEX_8_BIT_DISP",
276*9a0e4156SSadaf Ebrahimi    13 : "M68K_AM_PCI_INDEX_BASE_DISP",
277*9a0e4156SSadaf Ebrahimi    14 : "M68K_AM_PC_MEMI_POST_INDEX",
278*9a0e4156SSadaf Ebrahimi    15 : "M68K_AM_PC_MEMI_PRE_INDEX",
279*9a0e4156SSadaf Ebrahimi    16 : "M68K_AM_ABSOLUTE_DATA_SHORT",
280*9a0e4156SSadaf Ebrahimi    17 : "M68K_AM_ABSOLUTE_DATA_LONG",
281*9a0e4156SSadaf Ebrahimi    18 : "M68K_AM_IMMEDIATE",
282*9a0e4156SSadaf Ebrahimi    }
283*9a0e4156SSadaf Ebrahimi
284*9a0e4156SSadaf Ebrahimi
285*9a0e4156SSadaf Ebrahimi# Operand type for instruction's operands
286*9a0e4156SSadaf Ebrahimi
287*9a0e4156SSadaf Ebrahimimap_op_str = {
288*9a0e4156SSadaf Ebrahimi    0 : "M68K_OP_INVALID",
289*9a0e4156SSadaf Ebrahimi    1 : "M68K_OP_REG",
290*9a0e4156SSadaf Ebrahimi    2 : "M68K_OP_IMM",
291*9a0e4156SSadaf Ebrahimi    3 : "M68K_OP_MEM",
292*9a0e4156SSadaf Ebrahimi    4 : "M68K_OP_FP",
293*9a0e4156SSadaf Ebrahimi    5 : "M68K_OP_REG_BITS",
294*9a0e4156SSadaf Ebrahimi    6 : "M68K_OP_REG_PAIR",
295*9a0e4156SSadaf Ebrahimi}
296*9a0e4156SSadaf Ebrahimi
297*9a0e4156SSadaf Ebrahimi
298*9a0e4156SSadaf Ebrahimidef debug(insn, op):
299*9a0e4156SSadaf Ebrahimi    if len(sys.argv) > 3:
300*9a0e4156SSadaf Ebrahimi        print("id %d type %s address_mode %s" % (insn.id, map_op_str[op.type], map_address_mode_str[op.address_mode]))
301*9a0e4156SSadaf Ebrahimi
302*9a0e4156SSadaf Ebrahimi
303*9a0e4156SSadaf Ebrahimidef dump_ops(insn):
304*9a0e4156SSadaf Ebrahimi    str = ''
305*9a0e4156SSadaf Ebrahimi    mnemonic = insn.insn_name()
306*9a0e4156SSadaf Ebrahimi
307*9a0e4156SSadaf Ebrahimi    i = 0
308*9a0e4156SSadaf Ebrahimi    while i < len(insn.operands):
309*9a0e4156SSadaf Ebrahimi        if i > 0:
310*9a0e4156SSadaf Ebrahimi            str += ','
311*9a0e4156SSadaf Ebrahimi        op = insn.operands[i]
312*9a0e4156SSadaf Ebrahimi        debug(insn, op)
313*9a0e4156SSadaf Ebrahimi        # "data" instruction generated by SKIPDATA option has no detail
314*9a0e4156SSadaf Ebrahimi        if insn.id == M68K_INS_INVALID:
315*9a0e4156SSadaf Ebrahimi            return format("0x%04x" % (op.imm))
316*9a0e4156SSadaf Ebrahimi        if op.type == M68K_OP_REG:
317*9a0e4156SSadaf Ebrahimi            str_op_reg = dump_op_ea(insn, op)
318*9a0e4156SSadaf Ebrahimi            if str_op_reg == '' or op.address_mode == M68K_AM_REG_DIRECT_ADDR:
319*9a0e4156SSadaf Ebrahimi                str_op_reg = dump_op_reg(insn, op.reg)
320*9a0e4156SSadaf Ebrahimi            str += str_op_reg
321*9a0e4156SSadaf Ebrahimi        if op.type == M68K_OP_IMM:
322*9a0e4156SSadaf Ebrahimi            str_op_imm = format("#%u" % (op.imm))
323*9a0e4156SSadaf Ebrahimi            if mnemonic in ["bkpt"]:
324*9a0e4156SSadaf Ebrahimi                str_op_imm = format("%u" % (op.imm))
325*9a0e4156SSadaf Ebrahimi            signed_insn = [ "move", "moveq", "cmp", "cmpi", "ori", "bclr", "pack", "unpk", "sub", "add" ]
326*9a0e4156SSadaf Ebrahimi            if mnemonic in signed_insn:
327*9a0e4156SSadaf Ebrahimi                if insn.op_size.size == 1 or mnemonic == "moveq":
328*9a0e4156SSadaf Ebrahimi                    str_op_imm = format("#%d" % s8(op.imm))
329*9a0e4156SSadaf Ebrahimi                if insn.op_size.size == 2 or mnemonic == "pack":
330*9a0e4156SSadaf Ebrahimi                    str_op_imm = format("#%d" % s16(op.imm))
331*9a0e4156SSadaf Ebrahimi                if insn.op_size.size == 4:
332*9a0e4156SSadaf Ebrahimi                    str_op_imm = format("#%d" % (op.imm))
333*9a0e4156SSadaf Ebrahimi
334*9a0e4156SSadaf Ebrahimi            dbxx_insn = [ "dbt", "dbf", "dbhi", "dbls", "dbcc", "dbcs", "dbne", "dbeq", "dbvc", "dbvs", "dbpl", "dbmi", "dbge", "dblt", "dbgt", "dble", "dbra" ]
335*9a0e4156SSadaf Ebrahimi            if is_branch(insn) or mnemonic in dbxx_insn:
336*9a0e4156SSadaf Ebrahimi                str_op_imm = format("0x%x" % (op.imm & 0xffffffff))
337*9a0e4156SSadaf Ebrahimi            str += str_op_imm
338*9a0e4156SSadaf Ebrahimi        if op.type == M68K_OP_MEM:
339*9a0e4156SSadaf Ebrahimi            str_op_mem = dump_op_ea(insn, op)
340*9a0e4156SSadaf Ebrahimi            if str_op_mem == '':
341*9a0e4156SSadaf Ebrahimi                str_op_mem = format("0x%x" % (op.imm))
342*9a0e4156SSadaf Ebrahimi            str += str_op_mem
343*9a0e4156SSadaf Ebrahimi        if op.type in [ M68K_OP_REG_BITS, M68K_OP_REG_PAIR ]:
344*9a0e4156SSadaf Ebrahimi            str += dump_op_ea(insn, op)
345*9a0e4156SSadaf Ebrahimi
346*9a0e4156SSadaf Ebrahimi#        if insn.address == 0x3127c:
347*9a0e4156SSadaf Ebrahimi#            import pdb;pdb.set_trace()
348*9a0e4156SSadaf Ebrahimi#        print("type %u am %u\n" % (op.type, op.address_mode))
349*9a0e4156SSadaf Ebrahimi        i += 1
350*9a0e4156SSadaf Ebrahimi    return str
351*9a0e4156SSadaf Ebrahimi
352*9a0e4156SSadaf Ebrahimi
353*9a0e4156SSadaf Ebrahimidef is_branch(insn):
354*9a0e4156SSadaf Ebrahimi    mnemonic = insn.insn_name()
355*9a0e4156SSadaf Ebrahimi    branch_insn = [ "bsr", "bra", "bhi", "bls", "bcc", "bcs", "bne", "beq", "bvc", "bvs", "bpl", "bmi", "bge", "blt", "bgt", "ble" ];
356*9a0e4156SSadaf Ebrahimi    return mnemonic in branch_insn
357*9a0e4156SSadaf Ebrahimi
358*9a0e4156SSadaf Ebrahimidef dump_mnemonic(insn):
359*9a0e4156SSadaf Ebrahimi    # "data" instruction generated by SKIPDATA option has no detail
360*9a0e4156SSadaf Ebrahimi    if insn.id == M68K_INS_INVALID:
361*9a0e4156SSadaf Ebrahimi        return ".short"
362*9a0e4156SSadaf Ebrahimi    mnemonic = insn.insn_name()
363*9a0e4156SSadaf Ebrahimi    ext = { 0: '', 1:'b', 2:'w', 4:'l' }
364*9a0e4156SSadaf Ebrahimi    if is_branch(insn):
365*9a0e4156SSadaf Ebrahimi        ext.update({ 1:'s', 2:'w', 4:'l' })
366*9a0e4156SSadaf Ebrahimi
367*9a0e4156SSadaf Ebrahimi    no_size = [ "pea", "lea", "bset", "bclr", "bchg", "btst", "nbcd", "abcd", "sbcd", "exg", "scc", "sls", "scs", "shi" ]
368*9a0e4156SSadaf Ebrahimi    sxx_insn = [ "st", "sf", "shi", "sls", "scc", "scs", "sne", "seq", "svc", "svs", "spl", "smi", "sge", "slt", "sgt", "sle", "stop" ]
369*9a0e4156SSadaf Ebrahimi    no_size += sxx_insn
370*9a0e4156SSadaf Ebrahimi    no_size += [ "tas" ]
371*9a0e4156SSadaf Ebrahimi    if mnemonic in no_size:
372*9a0e4156SSadaf Ebrahimi        ext.update({ 0:'', 1:'', 2:'', 4:'' })
373*9a0e4156SSadaf Ebrahimi    return mnemonic + ext[insn.op_size.size]
374*9a0e4156SSadaf Ebrahimi
375*9a0e4156SSadaf Ebrahimidef print_insn_detail_np(insn):
376*9a0e4156SSadaf Ebrahimi    # objdump format hack
377*9a0e4156SSadaf Ebrahimi    if insn.size == 2:
378*9a0e4156SSadaf Ebrahimi        space = ' ' * 11
379*9a0e4156SSadaf Ebrahimi    if insn.size == 4:
380*9a0e4156SSadaf Ebrahimi        space = ' ' * 6
381*9a0e4156SSadaf Ebrahimi    if insn.size >= 6:
382*9a0e4156SSadaf Ebrahimi        space = ' '
383*9a0e4156SSadaf Ebrahimi    space_ops = ''
384*9a0e4156SSadaf Ebrahimi    if len(insn.operands) > 0:
385*9a0e4156SSadaf Ebrahimi        space_ops = ' '
386*9a0e4156SSadaf Ebrahimi
387*9a0e4156SSadaf Ebrahimi    print("   %x:\t%s%s\t%s%s%s" % (insn.address, dump_bytes(insn._raw.bytes, min(insn.size, 6)), space, dump_mnemonic(insn), space_ops, dump_ops(insn)))
388*9a0e4156SSadaf Ebrahimi
389*9a0e4156SSadaf Ebrahimi    if insn.size > 6:
390*9a0e4156SSadaf Ebrahimi        delta = min(insn.size, 6)
391*9a0e4156SSadaf Ebrahimi        print("   %x:\t%s " % (insn.address+delta, dump_bytes(insn._raw.bytes[delta:], min(insn.size-delta, 6))))
392*9a0e4156SSadaf Ebrahimi
393*9a0e4156SSadaf Ebrahimi
394*9a0e4156SSadaf Ebrahimidef print_objdump_dumpheader(filename='', address=0):
395*9a0e4156SSadaf Ebrahimi    print(objdump_dumpheader_fmt % (filename, address))
396*9a0e4156SSadaf Ebrahimi
397*9a0e4156SSadaf Ebrahimi# ## Test class Cs
398*9a0e4156SSadaf Ebrahimidef test_class():
399*9a0e4156SSadaf Ebrahimi    for (arch, mode, code, comment) in all_tests:
400*9a0e4156SSadaf Ebrahimi        filename = "/dev/stdin"
401*9a0e4156SSadaf Ebrahimi        address = 0
402*9a0e4156SSadaf Ebrahimi        if len(sys.argv) > 1:
403*9a0e4156SSadaf Ebrahimi            filename = sys.argv[1]
404*9a0e4156SSadaf Ebrahimi        if len(sys.argv) > 2:
405*9a0e4156SSadaf Ebrahimi            address = int(sys.argv[2],16)
406*9a0e4156SSadaf Ebrahimi        if len(sys.argv) > 3:
407*9a0e4156SSadaf Ebrahimi            debug_mode = True
408*9a0e4156SSadaf Ebrahimi
409*9a0e4156SSadaf Ebrahimi        with open(filename, "rb") as f:
410*9a0e4156SSadaf Ebrahimi            code = f.read()
411*9a0e4156SSadaf Ebrahimi
412*9a0e4156SSadaf Ebrahimi        try:
413*9a0e4156SSadaf Ebrahimi            md = Cs(arch, mode)
414*9a0e4156SSadaf Ebrahimi            md.detail = True
415*9a0e4156SSadaf Ebrahimi
416*9a0e4156SSadaf Ebrahimi            print_objdump_dumpheader(filename, address)
417*9a0e4156SSadaf Ebrahimi
418*9a0e4156SSadaf Ebrahimi            for insn in md.disasm(code, address):
419*9a0e4156SSadaf Ebrahimi                print_insn_detail_np(insn)
420*9a0e4156SSadaf Ebrahimi
421*9a0e4156SSadaf Ebrahimi        except CsError as e:
422*9a0e4156SSadaf Ebrahimi            print("ERROR: %s" % e)
423*9a0e4156SSadaf Ebrahimi
424*9a0e4156SSadaf Ebrahimi
425*9a0e4156SSadaf Ebrahimiif __name__ == '__main__':
426*9a0e4156SSadaf Ebrahimi    test_class()
427