psxmem: Add support for Lightrec's custom mem init sequence
[pcsx_rearmed.git] / deps / lightrec / disassembler.h
CommitLineData
98fa08a5 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
d16005f8 2/*
98fa08a5 3 * Copyright (C) 2014-2021 Paul Cercueil <paul@crapouillou.net>
d16005f8
PC
4 */
5
6#ifndef __DISASSEMBLER_H__
7#define __DISASSEMBLER_H__
8
9#include "debug.h"
10#include "lightrec.h"
11
12#ifndef __packed
13#define __packed __attribute__((packed))
14#endif
15
98fa08a5
PC
16#define BIT(x) (1ULL << (x))
17
18/* Flags for all opcodes */
19#define LIGHTREC_NO_DS BIT(0)
20#define LIGHTREC_UNLOAD_RS BIT(1)
21#define LIGHTREC_UNLOAD_RT BIT(2)
22#define LIGHTREC_UNLOAD_RD BIT(3)
23#define LIGHTREC_SYNC BIT(4)
24
25/* Flags for load/store opcodes */
22eee2ac
PC
26#define LIGHTREC_SMC BIT(5)
27#define LIGHTREC_NO_INVALIDATE BIT(6)
28#define LIGHTREC_NO_MASK BIT(7)
29
30/* I/O mode for load/store opcodes */
31#define LIGHTREC_IO_MODE_LSB 8
32#define LIGHTREC_IO_MODE(x) ((x) << LIGHTREC_IO_MODE_LSB)
33#define LIGHTREC_IO_UNKNOWN 0x0
34#define LIGHTREC_IO_DIRECT 0x1
35#define LIGHTREC_IO_HW 0x2
36#define LIGHTREC_IO_RAM 0x3
37#define LIGHTREC_IO_BIOS 0x4
38#define LIGHTREC_IO_SCRATCH 0x5
39#define LIGHTREC_IO_MASK LIGHTREC_IO_MODE(0x7)
40#define LIGHTREC_FLAGS_GET_IO_MODE(x) \
41 (((x) & LIGHTREC_IO_MASK) >> LIGHTREC_IO_MODE_LSB)
98fa08a5
PC
42
43/* Flags for branches */
44#define LIGHTREC_EMULATE_BRANCH BIT(5)
45#define LIGHTREC_LOCAL_BRANCH BIT(6)
46
47/* Flags for div/mult opcodes */
48#define LIGHTREC_NO_LO BIT(5)
49#define LIGHTREC_NO_HI BIT(6)
50#define LIGHTREC_NO_DIV_CHECK BIT(7)
d16005f8
PC
51
52struct block;
53
54enum standard_opcodes {
55 OP_SPECIAL = 0x00,
56 OP_REGIMM = 0x01,
57 OP_J = 0x02,
58 OP_JAL = 0x03,
59 OP_BEQ = 0x04,
60 OP_BNE = 0x05,
61 OP_BLEZ = 0x06,
62 OP_BGTZ = 0x07,
63 OP_ADDI = 0x08,
64 OP_ADDIU = 0x09,
65 OP_SLTI = 0x0a,
66 OP_SLTIU = 0x0b,
67 OP_ANDI = 0x0c,
68 OP_ORI = 0x0d,
69 OP_XORI = 0x0e,
70 OP_LUI = 0x0f,
71 OP_CP0 = 0x10,
72 OP_CP2 = 0x12,
73 OP_LB = 0x20,
74 OP_LH = 0x21,
75 OP_LWL = 0x22,
76 OP_LW = 0x23,
77 OP_LBU = 0x24,
78 OP_LHU = 0x25,
79 OP_LWR = 0x26,
80 OP_SB = 0x28,
81 OP_SH = 0x29,
82 OP_SWL = 0x2a,
83 OP_SW = 0x2b,
84 OP_SWR = 0x2e,
85 OP_LWC2 = 0x32,
86 OP_SWC2 = 0x3a,
87
d16005f8 88 OP_META_MOV = 0x16,
98fa08a5
PC
89
90 OP_META_EXTC = 0x17,
91 OP_META_EXTS = 0x18,
d16005f8
PC
92};
93
94enum special_opcodes {
95 OP_SPECIAL_SLL = 0x00,
96 OP_SPECIAL_SRL = 0x02,
97 OP_SPECIAL_SRA = 0x03,
98 OP_SPECIAL_SLLV = 0x04,
99 OP_SPECIAL_SRLV = 0x06,
100 OP_SPECIAL_SRAV = 0x07,
101 OP_SPECIAL_JR = 0x08,
102 OP_SPECIAL_JALR = 0x09,
103 OP_SPECIAL_SYSCALL = 0x0c,
104 OP_SPECIAL_BREAK = 0x0d,
105 OP_SPECIAL_MFHI = 0x10,
106 OP_SPECIAL_MTHI = 0x11,
107 OP_SPECIAL_MFLO = 0x12,
108 OP_SPECIAL_MTLO = 0x13,
109 OP_SPECIAL_MULT = 0x18,
110 OP_SPECIAL_MULTU = 0x19,
111 OP_SPECIAL_DIV = 0x1a,
112 OP_SPECIAL_DIVU = 0x1b,
113 OP_SPECIAL_ADD = 0x20,
114 OP_SPECIAL_ADDU = 0x21,
115 OP_SPECIAL_SUB = 0x22,
116 OP_SPECIAL_SUBU = 0x23,
117 OP_SPECIAL_AND = 0x24,
118 OP_SPECIAL_OR = 0x25,
119 OP_SPECIAL_XOR = 0x26,
120 OP_SPECIAL_NOR = 0x27,
121 OP_SPECIAL_SLT = 0x2a,
122 OP_SPECIAL_SLTU = 0x2b,
123};
124
125enum regimm_opcodes {
126 OP_REGIMM_BLTZ = 0x00,
127 OP_REGIMM_BGEZ = 0x01,
128 OP_REGIMM_BLTZAL = 0x10,
129 OP_REGIMM_BGEZAL = 0x11,
130};
131
132enum cp0_opcodes {
133 OP_CP0_MFC0 = 0x00,
134 OP_CP0_CFC0 = 0x02,
135 OP_CP0_MTC0 = 0x04,
136 OP_CP0_CTC0 = 0x06,
137 OP_CP0_RFE = 0x10,
138};
139
140enum cp2_opcodes {
141 OP_CP2_BASIC = 0x00,
142};
143
144enum cp2_basic_opcodes {
145 OP_CP2_BASIC_MFC2 = 0x00,
146 OP_CP2_BASIC_CFC2 = 0x02,
147 OP_CP2_BASIC_MTC2 = 0x04,
148 OP_CP2_BASIC_CTC2 = 0x06,
149};
150
151struct opcode_r {
152#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
153 u32 zero :6;
154 u32 rs :5;
155 u32 rt :5;
156 u32 rd :5;
157 u32 imm :5;
158 u32 op :6;
159#else
160 u32 op :6;
161 u32 imm :5;
162 u32 rd :5;
163 u32 rt :5;
164 u32 rs :5;
165 u32 zero :6;
166#endif
167} __packed;
168
169struct opcode_i {
170#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
171 u32 op :6;
172 u32 rs :5;
173 u32 rt :5;
174 u32 imm :16;
175#else
176 u32 imm :16;
177 u32 rt :5;
178 u32 rs :5;
179 u32 op :6;
180#endif
181} __packed;
182
183struct opcode_j {
184#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
185 u32 op :6;
186 u32 imm :26;
187#else
188 u32 imm :26;
189 u32 op :6;
190#endif
191} __packed;
192
193union code {
194 /* Keep in sync with struct opcode */
195 u32 opcode;
196 struct opcode_r r;
197 struct opcode_i i;
198 struct opcode_j j;
199};
200
201struct opcode {
202 /* Keep this union at the first position */
203 union {
204 union code c;
205
206 /* Keep in sync with union code */
207 u32 opcode;
208 struct opcode_r r;
209 struct opcode_i i;
210 struct opcode_j j;
211 };
212 u16 flags;
d16005f8
PC
213};
214
98fa08a5 215void lightrec_print_disassembly(const struct block *block, const u32 *code);
d16005f8
PC
216
217#endif /* __DISASSEMBLER_H__ */