diff options
| author | graham sanderson <graham.sanderson@raspberrypi.org> | 2020-12-12 13:04:10 -0600 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2021-01-29 23:57:10 +1100 |
| commit | 40d2010882409e71080f519312488f5bb951238b (patch) | |
| tree | ead21159f6f8e73e4bd956131cb0eb220d9b8c0b /py/asmthumb.h | |
| parent | fe16e785fe76ca2c84b82512c427c7fa57176abe (diff) | |
py/asmthumb: Add support for ARMv6M in native emitter.
Adds a new compile-time option MICROPY_EMIT_THUMB_ARMV7M which is enabled
by default (to get existing behaviour) and which should be disabled (set to
0) when building native emitter support (@micropython.native) on ARMv6M
targets.
Diffstat (limited to 'py/asmthumb.h')
| -rw-r--r-- | py/asmthumb.h | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/py/asmthumb.h b/py/asmthumb.h index 17b694a74..3c4533618 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -157,6 +157,7 @@ static inline void asm_thumb_sub_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint #define ASM_THUMB_FORMAT_3_CMP (0x2800) #define ASM_THUMB_FORMAT_3_ADD (0x3000) #define ASM_THUMB_FORMAT_3_SUB (0x3800) +#define ASM_THUMB_FORMAT_3_LDR (0x4800) #define ASM_THUMB_FORMAT_3_ENCODE(op, rlo, i8) ((op) | ((rlo) << 8) | (i8)) @@ -177,6 +178,9 @@ static inline void asm_thumb_add_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { static inline void asm_thumb_sub_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { asm_thumb_format_3(as, ASM_THUMB_FORMAT_3_SUB, rlo, i8); } +static inline void asm_thumb_ldr_rlo_pcrel_i8(asm_thumb_t *as, uint rlo, uint i8) { + asm_thumb_format_3(as, ASM_THUMB_FORMAT_3_LDR, rlo, i8); +} // FORMAT 4: ALU operations @@ -202,6 +206,12 @@ void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src); static inline void asm_thumb_cmp_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src) { asm_thumb_format_4(as, ASM_THUMB_FORMAT_4_CMP, rlo_dest, rlo_src); } +static inline void asm_thumb_mvn_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src) { + asm_thumb_format_4(as, ASM_THUMB_FORMAT_4_MVN, rlo_dest, rlo_src); +} +static inline void asm_thumb_neg_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src) { + asm_thumb_format_4(as, ASM_THUMB_FORMAT_4_NEG, rlo_dest, rlo_src); +} // FORMAT 5: hi register operations (add, cmp, mov, bx) // For add/cmp/mov, at least one of the args must be a high register @@ -263,6 +273,32 @@ static inline void asm_thumb_ldrb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uin static inline void asm_thumb_ldrh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint byte_offset) { asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_10_LDRH, rlo_dest, rlo_base, byte_offset); } +static inline void asm_thumb_lsl_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_src, uint shift) { + asm_thumb_format_1(as, ASM_THUMB_FORMAT_1_LSL, rlo_dest, rlo_src, shift); +} +static inline void asm_thumb_asr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_src, uint shift) { + asm_thumb_format_1(as, ASM_THUMB_FORMAT_1_ASR, rlo_dest, rlo_src, shift); +} + +// FORMAT 11: sign/zero extend + +#define ASM_THUMB_FORMAT_11_ENCODE(op, rlo_dest, rlo_src) \ + ((op) | ((rlo_src) << 3) | (rlo_dest)) + +#define ASM_THUMB_FORMAT_11_SXTH (0xb200) +#define ASM_THUMB_FORMAT_11_SXTB (0xb240) +#define ASM_THUMB_FORMAT_11_UXTH (0xb280) +#define ASM_THUMB_FORMAT_11_UXTB (0xb2c0) + +static inline void asm_thumb_format_11(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src) { + assert(rlo_dest < ASM_THUMB_REG_R8); + assert(rlo_src < ASM_THUMB_REG_R8); + asm_thumb_op16(as, ASM_THUMB_FORMAT_11_ENCODE(op, rlo_dest, rlo_src)); +} + +static inline void asm_thumb_sxth_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src) { + asm_thumb_format_11(as, ASM_THUMB_FORMAT_11_SXTH, rlo_dest, rlo_src); +} // TODO convert these to above format style @@ -270,7 +306,12 @@ static inline void asm_thumb_ldrh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uin #define ASM_THUMB_OP_MOVT (0xf2c0) void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src); + +#if MICROPY_EMIT_THUMB_ARMV7M size_t asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src); +#else +void asm_thumb_mov_rlo_i16(asm_thumb_t *as, uint rlo_dest, int i16_src); +#endif // these return true if the destination is in range, false otherwise bool asm_thumb_b_n_label(asm_thumb_t *as, uint label); @@ -344,7 +385,11 @@ void asm_thumb_bl_ind(asm_thumb_t *as, uint fun_id, uint reg_temp); // convenien #define ASM_MOV_LOCAL_REG(as, local_num, reg) asm_thumb_mov_local_reg((as), (local_num), (reg)) #define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_thumb_mov_reg_i32_optimised((as), (reg_dest), (imm)) +#if MICROPY_EMIT_THUMB_ARMV7M #define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_thumb_mov_reg_i16((as), ASM_THUMB_OP_MOVW, (reg_dest), (imm)) +#else +#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_thumb_mov_rlo_i16((as), (reg_dest), (imm)) +#endif #define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_thumb_mov_reg_i32((as), (reg_dest), (imm)) #define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_thumb_mov_reg_local((as), (reg_dest), (local_num)) #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_thumb_mov_reg_reg((as), (reg_dest), (reg_src)) |
