Skip to content

Commit 8721087

Browse files
committed
py: Big improvements to inline assembler.
Improved the Thumb assembler back end. Added many more Thumb instructions to the inline assembler. Improved parsing of assembler instructions and arguments. Assembler functions can now be passed the address of any object that supports the buffer protocol (to get the address of the buffer). Added an example of how to sum numbers from an array in assembler.
1 parent 82c7b1b commit 8721087

7 files changed

Lines changed: 390 additions & 159 deletions

File tree

examples/asmled.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# flash LED #1 using inline assembler
2+
# this version is overly verbose and uses word stores
23
@micropython.asm_thumb
34
def flash_led(r0):
45
movw(r1, (stm.GPIOA + stm.GPIO_BSRRL) & 0xffff)
@@ -13,69 +14,72 @@ def flash_led(r0):
1314
label(loop1)
1415

1516
# turn LED on
16-
str(r2, r1, 0)
17+
str(r2, [r1, 0])
1718

1819
# delay for a bit
1920
movw(r4, 5599900 & 0xffff)
2021
movt(r4, (5599900 >> 16) & 0xffff)
2122
label(delay_on)
22-
subs(r4, r4, 1)
23+
sub(r4, r4, 1)
2324
cmp(r4, 0)
2425
bgt(delay_on)
2526

2627
# turn LED off
27-
str(r3, r1, 0)
28+
str(r3, [r1, 0])
2829

2930
# delay for a bit
3031
movw(r4, 5599900 & 0xffff)
3132
movt(r4, (5599900 >> 16) & 0xffff)
3233
label(delay_off)
33-
subs(r4, r4, 1)
34+
sub(r4, r4, 1)
3435
cmp(r4, 0)
3536
bgt(delay_off)
3637

3738
# loop r0 times
38-
subs(r0, r0, 1)
39+
sub(r0, r0, 1)
3940
label(loop_entry)
4041
cmp(r0, 0)
4142
bgt(loop1)
4243

43-
# flash LED #1 using inline assembler
44-
# this version uses the convenience assembler operation 'movwt'
44+
# flash LED #2 using inline assembler
45+
# this version uses half-word sortes, and the convenience assembler operation 'movwt'
4546
@micropython.asm_thumb
4647
def flash_led_v2(r0):
47-
movwt(r1, stm.GPIOA + stm.GPIO_BSRRL)
48-
movwt(r2, 1 << 13)
49-
movwt(r3, 1 << (16 + 13))
48+
# get the GPIOA address in r1
49+
movwt(r1, stm.GPIOA)
50+
51+
# get the bit mask for PA14 (the pin LED #2 is on)
52+
movw(r2, 1 << 14)
5053

5154
b(loop_entry)
5255

5356
label(loop1)
5457

5558
# turn LED on
56-
str(r2, r1, 0)
59+
strh(r2, [r1, stm.GPIO_BSRRL])
5760

5861
# delay for a bit
5962
movwt(r4, 5599900)
6063
label(delay_on)
61-
subs(r4, r4, 1)
64+
sub(r4, r4, 1)
6265
cmp(r4, 0)
6366
bgt(delay_on)
6467

6568
# turn LED off
66-
str(r3, r1, 0)
69+
strh(r2, [r1, stm.GPIO_BSRRH])
6770

6871
# delay for a bit
6972
movwt(r4, 5599900)
7073
label(delay_off)
71-
subs(r4, r4, 1)
74+
sub(r4, r4, 1)
7275
cmp(r4, 0)
7376
bgt(delay_off)
7477

7578
# loop r0 times
76-
subs(r0, r0, 1)
79+
sub(r0, r0, 1)
7780
label(loop_entry)
7881
cmp(r0, 0)
7982
bgt(loop1)
8083

84+
flash_led(5)
8185
flash_led_v2(5)

examples/asmsum.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
@micropython.asm_thumb
2+
def asm_sum_words(r0, r1):
3+
4+
# r0 = len
5+
# r1 = ptr
6+
# r2 = sum
7+
# r3 = dummy
8+
mov(r2, 0)
9+
10+
b(loop_entry)
11+
12+
label(loop1)
13+
ldr(r3, [r1, 0])
14+
add(r2, r2, r3)
15+
16+
add(r1, r1, 4)
17+
sub(r0, r0, 1)
18+
19+
label(loop_entry)
20+
cmp(r0, 0)
21+
bgt(loop1)
22+
23+
mov(r0, r2)
24+
25+
@micropython.asm_thumb
26+
def asm_sum_bytes(r0, r1):
27+
28+
# r0 = len
29+
# r1 = ptr
30+
# r2 = sum
31+
# r3 = dummy
32+
mov(r2, 0)
33+
34+
b(loop_entry)
35+
36+
label(loop1)
37+
ldrb(r3, [r1, 0])
38+
add(r2, r2, r3)
39+
40+
add(r1, r1, 1)
41+
sub(r0, r0, 1)
42+
43+
label(loop_entry)
44+
cmp(r0, 0)
45+
bgt(loop1)
46+
47+
mov(r0, r2)
48+
49+
import array
50+
51+
b = array.array('l', (100, 200, 300, 400))
52+
n = asm_sum_words(len(b), b)
53+
print(b, n)
54+
55+
b = array.array('b', (10, 20, 30, 40, 50, 60, 70, 80))
56+
n = asm_sum_bytes(len(b), b)
57+
print(b, n)

py/asmthumb.c

Lines changed: 33 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -230,33 +230,33 @@ STATIC int get_label_dest(asm_thumb_t *as, uint label) {
230230
return as->label_offsets[label];
231231
}
232232

233-
#define OP_MOVS_RLO_I8(rlo_dest, i8_src) (0x2000 | ((rlo_dest) << 8) | (i8_src))
233+
#define OP_FORMAT_2(op, rlo_dest, rlo_src, src_b) ((op) | ((src_b) << 6) | ((rlo_src) << 3) | (rlo_dest))
234234

235-
// the i8_src value will be zero extended into the r32 register!
236-
void asm_thumb_movs_rlo_i8(asm_thumb_t *as, uint rlo_dest, int i8_src) {
235+
void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b) {
237236
assert(rlo_dest < REG_R8);
238-
// movs rlo_dest, #i8_src
239-
asm_thumb_write_op16(as, OP_MOVS_RLO_I8(rlo_dest, i8_src));
237+
assert(rlo_src < REG_R8);
238+
asm_thumb_write_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b));
240239
}
241240

242-
#define OP_MOVW (0xf240)
243-
#define OP_MOVT (0xf2c0)
241+
#define OP_FORMAT_3(op, rlo, i8) ((op) | ((rlo) << 8) | (i8))
244242

245-
// if loading lo half with movw, the i16 value will be zero extended into the r32 register!
246-
STATIC void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) {
247-
assert(reg_dest < REG_R15);
248-
// mov[wt] reg_dest, #i16_src
249-
asm_thumb_write_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff));
243+
void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) {
244+
assert(rlo < REG_R8);
245+
asm_thumb_write_op16(as, OP_FORMAT_3(op, rlo, i8));
250246
}
251247

252-
// the i16_src value will be zero extended into the r32 register!
253-
void asm_thumb_movw_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) {
254-
asm_thumb_mov_reg_i16(as, OP_MOVW, reg_dest, i16_src);
248+
#define OP_FORMAT_4(op, rlo_dest, rlo_src) ((op) | ((rlo_src) << 3) | (rlo_dest))
249+
250+
void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src) {
251+
assert(rlo_dest < REG_R8);
252+
assert(rlo_src < REG_R8);
253+
asm_thumb_write_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src));
255254
}
256255

257-
// the i16_src value will be zero extended into the r32 register!
258-
void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) {
259-
asm_thumb_mov_reg_i16(as, OP_MOVT, reg_dest, i16_src);
256+
#define OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset) ((op) | (((offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest))
257+
258+
void asm_thumb_format_9_10(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_base, uint offset) {
259+
asm_thumb_write_op16(as, OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset));
260260
}
261261

262262
void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) {
@@ -275,42 +275,24 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) {
275275
asm_thumb_write_op16(as, 0x4600 | op_lo);
276276
}
277277

278-
#define OP_ADD_RLO_RLO_RLO(rlo_dest, rlo_src_a, rlo_src_b) (0x1800 | ((rlo_src_b) << 6) | ((rlo_src_a) << 3) | (rlo_dest))
279-
280-
void asm_thumb_add_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b) {
281-
asm_thumb_write_op16(as, OP_ADD_RLO_RLO_RLO(rlo_dest, rlo_src_a, rlo_src_b));
282-
}
283-
284-
#define OP_SUBS_RLO_RLO_I3(rlo_dest, rlo_src, i3_src) (0x1e00 | ((i3_src) << 6) | ((rlo_src) << 3) | (rlo_dest))
285-
286-
void asm_thumb_subs_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint rlo_src, int i3_src) {
287-
assert(rlo_dest < REG_R8);
288-
assert(rlo_src < REG_R8);
289-
asm_thumb_write_op16(as, OP_SUBS_RLO_RLO_I3(rlo_dest, rlo_src, i3_src));
290-
}
291-
292-
#define OP_CMP_REG_REG(rlo_a, rlo_b) (0x4280 | ((rlo_b) << 3) | (rlo_a))
293-
294-
void asm_thumb_cmp_reg_reg(asm_thumb_t *as, uint rlo_a, uint rlo_b) {
295-
asm_thumb_write_op16(as, OP_CMP_REG_REG(rlo_a, rlo_b));
296-
}
297-
298-
#define OP_CMP_RLO_I8(rlo, i8) (0x2800 | ((rlo) << 8) | (i8))
278+
#define OP_MOVW (0xf240)
279+
#define OP_MOVT (0xf2c0)
299280

300-
void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8) {
301-
assert(rlo < REG_R8);
302-
asm_thumb_write_op16(as, OP_CMP_RLO_I8(rlo, i8));
281+
// if loading lo half with movw, the i16 value will be zero extended into the r32 register!
282+
STATIC void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) {
283+
assert(reg_dest < REG_R15);
284+
// mov[wt] reg_dest, #i16_src
285+
asm_thumb_write_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff));
303286
}
304287

305-
#define OP_LDR_RLO_RLO_I5(rlo_dest, rlo_base, word_offset) (0x6800 | (((word_offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest))
306-
#define OP_STR_RLO_RLO_I5(rlo_dest, rlo_base, word_offset) (0x6000 | (((word_offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest))
307-
308-
void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint word_offset) {
309-
asm_thumb_write_op16(as, OP_LDR_RLO_RLO_I5(rlo_dest, rlo_base, word_offset));
288+
// the i16_src value will be zero extended into the r32 register!
289+
void asm_thumb_movw_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) {
290+
asm_thumb_mov_reg_i16(as, OP_MOVW, reg_dest, i16_src);
310291
}
311292

312-
void asm_thumb_str_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint word_offset) {
313-
asm_thumb_write_op16(as, OP_STR_RLO_RLO_I5(rlo_src, rlo_base, word_offset));
293+
// the i16_src value will be zero extended into the r32 register!
294+
void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) {
295+
asm_thumb_mov_reg_i16(as, OP_MOVT, reg_dest, i16_src);
314296
}
315297

316298
void asm_thumb_ite_ge(asm_thumb_t *as) {
@@ -353,7 +335,7 @@ void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, machine_uint_t i32) {
353335

354336
void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) {
355337
if (reg_dest < 8 && UNSIGNED_FIT8(i32)) {
356-
asm_thumb_movs_rlo_i8(as, reg_dest, i32);
338+
asm_thumb_mov_rlo_i8(as, reg_dest, i32);
357339
} else if (UNSIGNED_FIT16(i32)) {
358340
asm_thumb_mov_reg_i16(as, OP_MOVW, reg_dest, i32);
359341
} else {
@@ -452,7 +434,7 @@ void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp
452434
asm_thumb_mov_reg_i32(as, reg_temp, (machine_uint_t)fun_ptr);
453435
asm_thumb_write_op16(as, OP_BLX(reg_temp));
454436
} else if (1) {
455-
asm_thumb_write_op16(as, OP_LDR_RLO_RLO_I5(reg_temp, REG_R7, fun_id));
437+
asm_thumb_write_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, REG_R7, fun_id));
456438
asm_thumb_write_op16(as, OP_BLX(reg_temp));
457439
} else {
458440
// use SVC

py/asmthumb.h

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,93 @@ void asm_thumb_label_assign(asm_thumb_t *as, uint label);
5858
// argument order follows ARM, in general dest is first
5959
// note there is a difference between movw and mov.w, and many others!
6060

61-
void asm_thumb_movs_rlo_i8(asm_thumb_t *as, uint rlo_dest, int i8_src);
61+
// FORMAT 2: add/subtract
62+
63+
#define ASM_THUMB_FORMAT_2_ADD (0x1800)
64+
#define ASM_THUMB_FORMAT_2_SUB (0x1a00)
65+
#define ASM_THUMB_FORMAT_2_REG_OPERAND (0x0000)
66+
#define ASM_THUMB_FORMAT_2_IMM_OPERAND (0x0400)
67+
68+
void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b);
69+
70+
static inline void asm_thumb_add_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b)
71+
{ asm_thumb_format_2(as, ASM_THUMB_FORMAT_2_ADD | ASM_THUMB_FORMAT_2_REG_OPERAND, rlo_dest, rlo_src_a, rlo_src_b); }
72+
static inline void asm_thumb_add_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, int i3_src)
73+
{ asm_thumb_format_2(as, ASM_THUMB_FORMAT_2_ADD | ASM_THUMB_FORMAT_2_IMM_OPERAND, rlo_dest, rlo_src_a, i3_src); }
74+
static inline void asm_thumb_sub_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b)
75+
{ asm_thumb_format_2(as, ASM_THUMB_FORMAT_2_SUB | ASM_THUMB_FORMAT_2_REG_OPERAND, rlo_dest, rlo_src_a, rlo_src_b); }
76+
static inline void asm_thumb_sub_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, int i3_src)
77+
{ asm_thumb_format_2(as, ASM_THUMB_FORMAT_2_SUB | ASM_THUMB_FORMAT_2_IMM_OPERAND, rlo_dest, rlo_src_a, i3_src); }
78+
79+
// FORMAT 3: move/compare/add/subtract immediate
80+
// These instructions all do zero extension of the i8 value
81+
82+
#define ASM_THUMB_FORMAT_3_MOV (0x2000)
83+
#define ASM_THUMB_FORMAT_3_CMP (0x2800)
84+
#define ASM_THUMB_FORMAT_3_ADD (0x3000)
85+
#define ASM_THUMB_FORMAT_3_SUB (0x3800)
86+
87+
void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8);
88+
89+
static inline void asm_thumb_mov_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { asm_thumb_format_3(as, ASM_THUMB_FORMAT_3_MOV, rlo, i8); }
90+
static inline void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { asm_thumb_format_3(as, ASM_THUMB_FORMAT_3_CMP, rlo, i8); }
91+
static inline void asm_thumb_add_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { asm_thumb_format_3(as, ASM_THUMB_FORMAT_3_ADD, rlo, i8); }
92+
static inline void asm_thumb_sub_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { asm_thumb_format_3(as, ASM_THUMB_FORMAT_3_SUB, rlo, i8); }
93+
94+
// FORMAT 4: ALU operations
95+
96+
#define ASM_THUMB_FORMAT_4_AND (0x4000)
97+
#define ASM_THUMB_FORMAT_4_EOR (0x4040)
98+
#define ASM_THUMB_FORMAT_4_LSL (0x4080)
99+
#define ASM_THUMB_FORMAT_4_LSR (0x40c0)
100+
#define ASM_THUMB_FORMAT_4_ASR (0x4100)
101+
#define ASM_THUMB_FORMAT_4_ADC (0x4140)
102+
#define ASM_THUMB_FORMAT_4_SBC (0x4180)
103+
#define ASM_THUMB_FORMAT_4_ROR (0x41c0)
104+
#define ASM_THUMB_FORMAT_4_TST (0x4200)
105+
#define ASM_THUMB_FORMAT_4_NEG (0x4240)
106+
#define ASM_THUMB_FORMAT_4_CMP (0x4280)
107+
#define ASM_THUMB_FORMAT_4_CMN (0x42c0)
108+
#define ASM_THUMB_FORMAT_4_ORR (0x4300)
109+
#define ASM_THUMB_FORMAT_4_MUL (0x4340)
110+
#define ASM_THUMB_FORMAT_4_BIC (0x4380)
111+
#define ASM_THUMB_FORMAT_4_MVN (0x43c0)
112+
113+
void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src);
114+
115+
static inline void asm_thumb_cmp_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src) { asm_thumb_format_4(as, ASM_THUMB_FORMAT_4_CMP, rlo_dest, rlo_src); }
116+
117+
// FORMAT 9: load/store with immediate offset
118+
// For word transfers the offset must be aligned, and >>2
119+
120+
// FORMAT 10: load/store halfword
121+
// The offset must be aligned, and >>1
122+
// The load is zero extended into the register
123+
124+
#define ASM_THUMB_FORMAT_9_STR (0x6000)
125+
#define ASM_THUMB_FORMAT_9_LDR (0x6800)
126+
#define ASM_THUMB_FORMAT_9_WORD_TRANSFER (0x0000)
127+
#define ASM_THUMB_FORMAT_9_BYTE_TRANSFER (0x1000)
128+
129+
#define ASM_THUMB_FORMAT_10_STRH (0x8000)
130+
#define ASM_THUMB_FORMAT_10_LDRH (0x8800)
131+
132+
void asm_thumb_format_9_10(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_base, uint offset);
133+
134+
static inline void asm_thumb_str_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint word_offset)
135+
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_src, rlo_base, word_offset); }
136+
static inline void asm_thumb_strb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint byte_offset)
137+
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER, rlo_src, rlo_base, byte_offset); }
138+
static inline void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint word_offset)
139+
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_dest, rlo_base, word_offset); }
140+
static inline void asm_thumb_ldrb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint byte_offset)
141+
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER , rlo_dest, rlo_base, byte_offset); }
142+
143+
// TODO convert these to above format style
144+
145+
void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src);
62146
void asm_thumb_movw_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src);
63147
void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src);
64-
void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src);
65-
void asm_thumb_add_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b);
66-
void asm_thumb_subs_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint rlo_src, int i3_src);
67-
void asm_thumb_cmp_reg_reg(asm_thumb_t *as, uint rlo_a, uint rlo_b);
68-
void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8);
69-
void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint word_offset);
70-
void asm_thumb_str_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint word_offset);
71148
void asm_thumb_ite_ge(asm_thumb_t *as);
72149
void asm_thumb_b_n(asm_thumb_t *as, uint label);
73150
void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label);

0 commit comments

Comments
 (0)