Added fallback for numbers that can't be encoded on arm64
This commit is contained in:
@ -3,7 +3,7 @@ package arm
|
|||||||
import "git.urbach.dev/cli/q/src/cpu"
|
import "git.urbach.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// AddRegisterNumber adds a number to a register.
|
// AddRegisterNumber adds a number to a register.
|
||||||
func AddRegisterNumber(destination cpu.Register, source cpu.Register, number int) uint32 {
|
func AddRegisterNumber(destination cpu.Register, source cpu.Register, number int) (code uint32, encodable bool) {
|
||||||
return addRegisterNumber(destination, source, number, 0)
|
return addRegisterNumber(destination, source, number, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,23 +13,23 @@ func AddRegisterRegister(destination cpu.Register, source cpu.Register, operand
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addRegisterNumber adds the register and optionally updates the condition flags based on the result.
|
// addRegisterNumber adds the register and optionally updates the condition flags based on the result.
|
||||||
func addRegisterNumber(destination cpu.Register, source cpu.Register, number int, flags uint32) uint32 {
|
func addRegisterNumber(destination cpu.Register, source cpu.Register, number int, flags uint32) (code uint32, encodable bool) {
|
||||||
shift := uint32(0)
|
shift := uint32(0)
|
||||||
|
|
||||||
if number > mask12 {
|
if number > mask12 {
|
||||||
if number&mask12 != 0 {
|
if number&mask12 != 0 {
|
||||||
panic("number can't be encoded")
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
shift = 1
|
shift = 1
|
||||||
number >>= 12
|
number >>= 12
|
||||||
|
|
||||||
if number > mask12 {
|
if number > mask12 {
|
||||||
panic("number can't be encoded")
|
return 0, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return flags<<29 | 0b100100010<<23 | shift<<22 | reg2Imm(destination, source, number)
|
return flags<<29 | 0b100100010<<23 | shift<<22 | reg2Imm(destination, source, number), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// addRegisterRegister adds the registers and optionally updates the condition flags based on the result.
|
// addRegisterRegister adds the registers and optionally updates the condition flags based on the result.
|
||||||
|
@ -21,7 +21,8 @@ func TestAddRegisterNumber(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("add %s, %s, %d", pattern.Destination, pattern.Source, pattern.Number)
|
t.Logf("add %s, %s, %d", pattern.Destination, pattern.Source, pattern.Number)
|
||||||
code := arm.AddRegisterNumber(pattern.Destination, pattern.Source, pattern.Number)
|
code, encodable := arm.AddRegisterNumber(pattern.Destination, pattern.Source, pattern.Number)
|
||||||
|
assert.True(t, encodable)
|
||||||
assert.DeepEqual(t, code, pattern.Code)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package arm
|
|||||||
import "git.urbach.dev/cli/q/src/cpu"
|
import "git.urbach.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// CompareRegisterNumber is an alias for a subtraction that updates the conditional flags and discards the result.
|
// CompareRegisterNumber is an alias for a subtraction that updates the conditional flags and discards the result.
|
||||||
func CompareRegisterNumber(register cpu.Register, number int) uint32 {
|
func CompareRegisterNumber(register cpu.Register, number int) (code uint32, encodable bool) {
|
||||||
if number < 0 {
|
if number < 0 {
|
||||||
return addRegisterNumber(ZR, register, -number, 1)
|
return addRegisterNumber(ZR, register, -number, 1)
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,8 @@ func TestCompareRegisterNumber(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("cmp %s, %d", pattern.Source, pattern.Number)
|
t.Logf("cmp %s, %d", pattern.Source, pattern.Number)
|
||||||
code := arm.CompareRegisterNumber(pattern.Source, pattern.Number)
|
code, encodable := arm.CompareRegisterNumber(pattern.Source, pattern.Number)
|
||||||
|
assert.True(t, encodable)
|
||||||
assert.DeepEqual(t, code, pattern.Code)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,8 @@ func MoveRegisterNumberSI(destination cpu.Register, number int) (uint32, bool) {
|
|||||||
// MoveRegisterRegister copies a register to another register.
|
// MoveRegisterRegister copies a register to another register.
|
||||||
func MoveRegisterRegister(destination cpu.Register, source cpu.Register) uint32 {
|
func MoveRegisterRegister(destination cpu.Register, source cpu.Register) uint32 {
|
||||||
if source == SP || destination == SP {
|
if source == SP || destination == SP {
|
||||||
return AddRegisterNumber(destination, source, 0)
|
code, _ := AddRegisterNumber(destination, source, 0)
|
||||||
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
return OrRegisterRegister(destination, ZR, source)
|
return OrRegisterRegister(destination, ZR, source)
|
||||||
|
@ -3,7 +3,7 @@ package arm
|
|||||||
import "git.urbach.dev/cli/q/src/cpu"
|
import "git.urbach.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// SubRegisterNumber subtracts a number from the given register.
|
// SubRegisterNumber subtracts a number from the given register.
|
||||||
func SubRegisterNumber(destination cpu.Register, source cpu.Register, number int) uint32 {
|
func SubRegisterNumber(destination cpu.Register, source cpu.Register, number int) (code uint32, encodable bool) {
|
||||||
return subRegisterNumber(destination, source, number, 0)
|
return subRegisterNumber(destination, source, number, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,23 +13,23 @@ func SubRegisterRegister(destination cpu.Register, source cpu.Register, operand
|
|||||||
}
|
}
|
||||||
|
|
||||||
// subRegisterNumber subtracts the register and optionally updates the condition flags based on the result.
|
// subRegisterNumber subtracts the register and optionally updates the condition flags based on the result.
|
||||||
func subRegisterNumber(destination cpu.Register, source cpu.Register, number int, flags uint32) uint32 {
|
func subRegisterNumber(destination cpu.Register, source cpu.Register, number int, flags uint32) (code uint32, encodable bool) {
|
||||||
shift := uint32(0)
|
shift := uint32(0)
|
||||||
|
|
||||||
if number > mask12 {
|
if number > mask12 {
|
||||||
if number&mask12 != 0 {
|
if number&mask12 != 0 {
|
||||||
panic("number can't be encoded")
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
shift = 1
|
shift = 1
|
||||||
number >>= 12
|
number >>= 12
|
||||||
|
|
||||||
if number > mask12 {
|
if number > mask12 {
|
||||||
panic("number can't be encoded")
|
return 0, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return flags<<29 | 0b110100010<<23 | shift<<22 | reg2Imm(destination, source, number)
|
return flags<<29 | 0b110100010<<23 | shift<<22 | reg2Imm(destination, source, number), true
|
||||||
}
|
}
|
||||||
|
|
||||||
// subRegisterRegister subtracts the registers and optionally updates the condition flags based on the result.
|
// subRegisterRegister subtracts the registers and optionally updates the condition flags based on the result.
|
||||||
|
@ -22,7 +22,8 @@ func TestSubRegisterNumber(t *testing.T) {
|
|||||||
|
|
||||||
for _, pattern := range usagePatterns {
|
for _, pattern := range usagePatterns {
|
||||||
t.Logf("sub %s, %s, %d", pattern.Destination, pattern.Source, pattern.Number)
|
t.Logf("sub %s, %s, %d", pattern.Destination, pattern.Source, pattern.Number)
|
||||||
code := arm.SubRegisterNumber(pattern.Destination, pattern.Source, pattern.Number)
|
code, encodable := arm.SubRegisterNumber(pattern.Destination, pattern.Source, pattern.Number)
|
||||||
|
assert.True(t, encodable)
|
||||||
assert.DeepEqual(t, code, pattern.Code)
|
assert.DeepEqual(t, code, pattern.Code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,45 @@ import (
|
|||||||
"git.urbach.dev/cli/q/src/asm"
|
"git.urbach.dev/cli/q/src/asm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *compiler) compileARM(x asm.Instruction) {
|
func (c *compiler) ARM(x asm.Instruction) {
|
||||||
switch x.Mnemonic {
|
switch x.Mnemonic {
|
||||||
|
case asm.MOVE:
|
||||||
|
switch x.Type {
|
||||||
|
case asm.TypeRegisterRegister:
|
||||||
|
operands := c.assembler.Param.RegisterRegister[x.Index]
|
||||||
|
c.append(arm.MoveRegisterRegister(operands.Destination, operands.Source))
|
||||||
|
|
||||||
|
case asm.TypeRegisterNumber:
|
||||||
|
operands := c.assembler.Param.RegisterNumber[x.Index]
|
||||||
|
c.code = arm.MoveRegisterNumber(c.code, operands.Register, operands.Number)
|
||||||
|
|
||||||
|
case asm.TypeRegisterLabel:
|
||||||
|
operands := c.assembler.Param.RegisterLabel[x.Index]
|
||||||
|
position := Address(len(c.code))
|
||||||
|
c.append(arm.LoadAddress(operands.Register, 0))
|
||||||
|
|
||||||
|
if operands.Label.Type == asm.DataLabel {
|
||||||
|
c.dataPointers = append(c.dataPointers, &pointer{
|
||||||
|
Position: position,
|
||||||
|
OpSize: 0,
|
||||||
|
Size: 4,
|
||||||
|
Resolve: func() Address {
|
||||||
|
destination, exists := c.dataLabels[operands.Label.Name]
|
||||||
|
|
||||||
|
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.CALL:
|
case asm.CALL:
|
||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeLabel:
|
case asm.TypeLabel:
|
||||||
@ -84,11 +121,19 @@ func (c *compiler) compileARM(x asm.Instruction) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case asm.RETURN:
|
||||||
|
c.append(arm.LoadPair(arm.FP, arm.LR, arm.SP, 16))
|
||||||
|
c.append(arm.Return())
|
||||||
|
|
||||||
|
case asm.SYSCALL:
|
||||||
|
c.append(arm.Syscall())
|
||||||
|
|
||||||
case asm.PUSH:
|
case asm.PUSH:
|
||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegister:
|
case asm.TypeRegister:
|
||||||
operand := c.assembler.Param.Register[x.Index]
|
operand := c.assembler.Param.Register[x.Index]
|
||||||
c.append(arm.SubRegisterNumber(arm.SP, arm.SP, 16))
|
code, _ := arm.SubRegisterNumber(arm.SP, arm.SP, 16)
|
||||||
|
c.append(code)
|
||||||
c.append(arm.StoreRegister(operand.Register, arm.SP, 0, 8))
|
c.append(arm.StoreRegister(operand.Register, arm.SP, 0, 8))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +142,8 @@ func (c *compiler) compileARM(x asm.Instruction) {
|
|||||||
case asm.TypeRegister:
|
case asm.TypeRegister:
|
||||||
operand := c.assembler.Param.Register[x.Index]
|
operand := c.assembler.Param.Register[x.Index]
|
||||||
c.append(arm.LoadRegister(operand.Register, arm.SP, 0, 8))
|
c.append(arm.LoadRegister(operand.Register, arm.SP, 0, 8))
|
||||||
c.append(arm.AddRegisterNumber(arm.SP, arm.SP, 16))
|
code, _ := arm.AddRegisterNumber(arm.SP, arm.SP, 16)
|
||||||
|
c.append(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
case asm.AND:
|
case asm.AND:
|
||||||
@ -158,7 +204,15 @@ func (c *compiler) compileARM(x asm.Instruction) {
|
|||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegisterNumber:
|
case asm.TypeRegisterNumber:
|
||||||
operand := c.assembler.Param.RegisterNumber[x.Index]
|
operand := c.assembler.Param.RegisterNumber[x.Index]
|
||||||
c.append(arm.AddRegisterNumber(operand.Register, operand.Register, operand.Number))
|
code, encodable := arm.AddRegisterNumber(operand.Register, operand.Register, operand.Number)
|
||||||
|
|
||||||
|
if encodable {
|
||||||
|
c.append(code)
|
||||||
|
} else {
|
||||||
|
tmp := arm.X28
|
||||||
|
c.code = arm.MoveRegisterNumber(c.code, tmp, operand.Number)
|
||||||
|
c.append(arm.AddRegisterRegister(operand.Register, operand.Register, tmp))
|
||||||
|
}
|
||||||
case asm.TypeRegisterRegister:
|
case asm.TypeRegisterRegister:
|
||||||
operand := c.assembler.Param.RegisterRegister[x.Index]
|
operand := c.assembler.Param.RegisterRegister[x.Index]
|
||||||
c.append(arm.AddRegisterRegister(operand.Destination, operand.Destination, operand.Source))
|
c.append(arm.AddRegisterRegister(operand.Destination, operand.Destination, operand.Source))
|
||||||
@ -168,7 +222,15 @@ func (c *compiler) compileARM(x asm.Instruction) {
|
|||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegisterNumber:
|
case asm.TypeRegisterNumber:
|
||||||
operand := c.assembler.Param.RegisterNumber[x.Index]
|
operand := c.assembler.Param.RegisterNumber[x.Index]
|
||||||
c.append(arm.SubRegisterNumber(operand.Register, operand.Register, operand.Number))
|
code, encodable := arm.SubRegisterNumber(operand.Register, operand.Register, operand.Number)
|
||||||
|
|
||||||
|
if encodable {
|
||||||
|
c.append(code)
|
||||||
|
} else {
|
||||||
|
tmp := arm.X28
|
||||||
|
c.code = arm.MoveRegisterNumber(c.code, tmp, operand.Number)
|
||||||
|
c.append(arm.SubRegisterRegister(operand.Register, operand.Register, tmp))
|
||||||
|
}
|
||||||
case asm.TypeRegisterRegister:
|
case asm.TypeRegisterRegister:
|
||||||
operand := c.assembler.Param.RegisterRegister[x.Index]
|
operand := c.assembler.Param.RegisterRegister[x.Index]
|
||||||
c.append(arm.SubRegisterRegister(operand.Destination, operand.Destination, operand.Source))
|
c.append(arm.SubRegisterRegister(operand.Destination, operand.Destination, operand.Source))
|
||||||
@ -178,7 +240,15 @@ func (c *compiler) compileARM(x asm.Instruction) {
|
|||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegisterNumber:
|
case asm.TypeRegisterNumber:
|
||||||
operand := c.assembler.Param.RegisterNumber[x.Index]
|
operand := c.assembler.Param.RegisterNumber[x.Index]
|
||||||
c.append(arm.CompareRegisterNumber(operand.Register, operand.Number))
|
code, encodable := arm.CompareRegisterNumber(operand.Register, operand.Number)
|
||||||
|
|
||||||
|
if encodable {
|
||||||
|
c.append(code)
|
||||||
|
} else {
|
||||||
|
tmp := arm.X28
|
||||||
|
c.code = arm.MoveRegisterNumber(c.code, tmp, operand.Number)
|
||||||
|
c.append(arm.CompareRegisterRegister(operand.Register, tmp))
|
||||||
|
}
|
||||||
case asm.TypeRegisterRegister:
|
case asm.TypeRegisterRegister:
|
||||||
operand := c.assembler.Param.RegisterRegister[x.Index]
|
operand := c.assembler.Param.RegisterRegister[x.Index]
|
||||||
c.append(arm.CompareRegisterRegister(operand.Destination, operand.Source))
|
c.append(arm.CompareRegisterRegister(operand.Destination, operand.Source))
|
||||||
@ -219,43 +289,6 @@ func (c *compiler) compileARM(x asm.Instruction) {
|
|||||||
case asm.JE, asm.JNE, asm.JG, asm.JGE, asm.JL, asm.JLE, asm.JUMP:
|
case asm.JE, asm.JNE, asm.JG, asm.JGE, asm.JL, asm.JLE, asm.JUMP:
|
||||||
c.jumpARM(x)
|
c.jumpARM(x)
|
||||||
|
|
||||||
case asm.MOVE:
|
|
||||||
switch x.Type {
|
|
||||||
case asm.TypeRegisterRegister:
|
|
||||||
operands := c.assembler.Param.RegisterRegister[x.Index]
|
|
||||||
c.append(arm.MoveRegisterRegister(operands.Destination, operands.Source))
|
|
||||||
|
|
||||||
case asm.TypeRegisterNumber:
|
|
||||||
operands := c.assembler.Param.RegisterNumber[x.Index]
|
|
||||||
c.code = arm.MoveRegisterNumber(c.code, operands.Register, operands.Number)
|
|
||||||
|
|
||||||
case asm.TypeRegisterLabel:
|
|
||||||
operands := c.assembler.Param.RegisterLabel[x.Index]
|
|
||||||
position := Address(len(c.code))
|
|
||||||
c.append(arm.LoadAddress(operands.Register, 0))
|
|
||||||
|
|
||||||
if operands.Label.Type == asm.DataLabel {
|
|
||||||
c.dataPointers = append(c.dataPointers, &pointer{
|
|
||||||
Position: position,
|
|
||||||
OpSize: 0,
|
|
||||||
Size: 4,
|
|
||||||
Resolve: func() Address {
|
|
||||||
destination, exists := c.dataLabels[operands.Label.Name]
|
|
||||||
|
|
||||||
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.SHIFTL:
|
case asm.SHIFTL:
|
||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegisterNumber:
|
case asm.TypeRegisterNumber:
|
||||||
@ -274,13 +307,6 @@ func (c *compiler) compileARM(x asm.Instruction) {
|
|||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
case asm.RETURN:
|
|
||||||
c.append(arm.LoadPair(arm.FP, arm.LR, arm.SP, 16))
|
|
||||||
c.append(arm.Return())
|
|
||||||
|
|
||||||
case asm.SYSCALL:
|
|
||||||
c.append(arm.Syscall())
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("unknown mnemonic: " + x.Mnemonic.String())
|
panic("unknown mnemonic: " + x.Mnemonic.String())
|
||||||
}
|
}
|
@ -28,12 +28,12 @@ func Finalize(a *asm.Assembler, dlls dll.List) ([]byte, []byte) {
|
|||||||
switch config.TargetArch {
|
switch config.TargetArch {
|
||||||
case config.ARM:
|
case config.ARM:
|
||||||
for _, x := range a.Instructions {
|
for _, x := range a.Instructions {
|
||||||
c.compileARM(x)
|
c.ARM(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
case config.X86:
|
case config.X86:
|
||||||
for _, x := range a.Instructions {
|
for _, x := range a.Instructions {
|
||||||
c.compileX86(x)
|
c.X86(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,30 @@ import (
|
|||||||
"git.urbach.dev/cli/q/src/x86"
|
"git.urbach.dev/cli/q/src/x86"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *compiler) compileX86(x asm.Instruction) {
|
func (c *compiler) X86(x asm.Instruction) {
|
||||||
switch x.Mnemonic {
|
switch x.Mnemonic {
|
||||||
|
case asm.MOVE:
|
||||||
|
c.move(x)
|
||||||
|
|
||||||
|
case asm.CALL:
|
||||||
|
c.call(x)
|
||||||
|
|
||||||
|
case asm.LABEL:
|
||||||
|
label := c.assembler.Param.Label[x.Index]
|
||||||
|
c.codeLabels[label.Name] = Address(len(c.code))
|
||||||
|
|
||||||
|
case asm.LOAD:
|
||||||
|
c.load(x)
|
||||||
|
|
||||||
|
case asm.STORE:
|
||||||
|
c.store(x)
|
||||||
|
|
||||||
|
case asm.RETURN:
|
||||||
|
c.code = x86.Return(c.code)
|
||||||
|
|
||||||
|
case asm.SYSCALL:
|
||||||
|
c.code = x86.Syscall(c.code)
|
||||||
|
|
||||||
case asm.ADD:
|
case asm.ADD:
|
||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegisterNumber:
|
case asm.TypeRegisterNumber:
|
||||||
@ -81,9 +103,6 @@ func (c *compiler) compileX86(x asm.Instruction) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case asm.CALL:
|
|
||||||
c.call(x)
|
|
||||||
|
|
||||||
case asm.COMMENT:
|
case asm.COMMENT:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -103,16 +122,6 @@ func (c *compiler) compileX86(x asm.Instruction) {
|
|||||||
case asm.JE, asm.JNE, asm.JG, asm.JGE, asm.JL, asm.JLE, asm.JUMP:
|
case asm.JE, asm.JNE, asm.JG, asm.JGE, asm.JL, asm.JLE, asm.JUMP:
|
||||||
c.jumpX86(x)
|
c.jumpX86(x)
|
||||||
|
|
||||||
case asm.LABEL:
|
|
||||||
label := c.assembler.Param.Label[x.Index]
|
|
||||||
c.codeLabels[label.Name] = Address(len(c.code))
|
|
||||||
|
|
||||||
case asm.LOAD:
|
|
||||||
c.load(x)
|
|
||||||
|
|
||||||
case asm.MOVE:
|
|
||||||
c.move(x)
|
|
||||||
|
|
||||||
case asm.NEGATE:
|
case asm.NEGATE:
|
||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegister:
|
case asm.TypeRegister:
|
||||||
@ -147,9 +156,6 @@ func (c *compiler) compileX86(x asm.Instruction) {
|
|||||||
c.code = x86.PushRegister(c.code, operands.Register)
|
c.code = x86.PushRegister(c.code, operands.Register)
|
||||||
}
|
}
|
||||||
|
|
||||||
case asm.RETURN:
|
|
||||||
c.code = x86.Return(c.code)
|
|
||||||
|
|
||||||
case asm.SHIFTL:
|
case asm.SHIFTL:
|
||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegisterNumber:
|
case asm.TypeRegisterNumber:
|
||||||
@ -168,12 +174,6 @@ func (c *compiler) compileX86(x asm.Instruction) {
|
|||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
case asm.STORE:
|
|
||||||
c.store(x)
|
|
||||||
|
|
||||||
case asm.SYSCALL:
|
|
||||||
c.code = x86.Syscall(c.code)
|
|
||||||
|
|
||||||
case asm.XOR:
|
case asm.XOR:
|
||||||
switch x.Type {
|
switch x.Type {
|
||||||
case asm.TypeRegisterNumber:
|
case asm.TypeRegisterNumber:
|
18
src/asmc/bench_test.go
Normal file
18
src/asmc/bench_test.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package asmc_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.urbach.dev/cli/q/src/asm"
|
||||||
|
"git.urbach.dev/cli/q/src/asmc"
|
||||||
|
"git.urbach.dev/cli/q/src/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkFinalize(b *testing.B) {
|
||||||
|
a := asm.Assembler{}
|
||||||
|
a.RegisterNumber(asm.MOVE, cpu.Register(0), 0)
|
||||||
|
|
||||||
|
for b.Loop() {
|
||||||
|
asmc.Finalize(&a, nil)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user