Implemented more arm64 instructions

This commit is contained in:
2025-03-06 23:13:14 +01:00
parent cb908e7b31
commit 0ac7fc9a85
26 changed files with 232 additions and 73 deletions

View File

@ -1,7 +1,10 @@
package asmc
import (
"encoding/binary"
"fmt"
"math"
"strings"
"git.urbach.dev/cli/q/src/arm"
"git.urbach.dev/cli/q/src/asm"
@ -12,11 +15,11 @@ func (c *compiler) compileARM(x asm.Instruction) {
case asm.CALL:
switch data := x.Data.(type) {
case *asm.Label:
position := len(c.code)
c.code = arm.Call(c.code, 0)
position := Address(len(c.code))
c.append(arm.Call(0))
pointer := &pointer{
Position: Address(position),
Position: position,
OpSize: 0,
Size: 4,
}
@ -28,8 +31,8 @@ func (c *compiler) compileARM(x asm.Instruction) {
panic(fmt.Sprintf("unknown jump label %s", data.Name))
}
distance := (destination - pointer.Position) / 4
return arm.EncodeCall(distance)
distance := (destination - position) / 4
return arm.Call(distance)
}
c.codePointers = append(c.codePointers, pointer)
@ -37,20 +40,67 @@ func (c *compiler) compileARM(x asm.Instruction) {
case asm.LABEL:
c.codeLabels[x.Data.(*asm.Label).Name] = Address(len(c.code))
c.append(0xa9be7bfd)
c.append(0x910003fd)
case asm.LOAD:
switch operands := x.Data.(type) {
case *asm.MemoryRegister:
if operands.Address.OffsetRegister == math.MaxUint8 {
c.append(arm.LoadRegister(operands.Register, operands.Address.Base, int16(operands.Address.Offset), operands.Address.Length))
} else {
// TODO: LoadDynamicRegister
panic("not implemented")
}
}
case asm.MOVE:
switch operands := x.Data.(type) {
case *asm.RegisterRegister:
c.append(arm.MoveRegisterRegister(operands.Destination, operands.Source))
case *asm.RegisterNumber:
c.code = arm.MoveRegisterNumber(c.code, operands.Register, operands.Number)
c.append(arm.MoveRegisterNumber(operands.Register, operands.Number))
case *asm.RegisterLabel:
position := Address(len(c.code))
c.append(arm.LoadAddress(operands.Register, 0))
if strings.HasPrefix(operands.Label, "data ") {
c.dataPointers = append(c.dataPointers, &pointer{
Position: position,
OpSize: 0,
Size: 4,
Resolve: func() Address {
destination, exists := c.dataLabels[operands.Label]
if !exists {
panic("unknown label")
}
destination += c.dataStart - c.codeStart
distance := destination - position + 8
return arm.LoadAddress(operands.Register, int(distance))
},
})
} else {
panic("not implemented")
}
}
case asm.RETURN:
c.code = arm.Return(c.code)
c.append(0xa8c27bfd)
c.append(0xd65f03c0)
c.append(arm.Return())
case asm.SYSCALL:
c.code = arm.Syscall(c.code)
c.append(arm.Syscall())
default:
c.code = arm.Nop(c.code)
panic("unknown mnemonic: " + x.Mnemonic.String())
}
}
func (c *compiler) append(code uint32) {
c.code = binary.LittleEndian.AppendUint32(c.code, code)
}