summaryrefslogtreecommitdiff
path: root/py/emitinlinethumb.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/emitinlinethumb.c')
-rw-r--r--py/emitinlinethumb.c45
1 files changed, 21 insertions, 24 deletions
diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c
index eaa3475b8..60e682fa0 100644
--- a/py/emitinlinethumb.c
+++ b/py/emitinlinethumb.c
@@ -44,20 +44,19 @@ typedef enum {
struct _emit_inline_asm_t {
uint16_t pass;
- uint16_t success;
scope_t *scope;
+ mp_obj_t *error_slot;
mp_uint_t max_num_labels;
qstr *label_lookup;
asm_thumb_t *as;
};
-STATIC void emit_inline_thumb_error(emit_inline_asm_t *emit, const char *fmt, ...) {
- printf("SyntaxError: ");
- emit->success = false;
- va_list ap;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
+STATIC void emit_inline_thumb_error_msg(emit_inline_asm_t *emit, const char *msg) {
+ *emit->error_slot = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg);
+}
+
+STATIC void emit_inline_thumb_error_exc(emit_inline_asm_t *emit, mp_obj_t exc) {
+ *emit->error_slot = exc;
}
emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t max_num_labels) {
@@ -75,15 +74,15 @@ void emit_inline_thumb_free(emit_inline_asm_t *emit) {
m_del_obj(emit_inline_asm_t, emit);
}
-STATIC void emit_inline_thumb_start_pass(emit_inline_asm_t *emit, pass_kind_t pass, scope_t *scope) {
+STATIC void emit_inline_thumb_start_pass(emit_inline_asm_t *emit, pass_kind_t pass, scope_t *scope, mp_obj_t *error_slot) {
emit->pass = pass;
- emit->success = true;
emit->scope = scope;
+ emit->error_slot = error_slot;
asm_thumb_start_pass(emit->as, pass == MP_PASS_EMIT ? ASM_THUMB_PASS_EMIT : ASM_THUMB_PASS_COMPUTE);
asm_thumb_entry(emit->as, 0);
}
-STATIC bool emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
+STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
asm_thumb_exit(emit->as);
asm_thumb_end_pass(emit->as);
@@ -91,23 +90,21 @@ STATIC bool emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
void *f = asm_thumb_get_code(emit->as);
mp_emit_glue_assign_native(emit->scope->raw_code, MP_CODE_NATIVE_ASM, f, asm_thumb_get_code_size(emit->as), emit->scope->num_pos_args, 0);
}
-
- return emit->success;
}
STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params) {
if (n_params > 4) {
- emit_inline_thumb_error(emit, "can only have up to 4 parameters to inline thumb assembly\n");
+ emit_inline_thumb_error_msg(emit, "can only have up to 4 parameters to Thumb assembly");
return 0;
}
for (mp_uint_t i = 0; i < n_params; i++) {
if (!MP_PARSE_NODE_IS_ID(pn_params[i])) {
- emit_inline_thumb_error(emit, "parameter to inline assembler must be an identifier\n");
+ emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3");
return 0;
}
const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i]));
if (!(strlen(p) == 2 && p[0] == 'r' && p[1] == '0' + i)) {
- emit_inline_thumb_error(emit, "parameter %d to inline assembler must be r%d\n", i + 1, i);
+ emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3");
return 0;
}
}
@@ -161,7 +158,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
const reg_name_t *r = &reg_name_table[i];
if (reg_str[0] == r->name[0] && reg_str[1] == r->name[1] && reg_str[2] == r->name[2] && (reg_str[2] == '\0' || reg_str[3] == '\0')) {
if (r->reg > max_reg) {
- emit_inline_thumb_error(emit, "'%s' expects at most r%d\n", op, max_reg);
+ emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects at most r%d", op, max_reg));
return 0;
} else {
return r->reg;
@@ -169,18 +166,18 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
}
}
}
- emit_inline_thumb_error(emit, "'%s' expects a register\n", op);
+ emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a register", op));
return 0;
}
STATIC int get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, int fit_mask) {
if (!MP_PARSE_NODE_IS_SMALL_INT(pn)) {
- emit_inline_thumb_error(emit, "'%s' expects an integer\n", op);
+ emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op));
return 0;
}
int i = MP_PARSE_NODE_LEAF_SMALL_INT(pn);
if ((i & (~fit_mask)) != 0) {
- emit_inline_thumb_error(emit, "'%s' integer 0x%x does not fit in mask 0x%x\n", op, i, fit_mask);
+ emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' integer 0x%x does not fit in mask 0x%x", op, i, fit_mask));
return 0;
}
return i;
@@ -204,13 +201,13 @@ STATIC bool get_arg_addr(emit_inline_asm_t *emit, const char *op, mp_parse_node_
return true;
bad_arg:
- emit_inline_thumb_error(emit, "'%s' expects an address of the form [a, b]\n", op);
+ emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an address of the form [a, b]", op));
return false;
}
STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
if (!MP_PARSE_NODE_IS_ID(pn)) {
- emit_inline_thumb_error(emit, "'%s' expects a label\n", op);
+ emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op));
return 0;
}
qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn);
@@ -221,7 +218,7 @@ STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_
}
// only need to have the labels on the last pass
if (emit->pass == MP_PASS_EMIT) {
- emit_inline_thumb_error(emit, "label '%s' not defined\n", qstr_str(label_qstr));
+ emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "label '%s' not defined", qstr_str(label_qstr)));
}
return 0;
}
@@ -450,7 +447,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
return;
unknown_op:
- emit_inline_thumb_error(emit, "unsupported Thumb instruction '%s' with %d arguments\n", op_str, n_args);
+ emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "unsupported Thumb instruction '%s' with %d arguments", op_str, n_args));
}
const emit_inline_asm_method_table_t emit_inline_thumb_method_table = {