Commit 0b610de0 authored by Damien George's avatar Damien George
Browse files

py: Make macro names in assemblers consistent, and tidy up a bit.

parent d66e4866
...@@ -45,9 +45,8 @@ struct _asm_arm_t { ...@@ -45,9 +45,8 @@ struct _asm_arm_t {
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;
uint push_reglist; uint push_reglist;
uint stack_adjust; uint stack_adjust;
}; };
...@@ -57,7 +56,7 @@ asm_arm_t *asm_arm_new(uint max_num_labels) { ...@@ -57,7 +56,7 @@ asm_arm_t *asm_arm_new(uint max_num_labels) {
as = m_new0(asm_arm_t, 1); as = m_new0(asm_arm_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;
} }
...@@ -66,7 +65,7 @@ void asm_arm_free(asm_arm_t *as, bool free_code) { ...@@ -66,7 +65,7 @@ void asm_arm_free(asm_arm_t *as, bool free_code) {
if (free_code) { if (free_code) {
MP_PLAT_FREE_EXEC(as->code_base, as->code_size); MP_PLAT_FREE_EXEC(as->code_base, as->code_size);
} }
m_del(mp_uint_t, as->label_offsets, as->max_num_labels);
m_del_obj(asm_arm_t, as); m_del_obj(asm_arm_t, as);
} }
...@@ -74,7 +73,7 @@ void asm_arm_start_pass(asm_arm_t *as, uint pass) { ...@@ -74,7 +73,7 @@ void asm_arm_start_pass(asm_arm_t *as, uint pass) {
as->pass = pass; as->pass = pass;
as->code_offset = 0; as->code_offset = 0;
if (pass == ASM_ARM_PASS_COMPUTE) { if (pass == ASM_ARM_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));
} }
} }
...@@ -127,7 +126,7 @@ STATIC void emit(asm_arm_t *as, uint op) { ...@@ -127,7 +126,7 @@ STATIC void emit(asm_arm_t *as, uint op) {
// Insert word into instruction flow, add "ALWAYS" condition code // Insert word into instruction flow, add "ALWAYS" condition code
STATIC void emit_al(asm_arm_t *as, uint op) { STATIC void emit_al(asm_arm_t *as, uint op) {
emit(as, op | ARM_CC_AL); emit(as, op | ASM_ARM_CC_AL);
} }
// Basic instructions without condition code // Basic instructions without condition code
...@@ -178,7 +177,7 @@ void asm_arm_bkpt(asm_arm_t *as) { ...@@ -178,7 +177,7 @@ void asm_arm_bkpt(asm_arm_t *as) {
// 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
...@@ -194,30 +193,36 @@ void asm_arm_entry(asm_arm_t *as, int num_locals) { ...@@ -194,30 +193,36 @@ void asm_arm_entry(asm_arm_t *as, int num_locals) {
} }
as->stack_adjust = 0; as->stack_adjust = 0;
as->num_locals = num_locals; as->push_reglist = 1 << ASM_ARM_REG_R1
as->push_reglist = 1 << REG_R1 | 1 << REG_R2 | 1 << REG_R3 | 1 << REG_R4 | 1 << ASM_ARM_REG_R2
| 1 << REG_R5 | 1 << REG_R6 | 1 << REG_R7 | 1 << REG_R8; | 1 << ASM_ARM_REG_R3
| 1 << ASM_ARM_REG_R4
| 1 << ASM_ARM_REG_R5
| 1 << ASM_ARM_REG_R6
| 1 << ASM_ARM_REG_R7
| 1 << ASM_ARM_REG_R8;
// Only adjust the stack if there are more locals than usable registers // Only adjust the stack if there are more locals than usable registers
if(num_locals > 3) { if(num_locals > 3) {
as->stack_adjust = num_locals * 4; as->stack_adjust = num_locals * 4;
// Align stack to 8 bytes // Align stack to 8 bytes
if(as->num_locals & 1) if (num_locals & 1) {
as->stack_adjust += 4; as->stack_adjust += 4;
}
} }
emit_al(as, asm_arm_op_push(as->push_reglist | 1 << REG_LR)); emit_al(as, asm_arm_op_push(as->push_reglist | 1 << ASM_ARM_REG_LR));
if (as->stack_adjust > 0) { if (as->stack_adjust > 0) {
emit_al(as, asm_arm_op_sub_imm(REG_SP, REG_SP, as->stack_adjust)); emit_al(as, asm_arm_op_sub_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust));
} }
} }
void asm_arm_exit(asm_arm_t *as) { void asm_arm_exit(asm_arm_t *as) {
if (as->stack_adjust > 0) { if (as->stack_adjust > 0) {
emit_al(as, asm_arm_op_add_imm(REG_SP, REG_SP, as->stack_adjust)); emit_al(as, asm_arm_op_add_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust));
} }
emit_al(as, asm_arm_op_pop(as->push_reglist | (1 << REG_PC))); emit_al(as, asm_arm_op_pop(as->push_reglist | (1 << ASM_ARM_REG_PC)));
} }
void asm_arm_label_assign(asm_arm_t *as, uint label) { void asm_arm_label_assign(asm_arm_t *as, uint label) {
...@@ -289,8 +294,8 @@ void asm_arm_cmp_reg_reg(asm_arm_t *as, uint rd, uint rn) { ...@@ -289,8 +294,8 @@ void asm_arm_cmp_reg_reg(asm_arm_t *as, uint rd, uint rn) {
void asm_arm_less_op(asm_arm_t *as, uint rd, uint rn, uint rm) { void asm_arm_less_op(asm_arm_t *as, uint rd, uint rn, uint rm) {
asm_arm_cmp_reg_reg(as, rn, rm); // cmp rn, rm asm_arm_cmp_reg_reg(as, rn, rm); // cmp rn, rm
emit(as, asm_arm_op_mov_imm(rd, 1) | ARM_CC_LT); // movlt rd, #1 emit(as, asm_arm_op_mov_imm(rd, 1) | ASM_ARM_CC_LT); // movlt rd, #1
emit(as, asm_arm_op_mov_imm(rd, 0) | ARM_CC_GE); // movge rd, #0 emit(as, asm_arm_op_mov_imm(rd, 0) | ASM_ARM_CC_GE); // movge rd, #0
} }
void asm_arm_add_reg(asm_arm_t *as, uint rd, uint rn, uint rm) { void asm_arm_add_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
...@@ -300,13 +305,13 @@ void asm_arm_add_reg(asm_arm_t *as, uint rd, uint rn, uint rm) { ...@@ -300,13 +305,13 @@ void asm_arm_add_reg(asm_arm_t *as, uint rd, uint rn, uint rm) {
void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num) { void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num) {
// add rd, sp, #local_num*4 // add rd, sp, #local_num*4
emit_al(as, asm_arm_op_add_imm(rd, REG_SP, local_num << 2)); emit_al(as, asm_arm_op_add_imm(rd, ASM_ARM_REG_SP, local_num << 2));
} }
void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label) { void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label) {
assert(label < as->max_num_labels); assert(label < as->max_num_labels);
int dest = as->label_offsets[label]; mp_uint_t dest = as->label_offsets[label];
int rel = dest - as->code_offset; mp_int_t rel = dest - as->code_offset;
rel -= 8; // account for instruction prefetch, PC is 8 bytes ahead of this instruction rel -= 8; // account for instruction prefetch, PC is 8 bytes ahead of this instruction
rel >>= 2; // in ARM mode the branch target is 32-bit aligned, so the 2 LSB are omitted rel >>= 2; // in ARM mode the branch target is 32-bit aligned, so the 2 LSB are omitted
...@@ -318,21 +323,21 @@ void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label) { ...@@ -318,21 +323,21 @@ void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label) {
} }
void asm_arm_b_label(asm_arm_t *as, uint label) { void asm_arm_b_label(asm_arm_t *as, uint label) {
asm_arm_bcc_label(as, ARM_CC_AL, label); asm_arm_bcc_label(as, ASM_ARM_CC_AL, label);
} }
void asm_arm_bl_ind(asm_arm_t *as, void *fun_ptr, uint fun_id, uint reg_temp) { void asm_arm_bl_ind(asm_arm_t *as, void *fun_ptr, uint fun_id, uint reg_temp) {
// If the table offset fits into the ldr instruction // If the table offset fits into the ldr instruction
if(fun_id < (0x1000 / 4)) { if(fun_id < (0x1000 / 4)) {
emit_al(as, asm_arm_op_mov_reg(REG_LR, REG_PC)); // mov lr, pc emit_al(as, asm_arm_op_mov_reg(ASM_ARM_REG_LR, ASM_ARM_REG_PC)); // mov lr, pc
emit_al(as, 0x597f000 | (fun_id << 2)); // ldr pc, [r7, #fun_id*4] emit_al(as, 0x597f000 | (fun_id << 2)); // ldr pc, [r7, #fun_id*4]
return; return;
} }
emit_al(as, 0x59f0004 | (reg_temp << 12)); // ldr rd, [pc, #4] emit_al(as, 0x59f0004 | (reg_temp << 12)); // ldr rd, [pc, #4]
// Set lr after fun_ptr // Set lr after fun_ptr
emit_al(as, asm_arm_op_add_imm(REG_LR, REG_PC, 4)); // add lr, pc, #4 emit_al(as, asm_arm_op_add_imm(ASM_ARM_REG_LR, ASM_ARM_REG_PC, 4)); // add lr, pc, #4
emit_al(as, asm_arm_op_mov_reg(REG_PC, reg_temp)); // mov pc, reg_temp emit_al(as, asm_arm_op_mov_reg(ASM_ARM_REG_PC, reg_temp)); // mov pc, reg_temp
emit(as, (uint) fun_ptr); emit(as, (uint) fun_ptr);
} }
......
...@@ -28,41 +28,41 @@ ...@@ -28,41 +28,41 @@
#define ASM_ARM_PASS_COMPUTE (1) #define ASM_ARM_PASS_COMPUTE (1)
#define ASM_ARM_PASS_EMIT (2) #define ASM_ARM_PASS_EMIT (2)
#define REG_R0 (0) #define ASM_ARM_REG_R0 (0)
#define REG_R1 (1) #define ASM_ARM_REG_R1 (1)
#define REG_R2 (2) #define ASM_ARM_REG_R2 (2)
#define REG_R3 (3) #define ASM_ARM_REG_R3 (3)
#define REG_R4 (4) #define ASM_ARM_REG_R4 (4)
#define REG_R5 (5) #define ASM_ARM_REG_R5 (5)
#define REG_R6 (6) #define ASM_ARM_REG_R6 (6)
#define REG_R7 (7) #define ASM_ARM_REG_R7 (7)
#define REG_R8 (8) #define ASM_ARM_REG_R8 (8)
#define REG_R9 (9) #define ASM_ARM_REG_R9 (9)
#define REG_R10 (10) #define ASM_ARM_REG_R10 (10)
#define REG_R11 (11) #define ASM_ARM_REG_R11 (11)
#define REG_R12 (12) #define ASM_ARM_REG_R12 (12)
#define REG_R13 (13) #define ASM_ARM_REG_R13 (13)
#define REG_R14 (14) #define ASM_ARM_REG_R14 (14)
#define REG_R15 (15) #define ASM_ARM_REG_R15 (15)
#define REG_SP (REG_R13) #define ASM_ARM_REG_SP (ASM_ARM_REG_R13)
#define REG_LR (REG_R14) #define ASM_ARM_REG_LR (ASM_ARM_REG_R14)
#define REG_PC (REG_R15) #define ASM_ARM_REG_PC (ASM_ARM_REG_R15)
#define ARM_CC_EQ (0x0 << 28) #define ASM_ARM_CC_EQ (0x0 << 28)
#define ARM_CC_NE (0x1 << 28) #define ASM_ARM_CC_NE (0x1 << 28)
#define ARM_CC_CS (0x2 << 28) #define ASM_ARM_CC_CS (0x2 << 28)
#define ARM_CC_CC (0x3 << 28) #define ASM_ARM_CC_CC (0x3 << 28)
#define ARM_CC_MI (0x4 << 28) #define ASM_ARM_CC_MI (0x4 << 28)
#define ARM_CC_PL (0x5 << 28) #define ASM_ARM_CC_PL (0x5 << 28)
#define ARM_CC_VS (0x6 << 28) #define ASM_ARM_CC_VS (0x6 << 28)
#define ARM_CC_VC (0x7 << 28) #define ASM_ARM_CC_VC (0x7 << 28)
#define ARM_CC_HI (0x8 << 28) #define ASM_ARM_CC_HI (0x8 << 28)
#define ARM_CC_LS (0x9 << 28) #define ASM_ARM_CC_LS (0x9 << 28)
#define ARM_CC_GE (0xa << 28) #define ASM_ARM_CC_GE (0xa << 28)
#define ARM_CC_LT (0xb << 28) #define ASM_ARM_CC_LT (0xb << 28)
#define ARM_CC_GT (0xc << 28) #define ASM_ARM_CC_GT (0xc << 28)
#define ARM_CC_LE (0xd << 28) #define ASM_ARM_CC_LE (0xd << 28)
#define ARM_CC_AL (0xe << 28) #define ASM_ARM_CC_AL (0xe << 28)
typedef struct _asm_arm_t asm_arm_t; typedef struct _asm_arm_t asm_arm_t;
......
...@@ -68,18 +68,7 @@ void asm_thumb_free(asm_thumb_t *as, bool free_code) { ...@@ -68,18 +68,7 @@ void asm_thumb_free(asm_thumb_t *as, bool free_code) {
if (free_code) { if (free_code) {
MP_PLAT_FREE_EXEC(as->code_base, as->code_size); MP_PLAT_FREE_EXEC(as->code_base, as->code_size);
} }
/* m_del(mp_uint_t, as->label_offsets, as->max_num_labels);
if (as->label != NULL) {
int i;
for (i = 0; i < as->label->len; ++i)
{
Label *lab = &g_array_index(as->label, Label, i);
if (lab->unresolved != NULL)
g_array_free(lab->unresolved, true);
}
g_array_free(as->label, true);
}
*/
m_del_obj(asm_thumb_t, as); m_del_obj(asm_thumb_t, as);
} }
...@@ -284,23 +273,23 @@ void asm_thumb_op32(asm_thumb_t *as, uint op1, uint op2) { ...@@ -284,23 +273,23 @@ void asm_thumb_op32(asm_thumb_t *as, uint op1, uint op2) {
#define OP_FORMAT_2(op, rlo_dest, rlo_src, src_b) ((op) | ((src_b) << 6) | ((rlo_src) << 3) | (rlo_dest)) #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) { 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); assert(rlo_dest < ASM_THUMB_REG_R8);
assert(rlo_src < REG_R8); assert(rlo_src < ASM_THUMB_REG_R8);
asm_thumb_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b)); 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)) #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) { void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) {
assert(rlo < REG_R8); assert(rlo < ASM_THUMB_REG_R8);
asm_thumb_op16(as, OP_FORMAT_3(op, rlo, i8)); 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)) #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) { void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src) {
assert(rlo_dest < REG_R8); assert(rlo_dest < ASM_THUMB_REG_R8);
assert(rlo_src < REG_R8); assert(rlo_src < ASM_THUMB_REG_R8);
asm_thumb_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src)); asm_thumb_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src));
} }
...@@ -331,7 +320,7 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { ...@@ -331,7 +320,7 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) {
// if loading lo half with movw, the i16 value will be zero extended into the r32 register! // 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) { 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); assert(reg_dest < ASM_THUMB_REG_R15);
// mov[wt] reg_dest, #i16_src // 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)); asm_thumb_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff));
} }
...@@ -409,14 +398,14 @@ void asm_thumb_mov_reg_i32_aligned(asm_thumb_t *as, uint reg_dest, int i32) { ...@@ -409,14 +398,14 @@ void asm_thumb_mov_reg_i32_aligned(asm_thumb_t *as, uint reg_dest, int i32) {
#define OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset) (0x9800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff)) #define OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset) (0x9800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num, uint rlo_src) { void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num, uint rlo_src) {
assert(rlo_src < REG_R8); assert(rlo_src < ASM_THUMB_REG_R8);
int word_offset = local_num; int word_offset = local_num;
assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0); assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset)); asm_thumb_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset));
} }
void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) { void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) {
assert(rlo_dest < REG_R8); assert(rlo_dest < ASM_THUMB_REG_R8);
int word_offset = local_num; int word_offset = local_num;
assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0); assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset)); asm_thumb_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset));
...@@ -425,7 +414,7 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) { ...@@ -425,7 +414,7 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) {
#define OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset) (0xa800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff)) #define OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset) (0xa800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num) { void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num) {
assert(rlo_dest < REG_R8); assert(rlo_dest < ASM_THUMB_REG_R8);
int word_offset = local_num; int word_offset = local_num;
assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0); assert(as->pass < ASM_THUMB_PASS_EMIT || word_offset >= 0);
asm_thumb_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset)); asm_thumb_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset));
...@@ -439,7 +428,7 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) { ...@@ -439,7 +428,7 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) {
mp_uint_t dest = get_label_dest(as, label); mp_uint_t dest = get_label_dest(as, label);
mp_int_t 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 != -1 && 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
// calculate rel assuming 12 bit relative jump // calculate rel assuming 12 bit relative jump
if (SIGNED_FIT12(rel)) { if (SIGNED_FIT12(rel)) {
...@@ -462,7 +451,7 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) { ...@@ -462,7 +451,7 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) {
mp_uint_t dest = get_label_dest(as, label); mp_uint_t dest = get_label_dest(as, label);
mp_int_t 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 != -1 && 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
// calculate rel assuming 9 bit relative jump // calculate rel assuming 9 bit relative jump
if (SIGNED_FIT9(rel)) { if (SIGNED_FIT9(rel)) {
...@@ -482,17 +471,17 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) { ...@@ -482,17 +471,17 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) {
void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp) { void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp) {
/* TODO make this use less bytes /* TODO make this use less bytes
uint rlo_base = REG_R3; uint rlo_base = ASM_THUMB_REG_R3;
uint rlo_dest = REG_R7; uint rlo_dest = ASM_THUMB_REG_R7;
uint word_offset = 4; uint word_offset = 4;
asm_thumb_op16(as, 0x0000); asm_thumb_op16(as, 0x0000);
asm_thumb_op16(as, 0x6800 | (word_offset << 6) | (rlo_base << 3) | rlo_dest); // ldr rlo_dest, [rlo_base, #offset] asm_thumb_op16(as, 0x6800 | (word_offset << 6) | (rlo_base << 3) | rlo_dest); // ldr rlo_dest, [rlo_base, #offset]
asm_thumb_op16(as, 0x4780 | (REG_R9 << 3)); // blx reg asm_thumb_op16(as, 0x4780 | (ASM_THUMB_REG_R9 << 3)); // blx reg
*/ */
if (fun_id < 32) { if (fun_id < 32) {
// load ptr to function from table, indexed by fun_id (must be in range 0-31); 4 bytes // 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, REG_R7, fun_id)); 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, OP_BLX(reg_temp)); asm_thumb_op16(as, OP_BLX(reg_temp));
} else { } else {
// load ptr to function into register using immediate; 6 bytes // load ptr to function into register using immediate; 6 bytes
......
...@@ -27,38 +27,38 @@ ...@@ -27,38 +27,38 @@
#define ASM_THUMB_PASS_COMPUTE (1) #define ASM_THUMB_PASS_COMPUTE (1)
#define ASM_THUMB_PASS_EMIT (2) #define ASM_THUMB_PASS_EMIT (2)
#define REG_R0 (0) #define ASM_THUMB_REG_R0 (0)
#define REG_R1 (1) #define ASM_THUMB_REG_R1 (1)
#define REG_R2 (2) #define ASM_THUMB_REG_R2 (2)
#define REG_R3 (3) #define ASM_THUMB_REG_R3 (3)
#define REG_R4 (4) #define ASM_THUMB_REG_R4 (4)
#define REG_R5 (5) #define ASM_THUMB_REG_R5 (5)
#define REG_R6 (6) #define ASM_THUMB_REG_R6 (6)
#define REG_R7 (7) #define ASM_THUMB_REG_R7 (7)
#define REG_R8 (8) #define ASM_THUMB_REG_R8 (8)
#define REG_R9 (9) #define ASM_THUMB_REG_R9 (9)
#define REG_R10 (10) #define ASM_THUMB_REG_R10 (10)
#define REG_R11 (11) #define ASM_THUMB_REG_R11 (11)
#define REG_R12 (12) #define ASM_THUMB_REG_R12 (12)
#define REG_R13 (13) #define ASM_THUMB_REG_R13 (13)
#define REG_R14 (14) #define ASM_THUMB_REG_R14 (14)
#define REG_R15 (15) #define ASM_THUMB_REG_R15 (15)
#define REG_LR (REG_R14) #define ASM_THUMB_REG_LR (REG_R14)
#define THUMB_CC_EQ (0x0) #define ASM_THUMB_CC_EQ (0x0)
#define THUMB_CC_NE (0x1) #define ASM_THUMB_CC_NE (0x1)
#define THUMB_CC_CS (0x2) #define ASM_THUMB_CC_CS (0x2)
#define THUMB_CC_CC (0x3) #define ASM_THUMB_CC_CC (0x3)
#define THUMB_CC_MI (0x4) #define ASM_THUMB_CC_MI (0x4)
#define THUMB_CC_PL (0x5) #define ASM_THUMB_CC_PL (0x5)
#define THUMB_CC_VS (0x6) #define ASM_THUMB_CC_VS (0x6)
#define THUMB_CC_VC (0x7) #define ASM_THUMB_CC_VC (0x7)
#define THUMB_CC_HI (0x8) #define ASM_THUMB_CC_HI (0x8)
#define THUMB_CC_LS (0x9) #define ASM_THUMB_CC_LS (0x9)
#define THUMB_CC_GE (0xa) #define ASM_THUMB_CC_GE (0xa)
#define THUMB_CC_LT (0xb) #define ASM_THUMB_CC_LT (0xb)
#define THUMB_CC_GT (0xc) #define ASM_THUMB_CC_GT (0xc)
#define THUMB_CC_LE (0xd) #define ASM_THUMB_CC_LE (0xd)
typedef struct _asm_thumb_t asm_thumb_t; typedef struct _asm_thumb_t asm_thumb_t;
......
...@@ -114,17 +114,17 @@ struct _asm_x64_t { ...@@ -114,17 +114,17 @@ struct _asm_x64_t {
byte *code_base; byte *code_base;
byte dummy_data[8]; byte dummy_data[8];
uint max_num_labels; mp_uint_t max_num_labels;
int *label_offsets; mp_uint_t *label_offsets;
int num_locals; int num_locals;
}; };
asm_x64_t *asm_x64_new(uint max_num_labels) { asm_x64_t *asm_x64_new(mp_uint_t max_num_labels) {
asm_x64_t *as; asm_x64_t *as;
as = m_new0(asm_x64_t, 1); as = m_new0(asm_x64_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;
} }
...@@ -133,18 +133,7 @@ void asm_x64_free(asm_x64_t *as, bool free_code) { ...@@ -133,18 +133,7 @@ void asm_x64_free(asm_x64_t *as, bool free_code) {
if (free_code) { if (free_code) {
MP_PLAT_FREE_EXEC(as->code_base, as->code_size); MP_PLAT_FREE_EXEC(as->code_base, as->code_size);
} }
/* m_del(mp_uint_t, as->label_offsets, as->max_num_labels);
if (as->label != NULL) {
int i;
for (i = 0; i < as->label->len; ++i)
{
Label* lab = &g_array_index(as->label, Label, i);
if (lab->unresolved != NULL)
g_array_free(lab->unresolved, true);
}
g_array_free(as->label, true);
}
*/
m_del_obj(asm_x64_t, as); m_del_obj(asm_x64_t, as);
} }
...@@ -153,7 +142,7 @@ void asm_x64_start_pass(asm_x64_t *as, uint pass) { ...@@ -153,7 +142,7 @@ void asm_x64_start_pass(asm_x64_t *as, uint pass) {
as->code_offset = 0; as->code_offset = 0;
if (pass == ASM_X64_PASS_COMPUTE) { if (pass == ASM_X64_PASS_COMPUTE) {
// reset all labels // reset all labels
memset(as->label_offsets, -1, as->max_num_labels * sizeof(int)); memset(as->label_offsets, -1, as->max_num_labels * sizeof(mp_uint_t));
} }
} }
...@@ -192,7 +181,7 @@ STATIC byte *asm_x64_get_cur_to_write_bytes(asm_x64_t *as, int num_bytes_to_writ ...@@ -192,7 +181,7 @@ STATIC byte *asm_x64_get_cur_to_write_bytes(asm_x64_t *as, int num_bytes_to_writ
} }
} }
uint asm_x64_get_code_size(asm_x64_t *as) { mp_uint_t asm_x64_get_code_size(asm_x64_t *as) {
return as->code_size; return as->code_size;
} }
...@@ -252,9 +241,9 @@ STATIC void asm_x64_write_word32_to(asm_x64_t *as, int offset, int w32) { ...