Update
[pcsx_rearmed.git] / deps / lightrec / disassembler.h
CommitLineData
d16005f8 1/*
a59e5536 2 * Copyright (C) 2014-2020 Paul Cercueil <paul@crapouillou.net>
d16005f8
PC
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 */
14
15#ifndef __DISASSEMBLER_H__
16#define __DISASSEMBLER_H__
17
18#include "debug.h"
19#include "lightrec.h"
20
21#ifndef __packed
22#define __packed __attribute__((packed))
23#endif
24
25#define LIGHTREC_DIRECT_IO (1 << 0)
26#define LIGHTREC_NO_INVALIDATE (1 << 1)
27#define LIGHTREC_NO_DS (1 << 2)
28#define LIGHTREC_SMC (1 << 3)
29#define LIGHTREC_EMULATE_BRANCH (1 << 4)
30#define LIGHTREC_LOCAL_BRANCH (1 << 5)
31#define LIGHTREC_HW_IO (1 << 6)
32#define LIGHTREC_MULT32 (1 << 7)
33
34struct block;
35
36enum standard_opcodes {
37 OP_SPECIAL = 0x00,
38 OP_REGIMM = 0x01,
39 OP_J = 0x02,
40 OP_JAL = 0x03,
41 OP_BEQ = 0x04,
42 OP_BNE = 0x05,
43 OP_BLEZ = 0x06,
44 OP_BGTZ = 0x07,
45 OP_ADDI = 0x08,
46 OP_ADDIU = 0x09,
47 OP_SLTI = 0x0a,
48 OP_SLTIU = 0x0b,
49 OP_ANDI = 0x0c,
50 OP_ORI = 0x0d,
51 OP_XORI = 0x0e,
52 OP_LUI = 0x0f,
53 OP_CP0 = 0x10,
54 OP_CP2 = 0x12,
55 OP_LB = 0x20,
56 OP_LH = 0x21,
57 OP_LWL = 0x22,
58 OP_LW = 0x23,
59 OP_LBU = 0x24,
60 OP_LHU = 0x25,
61 OP_LWR = 0x26,
62 OP_SB = 0x28,
63 OP_SH = 0x29,
64 OP_SWL = 0x2a,
65 OP_SW = 0x2b,
66 OP_SWR = 0x2e,
67 OP_LWC2 = 0x32,
68 OP_SWC2 = 0x3a,
69
70 OP_META_REG_UNLOAD = 0x11,
71
72 OP_META_BEQZ = 0x14,
73 OP_META_BNEZ = 0x15,
74
75 OP_META_MOV = 0x16,
76 OP_META_SYNC = 0x17,
77};
78
79enum special_opcodes {
80 OP_SPECIAL_SLL = 0x00,
81 OP_SPECIAL_SRL = 0x02,
82 OP_SPECIAL_SRA = 0x03,
83 OP_SPECIAL_SLLV = 0x04,
84 OP_SPECIAL_SRLV = 0x06,
85 OP_SPECIAL_SRAV = 0x07,
86 OP_SPECIAL_JR = 0x08,
87 OP_SPECIAL_JALR = 0x09,
88 OP_SPECIAL_SYSCALL = 0x0c,
89 OP_SPECIAL_BREAK = 0x0d,
90 OP_SPECIAL_MFHI = 0x10,
91 OP_SPECIAL_MTHI = 0x11,
92 OP_SPECIAL_MFLO = 0x12,
93 OP_SPECIAL_MTLO = 0x13,
94 OP_SPECIAL_MULT = 0x18,
95 OP_SPECIAL_MULTU = 0x19,
96 OP_SPECIAL_DIV = 0x1a,
97 OP_SPECIAL_DIVU = 0x1b,
98 OP_SPECIAL_ADD = 0x20,
99 OP_SPECIAL_ADDU = 0x21,
100 OP_SPECIAL_SUB = 0x22,
101 OP_SPECIAL_SUBU = 0x23,
102 OP_SPECIAL_AND = 0x24,
103 OP_SPECIAL_OR = 0x25,
104 OP_SPECIAL_XOR = 0x26,
105 OP_SPECIAL_NOR = 0x27,
106 OP_SPECIAL_SLT = 0x2a,
107 OP_SPECIAL_SLTU = 0x2b,
108};
109
110enum regimm_opcodes {
111 OP_REGIMM_BLTZ = 0x00,
112 OP_REGIMM_BGEZ = 0x01,
113 OP_REGIMM_BLTZAL = 0x10,
114 OP_REGIMM_BGEZAL = 0x11,
115};
116
117enum cp0_opcodes {
118 OP_CP0_MFC0 = 0x00,
119 OP_CP0_CFC0 = 0x02,
120 OP_CP0_MTC0 = 0x04,
121 OP_CP0_CTC0 = 0x06,
122 OP_CP0_RFE = 0x10,
123};
124
125enum cp2_opcodes {
126 OP_CP2_BASIC = 0x00,
127};
128
129enum cp2_basic_opcodes {
130 OP_CP2_BASIC_MFC2 = 0x00,
131 OP_CP2_BASIC_CFC2 = 0x02,
132 OP_CP2_BASIC_MTC2 = 0x04,
133 OP_CP2_BASIC_CTC2 = 0x06,
134};
135
136struct opcode_r {
137#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
138 u32 zero :6;
139 u32 rs :5;
140 u32 rt :5;
141 u32 rd :5;
142 u32 imm :5;
143 u32 op :6;
144#else
145 u32 op :6;
146 u32 imm :5;
147 u32 rd :5;
148 u32 rt :5;
149 u32 rs :5;
150 u32 zero :6;
151#endif
152} __packed;
153
154struct opcode_i {
155#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
156 u32 op :6;
157 u32 rs :5;
158 u32 rt :5;
159 u32 imm :16;
160#else
161 u32 imm :16;
162 u32 rt :5;
163 u32 rs :5;
164 u32 op :6;
165#endif
166} __packed;
167
168struct opcode_j {
169#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
170 u32 op :6;
171 u32 imm :26;
172#else
173 u32 imm :26;
174 u32 op :6;
175#endif
176} __packed;
177
178union code {
179 /* Keep in sync with struct opcode */
180 u32 opcode;
181 struct opcode_r r;
182 struct opcode_i i;
183 struct opcode_j j;
184};
185
186struct opcode {
187 /* Keep this union at the first position */
188 union {
189 union code c;
190
191 /* Keep in sync with union code */
192 u32 opcode;
193 struct opcode_r r;
194 struct opcode_i i;
195 struct opcode_j j;
196 };
197 u16 flags;
198 u16 offset;
199 struct opcode *next;
200};
201
202struct opcode * lightrec_disassemble(struct lightrec_state *state,
203 const u32 *src, unsigned int *len);
204void lightrec_free_opcode_list(struct lightrec_state *state,
205 struct opcode *list);
206
207unsigned int lightrec_cycles_of_opcode(union code code);
208
209void lightrec_print_disassembly(const struct block *block,
210 const u32 *code, unsigned int length);
211
212#endif /* __DISASSEMBLER_H__ */