|
36 | 36 | #include "py/mphal.h" |
37 | 37 | #include "py/asmthumb.h" |
38 | 38 |
|
| 39 | +#define UNSIGNED_FIT5(x) ((uint32_t)(x) < 32) |
39 | 40 | #define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0) |
40 | 41 | #define UNSIGNED_FIT16(x) (((x) & 0xffff0000) == 0) |
41 | 42 | #define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80) |
42 | 43 | #define SIGNED_FIT9(x) (((x) & 0xffffff00) == 0) || (((x) & 0xffffff00) == 0xffffff00) |
43 | 44 | #define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800) |
44 | 45 | #define SIGNED_FIT23(x) (((x) & 0xffc00000) == 0) || (((x) & 0xffc00000) == 0xffc00000) |
45 | 46 |
|
| 47 | +#define OP_LDR_W_HI(reg_base) (0xf8d0 | (reg_base)) |
| 48 | +#define OP_LDR_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12)) |
| 49 | + |
46 | 50 | static inline byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int n) { |
47 | 51 | return mp_asm_base_get_cur_to_write_bytes(&as->base, n); |
48 | 52 | } |
@@ -304,6 +308,18 @@ void asm_thumb_mov_reg_pcrel(asm_thumb_t *as, uint rlo_dest, uint label) { |
304 | 308 | asm_thumb_add_reg_reg(as, rlo_dest, ASM_THUMB_REG_R15); // 2 bytes |
305 | 309 | } |
306 | 310 |
|
| 311 | +static inline void asm_thumb_ldr_reg_reg_i12(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset) { |
| 312 | + asm_thumb_op32(as, OP_LDR_W_HI(reg_base), OP_LDR_W_LO(reg_dest, word_offset * 4)); |
| 313 | +} |
| 314 | + |
| 315 | +void asm_thumb_ldr_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset) { |
| 316 | + if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8 && UNSIGNED_FIT5(word_offset)) { |
| 317 | + asm_thumb_ldr_rlo_rlo_i5(as, reg_dest, reg_base, word_offset); |
| 318 | + } else { |
| 319 | + asm_thumb_ldr_reg_reg_i12(as, reg_dest, reg_base, word_offset); |
| 320 | + } |
| 321 | +} |
| 322 | + |
307 | 323 | // this could be wrong, because it should have a range of +/- 16MiB... |
308 | 324 | #define OP_BW_HI(byte_offset) (0xf000 | (((byte_offset) >> 12) & 0x07ff)) |
309 | 325 | #define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff)) |
@@ -347,8 +363,6 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) { |
347 | 363 | } |
348 | 364 |
|
349 | 365 | #define OP_BLX(reg) (0x4780 | ((reg) << 3)) |
350 | | -#define OP_LDR_W_HI(reg_base) (0xf8d0 | (reg_base)) |
351 | | -#define OP_LDR_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12)) |
352 | 366 | #define OP_SVC(arg) (0xdf00 | (arg)) |
353 | 367 |
|
354 | 368 | void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp) { |
|
0 commit comments