Skip to content
Snippets Groups Projects
Commit ea8be373 authored by Damien George's avatar Damien George
Browse files

py/inlinethumb: Remove 30-bit restriction on movwt instruction.

movwt can now move a full 32-bit constant into a register.
parent 47dc5922
No related branches found
No related tags found
No related merge requests found
...@@ -21,8 +21,7 @@ Where immediate values are used, these are zero-extended to 32 bits. Thus ...@@ -21,8 +21,7 @@ Where immediate values are used, these are zero-extended to 32 bits. Thus
movt writes an immediate value to the top halfword of the destination register. movt writes an immediate value to the top halfword of the destination register.
It does not affect the contents of the bottom halfword. It does not affect the contents of the bottom halfword.
* movwt(Rd, imm30) ``Rd = imm30`` * movwt(Rd, imm32) ``Rd = imm32``
movwt is a pseudo-instruction: the MicroPython assembler emits a ``movw`` and a ``movt`` movwt is a pseudo-instruction: the MicroPython assembler emits a ``movw`` followed
to move a zero extended 30 bit value into Rd. Where the full 32 bits are required a by a ``movt`` to move a 32-bit value into Rd.
workround is to use the movw and movt operations.
...@@ -703,11 +703,10 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a ...@@ -703,11 +703,10 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
goto op_movw_movt; goto op_movw_movt;
} else if (ARMV7M && strcmp(op_str, "movwt") == 0) { } else if (ARMV7M && strcmp(op_str, "movwt") == 0) {
// this is a convenience instruction // this is a convenience instruction
// we clear the MSB since it might be set from extracting the small int value
mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15); mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15);
int i_src = get_arg_i(emit, op_str, pn_args[1], 0xffffffff); uint32_t i_src = get_arg_i(emit, op_str, pn_args[1], 0xffffffff);
asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVW, reg_dest, i_src & 0xffff); asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVW, reg_dest, i_src & 0xffff);
asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0x7fff); asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0xffff);
} else if (ARMV7M && strcmp(op_str, "ldrex") == 0) { } else if (ARMV7M && strcmp(op_str, "ldrex") == 0) {
mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15); mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15);
mp_parse_node_t pn_base, pn_offset; mp_parse_node_t pn_base, pn_offset;
......
# test constants in assembler
@micropython.asm_thumb
def c1():
movwt(r0, 0xffffffff)
movwt(r1, 0xf0000000)
sub(r0, r0, r1)
print(hex(c1()))
0xfffffff
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment