Implemented more arm64 instructions
This commit is contained in:
@ -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)
|
||||
}
|
||||
|
Reference in New Issue
Block a user