probe_rs/architecture/arm/core/
instructions.rs1pub(crate) mod aarch32 {
3 pub(crate) fn build_mov(rd: u16, rm: u16) -> u32 {
5 let mut ret = 0b1110_0001_1010_0000_0000_0000_0000_0000;
6
7 ret |= (rd as u32) << 12;
8 ret |= rm as u32;
9
10 ret
11 }
12
13 pub(crate) fn build_mcr(
15 coproc: u8,
16 opcode1: u8,
17 reg: u16,
18 ctrl_reg_n: u8,
19 ctrl_reg_m: u8,
20 opcode2: u8,
21 ) -> u32 {
22 let mut ret = 0b1110_1110_0000_0000_0000_0000_0001_0000;
23
24 ret |= (coproc as u32) << 8;
25 ret |= (opcode1 as u32) << 21;
26 ret |= (reg as u32) << 12;
27 ret |= (ctrl_reg_n as u32) << 16;
28 ret |= ctrl_reg_m as u32;
29 ret |= (opcode2 as u32) << 5;
30
31 ret
32 }
33
34 pub(crate) fn build_mrc(
35 coproc: u8,
36 opcode1: u8,
37 reg: u16,
38 ctrl_reg_n: u8,
39 ctrl_reg_m: u8,
40 opcode2: u8,
41 ) -> u32 {
42 let mut ret = 0b1110_1110_0001_0000_0000_0000_0001_0000;
43
44 ret |= (coproc as u32) << 8;
45 ret |= (opcode1 as u32) << 21;
46 ret |= (reg as u32) << 12;
47 ret |= (ctrl_reg_n as u32) << 16;
48 ret |= ctrl_reg_m as u32;
49 ret |= (opcode2 as u32) << 5;
50
51 ret
52 }
53
54 pub(crate) fn build_ldc(coproc: u8, ctrl_reg: u8, reg: u16, imm: u8) -> u32 {
55 let mut ret = 0b1110_1100_1011_0000_0000_0000_0000_0000;
56
57 ret |= (reg as u32) << 16;
58 ret |= (ctrl_reg as u32) << 12;
59 ret |= (coproc as u32) << 8;
60 ret |= (imm as u32) >> 2;
61
62 ret
63 }
64
65 pub(crate) fn build_stc(coproc: u8, ctrl_reg: u8, reg: u16, imm: u8) -> u32 {
66 let mut ret = 0b1110_1100_1010_0000_0000_0000_0000_0000;
67
68 ret |= (reg as u32) << 16;
69 ret |= (ctrl_reg as u32) << 12;
70 ret |= (coproc as u32) << 8;
71 ret |= (imm as u32) >> 2;
72
73 ret
74 }
75
76 pub(crate) fn build_mrs(reg: u16) -> u32 {
78 let mut ret = 0b1110_0001_0000_1111_0000_0000_0000_0000;
79
80 ret |= (reg as u32) << 12;
81
82 ret
83 }
84
85 pub(crate) fn build_msr(reg: u16) -> u32 {
87 let mut ret = 0b1110_0001_0010_1111_1111_0000_0000_0000;
88
89 ret |= reg as u32;
90
91 ret
92 }
93
94 pub(crate) fn build_vmrs(reg_target: u16, ctrl_reg: u8) -> u32 {
95 let mut ret = 0b1110_1110_1111_0000_0000_1010_0001_0000;
96
97 ret |= (reg_target as u32) << 12;
98 ret |= (ctrl_reg as u32) << 16;
99
100 ret
101 }
102
103 pub(crate) fn build_vmov(op: u8, reg1: u16, reg2: u16, vreg: u16) -> u32 {
104 let mut ret = 0b1110_1100_0100_0000_0000_1011_0001_0000;
105
106 ret |= (op as u32) << 20;
107 ret |= (reg2 as u32) << 16;
108 ret |= (reg1 as u32) << 12;
109 ret |= vreg as u32;
110
111 ret
112 }
113
114 #[cfg(test)]
115 mod tests {
116 use super::*;
117
118 #[test]
119 fn gen_mcr_instruction() {
120 let instr = build_mcr(14, 0, 2, 1, 2, 3);
121
122 assert_eq!(0xEE012E72, instr);
124 }
125
126 #[test]
127 fn gen_mrc_instruction() {
128 let instr = build_mrc(14, 0, 2, 1, 2, 3);
129
130 assert_eq!(0xEE112E72, instr);
132 }
133
134 #[test]
135 fn gen_mov_instruction() {
136 let instr = build_mov(2, 15);
137
138 assert_eq!(0xE1A0200F, instr);
140 }
141
142 #[test]
143 fn gen_ldc_instruction() {
144 let instr = build_ldc(14, 5, 2, 4);
145
146 assert_eq!(0xECB25E01, instr);
148 }
149
150 #[test]
151 fn gen_stc_instruction() {
152 let instr = build_stc(14, 5, 2, 4);
153
154 assert_eq!(0xECA25E01, instr);
156 }
157
158 #[test]
159 fn gen_mrs_instruction() {
160 let instr = build_mrs(2);
161
162 assert_eq!(0xE10F2000, instr);
164 }
165
166 #[test]
167 fn gen_msr_instruction() {
168 let instr = build_msr(2);
169
170 assert_eq!(0xE12FF002, instr);
172 }
173
174 #[test]
175 fn gen_vmrs_instruction() {
176 let instr = build_vmrs(2, 0b0111);
177
178 assert_eq!(0xEEF72A10, instr);
180 }
181
182 #[test]
183 fn gen_vmov_instruction() {
184 let instr = build_vmov(1, 1, 2, 3);
185
186 assert_eq!(0xEC521B13, instr);
188 }
189 }
190}
191
192pub(crate) mod thumb2 {
193 pub(crate) use super::aarch32::{build_mcr, build_mrc, build_vmov, build_vmrs};
195
196 pub(crate) fn build_ldr(reg_target: u16, reg_source: u16, imm: u8) -> u32 {
197 let mut ret = 0b1111_1000_0101_0000_0000_1011_0000_0000;
198
199 ret |= (reg_source as u32) << 16;
200 ret |= (reg_target as u32) << 12;
201 ret |= imm as u32;
202
203 ret
204 }
205
206 pub(crate) fn build_str(reg_target: u16, reg_source: u16, imm: u8) -> u32 {
207 let mut ret = 0b1111_1000_0100_0000_0000_1011_0000_0000;
208
209 ret |= (reg_source as u32) << 16;
210 ret |= (reg_target as u32) << 12;
211 ret |= imm as u32;
212
213 ret
214 }
215
216 #[cfg(test)]
217 mod tests {
218 use super::*;
219
220 #[test]
221 fn gen_ldr_instruction() {
222 let instr = build_ldr(2, 3, 4);
223
224 assert_eq!(0xF8532B04, instr);
226 }
227
228 #[test]
229 fn gen_str_instruction() {
230 let instr = build_str(2, 3, 4);
231
232 assert_eq!(0xF8432B04, instr);
234 }
235 }
236}
237
238pub(crate) mod aarch64 {
239 pub(crate) fn build_ldr(reg_target: u16, reg_source: u16, imm: u16) -> u32 {
240 let mut ret = 0b1111_1000_0100_0000_0000_0100_0000_0000;
241
242 ret |= (imm as u32) << 12;
243 ret |= (reg_source as u32) << 5;
244 ret |= reg_target as u32;
245
246 ret
247 }
248
249 pub(crate) fn build_ldrw(reg_target: u16, reg_source: u16, imm: u16) -> u32 {
250 let mut ret = 0b1011_1000_0100_0000_0000_0100_0000_0000;
251
252 ret |= (imm as u32) << 12;
253 ret |= (reg_source as u32) << 5;
254 ret |= reg_target as u32;
255
256 ret
257 }
258
259 pub(crate) fn build_ldrb(reg_target: u16, reg_source: u16, imm: u16) -> u32 {
260 let mut ret = 0b0011_1000_0100_0000_0000_0100_0000_0000;
261
262 ret |= (imm as u32) << 12;
263 ret |= (reg_source as u32) << 5;
264 ret |= reg_target as u32;
265
266 ret
267 }
268
269 pub(crate) fn build_mrs(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8, reg: u16) -> u32 {
270 let mut ret = 0b1101_0101_0011_0000_0000_0000_0000_0000;
271
272 ret |= (op0 as u32) << 19;
273 ret |= (op1 as u32) << 16;
274 ret |= (crn as u32) << 12;
275 ret |= (crm as u32) << 8;
276 ret |= (op2 as u32) << 5;
277 ret |= reg as u32;
278
279 ret
280 }
281
282 pub(crate) fn build_msr(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8, reg: u16) -> u32 {
283 let mut ret = 0b1101_0101_0001_0000_0000_0000_0000_0000;
284
285 ret |= (op0 as u32) << 19;
286 ret |= (op1 as u32) << 16;
287 ret |= (crn as u32) << 12;
288 ret |= (crm as u32) << 8;
289 ret |= (op2 as u32) << 5;
290 ret |= reg as u32;
291
292 ret
293 }
294
295 pub(crate) fn build_str(reg_target: u16, reg_source: u16, imm: u16) -> u32 {
296 let mut ret = 0b1111_1000_0000_0000_0000_0100_0000_0000;
297
298 ret |= (imm as u32) << 12;
299 ret |= (reg_source as u32) << 5;
300 ret |= reg_target as u32;
301
302 ret
303 }
304
305 pub(crate) fn build_strw(reg_target: u16, reg_source: u16, imm: u16) -> u32 {
306 let mut ret = 0b1011_1000_0000_0000_0000_0100_0000_0000;
307
308 ret |= (imm as u32) << 12;
309 ret |= (reg_source as u32) << 5;
310 ret |= reg_target as u32;
311
312 ret
313 }
314
315 pub(crate) fn build_strb(reg_target: u16, reg_source: u16, imm: u16) -> u32 {
316 let mut ret = 0b0011_1000_0000_0000_0000_0100_0000_0000;
317
318 ret |= (imm as u32) << 12;
319 ret |= (reg_source as u32) << 5;
320 ret |= reg_target as u32;
321
322 ret
323 }
324
325 pub(crate) fn build_ins_fp_to_gp(reg_target: u16, reg_source: u16, index: u16) -> u32 {
326 let mut ret = 0b0100_1110_0000_1000_0011_1100_0000_0000;
327
328 ret |= (index as u32) << 20;
329 ret |= (reg_source as u32) << 5;
330 ret |= reg_target as u32;
331
332 ret
333 }
334
335 pub(crate) fn build_ins_gp_to_fp(reg_target: u16, reg_source: u16, index: u16) -> u32 {
336 let mut ret = 0b0100_1110_0000_1000_0001_1100_0000_0000;
337
338 ret |= (index as u32) << 20;
339 ret |= (reg_source as u32) << 5;
340 ret |= reg_target as u32;
341
342 ret
343 }
344
345 #[cfg(test)]
346 mod tests {
347 use super::*;
348 #[test]
349 fn gen_ldr_instruction() {
350 let instr = build_ldr(2, 3, 4);
351
352 assert_eq!(0xF8404462, instr);
354 }
355
356 #[test]
357 fn gen_ldrw_instruction() {
358 let instr = build_ldrw(2, 3, 4);
359
360 assert_eq!(0xB8404462, instr);
362 }
363
364 #[test]
365 fn gen_msr_instruction() {
366 let instr = build_msr(2, 3, 4, 1, 2, 3);
367
368 assert_eq!(0xD5134143, instr);
370 }
371
372 #[test]
373 fn gen_mrs_instruction() {
374 let instr = build_mrs(2, 3, 4, 1, 2, 3);
375
376 assert_eq!(0xD5334143, instr);
378 }
379
380 #[test]
381 fn gen_str_instruction() {
382 let instr = build_str(2, 3, 4);
383
384 assert_eq!(0xF8004462, instr);
386 }
387
388 #[test]
389 fn gen_strw_instruction() {
390 let instr = build_strw(2, 3, 4);
391
392 assert_eq!(0xB8004462, instr);
394 }
395
396 #[test]
397 fn gen_ins_gp_to_fp_instruction() {
398 let instr = build_ins_gp_to_fp(3, 2, 1);
399
400 assert_eq!(0x4E181C43, instr);
402 }
403
404 #[test]
405 fn gen_ins_fp_to_gp_instruction() {
406 let instr = build_ins_fp_to_gp(3, 2, 1);
407
408 assert_eq!(0x4E183C43, instr);
410 }
411 }
412}