8000 py/emitinlinextensa: Add the rest of LX6 opcodes to the assembler. · micropython/micropython@a8274c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit a8274c8

Browse files
committed
py/emitinlinextensa: Add the rest of LX6 opcodes to the assembler.
This commit expands the Xtensa inline assembler to support most if not all opcodes available on the ESP8266 and LX6 Xtensa cores. This is meant as a stepping stone to add inline assembler support for the ESP32, along to windowed-specific opcodes and additional opcodes that are present only on the LX7 core (ESP32-S3 and later). New opcodes being added are covered by tests, and the provided tests were expanded to also include opcodes available in the existing implementation. Given that the ESP8266 space requirements are tighter than ESP32's, certain opcodes that won't be commonly used have been put behind a define to save some space in the general use case. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent e07730c commit a8274c8

16 files changed

+1068
-11
lines changed

py/asmxtensa.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define WORD_SIZE (4)
3838
#define SIGNED_FIT8(x) ((((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80))
3939
#define SIGNED_FIT12(x) ((((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800))
40+
#define SIGNED_FIT18(x) ((((x) & 0xfffc0000) == 0) || (((x) & 0xfffc0000) == 0xfffc0000))
4041

4142
#define ET_OUT_OF_RANGE MP_ERROR_TEXT("ERROR: xtensa %q out of range")
4243

@@ -266,4 +267,31 @@ void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx) {
266267
asm_xtensa_op_callx8(as, ASM_XTENSA_REG_A8);
267268
}
268269

270+
void asm_xtensa_bit_branch(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t bit, mp_uint_t label, mp_uint_t condition) {
271+
uint32_t dest = get_label_dest(as, label);
272+
int32_t rel = dest - as->base.code_offset - 4;
273+
if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT8(rel)) {
274+
mp_obj_new_exception_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_bit_branch);
275+
}
276+
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(7, condition | ((bit >> 4) & 0x01), reg, bit & 0x0F, rel & 0xFF));
277+
}
278+
279+
void asm_xtensa_call0(asm_xtensa_t *as, mp_uint_t label) {
280+
uint32_t dest = get_label_dest(as, label);
281+
int32_t rel = dest - as->base.code_offset - 3;
282+
if (as->base.pass == MP_ASM_PASS_EMIT && (((rel & 0x3) != 0) || !SIGNED_FIT18(rel))) {
283+
mp_obj_new_exception_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_call0);
284+
}
285+
asm_xtensa_op_call0(as, rel);
286+
}
287+
288+
void asm_xtensa_l32r(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t label) {
289+
uint32_t dest = get_label_dest(as, label);
290+
int32_t rel = dest - as->base.code_offset;
291+
if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT18(rel)) {
292+
mp_obj_new_exception_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_l32r);
293+
}
294+
asm_xtensa_op_l32r(as, reg, as->base.code_offset, dest);
295+
}
296+
269297
#endif // MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA || MICROPY_EMIT_XTENSAWIN

py/asmxtensa.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@
6464
#define ASM_XTENSA_REG_A14 (14)
6565
#define ASM_XTENSA_REG_A15 (15)
6666

67-
// for bccz
67+
// for bccz and bcci
6868
#define ASM_XTENSA_CCZ_EQ (0)
6969
#define ASM_XTENSA_CCZ_NE (1)
70+
#define ASM_XTENSA_CCZ_LT (2)
71+
#define ASM_XTENSA_CCZ_GE (3)
7072

7173
// for bcc and setcc
7274
#define ASM_XTENSA_CC_NONE (0)
@@ -295,6 +297,10 @@ void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, u
295297
void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset);
296298
void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx);
297299
void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx);
300+
void asm_xtensa_bit_branch(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t bit, mp_uint_t label, mp_uint_t condition);
301+
void asm_xtensa_immediate_branch(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t immediate, mp_uint_t label, mp_uint_t cond);
302+
void asm_xtensa_call0(asm_xtensa_t *as, mp_uint_t label);
303+
void asm_xtensa_l32r(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t label);
298304

299305
// Holds a pointer to mp_fun_table
300306
#define ASM_XTENSA_REG_FUN_TABLE ASM_XTENSA_REG_A15

py/emitinlinextensa.c

Lines changed: 191 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_
174174
#define RRI8_B (2)
175175

176176
typedef struct _opcode_table_3arg_t {
177-
uint16_t name; // actually a qstr, which should fit in 16 bits
177+
qstr_short_t name;
178178
uint8_t type;
179179
uint8_t a0 : 4;
180180
uint8_t a1 : 4;
@@ -188,6 +188,13 @@ static const opcode_table_3arg_t opcode_table_3arg[] = {
188188
{MP_QSTR_add, RRR, 0, 8},
189189
{MP_QSTR_sub, RRR, 0, 12},
190190
{MP_QSTR_mull, RRR, 2, 8},
191+
{MP_QSTR_addx2, RRR, 0, 9},
192+
{MP_QSTR_addx4, RRR, 0, 10},
193+
{MP_QSTR_addx8, RRR, 0, 11},
194+
{MP_QSTR_subx2, RRR, 0, 13},
195+
{MP_QSTR_subx4, RRR, 0, 14},
196+
{MP_QSTR_subx8, RRR, 0, 15},
197+
{MP_QSTR_src, RRR, 1, 8},
191198

192199
// load/store/addi opcodes: reg, reg, imm
193200
// upper nibble of type encodes the range of the immediate arg
@@ -209,21 +216,58 @@ static const opcode_table_3arg_t opcode_table_3arg[] = {
209216
{MP_QSTR_bge, RRI8_B, ASM_XTENSA_CC_GE, 0},
210217
{MP_QSTR_bgeu, RRI8_B, ASM_XTENSA_CC_GEU, 0},
211218
{MP_QSTR_blt, RRI8_B, ASM_XTENSA_CC_LT, 0},
219+
{MP_QSTR_bltu, RRI8_B, ASM_XTENSA_CC_LTU, 0},
212220
{MP_QSTR_bnall, RRI8_B, ASM_XTENSA_CC_NALL, 0},
213221
{MP_QSTR_bne, RRI8_B, ASM_XTENSA_CC_NE, 0},
214222
{MP_QSTR_bnone, RRI8_B, ASM_XTENSA_CC_NONE, 0},
215223
};
216224

225+
// The index of the qstrs matches the CCZ condition value to be embedded into the opcode.
226+
static const qstr_short_t BCCZ_OPCODES[] = { MP_QSTR_beqz, MP_QSTR_bnez, MP_QSTR_bltz, MP_QSTR_bgez };
227+
228+
#if MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES
229+
typedef struct _single_opcode_t {
230+
qstr_short_t name;
231+
uint16_t value;
232+
} single_opcode_t;
233+
234+
static const single_opcode_t NOARGS_OPCODES[] = {
235+
{MP_QSTR_dsync, 0x2030},
236+
{MP_QSTR_esync, 0x2020},
237+
{MP_QSTR_extw, 0x20D0},
238+
{MP_QSTR_ill, 0x0000},
239+
{MP_QSTR_isync, 0x2000},
240+
{MP_QSTR_memw, 0x20C0},
241+
{MP_QSTR_rsync, 0x2010},
242+
};
243+
#endif
244+
217245
static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, mp_parse_node_t *pn_args) {
218246
size_t op_len;
219247
const char *op_str = (const char *)qstr_data(op, &op_len);
220248

221249
if (n_args == 0) {
222-
if (op == MP_QSTR_ret_n) {
250+
if (op == MP_QSTR_ret_n || op == MP_QSTR_ret) {
223251
asm_xtensa_op_ret_n(&emit->as);
224-
} else {
225-
goto unknown_op;
252+
return;
253+
} else if (op == MP_QSTR_nop) {
254+
asm_xtensa_op24(&emit->as, 0x20F0);
255+
return;
256+
} else if (op == MP_QSTR_nop_n) {
257+
asm_xtensa_op16(&emit->as, 0xF03D);
258+
return;
226259
}
260+
#if MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES
261+
for (size_t index = 0; index < MP_ARRAY_SIZE(NOARGS_OPCODES); index++) {
262+
const single_opcode_t *opcode = &NOARGS_OPCODES[index];
263+
if (op == opcode->name) {
264+
asm_xtensa_op24(&emit->as, opcode->value);
265+
return;
266+
}
267+
}
268+
#endif
269+
270+
goto unknown_op;
227271

228272
} else if (n_args == 1) {
229273
if (op == MP_QSTR_callx0) {
@@ -235,17 +279,49 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
235279
} else if (op == MP_QSTR_jx) {
236280
uint r0 = get_arg_reg(emit, op_str, pn_args[0]);
237281
asm_xtensa_op_jx(&emit->as, r0);
282+
} else if (op == MP_QSTR_ssl) {
283+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
284+
asm_xtensa_op_ssl(&emit->as, r0);
285+
} else if (op == MP_QSTR_ssr) {
286+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
287+
asm_xtensa_op_ssr(&emit->as, r0);
288+
} else if (op == MP_QSTR_ssai) {
289+
mp_uint_t sa = get_arg_i(emit, op_str, pn_args[0], 0, 31);
290+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 4, 4, sa & 0x0F, (sa >> 4) & 0x01));
291+
} else if (op == MP_QSTR_ssa8b) {
292+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
293+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 4, 3, r0, 0));
294+
} else if (op == MP_QSTR_ssa8l) {
295+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
296+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 4, 2, r0, 0));
297+
} else if (op == MP_QSTR_call0) {
298+
mp_uint_t label = get_arg_label(emit, op_str, pn_args[0]);
299+
asm_xtensa_call0(&emit->as, label);
300+
#if MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES
301+
} else if (op == MP_QSTR_fsync) {
302+
mp_uint_t imm3 = get_arg_i(emit, op_str, pn_args[0], 0, 7);
303+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 0, 2, 8 | imm3, 0));
304+
} else if (op == MP_QSTR_ill_n) {
305+
asm_xtensa_op16(&emit->as, 0xF06D);
306+
#endif
238307
} else {
239308
goto unknown_op;
240309
}
241310

242311
} else if (n_args == 2) {
243312
uint r0 = get_arg_reg(emit, op_str, pn_args[0]);
244-
if (op == MP_QSTR_beqz) {
245-
int label = get_arg_label(emit, op_str, pn_args[1]);
313+
for (size_t index = 0; index < MP_ARRAY_SIZE(BCCZ_OPCODES); index++) {
314+
if (op == BCCZ_OPCODES[index]) {
315+
mp_uint_t label = get_arg_label(emit, op_str, pn_args[1]);
316+
asm_xtensa_bccz_reg_label(&emit->as, index, r0, label);
317+
return;
318+
}
319+
}
320+
if (op == MP_QSTR_beqz_n) {
321+
mp_uint_t label = get_arg_label(emit, op_str, pn_args[1]);
246322
asm_xtensa_bccz_reg_label(&emit->as, ASM_XTENSA_CCZ_EQ, r0, label);
247-
} else if (op == MP_QSTR_bnez) {
248-
int label = get_arg_label(emit, op_str, pn_args[1]);
323+
} else if (op == MP_QSTR_bnez_n) {
324+
mp_uint_t label = get_arg_label(emit, op_str, pn_args[1]);
249325
asm_xtensa_bccz_reg_label(&emit->as, ASM_XTENSA_CCZ_NE, r0, label);
250326
} else if (op == MP_QSTR_mov || op == MP_QSTR_mov_n) {
251327
// we emit mov.n for both "mov" and "mov_n" opcodes
@@ -255,7 +331,47 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
255331
// for convenience we emit l32r if the integer doesn't fit in movi
256332
uint32_t imm = get_arg_i(emit, op_str, pn_args[1], 0, 0);
257333
asm_xtensa_mov_reg_i32(&emit->as, r0, imm);
258-
} else {
334+
} else if (op == MP_QSTR_abs_) {
335+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
336+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 6, r0, 1, r1));
337+
} else if (op == MP_QSTR_neg) {
338+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
339+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 6, r0, 0, r1));
340+
} else if (op == MP_QSTR_sll) {
341+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
342+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 10, r0, r1, 0));
343+
} else if (op == MP_QSTR_sra) {
344+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
345+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 11, r0, 0, r1));
346+
} else if (op == MP_QSTR_srl) {
347+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
348+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 9, r0, 0, r1));
349+
} else if (op == MP_QSTR_l32r) {
350+
mp_uint_t label = get_arg_label(emit, op_str, pn_args[1]);
351+
asm_xtensa_l32r(&emit->as, r0, label);
352+
} else if (op == MP_QSTR_movi_n) {
353+
mp_int_t imm = get_arg_i(emit, op_str, pn_args[1], -32, 95);
354+
asm_xtensa_op_movi_n(&emit->as, r0, imm);
355+
} else
356+
#if MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES
357+
if (op == MP_QSTR_rsr) {
358+
mp_uint_t sr = get_arg_i(emit, op_str, pn_args[1], 0, 255);
359+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RSR(0, 3, 0, sr, r0));
360+
} else if (op == MP_QSTR_rur) {
361+
mp_uint_t imm8 = get_arg_i(emit, op_str, pn_args[1], 0, 255);
362+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 3, 14, r0, (imm8 >> 4) & 0x0F, imm8 & 0x0F));
363+
} else if (op == MP_QSTR_wsr) {
364+
mp_uint_t sr = get_arg_i(emit, op_str, pn_args[1], 0, 255);
365+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RSR(0, 3, 1, sr, r0));
366+
} else if (op == MP_QSTR_wur) {
367+
mp_uint_t sr = get_arg_i(emit, op_str, pn_args[1], 0, 255);
368+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RSR(0, 3, 15, sr, r0));
369+
} else if (op == MP_QSTR_xsr) {
370+
mp_uint_t sr = get_arg_i(emit, op_str, pn_args[1], 0, 255);
371+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RSR(0, 1, 6, sr, r0));
372+
} else
373+
#endif
374+
{
259375
goto unknown_op;
260376
}
261377

@@ -289,7 +405,72 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
289405
return;
290406
}
291407
}
292-
goto unknown_op;
408+
409+
if (op == MP_QSTR_add_n) {
410+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
411+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
412+
mp_uint_t r2 = get_arg_reg(emit, op_str, pn_args[2]);
413+
asm_xtensa_op16(&emit->as, ASM_XTENSA_ENCODE_RRRN(10, r0, r1, r2));
414+
} else if (op == MP_QSTR_addi_n) {
415+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
416+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
417+
mp_int_t imm4 = get_arg_i(emit, op_str, pn_args[2], -1, 15);
418+
asm_xtensa_op16(&emit->as, ASM_XTENSA_ENCODE_RRRN(11, r0, r1, (imm4 != 0 ? imm4 : -1)));
419+
} else if (op == MP_QSTR_addmi) {
420+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
421+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
422+
mp_int_t imm8 = get_arg_i(emit, op_str, pn_args[2], -128 * 256, 127 * 256);
423+
if ((imm8 & 0xFF) != 0) {
424+
emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("%d is not a multiple of %d"), imm8, 256));
425+
} else {
426+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRI8(2, 13, r1, r0, imm8 >> 8));
427+
}
428+
} else if (op == MP_QSTR_bbci) {
429+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
430+
mp_uint_t bit = get_arg_i(emit, op_str, pn_args[1], 0, 31);
431+
mp_int_t label = get_arg_label(emit, op_str, pn_args[2]);
432+
asm_xtensa_bit_branch(&emit->as, r0, bit, label, 6);
433+
} else if (op == MP_QSTR_bbsi) {
434+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
435+
mp_uint_t bit = get_arg_i(emit, op_str, pn_args[1], 0, 31);
436+
mp_uint_t label = get_arg_label(emit, op_str, pn_args[2]);
437+
asm_xtensa_bit_branch(&emit->as, r0, bit, label, 14);
438+
} else if (op == MP_QSTR_slli) {
439+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
440+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
441+
mp_uint_t bits = 32 - get_arg_i(emit, op_str, pn_args[2], 1, 31);
442+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 0 | ((bits >> 4) & 0x01), r0, r1, bits & 0x0F));
443+
} else if (op == MP_QSTR_srai) {
444+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
445+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
446+
mp_uint_t bits = get_arg_i(emit, op_str, pn_args[2], 0, 31);
447+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 2 | ((bits >> 4) & 0x01), r0, bits & 0x0F, r1));
448+
} else if (op == MP_QSTR_srli) {
449+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
450+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
451+
mp_uint_t bits = get_arg_i(emit, op_str, pn_args[2], 0, 15);
452+
asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 4, r0, bits, r1));
453+
} else if (op == MP_QSTR_l32i_n) {
454+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
455+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
456+
mp_uint_t imm = get_arg_i(emit, op_str, pn_args[2], 0, 60);
457+
if ((imm & 0x03) != 0) {
458+
emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("%d is not a multiple of %d"), imm, 4));
459+
} else {
460+
asm_xtensa_op_l32i_n(&emit->as, r0, r1, imm >> 2);
461+
}
462+
} else if (op == MP_QSTR_s32i_n) {
463+
mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]);
464+
mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]);
465+
mp_uint_t imm = get_arg_i(emit, op_str, pn_args[2], 0, 60);
466+
if ((imm & 0x03) != 0) {
467+
emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("%d is not a multiple of %d"), imm, 4));
468+
} else {
469+
asm_xtensa_op_s32i_n(&emit->as, r0, r1, imm >> 2);
470+
}
471+
} else {
472+
goto unknown_op;
473+
}
293474

294475
} else {
295476
goto unknown_op;

py/mpconfig.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,11 @@
406406
#define MICROPY_EMIT_INLINE_XTENSA (0)
407407
#endif
408408

409+
// Whether to support uncommon Xtensa inline assembler opcodes
410+
#ifndef MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES
411+
#define MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES (0)
412+
#endif
413+
409414
// Whether to emit Xtensa-Windowed native code
410415
#ifndef MICROPY_EMIT_XTENSAWIN
411416
#define MICROPY_EMIT_XTENSAWIN (0)

tests/inlineasm/xtensa/asmargs.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# test passing arguments
2+
3+
4+
@micropython.asm_xtensa
5+
def arg0():
6+
movi(a2, 1)
7+
8+
9+
print(arg0())
10+
11+
12+
@micropython.asm_xtensa
13+
def arg1(a2):
14+
addi(a2, a2, 1)
15+
16+
17+
print(arg1(1))
18+
19+
20+
@micropython.asm_xtensa
21+
def arg2(a2, a3):
22+
add(a2, a2, a3)
23+
24+
25+
print(arg2(1, 2))
26+
27+
28+
@micropython.asm_xtensa
29+
def arg3(a2, a3, a4):
30+
add(a2, a2, a3)
31+
add(a2, a2, a4)
32+
33+
34+
print(arg3(1, 2, 3))
35+
36+
37+
@micropython.asm_xtensa
38+
def arg4(a2, a3, a4, a5):
39+
add(a2, a2, a3)
40+
add(a2, a2, a4)
41+
add(a2, a2, a5)
42+
43+
44+
print(arg4(1, 2, 3, 4))

tests/inlineasm/xtensa/asmargs.py.exp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
1
2+
2
3+
3
4+
6
5+
10

0 commit comments

Comments
 (0)
0