Improved x64 encoder

This commit is contained in:
Eduard Urbach 2024-07-20 12:49:26 +02:00
parent 2c2b6e93db
commit 53379ff5bc
Signed by: eduard
GPG key ID: 49226B848C78F6C8
9 changed files with 214 additions and 49 deletions

View file

@ -1,11 +1,18 @@
package x64
import "git.akyoto.dev/cli/q/src/build/cpu"
// encode is the core function that encodes an instruction.
func encode(code []byte, w byte, mod byte, reg byte, rm byte, opCodes ...byte) []byte {
func encode(code []byte, mod byte, reg cpu.Register, rm cpu.Register, numBytes byte, opCodes ...byte) []byte {
w := byte(0) // Indicates a 64-bit register.
r := byte(0) // Extension to the "reg" field in ModRM.
x := byte(0) // Extension to the SIB index field.
b := byte(0) // Extension to the "rm" field in ModRM or the SIB base (r8 up to r15 use this).
if numBytes == 8 {
w = 1
}
if reg > 0b111 {
r = 1
reg &= 0b111
@ -16,12 +23,12 @@ func encode(code []byte, w byte, mod byte, reg byte, rm byte, opCodes ...byte) [
rm &= 0b111
}
if w != 0 || r != 0 || x != 0 || b != 0 {
if w != 0 || r != 0 || x != 0 || b != 0 || (numBytes == 1 && (reg == RSP || reg == RBP || reg == RSI || reg == RDI)) {
code = append(code, REX(w, r, x, b))
}
code = append(code, opCodes...)
code = append(code, ModRM(mod, reg, rm))
code = append(code, ModRM(mod, byte(reg), byte(rm)))
return code
}