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,6 @@
package asmc
import (
"git.urbach.dev/cli/q/src/arm"
"git.urbach.dev/cli/q/src/asm"
"git.urbach.dev/cli/q/src/config"
"git.urbach.dev/cli/q/src/dll"
@ -31,10 +30,6 @@ func Finalize(a asm.Assembler, dlls dll.List) ([]byte, []byte) {
c.compileARM(x)
}
c.code = arm.MoveRegisterNumber(c.code, arm.X0, 0)
c.code = arm.MoveRegisterNumber(c.code, arm.X8, 0x5D)
c.code = arm.Syscall(c.code)
case config.X86:
for _, x := range a.Instructions {
c.compileX86(x)

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

View File

@ -12,4 +12,5 @@ type compiler struct {
dllPointers []*pointer
dlls dll.List
codeStart Address
dataStart Address
}

View File

@ -11,9 +11,9 @@ func (c *compiler) load(x asm.Instruction) {
switch operands := x.Data.(type) {
case *asm.MemoryRegister:
if operands.Address.OffsetRegister == math.MaxUint8 {
c.code = x86.LoadRegister(c.code, operands.Register, operands.Address.Offset, operands.Address.Length, operands.Address.Base)
c.code = x86.LoadRegister(c.code, operands.Register, operands.Address.Base, operands.Address.Offset, operands.Address.Length)
} else {
c.code = x86.LoadDynamicRegister(c.code, operands.Register, operands.Address.OffsetRegister, operands.Address.Length, operands.Address.Base)
c.code = x86.LoadDynamicRegister(c.code, operands.Register, operands.Address.Base, operands.Address.OffsetRegister, operands.Address.Length)
}
}
}

View File

@ -35,7 +35,7 @@ func (c *compiler) move(x asm.Instruction) {
panic("unknown label")
}
return destination
return config.BaseAddress + c.dataStart + destination + 8
},
})
} else {

View File

@ -77,16 +77,16 @@ restart:
}
}
dataStart, _ := fs.Align(c.codeStart+Address(len(c.code)), config.Align)
c.dataStart, _ = fs.Align(c.codeStart+Address(len(c.code)), config.Align)
for _, pointer := range c.dataPointers {
address := config.BaseAddress + dataStart + pointer.Resolve() + 8
slice := c.code[pointer.Position : pointer.Position+4]
address := pointer.Resolve()
slice := c.code[pointer.Position : pointer.Position+Address(pointer.Size)]
binary.LittleEndian.PutUint32(slice, uint32(address))
}
if config.TargetOS == config.Windows {
importsStart, _ := fs.Align(dataStart+Address(len(c.data)), config.Align)
importsStart, _ := fs.Align(c.dataStart+Address(len(c.data)), config.Align)
for _, pointer := range c.dllPointers {
destination := importsStart + pointer.Resolve()