Skip to content

Commit e242b17

Browse files
HenrikSolverdpgeorge
authored andcommitted
py/emitinlinethumb: Add support for MRS instruction.
Only IPSR and BASEPRI special registers supported at the moment, but easy to extend in the future.
1 parent 1f0aaec commit e242b17

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

py/emitinlinethumb.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@ STATIC const reg_name_t reg_name_table[] = {
161161
{15, "pc\0"},
162162
};
163163

164+
#define MAX_SPECIAL_REGISTER_NAME_LENGTH 7
165+
typedef struct _special_reg_name_t { byte reg; char name[MAX_SPECIAL_REGISTER_NAME_LENGTH + 1]; } special_reg_name_t;
166+
STATIC const special_reg_name_t special_reg_name_table[] = {
167+
{5, "IPSR"},
168+
{17, "BASEPRI"},
169+
};
170+
164171
// return empty string in case of error, so we can attempt to parse the string
165172
// without a special check if it was in fact a string
166173
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
196203
return 0;
197204
}
198205

206+
STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
207+
const char *reg_str = get_arg_str(pn);
208+
for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(special_reg_name_table); i++) {
209+
const special_reg_name_t *r = &special_reg_name_table[i];
210+
if (strcmp(r->name, reg_str) == 0) {
211+
return r->reg;
212+
}
213+
}
214+
emit_inline_thumb_error_exc(emit,
215+
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
216+
"'%s' expects a special register", op));
217+
return 0;
218+
}
219+
199220
#if MICROPY_EMIT_INLINE_THUMB_FLOAT
200221
STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
201222
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
627648
op_code_hi = 0xfa90;
628649
op_code = 0xf0a0;
629650
goto op_clz_rbit;
651+
} else if (ARMV7M && strcmp(op_str, "mrs") == 0){
652+
mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 12);
653+
mp_uint_t reg_src = get_arg_special_reg(emit, op_str, pn_args[1]);
654+
asm_thumb_op32(emit->as, 0xf3ef, 0x8000 | (reg_dest << 8) | reg_src);
630655
} else {
631656
if (strcmp(op_str, "and_") == 0) {
632657
op_code = ASM_THUMB_FORMAT_4_AND;

tests/inlineasm/asmspecialregs.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@micropython.asm_thumb
2+
def getIPSR():
3+
mrs(r0, IPSR)
4+
5+
@micropython.asm_thumb
6+
def getBASEPRI():
7+
mrs(r0, BASEPRI)
8+
9+
print(getBASEPRI())
10+
print(getIPSR())
11+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
0
2+
0

0 commit comments

Comments
 (0)