The Digital Motion Processor in the InvenSense MPU-6050 family (MPU-6050, MPU-6500, MPU-9150, MPU-9250) and, as DMP3, in the ICM-20948: its architecture, memory, instruction set, host interface and assembly language.
The instructions in alphabetical order. Each entry gives:
| Section | Contents |
|---|---|
| Function | one line |
| Cores | both, or one |
| Syntax | in the assembler’s form (Chapter 8) |
| Description | what it does |
| Flags | the effect on F and on R |
| Example | a checked example |
| Encoding | the bit fields, the bytes and the cycles per core |
| Operation | register-transfer notation |
Notation.
| Symbol | Meaning |
|---|---|
| M[a] | the 32-bit word at address a |
| P0, P1, P2 | the pointers’ addresses; P2.w is the destination word index |
| A | M[P0 + 4·a], with a from the ALU byte |
| B | M[P1 + 4·b], with b from the ALU byte |
| DEST | M[P2 + 4·P2.w] when the route is RAM, or the next FIFO item when it is the FIFO |
| R | the 64-bit result register |
| word(R) | R’s bits 61–30, the word a store takes |
| F | the flag |
| lane(x) | under fmode 2/6, x’s high half in place; under fmode 3/7, x’s low half sign-extended; otherwise x |
| wrap(x) | x modulo 2³² (2¹⁶ in a lane), as a signed value |
| ⌊x⌋ | the floor |
The examples run in the definitions harness of Chapter 3: P0 = 0x100, P1 = 0x110, P2 = 0x120
(word 0), fmode 1, no predicate, results to RAM.
Function: Add.
Cores: both.
Syntax: add A,B · add A,B,inc
Description.
fmode 1, 2 or 3.inc advances P2.w before the store.Flags. F := the exact sum < 0. R := the exact sum.
; given 0x100 = 0.75q
; given 0x110 = -0.25q
add 0,0
; expect 0x120 = 0.5q
; expect F = 0
| add A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | 0 | 0 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 28, lane 22 | 26, lane 20 |
Operation.
if (inc) P2.w := P2.w + 1
R := lane(A) + lane(B) F := R < 0
DEST := wrap(R)
Function: End a predicate.
Cores: both.
Syntax: always
Description. Disarms the predicate, so the instructions that follow run unconditionally. Every
conditional block ends with always.
Flags. None.
; given 0x100 = -1i, 0, 0
add 0,2 ; F := 1
if nf
clr.next ; skipped
always
inc ; runs
; expect 0x120 = 0
| always | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. predicate := none
Function: Bitwise AND.
Cores: both.
Syntax: and A,B · and A,B,inc
Description. Stores A AND B, under fmode 5, 6 or 7. It changes neither F nor R.
Flags. None.
; given 0x100 = 0ff0
; given 0x110 = 00ff
fmode 5
and 0,0
; expect 0x120 = 00f0
| and A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | 1 | 0 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 23, lane 17 | 22, lane 16 |
Operation. if (inc) P2.w := P2.w + 1; DEST := lane(A) AND lane(B)
Function: Relative branch.
Cores: MPU-6050.
Syntax: branch target · branch.m4 target
Description.
branch goes to target, at most 31 bytes forward or 32 back from the byte after it.branch.m4, a one-byte branch
to its own address + 1 + d.always and a mode byte before the next ALU
instruction.Flags. None. The mode register := 4.
; given 0x100 = 1i, 0, 0
add 0,2 ; F := 0
if nf
branch over
always
fmode 1
inc ; not reached
over: always
fmode 1
; expect 0x120 = 1i
| branch t | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
| byte 2 | 0 | 0 | d | |||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 2 | — |
| Cycles | 15 taken, 10 skipped | — |
| branch.m4 t | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | 0 | d | |||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | — |
| Cycles | 10 taken, 5 skipped | — |
Operation.
branch: PC := PC + 2 + sext6(d); mode := 4
branch.m4: PC := PC + 1 + sext6(d) (mode stays 4)
Function: Call a subroutine.
Cores: ICM-20948.
Syntax: call target · call.m4 target
Description.
call.m4 is the two-byte target alone.Flags. None. The mode register := 4.
call sub
fmode 1
end
sub: always
fmode 1
inc
ret
; expect 0x120 = 1i
| call t | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
| byte 2 | 0 | 1 | t | |||||
| byte 3 | t | |||||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 3 |
| Cycles | — | 13 |
| call.m4 t | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | 1 | t | |||||
| byte 2 | t | |||||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 2 |
| Cycles | — | 9 |
Operation. stack[sp] := PC + 3 (call.m4: + 2); sp := sp + 1 mod 4; PC := target; mode := 4
Function: Clamp to a symmetric range.
Cores: both.
Syntax: clamp A,B · clamp A,B,inc (also written min)
Description.
fmode 5, 6 or 7. For a non-negative A the result is
min(A, B).test after CLAMP asks
whether A sat exactly on its bound.Flags. F := D < 0, that is, A was clamped. R := D, where D = B − A when A ≥ 0 and A + B when A < 0.
; given 0x100 = -0.75q
; given 0x110 = 0.5q
fmode 5
clamp 0,0
; expect 0x120 = -0.5q
; expect F = 1
| clamp A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | 0 | 0 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 28, lane 22 | 26, lane 20 |
Operation.
if (inc) P2.w := P2.w + 1
a := lane(A); b := lane(B)
D := a >= 0 ? b - a : a + b; F := D < 0; R := D
DEST := wrap(a >= 0 ? min(a, b) : max(a, -b))
Function: Clear.
Cores: both.
Syntax: clr, and the aliases clr.d2 … clr.d7 and clr.e0 … clr.ef (MPU-6050) and clr.e7 (ICM-20948)
Description.
clr (0xDE) is the clear instruction. The aliases clear in the same way but cost as much as an
add.Flags. None.
; given 0x120 = 12345678
clr
; expect 0x120 = 0
| clr | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 12 | 11 |
| clr.d2 … clr.d7 (MPU), clr.e0 … clr.ef (MPU), clr.e7 (DMP3) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 0 | n | |||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 28 | 26 |
Operation. DEST := 0 (in the lane)
Function: Advance, then clear.
Cores: both.
Syntax: clr.next
Description. Advances P2.w, then stores 0 through the route. clr followed by three clr.next
clears a page.
Flags. None. On the MPU-6050 the advance sets R := 0.
; given 0x120 = 1i, 2i, 3i, 4i
clr
clr.next
clr.next
clr.next
; expect 0x120 = 0, 0, 0, 0
| clr.next | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 12 | 11 |
Operation. P2.w := P2.w + 1; DEST := 0
Function: Sign test.
Cores: both.
Syntax: cmp A,B
Description.
fmode 5, 6 or 7. It stores nothing.Flags. F := (A < 0 and B ≥ 0). R unchanged.
; given 0x100 = -1i
; given 0x110 = 5i
fmode 5
cmp 0,0
; expect F = 1
| cmp A,B | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | 0 | 1 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 17, lane 13 | 16, lane 12 |
Operation. F := lane(A) < 0 and lane(B) >= 0
Function: Compare with a constant.
Cores: ICM-20948.
Syntax: cmp.eq k,t · cmp.gt k,t · cmp.lt k,t · cmp.ne k,t
Description.
Flags. F := (M[P1 + 4k] AND 0x3F) cond t.
; given 0x110 = 0, 41i
cmp.lt 1,42
; expect F = 1
| cmp.eq / gt / lt / ne k,t | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
| byte 2 | 1 | 1 | 0 | 0 | 0 | 0 | k | |
| byte 3 | t | c | ||||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 3 |
| Cycles | — | 19 |
Operation. F := (M[P1 + 4k] AND 0x3F) {==, >, <, !=} t, with the condition from bits 1–0 of the third byte
Function: Decrement.
Cores: both.
Syntax: dec · dec.next
Description.
fmode 3/7, or 0x10000 under fmode 2/6.dec.next advances P2.w first.Flags. F := the exact result < 0. R := the exact result.
; given 0x120 = 0
dec
; expect 0x120 = -1i
; expect F = 1
| dec / dec.next | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 1 | 0 | next | 1 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 23, lane 19 | 21, lane 17 |
Operation. if (.next) P2.w := P2.w + 1; R := lane(M[P2 + 4·P2.w]) - 1; F := R < 0; DEST := wrap(R)
Function: End the pass.
Cores: both.
Syntax: end
Description.
end is skipped, which makes a conditional end.Flags. None.
; given 0x100 = 1i, 0, 0
add 0,2 ; F := 0
if nf
end ; ends here
always
inc ; not reached
; expect 0x120 = 1i
| end | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | — | — |
Operation. pass ends
Function: Route results to the FIFO.
Cores: both.
Syntax: fifo
Description.
store, and carries over into the next pass.Flags. None.
; given 0x100 = 11223344
fifo
mov 0
fmode 3
mov 0
; expect fifo = 112233443344
| fifo | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. route := FIFO
Function: Set the mode register.
Cores: both.
Syntax: fmode m, with m one of 0, 1, 2, 3, 5, 6, 7
Description.
Flags. None.
; given 0x100 = 00010001
; given 0x110 = 00010001
fmode 3
add 0,0 ; the low lane only
; expect 0x120 = 00000002
| fmode m | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 0 | m | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. mode := m
Function: Arm a predicate.
Cores: both.
Syntax: if f · if nf · if f.alt
Description.
if f arms a predicate under which instructions run only while F is set. if nf runs them only
while F is clear. if f.alt (0xDB) is the same as if f.always or if, and F stays frozen meanwhile.Flags. None.
; given 0x100 = -1i, 0, 0
add 0,2 ; F := 1
if f
inc.next ; runs
always
; expect 0x124 = 1i
| if f / if nf / if f.alt | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 1 | 0 | c | |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. predicate := F (if f), not F (if nf)
Function: Increment.
Cores: both.
Syntax: inc · inc.next
Description.
fmode 3/7, or 0x10000 under fmode 2/6.inc.next advances P2.w first.Flags. F := the exact result < 0. R := the exact result.
; given 0x120 = 7fffffff
inc
; expect 0x120 = 80000000
; expect F = 0
| inc / inc.next | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 1 | 0 | next | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 23, lane 19 | 21, lane 17 |
Operation. if (.next) P2.w := P2.w + 1; R := lane(M[P2 + 4·P2.w]) + 1; F := R < 0; DEST := wrap(R)
Function: Raise the host interrupt.
Cores: both, with different bytes.
Syntax: int · int.f4 n (MPU-6050)
Description.
int.f4 n (0xF4 0x41–0x7F) also raises it, and enters mode 4.Flags. None.
int
; expect ints = 1
| int | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | — |
| Cycles | 5 | — |
| int | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 1 |
| Cycles | — | 4 |
| int.f4 n | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
| byte 2 | 0 | 1 | n | |||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 2 | — |
| Cycles | 10 | — |
Operation. DMP_INT := 1
Function: Jump.
Cores: ICM-20948.
Syntax: jump target · jump.m4 target
Description.
jump.m4 is the two-byte target
alone.always and a mode byte.Flags. None. The mode register := 4.
jump over
inc ; not reached
over: always
fmode 1
; expect 0x120 = 0
| jump t | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
| byte 2 | 0 | 0 | t | |||||
| byte 3 | t | |||||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 3 |
| Cycles | — | 13 taken, 12 skipped |
| jump.m4 t | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | 0 | t | |||||
| byte 2 | t | |||||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 2 |
| Cycles | — | 9 |
Operation. PC := target; mode := 4
Function: Load the shifter.
Cores: ICM-20948.
Syntax: load k
Description. Fills the shifter with the four words of P0’s page, selects word k for the next shift’s store, and makes that word R.
Flags. R := word k. F unchanged.
; given 0x100 = 0, 0, 0x100i, 0
load 2
sar 4
; expect 0x120 = 0x10i
| load k | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 0 | 1 | k | |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 1 |
| Cycles | — | 15 |
Operation. shifter[0..3] := M[P0 .. P0 + 12]; select := k; R := M[P0 + 4k]
Function: Store R’s low word.
Cores: ICM-20948.
Syntax: lo · lo.next
Description.
mul that is the low part of the
product.lo.next advances P2.w first.Flags. None.
; given 0x100 = 3i
; given 0x110 = 5i
mul 0,0 ; 15 / 2^30 floors to 0
lo.next ; the low 30 bits: 15
; expect 0x120 = 0, 15i
| lo / lo.next | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | next |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 1 |
| Cycles | — | 11 |
Operation. if (.next) P2.w := P2.w + 1; DEST := sext30(R[29:0])
Function: Multiply-accumulate.
Cores: both.
Syntax: mac A,B · mac A,B,inc (also mac.m, op 2)
Description.
fmode 0: R := R + A·B, exactly, then stores ⌊R / 2³⁰⌋.mac A,B,inc starts one.
Beginning a sum with mul works on both cores.Flags. F := R < 0. R := R + A·B.
; given 0x100 = 0.5q, 0.5q
; given 0x110 = 0.5q, 0.25q
mul 0,0 ; R := 0.25
fmode 0
mac 1,1 ; R := 0.25 + 0.125
; expect 0x120 = 0.375q
| mac A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | x | 0 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 60 | 27 |
Operation.
if (inc) { P2.w := P2.w + 1; R := 0 } (DMP3: the adv form starts a new sum)
R := wrap64(R + A * B); F := R < 0
DEST := word(R)
Function: Multiply-subtract.
Cores: both.
Syntax: macn A,B · macn A,B,inc (also macn.m, op 3)
Description. Under fmode 0, R := R − A·B, exactly, then stores ⌊R / 2³⁰⌋. Otherwise as MAC.
Flags. F := R < 0. R := R − A·B.
; given 0x100 = 0.5q, 0.5q
; given 0x110 = 0.5q, 0.25q
mul 0,0 ; R := 0.25
fmode 0
macn 1,1 ; R := 0.25 - 0.125
; expect 0x120 = 0.125q
| macn A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | x | 1 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 60 | 27 |
Operation. R := wrap64(R - A * B); F := R < 0; DEST := word(R)
Function: Enter mode 4.
Cores: both.
Syntax: mode4 (ICM-20948) · nop.f4, nop.f440 (MPU-6050)
Description.
nop.f440 (F4 0x40) also enters mode 4 and does nothing else.Flags. None. The mode register := 4.
; given 0x120 = 5i
mode4
p2page 2 ; mode 4: P2 now points into the I/O space
fmode 1
p2page 2 ; back to memory
inc
; expect 0x120 = 6i
| mode4 (DMP3), nop.f4 (MPU) | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
| nop.f440 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
| byte 2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 2 | — |
| Cycles | 10 | — |
Operation. mode := 4
Function: Move a word.
Cores: both.
Syntax: mov k · mov k,inc
Description.
inc advances P2.w first.Flags. None.
; given 0x100 = 11111111, 22222222
mov 1
mov 0,inc
; expect 0x120 = 22222222, 11111111
| mov k[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 0 | 0 | k | adv | |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 18 | 17 |
Operation. if (inc) P2.w := P2.w + 1; DEST := M[P0 + 4k] (in the lane)
Function: Move with the half-words exchanged.
Cores: both.
Syntax: movx k · movx k,inc (also mov16)
Description.
fmode 2 the source’s low half goes to the destination’s high half; under fmode 3 the
source’s high half goes to the low half.Flags. None.
; given 0x100 = 01234567
movx 0
; expect 0x120 = 45670123
| movx k[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 0 | 1 | k | adv | |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 18 | 17 |
Operation. if (inc) P2.w := P2.w + 1; DEST := swap16(M[P0 + 4k]) (in the lane)
Function: Toggle the MOV substitution latch.
Cores: ICM-20948.
Syntax: movz
Description.
movz.Flags. None.
| movz | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 1 |
| Cycles | — | 4 |
Operation. movz := not movz; while set, MOV stores a FIFO-dependent value
Function: Multiply.
Cores: both.
Syntax: mul A,B · mul A,B,inc
Description.
fmode 1, 2 or 3. R takes the whole product, and the store takes
⌊A·B / 2³⁰⌋ wrapped.Flags. F := the exact product < 0. R := A·B.
; given 0x100 = 1.5q
; given 0x110 = 1.5q
mul 0,0 ; 2.25 wraps to -1.75
; expect 0x120 = -1.75q
; expect F = 0
| mul A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | 1 | 0 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 58, lane 52 | 25, lane 19 |
Operation. R := lane(A) * lane(B); F := R < 0; DEST := wrap(floor(R / 2^30))
Function: Multiply and negate.
Cores: both.
Syntax: nmul A,B · nmul A,B,inc
Description. As MUL, with the product negated before it is floored: ⌊−A·B / 2³⁰⌋. An NMUL by 1.0 negates exactly.
Flags. F := −A·B < 0. R := −A·B.
; given 0x100 = 0.3q
; given 0x110 = 1.0q
nmul 0,0
; expect 0x120 = -0.3q
| nmul A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | 1 | 1 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 58, lane 52 | 25, lane 19 |
Operation. R := -(lane(A) * lane(B)); F := R < 0; DEST := wrap(floor(R / 2^30))
Function: Advance the destination by two words.
Cores: both.
Syntax: p2inc2
Description. Adds 2 to P2.w, modulo 4.
Flags. On the MPU-6050, R := 0.
p2inc2
inc
; expect 0x128 = 1i
| p2inc2 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. P2.w := P2.w + 2
Function: Advance a pointer by one block.
Cores: both.
Syntax: p0blk · p1blk · p2blk
Description.
pNblk return the pointer. The block persists from pass to pass
until DMP_RST.Flags. None.
; given 0x520 = 0x41i
p2blk
inc ; 0x520
; expect 0x520 = 0x42i
| p0blk / p1blk / p2blk | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 0 | 1 | 1 | 1 | 1 | P | |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. Pn.block := Pn.block + 1 (MPU modulo 3, DMP3 modulo 4)
Function: Load a pointer’s bank.
Cores: both.
Syntax: p0bank n · p1bank n · p2bank n, with n 0–3
Description. Sets the pointer’s bank (bits 9–8 of its address).
Flags. On the MPU-6050, p2bank sets R := 0.
; given 0x320 = 9i
p2bank 3
inc
; expect 0x320 = 10i
| p0bank n / p1bank n / p2bank n | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 0 | 1 | 1 | P | bank | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. Pn.bank := n
Function: Load a pointer’s page.
Cores: both.
Syntax: p0page n · p1page n · p2page n, with n 0–15
Description.
p2page also resets P2.w to 0.Flags. On the MPU-6050, p2page sets R := 0.
; given 0x130 = 2i
p2page 3
inc
; expect 0x130 = 3i
| p0page n / p1page n / p2page n | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 0 | P | page | ||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. Pn.page := n; if (n = 2) P2.w := 0
Function: Return from a subroutine.
Cores: ICM-20948.
Syntax: ret
Description.
Flags. None.
call s
fmode 1
inc
end
s: ret
; expect 0x120 = 1i
| ret | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 1 |
| Cycles | — | 5 |
Operation. sp := sp - 1 mod 4; PC := stack[sp]
Function: Reverse subtract.
Cores: both.
Syntax: rsub A,B · rsub A,B,inc
Description.
fmode 1, 2 or 3. It is the comparison instruction (§3.3).Flags. F := the exact result < 0. R := the exact result.
; given 0x100 = 0.75q
; given 0x110 = 0.25q
rsub 0,0
; expect 0x120 = -0.5q
; expect F = 1
| rsub A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | 0 | 1 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 28, lane 22 | 26, lane 20 |
Operation. R := lane(B) + wrap(-lane(A)); F := R < 0; DEST := wrap(R)
Function: Shift the shifter.
Cores: ICM-20948.
Syntax: shl s · shl s,adv (s 1–31) · sar s · sar s,adv (s 1–32)
Description.
shl shifts every shifter word left by s, filling each word’s low bits from the top of the
next word’s 30-bit fraction.sar shifts every word right by s, arithmetically.adv advances P2.w first) and make it R.
The shifter keeps the shifted words, so shifts compound.mul, shl 30 stores the integer product (§3.2).Flags. R := the stored word. F unchanged.
; given 0x100 = 6i
; given 0x110 = 7i
mul 0,0
shl 30
; expect 0x120 = 42i
| shl s[,adv] / sar s[,adv] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
| byte 2 | 0 | adv | r | s | ||||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | — | 2 |
| Cycles | — | 15 |
Operation.
shl s: word[i] := (word[i] << s) | ((word[i+1 mod 4] << 2) >> (32 - s))
sar s: word[i] := word[i] >> s (arithmetic)
if (adv) P2.w := P2.w + 1; DEST := word[select]; R := word[select]
Function: Route results to memory.
Cores: both.
Syntax: store
Description.
fifo, and carries over into the next pass. After DMP_RST it is RAM.Flags. None.
; given 0x100 = 5i
fifo
store
mov 0
; expect 0x120 = 5i
; expect fifo =
| store | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. route := RAM
Function: Test the result for zero.
Cores: both.
Syntax: test
Description.
test runs.rsub then test tests equality.test sets F even while a predicate is armed.Flags. F := (lane(word(R)) = 0). R unchanged.
; given 0x100 = 9i
; given 0x110 = 9i
rsub 0,0
test
; expect F = 1
| test | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 5 | 4 |
Operation. F := lane(word(R)) = 0
Function: Exchange P0 and P1 for the operands.
Cores: MPU-6050.
Syntax: xchg01
Description.
xchg01 or at the end of the pass.cmp.cond.Flags. None.
; given 0x100 = 3i
; given 0x110 = 10i
xchg01
rsub 0,0 ; P0's word - P1's word = 3 - 10
xchg01
; expect 0x120 = -7i
| xchg01 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | — |
| Cycles | 5 | — |
Operation. xchg01 := not xchg01
Function: Exchange P0 and P2.
Cores: MPU-6050.
Syntax: xchg02
Description.
xchg02 or at the end of the pass.shl/sar.Flags. None.
; given 0x120 = 4i
xchg02
mov 0 ; P2's word 0 -> P0's page, word 0
xchg02
; expect 0x100 = 4i
| xchg02 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | — |
| Cycles | 5 | — |
Operation. xchg02 := not xchg02
Function: Bitwise exclusive OR.
Cores: both.
Syntax: xor A,B · xor A,B,inc
Description.
fmode 5, 6 or 7. It changes neither F nor R.Flags. None.
; given 0x100 = 0ff0
; given 0x110 = ffffffff
fmode 5
xor 0,0
; expect 0x120 = fffff00f
| xor A,B[,inc] | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| byte 1 | 0 | A | B | adv | 1 | 1 | ||
| MPU-6050 | ICM-20948 | |
|---|---|---|
| Bytes | 1 | 1 |
| Cycles | 23, lane 17 | 22, lane 16 |
Operation. if (inc) P2.w := P2.w + 1; DEST := lane(A) XOR lane(B)