diff options
Diffstat (limited to 'py/asmthumb.c')
-rw-r--r-- | py/asmthumb.c | 84 |
1 files changed, 33 insertions, 51 deletions
diff --git a/py/asmthumb.c b/py/asmthumb.c index 1cd971c76b..6bf6d66584 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -230,33 +230,33 @@ STATIC int get_label_dest(asm_thumb_t *as, uint label) { return as->label_offsets[label]; } -#define OP_MOVS_RLO_I8(rlo_dest, i8_src) (0x2000 | ((rlo_dest) << 8) | (i8_src)) +#define OP_FORMAT_2(op, rlo_dest, rlo_src, src_b) ((op) | ((src_b) << 6) | ((rlo_src) << 3) | (rlo_dest)) -// the i8_src value will be zero extended into the r32 register! -void asm_thumb_movs_rlo_i8(asm_thumb_t *as, uint rlo_dest, int i8_src) { +void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b) { assert(rlo_dest < REG_R8); - // movs rlo_dest, #i8_src - asm_thumb_write_op16(as, OP_MOVS_RLO_I8(rlo_dest, i8_src)); + assert(rlo_src < REG_R8); + asm_thumb_write_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b)); } -#define OP_MOVW (0xf240) -#define OP_MOVT (0xf2c0) +#define OP_FORMAT_3(op, rlo, i8) ((op) | ((rlo) << 8) | (i8)) -// 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) { - assert(reg_dest < REG_R15); - // mov[wt] reg_dest, #i16_src - asm_thumb_write_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); +void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) { + assert(rlo < REG_R8); + asm_thumb_write_op16(as, OP_FORMAT_3(op, rlo, i8)); } -// 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); +#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) { + assert(rlo_dest < REG_R8); + assert(rlo_src < REG_R8); + asm_thumb_write_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_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_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_write_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) { @@ -275,42 +275,24 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { asm_thumb_write_op16(as, 0x4600 | op_lo); } -#define OP_ADD_RLO_RLO_RLO(rlo_dest, rlo_src_a, rlo_src_b) (0x1800 | ((rlo_src_b) << 6) | ((rlo_src_a) << 3) | (rlo_dest)) - -void asm_thumb_add_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_src_a, uint rlo_src_b) { - asm_thumb_write_op16(as, OP_ADD_RLO_RLO_RLO(rlo_dest, rlo_src_a, rlo_src_b)); -} - -#define OP_SUBS_RLO_RLO_I3(rlo_dest, rlo_src, i3_src) (0x1e00 | ((i3_src) << 6) | ((rlo_src) << 3) | (rlo_dest)) - -void asm_thumb_subs_rlo_rlo_i3(asm_thumb_t *as, uint rlo_dest, uint rlo_src, int i3_src) { - assert(rlo_dest < REG_R8); - assert(rlo_src < REG_R8); - asm_thumb_write_op16(as, OP_SUBS_RLO_RLO_I3(rlo_dest, rlo_src, i3_src)); -} - -#define OP_CMP_REG_REG(rlo_a, rlo_b) (0x4280 | ((rlo_b) << 3) | (rlo_a)) - -void asm_thumb_cmp_reg_reg(asm_thumb_t *as, uint rlo_a, uint rlo_b) { - asm_thumb_write_op16(as, OP_CMP_REG_REG(rlo_a, rlo_b)); -} - -#define OP_CMP_RLO_I8(rlo, i8) (0x2800 | ((rlo) << 8) | (i8)) +#define OP_MOVW (0xf240) +#define OP_MOVT (0xf2c0) -void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8) { - assert(rlo < REG_R8); - asm_thumb_write_op16(as, OP_CMP_RLO_I8(rlo, i8)); +// 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) { + assert(reg_dest < REG_R15); + // mov[wt] reg_dest, #i16_src + asm_thumb_write_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); } -#define OP_LDR_RLO_RLO_I5(rlo_dest, rlo_base, word_offset) (0x6800 | (((word_offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest)) -#define OP_STR_RLO_RLO_I5(rlo_dest, rlo_base, word_offset) (0x6000 | (((word_offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest)) - -void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint word_offset) { - asm_thumb_write_op16(as, OP_LDR_RLO_RLO_I5(rlo_dest, rlo_base, word_offset)); +// 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); } -void asm_thumb_str_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint word_offset) { - asm_thumb_write_op16(as, OP_STR_RLO_RLO_I5(rlo_src, rlo_base, word_offset)); +// 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); } void asm_thumb_ite_ge(asm_thumb_t *as) { @@ -353,7 +335,7 @@ void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, machine_uint_t i32) { 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_movs_rlo_i8(as, reg_dest, 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); } else { @@ -452,7 +434,7 @@ void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp asm_thumb_mov_reg_i32(as, reg_temp, (machine_uint_t)fun_ptr); asm_thumb_write_op16(as, OP_BLX(reg_temp)); } else if (1) { - asm_thumb_write_op16(as, OP_LDR_RLO_RLO_I5(reg_temp, REG_R7, fun_id)); + asm_thumb_write_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, REG_R7, fun_id)); asm_thumb_write_op16(as, OP_BLX(reg_temp)); } else { // use SVC |