aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George2018-07-31 15:06:28 +1000
committerDamien George2018-07-31 15:06:28 +1000
commit1e3a7f561fffc2d06436b1ef09cb8b44262bb2bc (patch)
treea44621f11d4e42b000a0f495796d09d0109922d6
parentf6f6452b6f336559e4b44c7a49260bd9c2ba684b (diff)
py/asmthumb: Optimise native code calling runtime glue functions.
This patch makes the Thumb-2 native emitter use wide ldr instructions to call into the runtime, when the index into the native glue function table is 32 or greater. This reduces the generated assembler code from 10 bytes to 6 bytes, saving RAM and making native code run about 0.8% faster.
-rw-r--r--py/asmthumb.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/py/asmthumb.c b/py/asmthumb.c
index c5b45f2f5..ce9e4fdce 100644
--- a/py/asmthumb.c
+++ b/py/asmthumb.c
@@ -353,6 +353,8 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) {
}
#define OP_BLX(reg) (0x4780 | ((reg) << 3))
+#define OP_LDR_W_HI(reg_base) (0xf8d0 | (reg_base))
+#define OP_LDR_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12))
#define OP_SVC(arg) (0xdf00 | (arg))
void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp) {
@@ -370,8 +372,8 @@ void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp
asm_thumb_op16(as, ASM_THUMB_FORMAT_9_10_ENCODE(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, ASM_THUMB_REG_R7, fun_id));
asm_thumb_op16(as, OP_BLX(reg_temp));
} else {
- // load ptr to function into register using immediate; 6 bytes
- asm_thumb_mov_reg_i32(as, reg_temp, (mp_uint_t)fun_ptr);
+ // load ptr to function from table, indexed by fun_id using wide load; 6 bytes
+ asm_thumb_op32(as, OP_LDR_W_HI(ASM_THUMB_REG_R7), OP_LDR_W_LO(reg_temp, fun_id << 2));
asm_thumb_op16(as, OP_BLX(reg_temp));
}
}