Add APF opcodes to read/write data memory (take 2)

The new opcodes are LDDW (LoaD Data Word) and STDW (STore Data Word)

The only supported addressing mode is register-indirect with immediate
offset (register value + immediate value). Since there's a single
register bit encoded in the opcode, the other register is implicitly
used for the address operand. Hence, the following variations are
possible:

  lddw R0, [1234]R1  ; R0 = *(R1 + 1234)
  lddw R1, [1234]R0  ; R1 = *(R0 + 1234)
  stdw R0, [1234]R1  ; *(R1 + 1234) = R0
  stdw R1, [1234]R0  ; *(R0 + 1234) = R1

The immediate can also be specified to be length 0, making the memory
access equivalent to a plain register-indirect with no offset.

  lddw R0, R1  ; R0 = *R1
  lddw R1, R0  ; R1 = *R0
  stdw R0, R1  ; *R1 = R0
  stdw R1, R0  ; *R0 = R1

The encoding of the above instructions is a single byte, making a
typical counter increment more efficient, especially when the address
requires a multi-byte immediate:

  ldh   R1, 1234    ; address of our packet counter (3 bytes)
  lddw  R0, R1      ; load the counter from address 1234 (1 byte)
  add   R0, 1       ; increment the counter (2 bytes)
  stdw  R0, R1      ; write-back to data ram (1 byte)

Total: 7 bytes. Defining a separate INCW instruction would reduce the
above sequence down to 3 bytes (or 4 bytes if using an EXT opcode to
avoid wasting opcodes). This optimization can be added at a later point
if the data access patterns of production APF code justify it.

Bug: 73804303
Test: runtest -x tests/net/java/android/net/apf/ApfTest.java
Change-Id: Ibbd427e12987a1eef63b41d816af05a1bd9f9170
5 files changed