Implemented more arm64 instructions
This commit is contained in:
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -12,4 +12,5 @@ type compiler struct {
|
||||
dllPointers []*pointer
|
||||
dlls dll.List
|
||||
codeStart Address
|
||||
dataStart Address
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func (c *compiler) move(x asm.Instruction) {
|
||||
panic("unknown label")
|
||||
}
|
||||
|
||||
return destination
|
||||
return config.BaseAddress + c.dataStart + destination + 8
|
||||
},
|
||||
})
|
||||
} else {
|
||||
|
@ -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()
|
||||
|
Reference in New Issue
Block a user