Instruction operands must have the same size, except sign and zero extend move instructions.
In your case, you can add 16 bits to 64 bits register rsi in one instruction only this way:
add si, word [rsi+16]
translated into:
\x66\x03\x76\x10
Because si register(size a word) is a low part of rsi register, you can add to si without disturbing the upper bytes of rsi.
But it will work the same as a 64-bit add only if the 16-bit add result doesn't overflow. For example:
Let's say we have esi=0x0000FFFF, and we add 1 to si. We've got esi=0x00000000. And CF will be set, because of carry-out from the 16-bit add.
If you do need carry to propagate to the rest of RSI, zero-extend into any other register.
movzx rax, word ptr [rsi+16]
add rsi, rax
translated into:
\x48\x0F\xB7\x46\x10
\x48\x01\xC6
Also Ped7g noted:
but you will still pay performance penalty on some architectures, when you will use full rsi which is partially updated by si only, so performance wise it is still better to use some spare register to extend the word value to 64b first, and then add two 64b registers (if you will use rsi).
See also Why doesn't GCC use partial registers? for possible performance issues from writing SI and then reading RSI on P6-family CPUs, although that's not relevant for shellcode exploit payloads.