py/emitinlinethumb: Add support for MRS instruction.

Only IPSR and BASEPRI special registers supported at the moment, but easy
to extend in the future.
This commit is contained in:
Henrik Sölver 2015-11-21 22:27:54 +01:00 committed by Damien George
parent 1f0aaece3a
commit e242b1785f
3 changed files with 38 additions and 0 deletions

View File

@ -161,6 +161,13 @@ STATIC const reg_name_t reg_name_table[] = {
{15, "pc\0"}, {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 // 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 // without a special check if it was in fact a string
STATIC const char *get_arg_str(mp_parse_node_t pn) { STATIC const char *get_arg_str(mp_parse_node_t pn) {
@ -196,6 +203,20 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
return 0; 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 #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) { 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); const char *reg_str = get_arg_str(pn);
@ -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_hi = 0xfa90;
op_code = 0xf0a0; op_code = 0xf0a0;
goto op_clz_rbit; 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 { } else {
if (strcmp(op_str, "and_") == 0) { if (strcmp(op_str, "and_") == 0) {
op_code = ASM_THUMB_FORMAT_4_AND; op_code = ASM_THUMB_FORMAT_4_AND;

View File

@ -0,0 +1,11 @@
@micropython.asm_thumb
def getIPSR():
mrs(r0, IPSR)
@micropython.asm_thumb
def getBASEPRI():
mrs(r0, BASEPRI)
print(getBASEPRI())
print(getIPSR())

View File

@ -0,0 +1,2 @@
0
0