From e41b21c01ef0bf23d14a1e6277d7d89d80a9a394 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Feb 2015 16:32:52 +0000 Subject: [PATCH] py: Make more asmthumb functions inline to reduce code size. --- py/asmthumb.c | 44 +++++--------------------------------------- py/asmthumb.h | 29 ++++++++++++++++++++++++----- py/emitinlinethumb.c | 8 ++++---- 3 files changed, 33 insertions(+), 48 deletions(-) diff --git a/py/asmthumb.c b/py/asmthumb.c index d23be0ef2b..c361dbd0a8 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -260,21 +260,6 @@ void asm_thumb_op32(asm_thumb_t *as, uint op1, uint op2) { c[3] = op2 >> 8; } -#define OP_FORMAT_2(op, rlo_dest, rlo_src, src_b) ((op) | ((src_b) << 6) | ((rlo_src) << 3) | (rlo_dest)) - -void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b) { - assert(rlo_dest < ASM_THUMB_REG_R8); - assert(rlo_src < ASM_THUMB_REG_R8); - asm_thumb_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b)); -} - -#define OP_FORMAT_3(op, rlo, i8) ((op) | ((rlo) << 8) | (i8)) - -void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) { - assert(rlo < ASM_THUMB_REG_R8); - asm_thumb_op16(as, OP_FORMAT_3(op, rlo, i8)); -} - #define OP_FORMAT_4(op, rlo_dest, rlo_src) ((op) | ((rlo_src) << 3) | (rlo_dest)) void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src) { @@ -283,12 +268,6 @@ void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src) { asm_thumb_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src)); } -#define OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset) ((op) | (((offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest)) - -void asm_thumb_format_9_10(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_base, uint offset) { - asm_thumb_op16(as, OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset)); -} - void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { uint op_lo; if (reg_src < 8) { @@ -305,26 +284,13 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { asm_thumb_op16(as, 0x4600 | op_lo); } -#define OP_MOVW (0xf240) -#define OP_MOVT (0xf2c0) - // if loading lo half with movw, the i16 value will be zero extended into the r32 register! -STATIC void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) { +void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) { assert(reg_dest < ASM_THUMB_REG_R15); // mov[wt] reg_dest, #i16_src asm_thumb_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); } -// the i16_src value will be zero extended into the r32 register! -void asm_thumb_movw_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) { - asm_thumb_mov_reg_i16(as, OP_MOVW, reg_dest, i16_src); -} - -// the i16_src value will be zero extended into the r32 register! -void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) { - asm_thumb_mov_reg_i16(as, OP_MOVT, reg_dest, i16_src); -} - #define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff)) void asm_thumb_b_n(asm_thumb_t *as, uint label) { @@ -355,15 +321,15 @@ void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32) { // movw, movt does it in 8 bytes // ldr [pc, #], dw does it in 6 bytes, but we might not reach to end of code for dw - asm_thumb_mov_reg_i16(as, OP_MOVW, reg_dest, i32); - asm_thumb_mov_reg_i16(as, OP_MOVT, reg_dest, i32 >> 16); + asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, reg_dest, i32); + asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVT, reg_dest, i32 >> 16); } void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) { if (reg_dest < 8 && UNSIGNED_FIT8(i32)) { asm_thumb_mov_rlo_i8(as, reg_dest, i32); } else if (UNSIGNED_FIT16(i32)) { - asm_thumb_mov_reg_i16(as, OP_MOVW, reg_dest, i32); + asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, reg_dest, i32); } else { asm_thumb_mov_reg_i32(as, reg_dest, i32); } @@ -485,7 +451,7 @@ void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp if (fun_id < 32) { // load ptr to function from table, indexed by fun_id (must be in range 0-31); 4 bytes - asm_thumb_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, ASM_THUMB_REG_R7, fun_id)); + 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 diff --git a/py/asmthumb.h b/py/asmthumb.h index 83a7dc2703..8d413322f2 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -111,7 +111,14 @@ static inline void asm_thumb_it_cc(asm_thumb_t *as, uint cc, uint mask) #define ASM_THUMB_FORMAT_2_REG_OPERAND (0x0000) #define ASM_THUMB_FORMAT_2_IMM_OPERAND (0x0400) -void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b); +#define ASM_THUMB_FORMAT_2_ENCODE(op, rlo_dest, rlo_src, src_b) \ + ((op) | ((src_b) << 6) | ((rlo_src) << 3) | (rlo_dest)) + +static inline void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b) { + assert(rlo_dest < ASM_THUMB_REG_R8); + assert(rlo_src < ASM_THUMB_REG_R8); + asm_thumb_op16(as, ASM_THUMB_FORMAT_2_ENCODE(op, rlo_dest, rlo_src, src_b)); +} static inline void asm_thumb_add_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b) { asm_thumb_format_2(as, ASM_THUMB_FORMAT_2_ADD | ASM_THUMB_FORMAT_2_REG_OPERAND, rlo_dest, rlo_src_a, rlo_src_b); } @@ -130,7 +137,12 @@ static inline void asm_thumb_sub_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint #define ASM_THUMB_FORMAT_3_ADD (0x3000) #define ASM_THUMB_FORMAT_3_SUB (0x3800) -void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8); +#define ASM_THUMB_FORMAT_3_ENCODE(op, rlo, i8) ((op) | ((rlo) << 8) | (i8)) + +static inline void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) { + assert(rlo < ASM_THUMB_REG_R8); + asm_thumb_op16(as, ASM_THUMB_FORMAT_3_ENCODE(op, rlo, i8)); +} static inline void asm_thumb_mov_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { asm_thumb_format_3(as, ASM_THUMB_FORMAT_3_MOV, rlo, i8); } static inline void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { asm_thumb_format_3(as, ASM_THUMB_FORMAT_3_CMP, rlo, i8); } @@ -175,7 +187,11 @@ static inline void asm_thumb_cmp_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rl #define ASM_THUMB_FORMAT_10_STRH (0x8000) #define ASM_THUMB_FORMAT_10_LDRH (0x8800) -void asm_thumb_format_9_10(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_base, uint offset); +#define ASM_THUMB_FORMAT_9_10_ENCODE(op, rlo_dest, rlo_base, offset) \ + ((op) | (((offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest)) + +static inline void asm_thumb_format_9_10(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_base, uint offset) + { asm_thumb_op16(as, ASM_THUMB_FORMAT_9_10_ENCODE(op, rlo_dest, rlo_base, offset)); } static inline void asm_thumb_str_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint word_offset) { asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_src, rlo_base, word_offset); } @@ -192,9 +208,12 @@ static inline void asm_thumb_ldrh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uin // TODO convert these to above format style +#define ASM_THUMB_OP_MOVW (0xf240) +#define ASM_THUMB_OP_MOVT (0xf2c0) + void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src); -void asm_thumb_movw_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src); -void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src); +void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src); + void asm_thumb_b_n(asm_thumb_t *as, uint label); void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 614726ff89..3cde20ecc7 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -506,18 +506,18 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a } else if (strcmp(op_str, "movw") == 0) { mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15); int i_src = get_arg_i(emit, op_str, pn_args[1], 0xffff); - asm_thumb_movw_reg_i16(emit->as, reg_dest, i_src); + asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVW, reg_dest, i_src); } else if (strcmp(op_str, "movt") == 0) { mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15); int i_src = get_arg_i(emit, op_str, pn_args[1], 0xffff); - asm_thumb_movt_reg_i16(emit->as, reg_dest, i_src); + asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVT, reg_dest, i_src); } else if (strcmp(op_str, "movwt") == 0) { // this is a convenience instruction // we clear the MSB since it might be set from extracting the small int value mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15); int i_src = get_arg_i(emit, op_str, pn_args[1], 0xffffffff); - asm_thumb_movw_reg_i16(emit->as, reg_dest, i_src & 0xffff); - asm_thumb_movt_reg_i16(emit->as, reg_dest, (i_src >> 16) & 0x7fff); + asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVW, reg_dest, i_src & 0xffff); + asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0x7fff); } else if (strcmp(op_str, "ldrex") == 0) { mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15); mp_parse_node_t pn_base, pn_offset;