package arm import ( "git.urbach.dev/cli/q/src/cpu" ) // MoveRegisterRegister copies a register to another register. func MoveRegisterRegister(destination cpu.Register, source cpu.Register) uint32 { if source == SP || destination == SP { return AddRegisterNumber(destination, source, 0) } return 0b10101010<<24 | reg3(destination, ZR, source) } // MoveRegisterNumber moves an integer into the given register. func MoveRegisterNumber(destination cpu.Register, number int) uint32 { if number < 0 { return MoveInvertedWideImmediate(destination, ^number) } return MoveZero(destination, 0, uint16(number)) } // MoveInvertedWideImmediate moves an inverted 16-bit immediate value to a register. func MoveInvertedWideImmediate(destination cpu.Register, number int) uint32 { return 0b100100101<<23 | regImm(destination, number) } // MoveKeep moves a 16-bit integer into the given register and keeps all other bits. func MoveKeep(destination cpu.Register, halfword int, number uint16) uint32 { return mov(0b11, halfword, number, destination) } // MoveZero moves a 16-bit integer into the given register and clears all other bits to zero. func MoveZero(destination cpu.Register, halfword int, number uint16) uint32 { return mov(0b10, halfword, number, destination) } // mov encodes a generic move instruction. func mov(opCode uint32, halfword int, number uint16, destination cpu.Register) uint32 { return 1<<31 | opCode<<29 | 0b100101<<23 | uint32(halfword<<21) | uint32(number<<5) | uint32(destination) }