py: In asmthumb, clean up unit/int types and ite ops.
This commit is contained in:
parent
860805aae7
commit
851f15f34c
|
@ -42,17 +42,16 @@
|
||||||
#define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800)
|
#define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800)
|
||||||
|
|
||||||
struct _asm_thumb_t {
|
struct _asm_thumb_t {
|
||||||
uint pass;
|
mp_uint_t pass;
|
||||||
uint code_offset;
|
mp_uint_t code_offset;
|
||||||
uint code_size;
|
mp_uint_t code_size;
|
||||||
byte *code_base;
|
byte *code_base;
|
||||||
byte dummy_data[4];
|
byte dummy_data[4];
|
||||||
|
|
||||||
uint max_num_labels;
|
mp_uint_t max_num_labels;
|
||||||
int *label_offsets;
|
mp_uint_t *label_offsets;
|
||||||
int num_locals;
|
mp_uint_t push_reglist;
|
||||||
uint push_reglist;
|
mp_uint_t stack_adjust;
|
||||||
uint stack_adjust;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
asm_thumb_t *asm_thumb_new(uint max_num_labels) {
|
asm_thumb_t *asm_thumb_new(uint max_num_labels) {
|
||||||
|
@ -60,7 +59,7 @@ asm_thumb_t *asm_thumb_new(uint max_num_labels) {
|
||||||
|
|
||||||
as = m_new0(asm_thumb_t, 1);
|
as = m_new0(asm_thumb_t, 1);
|
||||||
as->max_num_labels = max_num_labels;
|
as->max_num_labels = max_num_labels;
|
||||||
as->label_offsets = m_new(int, max_num_labels);
|
as->label_offsets = m_new(mp_uint_t, max_num_labels);
|
||||||
|
|
||||||
return as;
|
return as;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +87,7 @@ void asm_thumb_start_pass(asm_thumb_t *as, uint pass) {
|
||||||
as->pass = pass;
|
as->pass = pass;
|
||||||
as->code_offset = 0;
|
as->code_offset = 0;
|
||||||
if (pass == ASM_THUMB_PASS_COMPUTE) {
|
if (pass == ASM_THUMB_PASS_COMPUTE) {
|
||||||
memset(as->label_offsets, -1, as->max_num_labels * sizeof(int));
|
memset(as->label_offsets, -1, as->max_num_labels * sizeof(mp_uint_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +168,7 @@ STATIC void asm_thumb_write_word32(asm_thumb_t *as, int w32) {
|
||||||
|
|
||||||
// locals:
|
// locals:
|
||||||
// - stored on the stack in ascending order
|
// - stored on the stack in ascending order
|
||||||
// - numbered 0 through as->num_locals-1
|
// - numbered 0 through num_locals-1
|
||||||
// - SP points to first local
|
// - SP points to first local
|
||||||
//
|
//
|
||||||
// | SP
|
// | SP
|
||||||
|
@ -222,7 +221,6 @@ void asm_thumb_entry(asm_thumb_t *as, int num_locals) {
|
||||||
}
|
}
|
||||||
as->push_reglist = reglist;
|
as->push_reglist = reglist;
|
||||||
as->stack_adjust = stack_adjust;
|
as->stack_adjust = stack_adjust;
|
||||||
as->num_locals = num_locals;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void asm_thumb_exit(asm_thumb_t *as) {
|
void asm_thumb_exit(asm_thumb_t *as) {
|
||||||
|
@ -262,7 +260,7 @@ void asm_thumb_data(asm_thumb_t* as, uint bytesize, uint val) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int get_label_dest(asm_thumb_t *as, uint label) {
|
STATIC mp_uint_t get_label_dest(asm_thumb_t *as, uint label) {
|
||||||
assert(label < as->max_num_labels);
|
assert(label < as->max_num_labels);
|
||||||
return as->label_offsets[label];
|
return as->label_offsets[label];
|
||||||
}
|
}
|
||||||
|
@ -348,15 +346,11 @@ 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);
|
asm_thumb_mov_reg_i16(as, OP_MOVT, reg_dest, i16_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void asm_thumb_ite_ge(asm_thumb_t *as) {
|
|
||||||
asm_thumb_op16(as, 0xbfac);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff))
|
#define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff))
|
||||||
|
|
||||||
void asm_thumb_b_n(asm_thumb_t *as, uint label) {
|
void asm_thumb_b_n(asm_thumb_t *as, uint label) {
|
||||||
int dest = get_label_dest(as, label);
|
mp_uint_t dest = get_label_dest(as, label);
|
||||||
int rel = dest - as->code_offset;
|
mp_int_t rel = dest - as->code_offset;
|
||||||
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
|
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
|
||||||
if (SIGNED_FIT12(rel)) {
|
if (SIGNED_FIT12(rel)) {
|
||||||
asm_thumb_op16(as, OP_B_N(rel));
|
asm_thumb_op16(as, OP_B_N(rel));
|
||||||
|
@ -368,8 +362,8 @@ void asm_thumb_b_n(asm_thumb_t *as, uint label) {
|
||||||
#define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff))
|
#define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff))
|
||||||
|
|
||||||
void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label) {
|
void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label) {
|
||||||
int dest = get_label_dest(as, label);
|
mp_uint_t dest = get_label_dest(as, label);
|
||||||
int rel = dest - as->code_offset;
|
mp_int_t rel = dest - as->code_offset;
|
||||||
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
|
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
|
||||||
if (SIGNED_FIT9(rel)) {
|
if (SIGNED_FIT9(rel)) {
|
||||||
asm_thumb_op16(as, OP_BCC_N(cond, rel));
|
asm_thumb_op16(as, OP_BCC_N(cond, rel));
|
||||||
|
@ -442,8 +436,8 @@ void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num)
|
||||||
#define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff))
|
#define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff))
|
||||||
|
|
||||||
void asm_thumb_b_label(asm_thumb_t *as, uint label) {
|
void asm_thumb_b_label(asm_thumb_t *as, uint label) {
|
||||||
int dest = get_label_dest(as, label);
|
mp_uint_t dest = get_label_dest(as, label);
|
||||||
int rel = dest - as->code_offset;
|
mp_int_t rel = dest - as->code_offset;
|
||||||
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
|
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
|
||||||
if (dest >= 0 && rel <= -4) {
|
if (dest >= 0 && rel <= -4) {
|
||||||
// is a backwards jump, so we know the size of the jump on the first pass
|
// is a backwards jump, so we know the size of the jump on the first pass
|
||||||
|
@ -465,8 +459,8 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) {
|
||||||
#define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff))
|
#define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff))
|
||||||
|
|
||||||
void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) {
|
void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) {
|
||||||
int dest = get_label_dest(as, label);
|
mp_uint_t dest = get_label_dest(as, label);
|
||||||
int rel = dest - as->code_offset;
|
mp_int_t rel = dest - as->code_offset;
|
||||||
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
|
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
|
||||||
if (dest >= 0 && rel <= -4) {
|
if (dest >= 0 && rel <= -4) {
|
||||||
// is a backwards jump, so we know the size of the jump on the first pass
|
// is a backwards jump, so we know the size of the jump on the first pass
|
||||||
|
|
|
@ -80,6 +80,14 @@ void asm_thumb_data(asm_thumb_t* as, uint bytesize, uint val);
|
||||||
// argument order follows ARM, in general dest is first
|
// argument order follows ARM, in general dest is first
|
||||||
// note there is a difference between movw and mov.w, and many others!
|
// note there is a difference between movw and mov.w, and many others!
|
||||||
|
|
||||||
|
#define ASM_THUMB_OP_ITE_EQ (0xbf0c)
|
||||||
|
#define ASM_THUMB_OP_ITE_CS (0xbf2c)
|
||||||
|
#define ASM_THUMB_OP_ITE_MI (0xbf4c)
|
||||||
|
#define ASM_THUMB_OP_ITE_VS (0xbf6c)
|
||||||
|
#define ASM_THUMB_OP_ITE_HI (0xbf8c)
|
||||||
|
#define ASM_THUMB_OP_ITE_GE (0xbfac)
|
||||||
|
#define ASM_THUMB_OP_ITE_GT (0xbfcc)
|
||||||
|
|
||||||
#define ASM_THUMB_OP_NOP (0xbf00)
|
#define ASM_THUMB_OP_NOP (0xbf00)
|
||||||
#define ASM_THUMB_OP_WFI (0xbf30)
|
#define ASM_THUMB_OP_WFI (0xbf30)
|
||||||
#define ASM_THUMB_OP_CPSID_I (0xb672) // cpsid i, disable irq
|
#define ASM_THUMB_OP_CPSID_I (0xb672) // cpsid i, disable irq
|
||||||
|
@ -165,17 +173,20 @@ static inline void asm_thumb_str_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint
|
||||||
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_src, rlo_base, 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); }
|
||||||
static inline void asm_thumb_strb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint byte_offset)
|
static inline void asm_thumb_strb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint byte_offset)
|
||||||
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER, rlo_src, rlo_base, byte_offset); }
|
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER, rlo_src, rlo_base, byte_offset); }
|
||||||
|
static inline void asm_thumb_strh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint byte_offset)
|
||||||
|
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_10_STRH, rlo_src, rlo_base, byte_offset); }
|
||||||
static inline void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint word_offset)
|
static inline void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint word_offset)
|
||||||
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_dest, rlo_base, word_offset); }
|
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_dest, rlo_base, word_offset); }
|
||||||
static inline void asm_thumb_ldrb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint byte_offset)
|
static inline void asm_thumb_ldrb_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_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER , rlo_dest, rlo_base, byte_offset); }
|
{ asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER , rlo_dest, rlo_base, byte_offset); }
|
||||||
|
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); }
|
||||||
|
|
||||||
// TODO convert these to above format style
|
// TODO convert these to above format style
|
||||||
|
|
||||||
void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src);
|
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_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_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src);
|
||||||
void asm_thumb_ite_ge(asm_thumb_t *as);
|
|
||||||
void asm_thumb_b_n(asm_thumb_t *as, uint label);
|
void asm_thumb_b_n(asm_thumb_t *as, uint label);
|
||||||
void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label);
|
void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label);
|
||||||
|
|
||||||
|
@ -189,4 +200,3 @@ void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num)
|
||||||
void asm_thumb_b_label(asm_thumb_t *as, uint label); // convenience ?
|
void asm_thumb_b_label(asm_thumb_t *as, uint label); // convenience ?
|
||||||
void asm_thumb_bcc_label(asm_thumb_t *as, int cc, uint label); // convenience: picks narrow or wide branch
|
void asm_thumb_bcc_label(asm_thumb_t *as, int cc, uint label); // convenience: picks narrow or wide branch
|
||||||
void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp); // convenience ?
|
void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp); // convenience ?
|
||||||
|
|
||||||
|
|
|
@ -274,7 +274,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
|
||||||
} else if (strcmp(op_str, "wfi") == 0) {
|
} else if (strcmp(op_str, "wfi") == 0) {
|
||||||
asm_thumb_op16(emit->as, ASM_THUMB_OP_WFI);
|
asm_thumb_op16(emit->as, ASM_THUMB_OP_WFI);
|
||||||
} else if (strcmp(op_str, "ite.ge") == 0) { // TODO correct name for this op?
|
} else if (strcmp(op_str, "ite.ge") == 0) { // TODO correct name for this op?
|
||||||
asm_thumb_ite_ge(emit->as);
|
asm_thumb_op16(emit->as, ASM_THUMB_OP_ITE_GE);
|
||||||
} else {
|
} else {
|
||||||
goto unknown_op;
|
goto unknown_op;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1537,7 +1537,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
|
||||||
asm_x86_setcc_r8(emit->as, ASM_X86_CC_JL, REG_RET);
|
asm_x86_setcc_r8(emit->as, ASM_X86_CC_JL, REG_RET);
|
||||||
#elif N_THUMB
|
#elif N_THUMB
|
||||||
asm_thumb_cmp_rlo_rlo(emit->as, REG_ARG_2, REG_ARG_3);
|
asm_thumb_cmp_rlo_rlo(emit->as, REG_ARG_2, REG_ARG_3);
|
||||||
asm_thumb_ite_ge(emit->as);
|
asm_thumb_op16(emit->as, ASM_THUMB_OP_ITE_GE);
|
||||||
asm_thumb_mov_rlo_i8(emit->as, REG_RET, 0); // if r0 >= r1
|
asm_thumb_mov_rlo_i8(emit->as, REG_RET, 0); // if r0 >= r1
|
||||||
asm_thumb_mov_rlo_i8(emit->as, REG_RET, 1); // if r0 < r1
|
asm_thumb_mov_rlo_i8(emit->as, REG_RET, 1); // if r0 < r1
|
||||||
#elif N_ARM
|
#elif N_ARM
|
||||||
|
|
Loading…
Reference in New Issue