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.
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``
to move a zero extended 30 bit value into Rd. Where the full 32 bits are required a
workround is to use the movw and movt operations.
movwt is a pseudo-instruction: the MicroPython assembler emits a ``movw`` followed
by a ``movt`` to move a 32-bit value into Rd.

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;
} else if (ARMV7M && strcmp(op_str, "movwt") == 0) {
// 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);
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_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) {
mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15);
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