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

movwt can now move a full 32-bit constant into a register.
This commit is contained in:
Damien George 2016-01-07 14:54:13 +00:00
parent 47dc5922ca
commit ea8be373a9
4 changed files with 14 additions and 7 deletions

View File

@ -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.

View File

@ -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;

View File

@ -0,0 +1,8 @@
# test constants in assembler
@micropython.asm_thumb
def c1():
movwt(r0, 0xffffffff)
movwt(r1, 0xf0000000)
sub(r0, r0, r1)
print(hex(c1()))

View File

@ -0,0 +1 @@
0xfffffff