1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/*
* disasm.c
*
* PowerPC 603e disassembler.
*
* When possible, invalid forms of instructions are checked for. To the best
* of my knowledge, all appropriate load/store instructions are checked. I'm
* not sure whether any other kinds of instructions need checking.
*/
/* Originally written by Bart Trzynadlowski for Supermodel project
*
* PowerPC 403 opcodes and MAME conversion by Ville Linde
*/
#ifndef MAME_CPU_POWERPC_PPC_DASM_H
#define MAME_CPU_POWERPC_PPC_DASM_H
#pragma once
class powerpc_disassembler : public util::disasm_interface
{
public:
powerpc_disassembler() = default;
virtual ~powerpc_disassembler() = default;
virtual u32 opcode_alignment() const override;
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
static offs_t dasm_one(std::ostream &stream, uint32_t pc, uint32_t op);
private:
/*
* Operand Formats
*
* These convey information on what operand fields are present and how they
* ought to be printed.
*
* I'm fairly certain all of these are used, but that is not guaranteed.
*/
enum
{
F_NONE, // <no operands>
F_LI, // LI*4+PC if AA=0 else LI*4
F_BCx, // BO, BI, target_addr used only by BCx
F_RT_RA_0_SIMM, // rT, rA|0, SIMM rA|0 means if rA == 0, print 0
F_ADDIS, // rT, rA, SIMM (printed as unsigned) only used by ADDIS
F_RT_RA_SIMM, // rT, rA, SIMM
F_RA_RT_UIMM, // rA, rT, UIMM
F_CMP_SIMM, // crfD, L, A, SIMM
F_CMP_UIMM, // crfD, L, A, UIMM
F_RT_RA_0_RB, // rT, rA|0, rB
F_RT_RA_RB, // rT, rA, rB
F_RT_D_RA_0, // rT, d(rA|0)
F_RT_D_RA, // rT, d(rA)
F_RA_RT_RB, // rA, rT, rB
F_FRT_D_RA_0, // frT, d(RA|0)
F_FRT_D_RA, // frT, d(RA)
F_FRT_RA_0_RB, // frT, rA|0, rB
F_FRT_RA_RB, // frT, rA, rB
F_TWI, // TO, rA, SIMM only used by TWI instruction
F_CMP, // crfD, L, rA, rB
F_RA_RT, // rA, rT
F_RA_0_RB, // rA|0, rB
F_FRT_FRB, // frT, frB
F_FCMP, // crfD, frA, frB
F_CRFD_CRFS, // crfD, crfS
F_MCRXR, // crfD only used by MCRXR
F_RT, // rT
F_MFSR, // rT, SR only used by MFSR
F_MTSR, // SR, rT only used by MTSR
F_MFFSx, // frT only used by MFFSx
F_FCRBD, // crbD FPSCR[crbD]
F_MTFSFIx, // crfD, IMM only used by MTFSFIx
F_RB, // rB
F_TW, // TO, rA, rB only used by TW
F_RT_RA_0_NB, // rT, rA|0, NB print 32 if NB == 0
F_SRAWIx, // rA, rT, SH only used by SRAWIx
F_BO_BI, // BO, BI
F_CRBD_CRBA_CRBB, // crbD, crbA, crbB
F_RT_SPR, // rT, SPR and TBR
F_MTSPR, // SPR, rT only used by MTSPR
F_MTCRF, // CRM, rT only used by MTCRF
F_MTFSFx, // FM, frB only used by MTFSFx
F_RT_DCR, // rT, DCR
F_MTDCR, // DCR, rT
F_RT_RA, // rT, rA
F_FRT_FRA_FRC_FRB, // frT, frA, frC, frB
F_FRT_FRA_FRB, // frT, frA, frB
F_FRT_FRA_FRC, // frT, frA, frC
F_RA_RT_SH_MB_ME, // rA, rT, SH, MB, ME
F_RLWNMx, // rT, rA, rB, MB, ME only used by RLWNMx
F_RT_RB // rT, rB
};
/*
* Flags
*/
enum
{
FL_OE = 1 << 0, // if there is an OE field
FL_RC = 1 << 1, // if there is an RC field
FL_LK = 1 << 2, // if there is an LK field
FL_AA = 1 << 3, // if there is an AA field
FL_CHECK_RA_RT = 1 << 4, // assert rA!=0 and rA!=rT
FL_CHECK_RA = 1 << 5, // assert rA!=0
FL_CHECK_LSWI = 1 << 6, // specific check for LSWI validity
FL_CHECK_LSWX = 1 << 7, // specific check for LSWX validity
FL_SO = 1 << 8 // use STEP_OUT
};
/*
* Instruction Descriptor
*
* Describes the layout of an instruction.
*/
struct IDESCR
{
char mnem[32]; // mnemonic
uint32_t match; // bit pattern of instruction after it has been masked
uint32_t mask; // mask of variable fields (AND with ~mask to compare w/
// bit pattern to determine a match)
int format; // operand format
int flags; // flags
};
static const IDESCR itab[];
static const char *const crbit[4];
static const char *const crnbit[4];
static std::string SPR(int spr_field);
static std::string DCR(int dcr_field);
static std::string DecodeSigned16(uint32_t op, int do_unsigned);
static uint32_t Mask(int mb, int me);
static bool Simplified(uint32_t op, uint32_t vpc, std::string &signed16, std::string &mnem, std::string &oprs);
};
#endif
|