Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

emit thumb: Add support for MRS instruction #1637

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 25 additions & 0 deletions py/emitinlinethumb.c
Expand Up @@ -161,6 +161,13 @@ STATIC const reg_name_t reg_name_table[] = {
{15, "pc\0"},
};

#define MAX_SPECIAL_REGISTER_NAME_LENGTH 7
typedef struct _special_reg_name_t { byte reg; char name[MAX_SPECIAL_REGISTER_NAME_LENGTH + 1]; } special_reg_name_t;
STATIC const special_reg_name_t special_reg_name_table[] = {
{5, "IPSR"},
{17, "BASEPRI"},
};

// return empty string in case of error, so we can attempt to parse the string
// without a special check if it was in fact a string
STATIC const char *get_arg_str(mp_parse_node_t pn) {
Expand Down Expand Up @@ -196,6 +203,20 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
return 0;
}

STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
const char *reg_str = get_arg_str(pn);
for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(special_reg_name_table); i++) {
const special_reg_name_t *r = &special_reg_name_table[i];
if (strcmp(r->name, reg_str) == 0) {
return r->reg;
}
}
emit_inline_thumb_error_exc(emit,
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
"'%s' expects a special register", op));
return 0;
}

#if MICROPY_EMIT_INLINE_THUMB_FLOAT
STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
const char *reg_str = get_arg_str(pn);
Expand Down Expand Up @@ -627,6 +648,10 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
op_code_hi = 0xfa90;
op_code = 0xf0a0;
goto op_clz_rbit;
} else if (ARMV7M && strcmp(op_str, "mrs") == 0){
mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 12);
mp_uint_t reg_src = get_arg_special_reg(emit, op_str, pn_args[1]);
asm_thumb_op32(emit->as, 0xf3ef, 0x8000 | (reg_dest << 8) | reg_src);
} else {
if (strcmp(op_str, "and_") == 0) {
op_code = ASM_THUMB_FORMAT_4_AND;
Expand Down
11 changes: 11 additions & 0 deletions tests/inlineasm/asmspecialregs.py
@@ -0,0 +1,11 @@
@micropython.asm_thumb
def getIPSR():
mrs(r0, IPSR)

@micropython.asm_thumb
def getBASEPRI():
mrs(r0, BASEPRI)

print(getBASEPRI())
print(getIPSR())

2 changes: 2 additions & 0 deletions tests/inlineasm/asmspecialregs.py.exp
@@ -0,0 +1,2 @@
0
0