@@ -200,6 +200,7 @@ static const qstr_short_t BRANCH_OPCODE_NAMES[] = {
200200
201201#define RRR (0)
202202#define RRI8 (1)
203+ #define RRRN (2)
203204
204205static const struct opcode_entry_t {
205206 qstr_short_t name ;
@@ -211,12 +212,13 @@ static const struct opcode_entry_t {
211212 uint32_t r : 6 ;
212213 uint32_t s : 6 ;
213214 uint32_t t : 6 ;
214- uint32_t shift : 4 ;
215- uint32_t kind : 1 ;
216- // 13 bits available here
215+ uint32_t shift : 3 ;
216+ uint32_t kind : 2 ;
217+ // 9 bits available here
217218} OPCODE_TABLE [] = {
218219 { MP_QSTR_abs_ , 2 , 6 , 0 , 0 , RRR_R0 , 1 , RRR_R1 , 0 , RRR },
219220 { MP_QSTR_add , 3 , 8 , 0 , 0 , RRR_R0 , RRR_R1 , RRR_R2 , 0 , RRR },
221+ { MP_QSTR_add_n , 3 , 0 , 0 , 10 , RRR_R0 , RRR_R1 , RRR_R2 , 0 , RRRN },
220222 { MP_QSTR_addi , 3 , 0 , 0 , 2 , 12 , RRR_R1 , RRR_R0 , 0 , RRI8 },
221223 { MP_QSTR_addx2 , 3 , 9 , 0 , 0 , RRR_R0 , RRR_R1 , RRR_R2 , 0 , RRR },
222224 { MP_QSTR_addx4 , 3 , 10 , 0 , 0 , RRR_R0 , RRR_R1 , RRR_R2 , 0 , RRR },
@@ -228,12 +230,17 @@ static const struct opcode_entry_t {
228230 { MP_QSTR_l16ui , 3 , 0 , 0 , 2 , 1 , RRR_R1 , RRR_R0 , 3 , RRI8 },
229231 { MP_QSTR_l32i , 3 , 0 , 0 , 2 , 2 , RRR_R1 , RRR_R0 , 5 , RRI8 },
230232 { MP_QSTR_l8ui , 3 , 0 , 0 , 2 , 0 , RRR_R1 , RRR_R0 , 1 , RRI8 },
233+ { MP_QSTR_mov , 2 , 0 , 0 , 13 , 0 , RRR_R1 , RRR_R0 , 0 , RRRN },
234+ { MP_QSTR_mov_n , 2 , 0 , 0 , 13 , 0 , RRR_R1 , RRR_R0 , 0 , RRRN },
231235 { MP_QSTR_mull , 3 , 8 , 2 , 0 , RRR_R0 , RRR_R1 , RRR_R2 , 0 , RRR },
232236 { MP_QSTR_neg , 2 , 6 , 0 , 0 , RRR_R0 , 0 , RRR_R1 , 0 , RRR },
233237 { MP_QSTR_nop , 0 , 0 , 0 , 0 , 2 , 0 , 15 , 0 , RRR },
238+ { MP_QSTR_nop_n , 0 , 0 , 0 , 13 , 15 , 0 , 3 , 0 , RRRN },
234239 { MP_QSTR_nsa , 2 , 4 , 0 , 0 , 14 , RRR_R1 , RRR_R0 , 0 , RRR },
235240 { MP_QSTR_nsau , 2 , 4 , 0 , 0 , 15 , RRR_R1 , RRR_R0 , 0 , RRR },
236241 { MP_QSTR_or_ , 3 , 2 , 0 , 0 , RRR_R0 , RRR_R1 , RRR_R2 , 0 , RRR },
242+ { MP_QSTR_ret , 0 , 0 , 0 , 13 , 15 , 0 , 0 , 0 , RRRN },
243+ { MP_QSTR_ret_n , 0 , 0 , 0 , 13 , 15 , 0 , 0 , 0 , RRRN },
237244 { MP_QSTR_s16i , 3 , 0 , 0 , 2 , 5 , RRR_R1 , RRR_R0 , 3 , RRI8 },
238245 { MP_QSTR_s32i , 3 , 0 , 0 , 2 , 6 , RRR_R1 , RRR_R0 , 5 , RRI8 },
239246 { MP_QSTR_s8i , 3 , 0 , 0 , 2 , 4 , RRR_R1 , RRR_R0 , 1 , RRI8 },
@@ -255,6 +262,7 @@ static const struct opcode_entry_t {
255262 { MP_QSTR_esync , 0 , 0 , 0 , 0 , 2 , 0 , 2 , 0 , RRR },
256263 { MP_QSTR_extw , 0 , 0 , 0 , 0 , 2 , 0 , 13 , 0 , RRR },
257264 { MP_QSTR_ill , 0 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , RRR },
265+ { MP_QSTR_ill_n , 0 , 0 , 0 , 13 , 15 , 0 , 6 , 0 , RRRN },
258266 { MP_QSTR_isync , 0 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , RRR },
259267 { MP_QSTR_memw , 0 , 0 , 0 , 0 , 2 , 0 , 12 , 0 , RRR },
260268 { MP_QSTR_rer , 2 , 4 , 0 , 0 , 6 , RRR_R1 , RRR_R0 , 0 , RRR },
@@ -281,10 +289,10 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
281289 goto unknown_op ;
282290 }
283291
284- uint32_t op24 = ((entry -> r & 0x0F ) << 12 ) | ((entry -> s & 0x0F ) << 8 ) | ((entry -> t & 0x0F ) << 4 ) | entry -> op0 ;
292+ uint32_t opcode = ((entry -> r & 0x0F ) << 12 ) | ((entry -> s & 0x0F ) << 8 ) | ((entry -> t & 0x0F ) << 4 ) | entry -> op0 ;
285293 if (entry -> kind == RRR ) {
286- op24 |= (entry -> op2 << 20 ) | (entry -> op1 << 16 );
287- } else {
294+ opcode |= (entry -> op2 << 20 ) | (entry -> op1 << 16 );
295+ } else if ( entry -> kind == RRI8 ) {
288296 int min = 0 ;
289297 int max = 0 ;
290298 int shift = entry -> shift ;
@@ -296,32 +304,28 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
296304 max = 127 ;
297305 }
298306 uint32_t immediate = get_arg_i (emit , op_str , pn_args [2 ], min , max );
299- op24 |= ((immediate >> shift ) & 0xFF ) << 16 ;
307+ opcode |= ((immediate >> shift ) & 0xFF ) << 16 ;
300308 }
301309 if (entry -> r >= RRR_R0 ) {
302- op24 |= get_arg_reg (emit , op_str , pn_args [(entry -> r >> 4 ) - 1 ]) << 12 ;
310+ opcode |= get_arg_reg (emit , op_str , pn_args [(entry -> r >> 4 ) - 1 ]) << 12 ;
303311 }
304312 if (entry -> s >= RRR_R0 ) {
305- op24 |= get_arg_reg (emit , op_str , pn_args [(entry -> s >> 4 ) - 1 ]) << 8 ;
313+ opcode |= get_arg_reg (emit , op_str , pn_args [(entry -> s >> 4 ) - 1 ]) << 8 ;
306314 }
307315 if (entry -> t >= RRR_R0 ) {
308- op24 |= get_arg_reg (emit , op_str , pn_args [(entry -> t >> 4 ) - 1 ]) << 4 ;
316+ opcode |= get_arg_reg (emit , op_str , pn_args [(entry -> t >> 4 ) - 1 ]) << 4 ;
317+ }
318+ if (entry -> kind == RRRN ) {
319+ assert ((opcode >> 16 ) == 0 && "Stray bits in narrow opcode" );
320+ asm_xtensa_op16 (& emit -> as , (uint16_t )(opcode & 0xFFFF ));
321+ } else {
322+ asm_xtensa_op24 (& emit -> as , opcode );
309323 }
310- asm_xtensa_op24 (& emit -> as , op24 );
311324 return ;
312325 }
313326 }
314327
315- if (n_args == 0 ) {
316- if (op == MP_QSTR_ret_n || op == MP_QSTR_ret ) {
317- asm_xtensa_op_ret_n (& emit -> as );
318- return ;
319- } else if (op == MP_QSTR_nop_n ) {
320- asm_xtensa_op16 (& emit -> as , 0xF03D );
321- return ;
322- }
323- goto unknown_op ;
324- } else if (n_args == 1 ) {
328+ if (n_args == 1 ) {
325329 if (op == MP_QSTR_j ) {
326330 int label = get_arg_label (emit , op_str , pn_args [0 ]);
327331 asm_xtensa_j_label (& emit -> as , label );
@@ -335,8 +339,6 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
335339 } else if (op == MP_QSTR_fsync ) {
336340 mp_uint_t imm3 = get_arg_i (emit , op_str , pn_args [0 ], 0 , 7 );
337341 asm_xtensa_op24 (& emit -> as , ASM_XTENSA_ENCODE_RRR (0 , 0 , 0 , 2 , 8 | imm3 , 0 ));
338- } else if (op == MP_QSTR_ill_n ) {
339- asm_xtensa_op16 (& emit -> as , 0xF06D );
340342 #endif
341343 } else {
342344 goto unknown_op ;
@@ -350,11 +352,7 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
350352 return ;
351353 }
352354 }
353- if (op == MP_QSTR_mov || op == MP_QSTR_mov_n ) {
354- // we emit mov.n for both "mov" and "mov_n" opcodes
355- uint r1 = get_arg_reg (emit , op_str , pn_args [1 ]);
356- asm_xtensa_op_mov_n (& emit -> as , r0 , r1 );
357- } else if (op == MP_QSTR_movi ) {
355+ if (op == MP_QSTR_movi ) {
358356 // for convenience we emit l32r if the integer doesn't fit in movi
359357 uint32_t imm = get_arg_i (emit , op_str , pn_args [1 ], 0 , 0 );
360358 asm_xtensa_mov_reg_i32 (& emit -> as , r0 , imm );
@@ -397,12 +395,7 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_
397395 }
398396 }
399397
400- if (op == MP_QSTR_add_n ) {
401- mp_uint_t r0 = get_arg_reg (emit , op_str , pn_args [0 ]);
402- mp_uint_t r1 = get_arg_reg (emit , op_str , pn_args [1 ]);
403- mp_uint_t r2 = get_arg_reg (emit , op_str , pn_args [2 ]);
404- asm_xtensa_op16 (& emit -> as , ASM_XTENSA_ENCODE_RRRN (10 , r0 , r1 , r2 ));
405- } else if (op == MP_QSTR_addi_n ) {
398+ if (op == MP_QSTR_addi_n ) {
406399 mp_uint_t r0 = get_arg_reg (emit , op_str , pn_args [0 ]);
407400 mp_uint_t r1 = get_arg_reg (emit , op_str , pn_args [1 ]);
408401 mp_int_t imm4 = get_arg_i (emit , op_str , pn_args [2 ], -1 , 15 );
0 commit comments