Telkin
Loading...
Searching...
No Matches
Assembly.h
Go to the documentation of this file.
1
#
pragma
once
2
3
#
include
<
telkin
/
Preprocessor
.
h
>
4
#
include
<
cafe
.
h
>
5
6
// thx to mkwcat/nsmbw-project for some of these
7
8
#
ifdef
TELKIN_NO_REGISTERS
9
#
define
TELKIN_REGISTERS_WARNING
(
)
10
#
else
11
#
define
TELKIN_REGISTERS_WARNING
(
)
_Pragma
(
"message \"WARNING: TELKIN_REGISTERS was not defined. It is recommended to globally define TELKIN_NO_REGISTERS if this was intentional\""
)
12
#
endif
13
14
#
ifdef
TELKIN_REGISTERS
15
#
define
tAssembly
(
...
)
__attribute__
(
(
naked
)
)
__attribute__
(
(
__noinline__
)
)
{
__asm__
volatile
(
PP_STR_VAL
(
__VA_ARGS__
)
)
;
}
16
#
else
17
#
define
tAssembly
(
...
)
18
TELKIN_REGISTERS_WARNING
(
)
19
__attribute__
(
(
naked
)
)
__attribute__
(
(
__noinline__
)
)
{
__asm__
volatile
(
PP_STR_VAL
(
__VA_ARGS__
)
)
;
}
20
#
endif
21
22
#
ifdef
__clangd__
23
#
define
tRegSave
__attribute__
(
(
)
)
24
#
else
25
#
define
tRegSave
__attribute__
(
(
preserve_all
)
)
// red hills compiler magic for ppc
26
#
endif
27
28
namespace
tk
::
ppc
{
29
30
enum
class
GPR
:
u8
{
31
r0
,
r1
,
r2
,
r3
,
r4
,
32
r5
,
r6
,
r7
,
r8
,
r9
,
33
r10
,
r11
,
r12
,
r13
,
r14
,
34
r15
,
r16
,
r17
,
r18
,
r19
,
35
r20
,
r21
,
r22
,
r23
,
r24
,
36
r25
,
r26
,
r27
,
r28
,
r29
,
37
r30
,
r31
,
38
39
sp
=
r1
40
};
41
42
enum
class
FPR
:
u8
{
43
f0
,
f1
,
f2
,
f3
,
f4
,
44
f5
,
f6
,
f7
,
f8
,
f9
,
45
f10
,
f11
,
f12
,
f13
,
f14
,
46
f15
,
f16
,
f17
,
f18
,
f19
,
47
f20
,
f21
,
f22
,
f23
,
f24
,
48
f25
,
f26
,
f27
,
f28
,
f29
,
49
f30
,
f31
50
};
51
52
enum
class
CR
:
u8
{
53
cr0
,
cr1
,
cr2
,
cr3
,
cr4
,
cr5
,
cr6
,
cr7
54
};
55
56
using
R
=
GPR
;
57
58
namespace
internal
{
59
// I-form: [ op:6 | LI:24 | AA:1 | LK:1 ]
60
consteval u32
I_form
(
u8
op
,
s32
li
,
bool
aa
,
bool
lk
) {
61
return
(
u32
(
op
) << 26)
62
| (
u32
(
li
& 0xFF'FF'FF) << 2)
63
| (
u32
(
aa
) << 1)
64
|
u32
(
lk
);
65
}
66
67
// B-form: [ op:6 | BO:5 | BI:5 | BD:14 | AA:1 | LK:1 ]
68
consteval u32
B_form
(
u8
op
,
u8
bo
,
u8
bi
,
s16
bd
,
bool
aa
,
bool
lk
) {
69
return
(
u32
(
op
) << 26)
70
| (
u32
(
bo
& 0x1F) << 21)
71
| (
u32
(
bi
& 0x1F) << 16)
72
| (
u32
(
bd
& 0x3FFF) << 2)
73
| (
u32
(
aa
) << 1)
74
|
u32
(
lk
);
75
}
76
77
// D-form: [ op:6 | RT/RS:5 | RA:5 | D:16 ]
78
consteval u32
D_form
(
u8
op
,
u8
rsd
,
u8
ra
,
s16
d
) {
79
return
(
u32
(
op
) << 26)
80
| (
u32
(
rsd
& 0x1F) << 21)
81
| (
u32
(
ra
& 0x1F) << 16)
82
|
u16
(
d
);
83
}
84
85
// X-form: [ op:6 | RT/RS:5 | RA:5 | RB:5 | XO:10 | Rc:1 ]
86
consteval u32
X_form
(
u8
op
,
u8
rsd
,
u8
ra
,
u8
rb
,
u16
xo
,
bool
rc
) {
87
return
(
u32
(
op
) << 26)
88
| (
u32
(
rsd
& 0x1F) << 21)
89
| (
u32
(
ra
& 0x1F) << 16)
90
| (
u32
(
rb
& 0x1F) << 11)
91
| (
u32
(
xo
& 0x3FF) << 1)
92
|
u32
(
rc
);
93
}
94
95
// XO-form: [ op:6 | RT:5 | RA:5 | RB:5 | OE:1 | XO:9 | Rc:1 ]
96
consteval u32
XO_form
(
u8
op
,
u8
rt
,
u8
ra
,
u8
rb
,
bool
oe
,
u16
xo
,
bool
rc
) {
97
return
(
u32
(
op
) << 26)
98
| (
u32
(
rt
& 0x1F) << 21)
99
| (
u32
(
ra
& 0x1F) << 16)
100
| (
u32
(
rb
& 0x1F) << 11)
101
| (
u32
(
oe
) << 10)
102
| (
u32
(
xo
& 0x1FF) << 1)
103
|
u32
(
rc
);
104
}
105
106
// A-form: [ op:6 | FRT:5 | FRA:5 | FRB:5 | FRC:5 | XO:5 | Rc:1 ]
107
consteval u32
A_form
(
u8
op
,
u8
frt
,
u8
fra
,
u8
frb
,
u8
frc
,
u8
xo
,
bool
rc
) {
108
return
(
u32
(
op
) << 26)
109
| (
u32
(
frt
& 0x1F) << 21)
110
| (
u32
(
fra
& 0x1F) << 16)
111
| (
u32
(
frb
& 0x1F) << 11)
112
| (
u32
(
frc
& 0x1F) << 6)
113
| (
u32
(
xo
& 0x1F) << 1)
114
|
u32
(
rc
);
115
}
116
117
// M-form: [ op:6 | RS:5 | RA:5 | SH:5 | MB:5 | ME:5 | Rc:1 ]
118
consteval u32
M_form
(
u8
op
,
u8
rs
,
u8
ra
,
u8
sh
,
u8
mb
,
u8
me
,
bool
rc
) {
119
return
(
u32
(
op
) << 26)
120
| (
u32
(
rs
& 0x1F) << 21)
121
| (
u32
(
ra
& 0x1F) << 16)
122
| (
u32
(
sh
& 0x1F) << 11)
123
| (
u32
(
mb
& 0x1F) << 6)
124
| (
u32
(
me
& 0x1F) << 1)
125
|
u32
(
rc
);
126
}
127
128
consteval u8
cr_field
(
CR
cr
) {
return
u8
(
cr
) << 2; }
129
}
130
131
// Instructions:
132
133
consteval u32
addi
(
R
rt
,
R
ra
,
s16
si
) {
return
internal
::
D_form
(14,
u8
(
rt
),
u8
(
ra
),
si
); }
134
consteval u32
addis
(
R
rt
,
R
ra
,
s16
si
) {
return
internal
::
D_form
(15,
u8
(
rt
),
u8
(
ra
),
si
); }
135
consteval u32
add
(
R
rt
,
R
ra
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
XO_form
(31,
u8
(
rt
),
u8
(
ra
),
u8
(
rb
),
false
, 266,
rc
); }
136
consteval u32
mullw
(
R
rt
,
R
ra
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
XO_form
(31,
u8
(
rt
),
u8
(
ra
),
u8
(
rb
),
false
, 235,
rc
); }
137
138
consteval u32
lwz
(
R
rt
,
R
ra
,
s16
d
) {
return
internal
::
D_form
(32,
u8
(
rt
),
u8
(
ra
),
d
); }
139
consteval u32
stw
(
R
rs
,
R
ra
,
s16
d
) {
return
internal
::
D_form
(36,
u8
(
rs
),
u8
(
ra
),
d
); }
140
consteval u32
stwu
(
R
rs
,
R
ra
,
s16
d
) {
return
internal
::
D_form
(37,
u8
(
rs
),
u8
(
ra
),
d
); }
141
consteval u32
lbz
(
R
rt
,
R
ra
,
s16
d
) {
return
internal
::
D_form
(34,
u8
(
rt
),
u8
(
ra
),
d
); }
142
consteval u32
stb
(
R
rs
,
R
ra
,
s16
d
) {
return
internal
::
D_form
(38,
u8
(
rs
),
u8
(
ra
),
d
); }
143
144
consteval u32
ori
(
R
ra
,
R
rs
,
u16
ui
) {
return
internal
::
D_form
(24,
u8
(
rs
),
u8
(
ra
),
s16
(
ui
)); }
145
consteval u32
oris
(
R
ra
,
R
rs
,
u16
ui
) {
return
internal
::
D_form
(25,
u8
(
rs
),
u8
(
ra
),
s16
(
ui
)); }
146
consteval u32
xori
(
R
ra
,
R
rs
,
u16
ui
) {
return
internal
::
D_form
(26,
u8
(
rs
),
u8
(
ra
),
s16
(
ui
)); }
147
consteval u32
andi
(
R
ra
,
R
rs
,
u16
ui
) {
return
internal
::
D_form
(28,
u8
(
rs
),
u8
(
ra
),
s16
(
ui
)); }
148
149
consteval u32
andr
(
R
ra
,
R
rs
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
X_form
(31,
u8
(
rs
),
u8
(
ra
),
u8
(
rb
), 28,
rc
); }
150
consteval u32
orr
(
R
ra
,
R
rs
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
X_form
(31,
u8
(
rs
),
u8
(
ra
),
u8
(
rb
), 444,
rc
); }
151
consteval u32
xorr
(
R
ra
,
R
rs
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
X_form
(31,
u8
(
rs
),
u8
(
ra
),
u8
(
rb
), 316,
rc
); }
152
consteval u32
norr
(
R
ra
,
R
rs
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
X_form
(31,
u8
(
rs
),
u8
(
ra
),
u8
(
rb
), 124,
rc
); }
153
154
consteval u32
mr
(
R
ra
,
R
rb
) {
return
orr
(
ra
,
rb
,
rb
); }
155
156
consteval u32
cmpw
(
R
ra
,
R
rb
,
CR
cr
=
CR
::
cr0
) {
return
internal
::
X_form
(31,
internal
::
cr_field
(
cr
),
u8
(
ra
),
u8
(
rb
), 0,
false
); }
157
consteval u32
cmpwi
(
R
ra
,
s16
simm
,
CR
cr
=
CR
::
cr0
) {
return
internal
::
D_form
(11,
internal
::
cr_field
(
cr
),
u8
(
ra
),
simm
); }
158
consteval u32
cmplw
(
R
ra
,
R
rb
,
CR
cr
=
CR
::
cr0
) {
return
internal
::
X_form
(31,
internal
::
cr_field
(
cr
),
u8
(
ra
),
u8
(
rb
), 32,
false
); }
159
consteval u32
cmplwi
(
R
ra
,
u16
uimm
,
CR
cr
=
CR
::
cr0
) {
return
internal
::
D_form
(10,
internal
::
cr_field
(
cr
),
u8
(
ra
),
s16
(
uimm
)); }
160
161
consteval u32
li
(
R
rt
,
s16
si
) {
return
addi
(
rt
,
R
::
r0
,
si
); }
162
consteval u32
lis
(
R
rt
,
s16
si
) {
return
addis
(
rt
,
R
::
r0
,
si
); }
163
164
consteval u32
bc
(
u8
bo
,
u8
bi
,
s16
byte_offset
) {
return
internal
::
B_form
(16,
bo
,
bi
,
byte_offset
>> 2,
false
,
false
); }
165
consteval u32
blt
(
s16
offset
) {
return
bc
(12, 0,
offset
); }
166
consteval u32
bgt
(
s16
offset
) {
return
bc
(12, 1,
offset
); }
167
consteval u32
beq
(
s16
offset
) {
return
bc
(12, 2,
offset
); }
168
consteval u32
bne
(
s16
offset
) {
return
bc
( 4, 2,
offset
); }
169
170
consteval u32
rlwinm
(
R
ra
,
R
rs
,
u8
sh
,
u8
mb
,
u8
me
,
bool
rc
=
false
) {
return
internal
::
M_form
(21,
u8
(
rs
),
u8
(
ra
),
sh
,
mb
,
me
,
rc
); }
171
172
consteval u32
slw
(
R
ra
,
R
rs
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
X_form
(31,
u8
(
rs
),
u8
(
ra
),
u8
(
rb
), 24,
rc
); }
173
consteval u32
srw
(
R
ra
,
R
rs
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
X_form
(31,
u8
(
rs
),
u8
(
ra
),
u8
(
rb
), 536,
rc
); }
174
consteval u32
sraw
(
R
ra
,
R
rs
,
R
rb
,
bool
rc
=
false
) {
return
internal
::
X_form
(31,
u8
(
rs
),
u8
(
ra
),
u8
(
rb
), 792,
rc
); }
175
consteval u32
srawi
(
R
ra
,
R
rs
,
u8
sh
,
bool
rc
=
false
) {
return
internal
::
X_form
(31,
u8
(
rs
),
u8
(
ra
),
sh
, 824,
rc
); }
176
177
consteval u32
b
(
s32
relative
) {
return
internal
::
I_form
(18,
relative
>> 2,
false
,
false
); }
178
consteval u32
bl
(
s32
relative
) {
return
internal
::
I_form
(18,
relative
>> 2,
false
,
true
); }
179
consteval u32
blr
() {
return
internal
::
X_form
(19, 20, 0, 0, 16,
false
); }
180
consteval u32
nop
() {
return
ori
(
R
::
r0
,
R
::
r0
, 0); }
181
182
consteval u32
mfspr
(
R
rt
,
u16
spr
) {
return
internal
::
X_form
(31,
u8
(
rt
),
spr
& 0x1F, (
spr
>> 5) & 0x1F, 339,
false
); }
183
consteval u32
mtspr
(
u16
spr
,
R
rs
) {
return
internal
::
X_form
(31,
u8
(
rs
),
spr
& 0x1F, (
spr
>> 5) & 0x1F, 467,
false
); }
184
185
consteval u32
mflr
(
R
rt
) {
return
mfspr
(
rt
, 8); }
186
consteval u32
mtlr
(
R
rs
) {
return
mtspr
(8,
rs
); }
187
188
}
189
190
#
ifdef
TELKIN_REGISTERS
191
#
include
<
telkin
/
DefineRegisters
.
h
>
192
#
endif
193
194
// It's recommended to use the tRegSave attribute directly in C++ instead of the below macros
195
#
define
tSaveVolatileRegisters
196
stwu
r1
,
-
0x3C
(
r1
)
;
197
stw
r0
,
0x08
(
r1
)
;
198
stw
r3
,
0x0C
(
r1
)
;
199
stw
r4
,
0x10
(
r1
)
;
200
stw
r5
,
0x14
(
r1
)
;
201
stw
r6
,
0x18
(
r1
)
;
202
stw
r7
,
0x1C
(
r1
)
;
203
stw
r8
,
0x20
(
r1
)
;
204
stw
r9
,
0x24
(
r1
)
;
205
stw
r10
,
0x28
(
r1
)
;
206
stw
r11
,
0x2C
(
r1
)
;
207
stw
r12
,
0x30
(
r1
)
;
208
mfcr
r0
;
209
stw
r0
,
0x34
(
r1
)
;
210
mfctr
r0
;
211
stw
r0
,
0x38
(
r1
)
;
212
mflr
r0
;
213
stw
r0
,
0x40
(
r1
)
214
215
#
define
tRestoreVolatileRegisters
216
lwz
r0
,
0x38
(
r1
)
;
217
mtctr
r0
;
218
lwz
r0
,
0x34
(
r1
)
;
219
mtcr
r0
;
220
lwz
r0
,
0x40
(
r1
)
;
221
mtlr
r0
;
222
lwz
r0
,
0x08
(
r1
)
;
223
lwz
r3
,
0x0C
(
r1
)
;
224
lwz
r4
,
0x10
(
r1
)
;
225
lwz
r5
,
0x14
(
r1
)
;
226
lwz
r6
,
0x18
(
r1
)
;
227
lwz
r7
,
0x1C
(
r1
)
;
228
lwz
r8
,
0x20
(
r1
)
;
229
lwz
r9
,
0x24
(
r1
)
;
230
lwz
r10
,
0x28
(
r1
)
;
231
lwz
r11
,
0x2C
(
r1
)
;
232
lwz
r12
,
0x30
(
r1
)
;
233
addi
r1
,
r1
,
0x3C
234
235
#
define
tSaveLR
236
stwu
r1
,
-
0x10
(
r1
)
;
237
mflr
r2
;
238
stw
r2
,
0x14
(
r1
)
239
240
#
define
tRestoreLR
241
lwz
r2
,
0x14
(
r1
)
;
242
mtlr
r2
;
243
addi
r1
,
r1
,
0x10
TELKIN_REGISTERS_WARNING
#define TELKIN_REGISTERS_WARNING()
Definition
Assembly.h:11
tk::ppc::internal
Definition
Assembly.h:58
tk::ppc::GPR
GPR
Definition
Assembly.h:30
tk::ppc::GPR::r15
@ r15
Definition
Assembly.h:34
tk::ppc::GPR::r25
@ r25
Definition
Assembly.h:36
tk::ppc::GPR::r13
@ r13
Definition
Assembly.h:33
tk::ppc::GPR::sp
@ sp
Definition
Assembly.h:39
tk::ppc::GPR::r9
@ r9
Definition
Assembly.h:32
tk::ppc::GPR::r14
@ r14
Definition
Assembly.h:33
tk::ppc::GPR::r21
@ r21
Definition
Assembly.h:35
tk::ppc::GPR::r7
@ r7
Definition
Assembly.h:32
tk::ppc::GPR::r4
@ r4
Definition
Assembly.h:31
tk::ppc::GPR::r11
@ r11
Definition
Assembly.h:33
tk::ppc::GPR::r27
@ r27
Definition
Assembly.h:36
tk::ppc::GPR::r18
@ r18
Definition
Assembly.h:34
tk::ppc::GPR::r16
@ r16
Definition
Assembly.h:34
tk::ppc::GPR::r26
@ r26
Definition
Assembly.h:36
tk::ppc::GPR::r1
@ r1
Definition
Assembly.h:31
tk::ppc::GPR::r19
@ r19
Definition
Assembly.h:34
tk::ppc::GPR::r31
@ r31
Definition
Assembly.h:37
tk::ppc::GPR::r8
@ r8
Definition
Assembly.h:32
tk::ppc::GPR::r29
@ r29
Definition
Assembly.h:36
tk::ppc::GPR::r20
@ r20
Definition
Assembly.h:35
tk::ppc::GPR::r3
@ r3
Definition
Assembly.h:31
tk::ppc::GPR::r10
@ r10
Definition
Assembly.h:33
tk::ppc::GPR::r22
@ r22
Definition
Assembly.h:35
tk::ppc::GPR::r24
@ r24
Definition
Assembly.h:35
tk::ppc::GPR::r6
@ r6
Definition
Assembly.h:32
tk::ppc::GPR::r30
@ r30
Definition
Assembly.h:37
tk::ppc::GPR::r0
@ r0
Definition
Assembly.h:31
tk::ppc::GPR::r2
@ r2
Definition
Assembly.h:31
tk::ppc::GPR::r17
@ r17
Definition
Assembly.h:34
tk::ppc::GPR::r12
@ r12
Definition
Assembly.h:33
tk::ppc::GPR::r28
@ r28
Definition
Assembly.h:36
tk::ppc::GPR::r5
@ r5
Definition
Assembly.h:32
tk::ppc::GPR::r23
@ r23
Definition
Assembly.h:35
tk::ppc::R
GPR R
Definition
Assembly.h:56
tk::ppc::FPR
FPR
Definition
Assembly.h:42
tk::ppc::FPR::f14
@ f14
Definition
Assembly.h:45
tk::ppc::FPR::f3
@ f3
Definition
Assembly.h:43
tk::ppc::FPR::f22
@ f22
Definition
Assembly.h:47
tk::ppc::FPR::f27
@ f27
Definition
Assembly.h:48
tk::ppc::FPR::f2
@ f2
Definition
Assembly.h:43
tk::ppc::FPR::f20
@ f20
Definition
Assembly.h:47
tk::ppc::FPR::f29
@ f29
Definition
Assembly.h:48
tk::ppc::FPR::f25
@ f25
Definition
Assembly.h:48
tk::ppc::FPR::f8
@ f8
Definition
Assembly.h:44
tk::ppc::FPR::f19
@ f19
Definition
Assembly.h:46
tk::ppc::FPR::f30
@ f30
Definition
Assembly.h:49
tk::ppc::FPR::f6
@ f6
Definition
Assembly.h:44
tk::ppc::FPR::f9
@ f9
Definition
Assembly.h:44
tk::ppc::FPR::f7
@ f7
Definition
Assembly.h:44
tk::ppc::FPR::f4
@ f4
Definition
Assembly.h:43
tk::ppc::FPR::f5
@ f5
Definition
Assembly.h:44
tk::ppc::FPR::f12
@ f12
Definition
Assembly.h:45
tk::ppc::FPR::f10
@ f10
Definition
Assembly.h:45
tk::ppc::FPR::f13
@ f13
Definition
Assembly.h:45
tk::ppc::FPR::f23
@ f23
Definition
Assembly.h:47
tk::ppc::FPR::f28
@ f28
Definition
Assembly.h:48
tk::ppc::FPR::f16
@ f16
Definition
Assembly.h:46
tk::ppc::FPR::f1
@ f1
Definition
Assembly.h:43
tk::ppc::FPR::f0
@ f0
Definition
Assembly.h:43
tk::ppc::FPR::f31
@ f31
Definition
Assembly.h:49
tk::ppc::FPR::f15
@ f15
Definition
Assembly.h:46
tk::ppc::FPR::f18
@ f18
Definition
Assembly.h:46
tk::ppc::FPR::f26
@ f26
Definition
Assembly.h:48
tk::ppc::FPR::f11
@ f11
Definition
Assembly.h:45
tk::ppc::FPR::f21
@ f21
Definition
Assembly.h:47
tk::ppc::FPR::f17
@ f17
Definition
Assembly.h:46
tk::ppc::FPR::f24
@ f24
Definition
Assembly.h:47
tk::ppc::CR
CR
Definition
Assembly.h:52
tk::ppc::CR::cr3
@ cr3
Definition
Assembly.h:53
tk::ppc::CR::cr5
@ cr5
Definition
Assembly.h:53
tk::ppc::CR::cr6
@ cr6
Definition
Assembly.h:53
tk::ppc::CR::cr7
@ cr7
Definition
Assembly.h:53
tk::ppc::CR::cr1
@ cr1
Definition
Assembly.h:53
tk::ppc::CR::cr0
@ cr0
Definition
Assembly.h:53
tk::ppc::CR::cr4
@ cr4
Definition
Assembly.h:53
tk::ppc::CR::cr2
@ cr2
Definition
Assembly.h:53
tk
Definition
Assembly.h:28
tk::getTitleID_t
u64(*)() getTitleID_t
Definition
Mod.h:16
core
include
telkin
Assembly.h
Generated by
1.14.0