Skip to content

Commit 12f36cc

Browse files
agattidpgeorge
authored andcommitted
py/asmxtensa: Implement the full set of Viper load/store operations.
This commit expands the implementation of Viper load/store operations that are optimised for the Xtensa platform. Now both load and store emitters should generate the shortest possible sequence in all cases. Redundant specialised operation emitters have been aliased to the general case implementation - this was the case of integer-indexed load/store operations with a fixed offset of zero. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent cd1b921 commit 12f36cc

File tree

3 files changed

+60
-44
lines changed

3 files changed

+60
-44
lines changed

py/asmxtensa.c

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -299,25 +299,47 @@ void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, u
299299
}
300300
}
301301

302-
void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset) {
303-
if (word_offset < 16) {
304-
asm_xtensa_op_s32i_n(as, reg_src, reg_base, word_offset);
305-
} else if (word_offset < 256) {
306-
asm_xtensa_op_s32i(as, reg_src, reg_base, word_offset);
302+
void asm_xtensa_load_reg_reg_offset(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint offset, uint operation_size) {
303+
assert(operation_size <= 2 && "Operation size value out of range.");
304+
305+
if (operation_size == 2 && MP_FIT_UNSIGNED(4, offset)) {
306+
asm_xtensa_op_l32i_n(as, reg_dest, reg_base, offset);
307+
return;
308+
}
309+
310+
if (MP_FIT_UNSIGNED(8, offset)) {
311+
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, operation_size, reg_base, reg_dest, offset));
312+
return;
313+
}
314+
315+
asm_xtensa_mov_reg_i32_optimised(as, reg_dest, offset << operation_size);
316+
asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest);
317+
if (operation_size == 2) {
318+
asm_xtensa_op_l32i_n(as, reg_dest, reg_dest, 0);
307319
} else {
308-
asm_xtensa_mov_reg_i32_optimised(as, REG_TEMP, word_offset * 4);
309-
asm_xtensa_op_add_n(as, REG_TEMP, reg_base, REG_TEMP);
310-
asm_xtensa_op_s32i_n(as, reg_src, REG_TEMP, 0);
320+
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, operation_size, reg_dest, reg_dest, 0));
311321
}
312322
}
313323

314-
void asm_xtensa_l16ui_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint halfword_offset) {
315-
if (halfword_offset < 256) {
316-
asm_xtensa_op_l16ui(as, reg_dest, reg_base, halfword_offset);
324+
void asm_xtensa_store_reg_reg_offset(asm_xtensa_t *as, uint reg_src, uint reg_base, uint offset, uint operation_size) {
325+
assert(operation_size <= 2 && "Operation size value out of range.");
326+
327+
if (operation_size == 2 && MP_FIT_UNSIGNED(4, offset)) {
328+
asm_xtensa_op_s32i_n(as, reg_src, reg_base, offset);
329+
return;
330+
}
331+
332+
if (MP_FIT_UNSIGNED(8, offset)) {
333+
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, 0x04 | operation_size, reg_base, reg_src, offset));
334+
return;
335+
}
336+
337+
asm_xtensa_mov_reg_i32_optimised(as, REG_TEMP, offset << operation_size);
338+
asm_xtensa_op_add_n(as, REG_TEMP, reg_base, REG_TEMP);
339+
if (operation_size == 2) {
340+
asm_xtensa_op_s32i_n(as, reg_src, REG_TEMP, 0);
317341
} else {
318-
asm_xtensa_mov_reg_i32_optimised(as, reg_dest, halfword_offset * 2);
319-
asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest);
320-
asm_xtensa_op_l16ui(as, reg_dest, reg_dest, 0);
342+
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, 0x04 | operation_size, REG_TEMP, reg_src, 0));
321343
}
322344
}
323345

py/asmxtensa.h

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,8 @@ void asm_xtensa_mov_local_reg(asm_xtensa_t *as, int local_num, uint reg_src);
293293
void asm_xtensa_mov_reg_local(asm_xtensa_t *as, uint reg_dest, int local_num);
294294
void asm_xtensa_mov_reg_local_addr(asm_xtensa_t *as, uint reg_dest, int local_num);
295295
void asm_xtensa_mov_reg_pcrel(asm_xtensa_t *as, uint reg_dest, uint label);
296-
void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint word_offset);
297-
void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset);
298-
void asm_xtensa_l16ui_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint halfword_offset);
296+
void asm_xtensa_load_reg_reg_offset(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint offset, uint operation_size);
297+
void asm_xtensa_store_reg_reg_offset(asm_xtensa_t *as, uint reg_src, uint reg_base, uint offset, uint operation_size);
299298
void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx);
300299
void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx);
301300
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);
@@ -420,32 +419,45 @@ void asm_xtensa_l32r(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t label);
420419
#define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_xtensa_op_mull((as), (reg_dest), (reg_dest), (reg_src))
421420

422421
#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (word_offset))
423-
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l8ui((as), (reg_dest), (reg_base), 0)
424-
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0)
425-
#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_xtensa_l16ui_optimised((as), (reg_dest), (reg_base), (uint16_offset))
422+
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) ASM_LOAD8_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0)
423+
#define ASM_LOAD8_REG_REG_OFFSET(as, reg_dest, reg_base, byte_offset) asm_xtensa_load_reg_reg_offset((as), (reg_dest), (reg_base), (byte_offset), 0)
424+
#define ASM_LOAD8_REG_REG_REG(as, reg_dest, reg_base, reg_index) \
425+
do { \
426+
asm_xtensa_op_add_n((as), (reg_base), (reg_index), (reg_base)); \
427+
asm_xtensa_op_l8ui((as), (reg_dest), (reg_base), 0); \
428+
} while (0)
429+
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) ASM_LOAD16_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0)
430+
#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, halfword_offset) asm_xtensa_load_reg_reg_offset((as), (reg_dest), (reg_base), (halfword_offset), 1)
426431
#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) \
427432
do { \
428433
asm_xtensa_op_addx2((as), (reg_base), (reg_index), (reg_base)); \
429434
asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0); \
430435
} while (0)
431-
#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l32i_n((as), (reg_dest), (reg_base), 0)
432-
#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_l32i_optimised((as), (reg_dest), (reg_base), (word_offset))
436+
#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0)
437+
#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_load_reg_reg_offset((as), (reg_dest), (reg_base), (word_offset), 2)
433438
#define ASM_LOAD32_REG_REG_REG(as, reg_dest, reg_base, reg_index) \
434439
do { \
435440
asm_xtensa_op_addx4((as), (reg_base), (reg_index), (reg_base)); \
436441
asm_xtensa_op_l32i_n((as), (reg_dest), (reg_base), 0); \
437442
} while (0)
438443

439444
#define ASM_STORE_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) ASM_STORE32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (word_offset))
440-
#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s8i((as), (reg_src), (reg_base), 0)
441-
#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s16i((as), (reg_src), (reg_base), 0)
445+
#define ASM_STORE8_REG_REG(as, reg_src, reg_base) ASM_STORE8_REG_REG_OFFSET((as), (reg_src), (reg_base), 0)
446+
#define ASM_STORE8_REG_REG_OFFSET(as, reg_src, reg_base, byte_offset) asm_xtensa_store_reg_reg_offset((as), (reg_src), (reg_base), (byte_offset), 0)
447+
#define ASM_STORE8_REG_REG_REG(as, reg_val, reg_base, reg_index) \
448+
do { \
449+
asm_xtensa_op_add_n((as), (reg_base), (reg_index), (reg_base)); \
450+
asm_xtensa_op_s8i((as), (reg_val), (reg_base), 0); \
451+
} while (0)
452+
#define ASM_STORE16_REG_REG(as, reg_src, reg_base) ASM_STORE16_REG_REG_OFFSET((as), (reg_src), (reg_base), 0)
453+
#define ASM_STORE16_REG_REG_OFFSET(as, reg_src, reg_base, halfword_offset) asm_xtensa_store_reg_reg_offset((as), (reg_src), (reg_base), (halfword_offset), 1)
442454
#define ASM_STORE16_REG_REG_REG(as, reg_val, reg_base, reg_index) \
443455
do { \
444456
asm_xtensa_op_addx2((as), (reg_base), (reg_index), (reg_base)); \
445457
asm_xtensa_op_s16i((as), (reg_val), (reg_base), 0); \
446458
} while (0)
447-
#define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s32i_n((as), (reg_src), (reg_base), 0)
448-
#define ASM_STORE32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_s32i_optimised((as), (reg_dest), (reg_base), (word_offset))
459+
#define ASM_STORE32_REG_REG(as, reg_src, reg_base) ASM_STORE32_REG_REG_OFFSET((as), (reg_src), (reg_base), 0)
460+
#define ASM_STORE32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_store_reg_reg_offset((as), (reg_dest), (reg_base), (word_offset), 2)
449461
#define ASM_STORE32_REG_REG_REG(as, reg_val, reg_base, reg_index) \
450462
do { \
451463
asm_xtensa_op_addx4((as), (reg_base), (reg_index), (reg_base)); \

py/emitnative.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,12 +1534,6 @@ static void emit_native_load_subscr(emit_t *emit) {
15341534
#ifdef ASM_LOAD8_REG_REG_OFFSET
15351535
ASM_LOAD8_REG_REG_OFFSET(emit->as, REG_RET, reg_base, index_value);
15361536
#else
1537-
#if N_XTENSA || N_XTENSAWIN
1538-
if (index_value >= 0 && index_value < 256) {
1539-
asm_xtensa_op_l8ui(emit->as, REG_RET, reg_base, index_value);
1540-
break;
1541-
}
1542-
#endif
15431537
if (index_value != 0) {
15441538
// index is non-zero
15451539
need_reg_single(emit, reg_index, 0);
@@ -1776,12 +1770,6 @@ static void emit_native_store_subscr(emit_t *emit) {
17761770
#ifdef ASM_STORE8_REG_REG_OFFSET
17771771
ASM_STORE8_REG_REG_OFFSET(emit->as, reg_value, reg_base, index_value);
17781772
#else
1779-
#if N_XTENSA || N_XTENSAWIN
1780-
if (index_value >= 0 && index_value < 256) {
1781-
asm_xtensa_op_s8i(emit->as, reg_value, reg_base, index_value);
1782-
break;
1783-
}
1784-
#endif
17851773
if (index_value != 0) {
17861774
// index is non-zero
17871775
ASM_MOV_REG_IMM(emit->as, reg_index, index_value);
@@ -1797,12 +1785,6 @@ static void emit_native_store_subscr(emit_t *emit) {
17971785
#ifdef ASM_STORE16_REG_REG_OFFSET
17981786
ASM_STORE16_REG_REG_OFFSET(emit->as, reg_value, reg_base, index_value);
17991787
#else
1800-
#if N_XTENSA || N_XTENSAWIN
1801-
if (index_value >= 0 && index_value < 256) {
1802-
asm_xtensa_op_s16i(emit->as, reg_value, reg_base, index_value);
1803-
break;
1804-
}
1805-
#endif
18061788
if (index_value != 0) {
18071789
// index is a non-zero immediate
18081790
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1);

0 commit comments

Comments
 (0)