Commit 36db6bcf authored by Damien George's avatar Damien George
Browse files

py, compiler: Improve passes; add an extra pass for native emitter.

parent ca25c15d
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#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 {
int pass; uint pass;
uint code_offset; uint code_offset;
uint code_size; uint code_size;
byte *code_base; byte *code_base;
...@@ -58,14 +58,9 @@ struct _asm_thumb_t { ...@@ -58,14 +58,9 @@ struct _asm_thumb_t {
asm_thumb_t *asm_thumb_new(uint max_num_labels) { asm_thumb_t *asm_thumb_new(uint max_num_labels) {
asm_thumb_t *as; asm_thumb_t *as;
as = m_new(asm_thumb_t, 1); as = m_new0(asm_thumb_t, 1);
as->pass = 0;
as->code_offset = 0;
as->code_size = 0;
as->code_base = NULL;
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(int, max_num_labels);
as->num_locals = 0;
return as; return as;
} }
...@@ -89,16 +84,16 @@ void asm_thumb_free(asm_thumb_t *as, bool free_code) { ...@@ -89,16 +84,16 @@ void asm_thumb_free(asm_thumb_t *as, bool free_code) {
m_del_obj(asm_thumb_t, as); m_del_obj(asm_thumb_t, as);
} }
void asm_thumb_start_pass(asm_thumb_t *as, int pass) { 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_2) { 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(int));
} }
} }
void asm_thumb_end_pass(asm_thumb_t *as) { void asm_thumb_end_pass(asm_thumb_t *as) {
if (as->pass == ASM_THUMB_PASS_2) { if (as->pass == ASM_THUMB_PASS_COMPUTE) {
// calculate size of code in bytes // calculate size of code in bytes
as->code_size = as->code_offset; as->code_size = as->code_offset;
as->code_base = m_new(byte, as->code_size); as->code_base = m_new(byte, as->code_size);
...@@ -120,7 +115,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) { ...@@ -120,7 +115,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) {
// all functions must go through this one to emit bytes // all functions must go through this one to emit bytes
STATIC byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int num_bytes_to_write) { STATIC byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int num_bytes_to_write) {
//printf("emit %d\n", num_bytes_to_write); //printf("emit %d\n", num_bytes_to_write);
if (as->pass < ASM_THUMB_PASS_3) { if (as->pass < ASM_THUMB_PASS_EMIT) {
as->code_offset += num_bytes_to_write; as->code_offset += num_bytes_to_write;
return as->dummy_data; return as->dummy_data;
} else { } else {
...@@ -224,12 +219,12 @@ void asm_thumb_exit(asm_thumb_t *as) { ...@@ -224,12 +219,12 @@ void asm_thumb_exit(asm_thumb_t *as) {
void asm_thumb_label_assign(asm_thumb_t *as, uint label) { void asm_thumb_label_assign(asm_thumb_t *as, uint label) {
assert(label < as->max_num_labels); assert(label < as->max_num_labels);
if (as->pass == ASM_THUMB_PASS_2) { if (as->pass < ASM_THUMB_PASS_EMIT) {
// assign label offset // assign label offset
assert(as->label_offsets[label] == -1); assert(as->label_offsets[label] == -1);
as->label_offsets[label] = as->code_offset; as->label_offsets[label] = as->code_offset;
} else if (as->pass == ASM_THUMB_PASS_3) { } else {
// ensure label offset has not changed from PASS_2 to PASS_3 // ensure label offset has not changed from PASS_COMPUTE to PASS_EMIT
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset); //printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
assert(as->label_offsets[label] == as->code_offset); assert(as->label_offsets[label] == as->code_offset);
} }
...@@ -383,20 +378,35 @@ void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) { ...@@ -383,20 +378,35 @@ void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) {
} }
} }
// i32 is stored as a full word in the code, and aligned to machine-word boundary
// TODO this is very inefficient, improve it!
void asm_thumb_mov_reg_i32_aligned(asm_thumb_t *as, uint reg_dest, int i32) {
// align on machine-word + 2
if ((as->code_offset & 3) == 0) {
asm_thumb_op16(as, ASM_THUMB_OP_NOP);
}
// jump over the i32 value (instruction prefect adds 4 to PC)
asm_thumb_op16(as, OP_B_N(0));
// store i32 on machine-word aligned boundary
asm_thumb_data(as, 4, i32);
// do the actual load of the i32 value
asm_thumb_mov_reg_i32_optimised(as, reg_dest, i32);
}
#define OP_STR_TO_SP_OFFSET(rlo_dest, word_offset) (0x9000 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff)) #define OP_STR_TO_SP_OFFSET(rlo_dest, word_offset) (0x9000 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
#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 < REG_R8);
int word_offset = as->num_locals - local_num - 1; int word_offset = as->num_locals - local_num - 1;
assert(as->pass < ASM_THUMB_PASS_3 || 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 < REG_R8);
int word_offset = as->num_locals - local_num - 1; int word_offset = as->num_locals - local_num - 1;
assert(as->pass < ASM_THUMB_PASS_3 || 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));
} }
...@@ -405,7 +415,7 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) { ...@@ -405,7 +415,7 @@ void asm_thumb_mov_reg_local(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) { 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 < REG_R8);
int word_offset = as->num_locals - local_num - 1; int word_offset = as->num_locals - local_num - 1;
assert(as->pass < ASM_THUMB_PASS_3 || 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));
} }
......
...@@ -24,9 +24,8 @@ ...@@ -24,9 +24,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#define ASM_THUMB_PASS_1 (1) #define ASM_THUMB_PASS_COMPUTE (1)
#define ASM_THUMB_PASS_2 (2) #define ASM_THUMB_PASS_EMIT (2)
#define ASM_THUMB_PASS_3 (3)
#define REG_R0 (0) #define REG_R0 (0)
#define REG_R1 (1) #define REG_R1 (1)
...@@ -71,7 +70,7 @@ typedef struct _asm_thumb_t asm_thumb_t; ...@@ -71,7 +70,7 @@ typedef struct _asm_thumb_t asm_thumb_t;
asm_thumb_t *asm_thumb_new(uint max_num_labels); asm_thumb_t *asm_thumb_new(uint max_num_labels);
void asm_thumb_free(asm_thumb_t *as, bool free_code); void asm_thumb_free(asm_thumb_t *as, bool free_code);
void asm_thumb_start_pass(asm_thumb_t *as, int pass); void asm_thumb_start_pass(asm_thumb_t *as, uint pass);
void asm_thumb_end_pass(asm_thumb_t *as); void asm_thumb_end_pass(asm_thumb_t *as);
uint asm_thumb_get_code_size(asm_thumb_t *as); uint asm_thumb_get_code_size(asm_thumb_t *as);
void *asm_thumb_get_code(asm_thumb_t *as); void *asm_thumb_get_code(asm_thumb_t *as);
...@@ -188,6 +187,7 @@ void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label); ...@@ -188,6 +187,7 @@ void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label);
void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, machine_uint_t i32_src); // convenience void asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, machine_uint_t i32_src); // convenience
void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32_src); // convenience void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32_src); // convenience
void asm_thumb_mov_reg_i32_aligned(asm_thumb_t *as, uint reg_dest, int i32); // convenience
void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num_dest, uint rlo_src); // convenience void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num_dest, uint rlo_src); // convenience
void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience
void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience
......
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
#define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80) #define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)
struct _asm_x64_t { struct _asm_x64_t {
int pass; uint pass;
uint code_offset; uint code_offset;
uint code_size; uint code_size;
byte *code_base; byte *code_base;
...@@ -138,14 +138,9 @@ void *alloc_mem(uint req_size, uint *alloc_size, bool is_exec) { ...@@ -138,14 +138,9 @@ void *alloc_mem(uint req_size, uint *alloc_size, bool is_exec) {
asm_x64_t *asm_x64_new(uint max_num_labels) { asm_x64_t *asm_x64_new(uint max_num_labels) {
asm_x64_t *as; asm_x64_t *as;
as = m_new(asm_x64_t, 1); as = m_new0(asm_x64_t, 1);
as->pass = 0;
as->code_offset = 0;
as->code_size = 0;
as->code_base = NULL;
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(int, max_num_labels);
as->num_locals = 0;
return as; return as;
} }
...@@ -170,17 +165,17 @@ void asm_x64_free(asm_x64_t *as, bool free_code) { ...@@ -170,17 +165,17 @@ void asm_x64_free(asm_x64_t *as, bool free_code) {
m_del_obj(asm_x64_t, as); m_del_obj(asm_x64_t, as);
} }
void asm_x64_start_pass(asm_x64_t *as, int pass) { void asm_x64_start_pass(asm_x64_t *as, uint pass) {
as->pass = pass; as->pass = pass;
as->code_offset = 0; as->code_offset = 0;
if (pass == ASM_X64_PASS_2) { 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(int));
} }
} }
void asm_x64_end_pass(asm_x64_t *as) { void asm_x64_end_pass(asm_x64_t *as) {
if (as->pass == ASM_X64_PASS_2) { if (as->pass == ASM_X64_PASS_COMPUTE) {
// calculate size of code in bytes // calculate size of code in bytes
as->code_size = as->code_offset; as->code_size = as->code_offset;
//as->code_base = m_new(byte, as->code_size); need to allocale executable memory //as->code_base = m_new(byte, as->code_size); need to allocale executable memory
...@@ -204,7 +199,7 @@ void asm_x64_end_pass(asm_x64_t *as) { ...@@ -204,7 +199,7 @@ void asm_x64_end_pass(asm_x64_t *as) {
// all functions must go through this one to emit bytes // all functions must go through this one to emit bytes
STATIC byte *asm_x64_get_cur_to_write_bytes(asm_x64_t *as, int num_bytes_to_write) { STATIC byte *asm_x64_get_cur_to_write_bytes(asm_x64_t *as, int num_bytes_to_write) {
//printf("emit %d\n", num_bytes_to_write); //printf("emit %d\n", num_bytes_to_write);
if (as->pass < ASM_X64_PASS_3) { if (as->pass < ASM_X64_PASS_EMIT) {
as->code_offset += num_bytes_to_write; as->code_offset += num_bytes_to_write;
return as->dummy_data; return as->dummy_data;
} else { } else {
...@@ -367,6 +362,15 @@ void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r ...@@ -367,6 +362,15 @@ void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r
} }
} }
// src_i64 is stored as a full word in the code, and aligned to machine-word boundary
void asm_x64_mov_i64_to_r64_aligned(asm_x64_t *as, int64_t src_i64, int dest_r64) {
// mov instruction uses 2 bytes for the instruction, before the i64
while (((as->code_offset + 2) & (WORD_SIZE - 1)) != 0) {
asm_x64_nop(as);
}
asm_x64_mov_i64_to_r64(as, src_i64, dest_r64);
}
void asm_x64_mov_i32_to_disp(asm_x64_t *as, int src_i32, int dest_r32, int dest_disp) void asm_x64_mov_i32_to_disp(asm_x64_t *as, int src_i32, int dest_r32, int dest_disp)
{ {
assert(0); assert(0);
...@@ -487,12 +491,12 @@ void asm_x64_setcc_r8(asm_x64_t *as, int jcc_type, int dest_r8) { ...@@ -487,12 +491,12 @@ void asm_x64_setcc_r8(asm_x64_t *as, int jcc_type, int dest_r8) {
void asm_x64_label_assign(asm_x64_t *as, int label) { void asm_x64_label_assign(asm_x64_t *as, int label) {
assert(label < as->max_num_labels); assert(label < as->max_num_labels);
if (as->pass == ASM_X64_PASS_2) { if (as->pass < ASM_X64_PASS_EMIT) {
// assign label offset // assign label offset
assert(as->label_offsets[label] == -1); assert(as->label_offsets[label] == -1);
as->label_offsets[label] = as->code_offset; as->label_offsets[label] = as->code_offset;
} else if (as->pass == ASM_X64_PASS_3) { } else {
// ensure label offset has not changed from PASS_2 to PASS_3 // ensure label offset has not changed from PASS_COMPUTE to PASS_EMIT
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset); //printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
assert(as->label_offsets[label] == as->code_offset); assert(as->label_offsets[label] == as->code_offset);
} }
......
...@@ -24,9 +24,8 @@ ...@@ -24,9 +24,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#define ASM_X64_PASS_1 (1) #define ASM_X64_PASS_COMPUTE (1)
#define ASM_X64_PASS_2 (2) #define ASM_X64_PASS_EMIT (2)
#define ASM_X64_PASS_3 (3)
#define REG_RAX (0) #define REG_RAX (0)
#define REG_RCX (1) #define REG_RCX (1)
...@@ -54,7 +53,7 @@ typedef struct _asm_x64_t asm_x64_t; ...@@ -54,7 +53,7 @@ typedef struct _asm_x64_t asm_x64_t;
asm_x64_t* asm_x64_new(uint max_num_labels); asm_x64_t* asm_x64_new(uint max_num_labels);
void asm_x64_free(asm_x64_t* as, bool free_code); void asm_x64_free(asm_x64_t* as, bool free_code);
void asm_x64_start_pass(asm_x64_t *as, int pass); void asm_x64_start_pass(asm_x64_t *as, uint pass);
void asm_x64_end_pass(asm_x64_t *as); void asm_x64_end_pass(asm_x64_t *as);
uint asm_x64_get_code_size(asm_x64_t* as); uint asm_x64_get_code_size(asm_x64_t* as);
void* asm_x64_get_code(asm_x64_t* as); void* asm_x64_get_code(asm_x64_t* as);
...@@ -71,6 +70,7 @@ void asm_x64_mov_i32_to_r64(asm_x64_t* as, int src_i32, int dest_r64); ...@@ -71,6 +70,7 @@ void asm_x64_mov_i32_to_r64(asm_x64_t* as, int src_i32, int dest_r64);
void asm_x64_mov_i64_to_r64(asm_x64_t* as, int64_t src_i64, int dest_r64); void asm_x64_mov_i64_to_r64(asm_x64_t* as, int64_t src_i64, int dest_r64);
void asm_x64_mov_i32_to_disp(asm_x64_t* as, int src_i32, int dest_r32, int dest_disp); void asm_x64_mov_i32_to_disp(asm_x64_t* as, int src_i32, int dest_r32, int dest_disp);
void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r64); void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r64);
void asm_x64_mov_i64_to_r64_aligned(asm_x64_t *as, int64_t src_i64, int dest_r64);
void asm_x64_xor_r64_to_r64(asm_x64_t *as, int src_r64, int dest_r64); void asm_x64_xor_r64_to_r64(asm_x64_t *as, int src_r64, int dest_r64);
void asm_x64_add_r64_to_r64(asm_x64_t* as, int src_r64, int dest_r64); void asm_x64_add_r64_to_r64(asm_x64_t* as, int src_r64, int dest_r64);
void asm_x64_add_i32_to_r32(asm_x64_t* as, int src_i32, int dest_r32); void asm_x64_add_i32_to_r32(asm_x64_t* as, int src_i32, int dest_r32);
......
...@@ -994,7 +994,7 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) { ...@@ -994,7 +994,7 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) {
// leaves function object on stack // leaves function object on stack
// returns function name // returns function name
qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) { qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this function // create a new scope for this function
scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (mp_parse_node_t)pns, emit_options); scope_t *s = scope_new_and_link(comp, SCOPE_FUNCTION, (mp_parse_node_t)pns, emit_options);
// store the function scope so the compiling function can use it at each pass // store the function scope so the compiling function can use it at each pass
...@@ -1043,7 +1043,7 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint ...@@ -1043,7 +1043,7 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
// leaves class object on stack // leaves class object on stack
// returns class name // returns class name
qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) { qstr compile_classdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint emit_options) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this class // create a new scope for this class
scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (mp_parse_node_t)pns, emit_options); scope_t *s = scope_new_and_link(comp, SCOPE_CLASS, (mp_parse_node_t)pns, emit_options);
// store the class scope so the compiling function can use it at each pass // store the class scope so the compiling function can use it at each pass
...@@ -1510,7 +1510,7 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) { ...@@ -1510,7 +1510,7 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
} }
void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) { if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
scope_declare_global(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); scope_declare_global(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
} else { } else {
...@@ -1524,7 +1524,7 @@ void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { ...@@ -1524,7 +1524,7 @@ void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
} }
void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) { if (MP_PARSE_NODE_IS_LEAF(pns->nodes[0])) {
scope_declare_nonlocal(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); scope_declare_nonlocal(comp->scope_cur, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]));
} else { } else {
...@@ -2056,7 +2056,7 @@ void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { ...@@ -2056,7 +2056,7 @@ void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1], PN_trailer_paren) && MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1], PN_trailer_paren)
&& MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[2]) && MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[2])
) { ) {
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
qstr const_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); qstr const_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
if (!MP_PARSE_NODE_IS_SMALL_INT(((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1])->nodes[0])) { if (!MP_PARSE_NODE_IS_SMALL_INT(((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1])->nodes[0])) {
...@@ -2153,7 +2153,7 @@ void compile_lambdef(compiler_t *comp, mp_parse_node_struct_t *pns) { ...@@ -2153,7 +2153,7 @@ void compile_lambdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
//mp_parse_node_t pn_params = pns->nodes[0]; //mp_parse_node_t pn_params = pns->nodes[0];
//mp_parse_node_t pn_body = pns->nodes[1]; //mp_parse_node_t pn_body = pns->nodes[1];
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this lambda // create a new scope for this lambda
scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (mp_parse_node_t)pns, comp->scope_cur->emit_options); scope_t *s = scope_new_and_link(comp, SCOPE_LAMBDA, (mp_parse_node_t)pns, comp->scope_cur->emit_options);
// store the lambda scope so the compiling function (this one) can use it at each pass // store the lambda scope so the compiling function (this one) can use it at each pass
...@@ -2499,7 +2499,7 @@ void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_ ...@@ -2499,7 +2499,7 @@ void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_
assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for)); assert(MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_comp_for));
mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1]; mp_parse_node_struct_t *pns_comp_for = (mp_parse_node_struct_t*)pns->nodes[1];
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// create a new scope for this comprehension // create a new scope for this comprehension
scope_t *s = scope_new_and_link(comp, kind, (mp_parse_node_t)pns, comp->scope_cur->emit_options); scope_t *s = scope_new_and_link(comp, kind, (mp_parse_node_t)pns, comp->scope_cur->emit_options);
// store the comprehension scope so the compiling function (this one) can use it at each pass // store the comprehension scope so the compiling function (this one) can use it at each pass
...@@ -3020,7 +3020,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { ...@@ -3020,7 +3020,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
comp->next_label = 1; comp->next_label = 1;
EMIT_ARG(start_pass, pass, scope); EMIT_ARG(start_pass, pass, scope);
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
// reset maximum stack sizes in scope // reset maximum stack sizes in scope
// they will be computed in this first pass // they will be computed in this first pass
scope->stack_size = 0; scope->stack_size = 0;
...@@ -3028,7 +3028,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { ...@@ -3028,7 +3028,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
} }
#if MICROPY_EMIT_CPYTHON #if MICROPY_EMIT_CPYTHON
if (comp->pass == PASS_3) { if (comp->pass == MP_PASS_EMIT) {
scope_print_info(scope); scope_print_info(scope);
} }
#endif #endif
...@@ -3053,7 +3053,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { ...@@ -3053,7 +3053,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
// work out number of parameters, keywords and default parameters, and add them to the id_info array // work out number of parameters, keywords and default parameters, and add them to the id_info array
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc) // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
comp->have_star = false; comp->have_star = false;
apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param); apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_param);
} }
...@@ -3073,7 +3073,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { ...@@ -3073,7 +3073,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
// work out number of parameters, keywords and default parameters, and add them to the id_info array // work out number of parameters, keywords and default parameters, and add them to the id_info array
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc) // must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
comp->have_star = false; comp->have_star = false;
apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param); apply_to_single_or_list(comp, pns->nodes[0], PN_varargslist, compile_scope_lambda_param);
} }
...@@ -3104,7 +3104,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { ...@@ -3104,7 +3104,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
#else #else
qstr qstr_arg = MP_QSTR_; qstr qstr_arg = MP_QSTR_;
#endif #endif
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
bool added; bool added;
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added); id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
assert(added); assert(added);
...@@ -3141,7 +3141,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { ...@@ -3141,7 +3141,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn; mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn;
assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef); assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
if (comp->pass == PASS_1) { if (comp->pass == MP_PASS_SCOPE) {
bool added; bool added;
id_info_t *id_info = scope_find_or_add_id(scope, MP_QSTR___class__, &added); id_info_t *id_info = scope_find_or_add_id(scope, MP_QSTR___class__, &added);
assert(added); assert(added);
...@@ -3177,6 +3177,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { ...@@ -3177,6 +3177,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
} }
#if MICROPY_EMIT_INLINE_THUMB #if MICROPY_EMIT_INLINE_THUMB
// requires 3 passes: SCOPE, CODE_SIZE, EMIT
STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) { STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
comp->pass = pass; comp->pass = pass;
comp->scope_cur = scope; comp->scope_cur = scope;
...@@ -3187,7 +3188,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind ...@@ -3187,7 +3188,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
return; return;
} }
if (comp->pass > PASS_1) { if (comp->pass > MP_PASS_SCOPE) {
EMIT_INLINE_ASM_ARG(start_pass, comp->pass, comp->scope_cur); EMIT_INLINE_ASM_ARG(start_pass, comp->pass, comp->scope_cur);
} }
...@@ -3199,7 +3200,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind ...@@ -3199,7 +3200,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
//qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name //qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
// parameters are in pns->nodes[1] // parameters are in pns->nodes[1]
if (comp->pass == PASS_2) { if (comp->pass == MP_PASS_CODE_SIZE) {
mp_parse_node_t *pn_params; mp_parse_node_t *pn_params;
int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params); int n_params = list_get(&pns->nodes[1], PN_typedargslist, &pn_params);
scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, n_params, pn_params); scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, n_params, pn_params);
...@@ -3212,7 +3213,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind ...@@ -3212,7 +3213,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
int num = list_get(&pn_body, PN_suite_block_stmts, &nodes); int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
/* /*
if (comp->pass == PASS_3) { if (comp->pass == MP_PASS_EMIT) {
//printf("----\n"); //printf("----\n");
scope_print_info(scope); scope_print_info(scope);
} }
...@@ -3250,7 +3251,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind ...@@ -3250,7 +3251,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
return; return;
} }
uint lab = comp_next_label(comp); uint lab = comp_next_label(comp);
if (pass > PASS_1) { if (pass > MP_PASS_SCOPE) {
EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0])); EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]));
} }
} else if (op == MP_QSTR_align) { } else if (op == MP_QSTR_align) {
...@@ -3258,7 +3259,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind ...@@ -3258,7 +3259,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
compile_syntax_error(comp, nodes[i], "inline assembler 'align' requires 1 argument"); compile_syntax_error(comp, nodes[i], "inline assembler 'align' requires 1 argument");