Added: lookup8 in VX4B using vlookup#225
Conversation
McCrea
left a comment
There was a problem hiding this comment.
Most of these are just stylistic, but some observations on the RISC-V ASM.
|
|
||
| FUNCTION_NAME: | ||
|
|
||
| { xm.entsp ROUND_UP(NSTACKBYTES, 16) ; xm.nop } |
There was a problem hiding this comment.
| { xm.entsp ROUND_UP(NSTACKBYTES, 16) ; xm.nop } | |
| xm.entsp ROUND_UP(NSTACKBYTES, 16) |
The packed nop isn't needed as we don't have issue modes any more. (The only - rare - case you might do this is to force alignment of later instructions.
There was a problem hiding this comment.
FYI nop (rather than xm.nop) is a standard mnemonic which will compress to a short instruction - so it's a bit more idiomatic if you do need a nop.
| FUNCTION_NAME: | ||
|
|
||
| { xm.entsp ROUND_UP(NSTACKBYTES, 16) ; xm.nop } | ||
| xm.stdsp x18, x19, 0*8 |
There was a problem hiding this comment.
Generally speaking, the ABI register naming is preferred to the numeric naming - e.g. xm.stdsp s2, s3, 0*8.
| sw x24, 3*8(sp) | ||
| addi count, x14, 0 | ||
| add out_data, out_data, start | ||
| add in_data, in_data, start | ||
| addi vec1_tmp, sp, STACK_VEC1_TMP | ||
| xm.mkmski mask, 32 | ||
| li thirty_two, 32 | ||
| // out_data substract 32 first for optimize in the loop | ||
| sub out_data, out_data, thirty_two |
There was a problem hiding this comment.
Looks like most of this sequence could be packetised.
| xm.vlookup lut, 5, 6 | ||
| xm.vlookup lut, 6, 7 | ||
| xm.vlookup lut, 7, 0 | ||
| bnez counter, FUNCTION_NAME.save |
There was a problem hiding this comment.
| bnez counter, FUNCTION_NAME.save | |
| xm.bt counter, FUNCTION_NAME.save |
Saves a couple of bytes and I think you could speculatively packetise the xm.zexti with it.
| xm.mkmsk mask, count | ||
|
|
||
| FUNCTION_NAME.save: | ||
| { xm.vstd vec1_tmp ; xm.nop } |
| xm.lddsp x22, x23, 2*8 | ||
| lw x24, 3*8(sp) | ||
|
|
||
| {xm.retsp ROUND_UP(NSTACKBYTES, 16); xm.nop} |
|
|
||
| #define FUNCTION_NAME lookup8_asm | ||
|
|
||
| .p2align 1 |
There was a problem hiding this comment.
This is sufficient for to be legal, but you may want to increase it.
at 2B alignment, because the function starts with a 4B instruction (a packet), the branching to it will always FNOP if this lands on a 2B (but not 4B) boundary.
You could increase it further to make the function FNOP-predictable or potentially FNOP-free, though you would need to consider the offset of the branch targets. I don't know if FNOP predictability is an aim of lib_nn in general.
| xm.stdsp x20, x21, 1*8 | ||
| xm.stdsp x22, x23, 2*8 | ||
| sw x24, 3*8(sp) | ||
| addi count, x14, 0 |
Implemented lookup8 in VX4B using the new VPU instruction xm.vlookup.
Tested with custom model, output is the same as the ref.