Skip to content

Commit ea8be37

Browse files
committed
py/inlinethumb: Remove 30-bit restriction on movwt instruction.
movwt can now move a full 32-bit constant into a register.
1 parent 47dc592 commit ea8be37

File tree

4 files changed

+14
-7
lines changed

4 files changed

+14
-7
lines changed

docs/reference/asm_thumb2_mov.rst

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ Where immediate values are used, these are zero-extended to 32 bits. Thus
2121
movt writes an immediate value to the top halfword of the destination register.
2222
It does not affect the contents of the bottom halfword.
2323

24-
* movwt(Rd, imm30) ``Rd = imm30``
24+
* movwt(Rd, imm32) ``Rd = imm32``
2525

26-
movwt is a pseudo-instruction: the MicroPython assembler emits a ``movw`` and a ``movt``
27-
to move a zero extended 30 bit value into Rd. Where the full 32 bits are required a
28-
workround is to use the movw and movt operations.
26+
movwt is a pseudo-instruction: the MicroPython assembler emits a ``movw`` followed
27+
by a ``movt`` to move a 32-bit value into Rd.

py/emitinlinethumb.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -703,11 +703,10 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
703703
goto op_movw_movt;
704704
} else if (ARMV7M && strcmp(op_str, "movwt") == 0) {
705705
// this is a convenience instruction
706-
// we clear the MSB since it might be set from extracting the small int value
707706
mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15);
708-
int i_src = get_arg_i(emit, op_str, pn_args[1], 0xffffffff);
707+
uint32_t i_src = get_arg_i(emit, op_str, pn_args[1], 0xffffffff);
709708
asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVW, reg_dest, i_src & 0xffff);
710-
asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0x7fff);
709+
asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0xffff);
711710
} else if (ARMV7M && strcmp(op_str, "ldrex") == 0) {
712711
mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15);
713712
mp_parse_node_t pn_base, pn_offset;

tests/inlineasm/asmconst.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# test constants in assembler
2+
3+
@micropython.asm_thumb
4+
def c1():
5+
movwt(r0, 0xffffffff)
6+
movwt(r1, 0xf0000000)
7+
sub(r0, r0, r1)
8+
print(hex(c1()))

tests/inlineasm/asmconst.py.exp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0xfffffff

0 commit comments

Comments
 (0)