8000 py/asmarm: Extend int-indexed 32-bit load/store offset ranges. · Carglglz/micropython@bbab2e9 · GitHub
[go: up one dir, main page]

Skip to content

Commit bbab2e9

Browse files
agattidpgeorge
authored andcommitted
py/asmarm: Extend int-indexed 32-bit load/store offset ranges.
This commit extends the range for int-indexed load/store opcode generators, making them emit correct code sequences for offsets that span more than 12 bits. This is necessary due to those generator bits being also used in the Viper emitter, where it's more probable to reference offsets that can not be embedded in the LDR/STR opcodes. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent 901c96d commit bbab2e9

File tree

3 files changed

+26
-17
lines changed

3 files changed

+26
-17
lines changed

py/asmarm.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,16 @@ void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs) {
333333
emit_al(as, 0x1a00050 | (rd << 12) | (rs << 8) | rd);
334334
}
335335

336-
void asm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn, uint byte_offset) {
337-
// ldr rd, [rn, #off]
338-
emit_al(as, 0x5900000 | (rn << 16) | (rd << 12) | byte_offset);
336+
void asm_arm_ldr_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset) {
337+
if (byte_offset < 0x1000) {
338+
// ldr rd, [rn, #off]
339+
emit_al(as, 0x5900000 | (rn << 16) | (rd << 12) | byte_offset);
340+
} else {
341+
// mov r8, #off
342+
// ldr rd, [rn, r8]
343+
asm_arm_mov_reg_i32_optimised(as, ASM_ARM_REG_R8, byte_offset);
344+
emit_al(as, 0x7900000 | (rn << 16) | (rd << 12) | ASM_ARM_REG_R8);
345+
}
339346
}
340347

341348
void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn) {
@@ -376,9 +383,16 @@ void asm_arm_ldr_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) {
376383
emit_al(as, 0x7900100 | (rm << 16) | (rd << 12) | rn);
377384
}
378385

379-
void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm, uint byte_offset) {
380-
// str rd, [rm, #off]
381-
emit_al(as, 0x5800000 | (rm << 16) | (rd << 12) | byte_offset);
386+
void asm_arm_str_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset) {
387+
if (byte_offset < 0x1000) {
388+
// str rd, [rm, #off]
389+
emit_al(as, 0x5800000 | (rm << 16) | (rd << 12) | byte_offset);
390+
} else {
391+
// mov r8, #off
392+
// str rd, [rm, r8]
393+
asm_arm_mov_reg_i32_optimised(as, ASM_ARM_REG_R8, byte_offset);
394+
emit_al(as, 0x7800000 | (rm << 16) | (rd << 12) | ASM_ARM_REG_R8);
395+
}
382396
}
383397

384398
void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm) {

py/asmarm.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ void asm_arm_lsr_reg_reg(asm_arm_t *as, uint rd, uint rs);
109109
void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs);
110110

111111
// memory
112-
void asm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn, uint byte_offset);
112+
void asm_arm_ldr_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset);
113113
void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn);
114114
void asm_arm_ldrh_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset);
115115
void asm_arm_ldrb_reg_reg(asm_arm_t *as, uint rd, uint rn);
116-
void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm, uint byte_offset);
116+
void asm_arm_str_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset);
117117
void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm);
118118
void asm_arm_strb_reg_reg(asm_arm_t *as, uint rd, uint rm);
119119

@@ -212,14 +212,14 @@ void asm_arm_bx_reg(asm_arm_t *as, uint reg_src);
212212
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_arm_ldrb_reg_reg((as), (reg_dest), (reg_base))
213213
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_arm_ldrh_reg_reg((as), (reg_dest), (reg_base))
214214
#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_arm_ldrh_reg_reg_offset((as), (reg_dest), (reg_base), 2 * (uint16_offset))
215-
#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 0)
216-
#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 4 * (word_offset))
215+
#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg_offset((as), (reg_dest), (reg_base), 0)
216+
#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_ldr_reg_reg_offset((as), (reg_dest), (reg_base), 4 * (word_offset))
217217

218218
#define ASM_STORE_REG_REG_OFFSET(as, reg_value, reg_base, word_offset) ASM_STORE32_REG_REG_OFFSET((as), (reg_value), (reg_base), (word_offset))
219219
#define ASM_STORE8_REG_REG(as, reg_value, reg_base) asm_arm_strb_reg_reg((as), (reg_value), (reg_base))
220220
#define ASM_STORE16_REG_REG(as, reg_value, reg_base) asm_arm_strh_reg_reg((as), (reg_value), (reg_base))
221-
#define ASM_STORE32_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 0)
222-
#define ASM_STORE32_REG_REG_OFFSET(as, reg_value, reg_base, word_offset) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 4 * (word_offset))
221+
#define ASM_STORE32_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg_offset((as), (reg_value), (reg_base), 0)
222+
#define ASM_STORE32_REG_REG_OFFSET(as, reg_value, reg_base, word_offset) asm_arm_str_reg_reg_offset((as), (reg_value), (reg_base), 4 * (word_offset))
223223

224224
#define ASM_LOAD8_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldrb_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index))
225225
#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldrh_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index))

py/emitnative.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,11 +1845,6 @@ static void emit_native_store_subscr(emit_t *emit) {
18451845
#else
18461846
if (index_value != 0) {
18471847
// index is a non-zero immediate
1848-
#if N_ARM
1849-
ASM_MOV_REG_IMM(emit->as, reg_index, index_value);
1850-
asm_arm_str_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
1851-
break;
1852-
#endif
18531848
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 2);
18541849
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 4*index to base
18551850
reg_base = reg_index;

0 commit comments

Comments
 (0)
0