-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathgct.h
235 lines (187 loc) · 6.09 KB
/
gct.h
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#pragma once
#define GCT_WRITE_8(ADDRESS, VALUE) \
.long 0x00000000 | ((ADDRESS) & 0x1FFFFFF); \
.long (VALUE & 0xFF)
#define GCT_FILL_8(ADDRESS, VALUE, COUNT) \
.long 0x00000000 | ((ADDRESS) & 0x1FFFFFF); \
.long (VALUE & 0xFF) | ((COUNT + 1) << 16)
#define GCT_WRITE_16(ADDRESS, VALUE) \
.long 0x02000000 | ((ADDRESS) & 0x1FFFFFF); \
.long (VALUE & 0xFFFF)
#define GCT_FILL_16(ADDRESS, VALUE, COUNT) \
.long 0x02000000 | ((ADDRESS) & 0x1FFFFFF); \
.long (VALUE & 0xFFFF) | ((COUNT + 1) << 16)
#define GCT_WRITE_32(ADDRESS, VALUE) \
.long 0x04000000 | ((ADDRESS) & 0x1FFFFFF); \
.long VALUE
#define GCT_WRITE_INSTR(ADDRESS, ...) \
.long 0x04000000 | ((ADDRESS) & 0x1FFFFFF); \
__VA_ARGS__
#define GCT_WRITE_STRING(ADDRESS, STRING) \
.long 0x06000000 | ((ADDRESS) & 0x1FFFFFF); \
.long string_##ADDRESS##_size; \
string_##ADDRESS:; \
.string STRING; \
.set string_##ADDRESS##_size, . - string_##ADDRESS; \
.align 3
#define GCT_STRING(ADDRESS, NAME) \
.long 0x06000000 | ((ADDRESS) & 0x1FFFFFF); \
.long NAME##_size; \
NAME:;
#define GCT_STRING_END(NAME) \
.set NAME##_size, . - NAME; \
.align 3
#define GCT_STRING_B_CALL(ADDRESS, NAME, DEST) \
b DEST - ((ADDRESS) + (. - NAME))
#define GCT_STRING_BL_CALL(ADDRESS, NAME, DEST) \
bl DEST - ((ADDRESS) + (. - NAME))
#define GCT_STRING_BC_CALL(ADDRESS, NAME, FIELD, CONDITION, DEST) \
b##CONDITION- FIELD, DEST - ((ADDRESS) + (. - NAME))
#define GCT_STRING_BCL_CALL(ADDRESS, NAME, FIELD, CONDITION, DEST) \
b##CONDITION##l- FIELD, DEST - ((ADDRESS) + (. - NAME))
#define GCT_STRING_PTR(ADDRESS, NAME, REG, DEST) \
lis REG, ((ADDRESS) + (DEST - NAME))@ha; \
addi REG, REG, ((ADDRESS) + (DEST - NAME))@l
#define GCT_STRING_PTR_LWZ(ADDRESS, NAME, REG, DEST) \
lis REG, ((ADDRESS) + (DEST - NAME))@ha; \
lwz REG, ((ADDRESS) + (DEST - NAME))@l(REG)
#define GCT_STRING_PTR_LBZ(ADDRESS, NAME, REG, DEST) \
lis REG, ((ADDRESS) + (DEST - NAME))@ha; \
lbz REG, ((ADDRESS) + (DEST - NAME))@l(REG)
#define GCT_STRING_PTR_LWZU(ADDRESS, NAME, REG, TMP_REG, DEST) \
lis TMP_REG, ((ADDRESS) + (DEST - NAME))@ha; \
lwzu REG, ((ADDRESS) + (DEST - NAME))@l(TMP_REG)
#define GCT_STRING_PTR_LBZU(ADDRESS, NAME, REG, TMP_REG, DEST) \
lis TMP_REG, ((ADDRESS) + (DEST - NAME))@ha; \
lbzu REG, ((ADDRESS) + (DEST - NAME))@l(TMP_REG)
#define GCT_STRING_PTR_STW(ADDRESS, NAME, REG, TMP_REG, DEST) \
lis TMP_REG, ((ADDRESS) + (DEST - NAME))@ha; \
stw REG, ((ADDRESS) + (DEST - NAME))@l(TMP_REG)
#define GCT_STRING_PTR_STWU(ADDRESS, NAME, REG, TMP_REG, DEST) \
lis TMP_REG, ((ADDRESS) + (DEST - NAME))@ha; \
stwu REG, ((ADDRESS) + (DEST - NAME))@l(TMP_REG)
#define GCT_IF_EQUAL_32(ADDRESS, VALUE) \
.long 0x20000000 | ((ADDRESS) & 0x1FFFFFF); \
.long VALUE
#define GCT_IF_NOT_EQUAL_32(ADDRESS, VALUE) \
.long 0x22000000 | ((ADDRESS) & 0x1FFFFFF); \
.long VALUE
#define GCT_IF_EQUAL_INST(ADDRESS, INST) \
.long 0x20000000 | ((ADDRESS) & 0x1FFFFFF); \
INST
#define GCT_IF_NOT_EQUAL_INST(ADDRESS, INST) \
.long 0x22000000 | ((ADDRESS) & 0x1FFFFFF); \
INST
#define GCT_ENDIF(COUNT) \
.long 0xE2000000 | ((COUNT) & 0xFF); \
.long 0x00000000
#define GCT_ELSE(COUNT) \
.long 0xE2100000 | ((COUNT) & 0xFF); \
.long 0x00000000
#define GCT_EXECUTE(NAME) \
.long 0xC0000000; \
.long (NAME##_size + 1) >> 3; \
NAME:
#define GCT_EXECUTE_END(NAME) \
.align 3; \
.set NAME##_size, . - NAME
#define GCT_INSERT(ADDRESS, NAME) \
.long 0xC2000000 | ((ADDRESS) & 0x1FFFFFF); \
.long (NAME##_size + 1) >> 3; \
.set NAME##_start, .
#define GCT_INSERT_END(NAME) \
nop; \
.align 3; \
.set NAME##_size, . - NAME##_start
#define GCT_WRITE_BRANCH(SRC, DEST) \
.long 0xC6000000 | (SRC & 0x1FFFFFF); \
.long DEST
#define B_CALL(ADDRESS) \
lis r12, (ADDRESS)@h; \
ori r12, r12, (ADDRESS)@l; \
b asm_call_thunk;
#define BL_CALL(ADDRESS) \
lis r12, (ADDRESS)@h; \
ori r12, r12, (ADDRESS)@l; \
bl asm_call_thunk;
#define BC_CALL(FIELD, CONDITION, ADDRESS) \
lis r12, (ADDRESS)@h; \
ori r12, r12, (ADDRESS)@l; \
b##CONDITION- FIELD, asm_call_thunk;
#define BCL_CALL(FIELD, CONDITION, ADDRESS) \
lis r12, (ADDRESS)@h; \
ori r12, r12, (ADDRESS)@l; \
b##CONDITION##l- FIELD, asm_call_thunk;
#define STRING(REG, STRING, SYM) \
bl SYM##_end; \
SYM:; \
.string STRING; \
.align 2; \
SYM##_end:; \
mflr REG
#define SHORT_PTR(REG, SYM, DATA...) \
bl short_##SYM##_end; \
short_##SYM:; \
.short DATA; \
.align 2; \
short_##SYM##_end:; \
mflr REG
#define FLOAT_PTR(REG, SYM, DATA...) \
bl short_##SYM##_end; \
short_##SYM:; \
.float DATA; \
.align 2; \
short_##SYM##_end:; \
mflr REG
#define PTR(REG, NAME) \
bl 4; \
mflr REG; \
addi REG, REG, (NAME) - (. - 4)
#define PTR_LWZ(REG, NAME) \
bl 4; \
mflr REG; \
lwz REG, (NAME) - (. - 4)(REG)
#define PTR_LBZ(REG, NAME) \
bl 4; \
mflr REG; \
lbz REG, (NAME) - (. - 4)(REG)
#define PTR_LWZU(REG, TMP_REG, NAME) \
bl 4; \
mflr TMP_REG; \
lwzu REG, (NAME) - (. - 4)(TMP_REG)
#define PTR_LBZU(REG, TMP_REG, NAME) \
bl 4; \
mflr TMP_REG; \
lbzu REG, (NAME) - (. - 4)(TMP_REG)
#define PTR_STW(REG, TMP_REG, NAME) \
bl 4; \
mflr TMP_REG; \
stw REG, (NAME) - (. - 4)(TMP_REG)
#define PTR_STWU(REG, TMP_REG, NAME) \
bl 4; \
mflr TMP_REG; \
stwu REG, (NAME) - (. - 4)(TMP_REG)
#define STACK_SIZE(REG_BASE, DATA_SIZE) \
(((32 - (REG_BASE)) << 2) + 8 + (DATA_SIZE))
#define STACK_PUSH(REG_BASE, DATA_SIZE) \
stwu sp, -STACK_SIZE(REG_BASE, DATA_SIZE)(sp); \
STACK_SAVELR(REG_BASE, DATA_SIZE); \
.if REG_BASE == 31; \
stw REG_BASE, STACK_SIZE(REG_BASE, DATA_SIZE) - 4(sp); \
.else; \
stmw REG_BASE, STACK_SIZE(REG_BASE, DATA_SIZE) - ((32 - (REG_BASE)) << 2)(sp); \
.endif
#define STACK_POP(REG_BASE, DATA_SIZE) \
STACK_RESTLR(REG_BASE, DATA_SIZE); \
.if REG_BASE == 31; \
lwz REG_BASE, STACK_SIZE(REG_BASE, DATA_SIZE) - 4(sp); \
.else; \
lmw REG_BASE, STACK_SIZE(REG_BASE, DATA_SIZE) - ((32 - (REG_BASE)) << 2)(sp); \
.endif; \
addi sp, sp, STACK_SIZE(REG_BASE, DATA_SIZE)
#define STACK_SAVELR(REG_BASE, DATA_SIZE) \
mflr r0; \
stw r0, STACK_SIZE(REG_BASE, DATA_SIZE) + 4(sp)
#define STACK_RESTLR(REG_BASE, DATA_SIZE) \
lwz r0, STACK_SIZE(REG_BASE, DATA_SIZE) + 4(sp); \
mtlr r0