q/src/arm/Move.go

44 lines
1.5 KiB
Go

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)
}