Skip to content

Commit 5bfb759

Browse files
committed
Incorporate emit_thumb into new emit framework.
1 parent 6cdd3af commit 5bfb759

5 files changed

Lines changed: 283 additions & 177 deletions

File tree

py/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CC = gcc
2-
CFLAGS = -Wall -ansi -std=gnu99 -Os -DEMIT_ENABLE_CPY -DEMIT_ENABLE_X64 #-DNDEBUG
2+
CFLAGS = -Wall -ansi -std=gnu99 -Os -DEMIT_ENABLE_CPY -DEMIT_ENABLE_X64 -DEMIT_ENABLE_THUMB #-DNDEBUG
33
LDFLAGS =
44

55
SRC = \

py/asmthumb.c

Lines changed: 46 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@ struct _asm_thumb_t {
2828
uint stack_adjust;
2929
};
3030

31-
asm_thumb_t *asm_thumb_new() {
31+
asm_thumb_t *asm_thumb_new(uint max_num_labels) {
3232
asm_thumb_t *as;
3333

3434
as = m_new(asm_thumb_t, 1);
3535
as->pass = 0;
3636
as->code_offset = 0;
3737
as->code_size = 0;
3838
as->code_base = NULL;
39-
as->label_offsets = NULL;
39+
as->max_num_labels = max_num_labels;
40+
as->label_offsets = m_new(int, max_num_labels);
4041
as->num_locals = 0;
4142

4243
return as;
@@ -65,23 +66,13 @@ void asm_thumb_start_pass(asm_thumb_t *as, int pass) {
6566
as->pass = pass;
6667
as->code_offset = 0;
6768
as->next_label = 1;
68-
if (pass == ASM_THUMB_PASS_1) {
69-
as->max_num_labels = 0;
70-
} else {
71-
if (pass == ASM_THUMB_PASS_2) {
72-
memset(as->label_offsets, -1, as->max_num_labels * sizeof(int));
73-
}
69+
if (pass == ASM_THUMB_PASS_2) {
70+
memset(as->label_offsets, -1, as->max_num_labels * sizeof(int));
7471
}
7572
}
7673

7774
void asm_thumb_end_pass(asm_thumb_t *as) {
78-
if (as->pass == ASM_THUMB_PASS_1) {
79-
// calculate number of labels need
80-
if (as->next_label > as->max_num_labels) {
81-
as->max_num_labels = as->next_label;
82-
}
83-
as->label_offsets = m_new(int, as->max_num_labels);
84-
} else if (as->pass == ASM_THUMB_PASS_2) {
75+
if (as->pass == ASM_THUMB_PASS_2) {
8576
// calculate size of code in bytes
8677
as->code_size = as->code_offset;
8778
as->code_base = m_new(byte, as->code_size);
@@ -226,20 +217,23 @@ int asm_thumb_label_new(asm_thumb_t *as) {
226217
}
227218

228219
void asm_thumb_label_assign(asm_thumb_t *as, int label) {
229-
if (as->pass > ASM_THUMB_PASS_1) {
230-
assert(label < as->max_num_labels);
231-
if (as->pass == ASM_THUMB_PASS_2) {
232-
// assign label offset
233-
assert(as->label_offsets[label] == -1);
234-
as->label_offsets[label] = as->code_offset;
235-
} else if (as->pass == ASM_THUMB_PASS_3) {
236-
// ensure label offset has not changed from PASS_2 to PASS_3
237-
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
238-
assert(as->label_offsets[label] == as->code_offset);
239-
}
220+
assert(label < as->max_num_labels);
221+
if (as->pass == ASM_THUMB_PASS_2) {
222+
// assign label offset
223+
assert(as->label_offsets[label] == -1);
224+
as->label_offsets[label] = as->code_offset;
225+
} else if (as->pass == ASM_THUMB_PASS_3) {
226+
// ensure label offset has not changed from PASS_2 to PASS_3
227+
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
228+
assert(as->label_offsets[label] == as->code_offset);
240229
}
241230
}
242231

232+
static int get_label_dest(asm_thumb_t *as, int label) {
233+
assert(label < as->max_num_labels);
234+
return as->label_offsets[label];
235+
}
236+
243237
// the i8 value will be zero extended into the r32 register!
244238
void asm_thumb_mov_reg_i8(asm_thumb_t *as, uint rlo_dest, int i8) {
245239
assert(rlo_dest < REG_R8);
@@ -339,23 +333,21 @@ void asm_thumb_ite_ge(asm_thumb_t *as) {
339333
#define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff))
340334

341335
void asm_thumb_b_label(asm_thumb_t *as, int label) {
342-
if (as->pass > ASM_THUMB_PASS_1) {
343-
int dest = as->label_offsets[label];
344-
int rel = dest - as->code_offset;
345-
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
346-
if (dest >= 0 && rel <= -4) {
347-
// is a backwards jump, so we know the size of the jump on the first pass
348-
// calculate rel assuming 12 bit relative jump
349-
if (SIGNED_FIT12(rel)) {
350-
asm_thumb_write_op16(as, OP_B(rel));
351-
} else {
352-
goto large_jump;
353-
}
336+
int dest = get_label_dest(as, label);
337+
int rel = dest - as->code_offset;
338+
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
339+
if (dest >= 0 && rel <= -4) {
340+
// is a backwards jump, so we know the size of the jump on the first pass
341+
// calculate rel assuming 12 bit relative jump
342+
if (SIGNED_FIT12(rel)) {
343+
asm_thumb_write_op16(as, OP_B(rel));
354344
} else {
355-
// is a forwards jump, so need to assume it's large
356-
large_jump:
357-
asm_thumb_write_op32(as, OP_BW_HI(rel), OP_BW_LO(rel));
345+
goto large_jump;
358346
}
347+
} else {
348+
// is a forwards jump, so need to assume it's large
349+
large_jump:
350+
asm_thumb_write_op32(as, OP_BW_HI(rel), OP_BW_LO(rel));
359351
}
360352
}
361353

@@ -372,23 +364,21 @@ void asm_thumb_cmp_reg_bz_label(asm_thumb_t *as, uint rlo, int label) {
372364
asm_thumb_write_op16(as, OP_CMP_REG_IMM(rlo, 0));
373365

374366
// branch if equal
375-
if (as->pass > ASM_THUMB_PASS_1) {
376-
int dest = as->label_offsets[label];
377-
int rel = dest - as->code_offset;
378-
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
379-
if (dest >= 0 && rel <= -4) {
380-
// is a backwards jump, so we know the size of the jump on the first pass
381-
// calculate rel assuming 12 bit relative jump
382-
if (SIGNED_FIT9(rel)) {
383-
asm_thumb_write_op16(as, OP_BEQ(rel));
384-
} else {
385-
goto large_jump;
386-
}
367+
int dest = get_label_dest(as, label);
368+
int rel = dest - as->code_offset;
369+
rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction
370+
if (dest >= 0 && rel <= -4) {
371+
// is a backwards jump, so we know the size of the jump on the first pass
372+
// calculate rel assuming 12 bit relative jump
373+
if (SIGNED_FIT9(rel)) {
374+
asm_thumb_write_op16(as, OP_BEQ(rel));
387375
} else {
388-
// is a forwards jump, so need to assume it's large
389-
large_jump:
390-
asm_thumb_write_op32(as, OP_BEQW_HI(rel), OP_BEQW_LO(rel));
376+
goto large_jump;
391377
}
378+
} else {
379+
// is a forwards jump, so need to assume it's large
380+
large_jump:
381+
asm_thumb_write_op32(as, OP_BEQW_HI(rel), OP_BEQW_LO(rel));
392382
}
393383
}
394384

py/asmthumb.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
typedef struct _asm_thumb_t asm_thumb_t;
3030

31-
asm_thumb_t *asm_thumb_new();
31+
asm_thumb_t *asm_thumb_new(uint max_num_labels);
3232
void asm_thumb_free(asm_thumb_t *as, bool free_code);
3333
void asm_thumb_start_pass(asm_thumb_t *as, int pass);
3434
void asm_thumb_end_pass(asm_thumb_t *as);

py/compile.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ typedef enum {
3030
#define EMIT_OPT_NONE (0)
3131
#define EMIT_OPT_BYTE_CODE (1)
3232
#define EMIT_OPT_NATIVE_PYTHON (2)
33+
#define EMIT_OPT_ASM_THUMB (3)
3334

3435
typedef struct _compiler_t {
3536
qstr qstr___class__;
@@ -41,6 +42,7 @@ typedef struct _compiler_t {
4142
qstr qstr_assertion_error;
4243
qstr qstr_micropython;
4344
qstr qstr_native;
45+
qstr qstr_asm_thumb;
4446

4547
pass_kind_t pass;
4648

@@ -759,6 +761,8 @@ static bool compile_built_in_decorator(compiler_t *comp, int name_len, py_parse_
759761
qstr attr = PY_PARSE_NODE_LEAF_ARG(name_nodes[1]);
760762
if (attr == comp->qstr_native) {
761763
*emit_options = EMIT_OPT_NATIVE_PYTHON;
764+
} else if (attr == comp->qstr_asm_thumb) {
765+
*emit_options = EMIT_OPT_ASM_THUMB;
762766
} else {
763767
printf("SyntaxError: invalid micropython decorator\n");
764768
}
@@ -2551,6 +2555,7 @@ void py_compile(py_parse_node_t pn) {
25512555
comp->qstr_assertion_error = qstr_from_str_static("AssertionError");
25522556
comp->qstr_micropython = qstr_from_str_static("micropython");
25532557
comp->qstr_native = qstr_from_str_static("native");
2558+
comp->qstr_asm_thumb = qstr_from_str_static("asm_thumb");
25542559

25552560
comp->max_num_labels = 0;
25562561
comp->break_label = 0;
@@ -2588,6 +2593,9 @@ void py_compile(py_parse_node_t pn) {
25882593
comp->emit_method_table = &emit_x64_method_table;
25892594
break;
25902595

2596+
//case EMIT_OPT_ASM_THUMB:
2597+
//if (em
2598+
25912599
default:
25922600
if (emit_bc == NULL) {
25932601
emit_bc = emit_bc_new(comp->max_num_labels);

0 commit comments

Comments
 (0)