package x64 import ( "encoding/binary" "git.akyoto.dev/cli/q/src/build/cpu" "git.akyoto.dev/cli/q/src/build/sizeof" ) // MoveRegisterNumber moves an integer into the given register. func MoveRegisterNumber(code []byte, destination cpu.Register, number int) []byte { w := byte(0) if sizeof.Signed(int64(number)) == 8 { w = 1 } if w == 0 && number < 0 { return MoveRegisterNumber32(code, destination, number) } b := byte(0) if destination > 0b111 { b = 1 destination &= 0b111 } if w != 0 || b != 0 { code = append(code, REX(w, 0, 0, b)) } code = append(code, 0xB8+byte(destination)) if w == 1 { return binary.LittleEndian.AppendUint64(code, uint64(number)) } else { return binary.LittleEndian.AppendUint32(code, uint32(number)) } } // MoveRegisterNumber32 moves an integer into the given register and sign-extends the register. func MoveRegisterNumber32(code []byte, destination cpu.Register, number int) []byte { b := byte(0) if destination > 0b111 { b = 1 destination &= 0b111 } code = append(code, REX(1, 0, 0, b)) code = append(code, 0xC7) code = append(code, ModRM(AddressDirect, 0, byte(destination))) return binary.LittleEndian.AppendUint32(code, uint32(number)) } // MoveRegisterRegister moves a register value into another register. func MoveRegisterRegister(code []byte, destination cpu.Register, source cpu.Register) []byte { return encode(code, AddressDirect, source, destination, 8, 0x89) }