Improved separation of concerns

This commit is contained in:
Eduard Urbach 2024-07-23 16:41:21 +02:00
parent dc5456b820
commit abba962455
Signed by: eduard
GPG key ID: 49226B848C78F6C8
36 changed files with 243 additions and 236 deletions

8
src/build/z/AddLabel.go Normal file
View file

@ -0,0 +1,8 @@
package z
import "git.akyoto.dev/cli/q/src/build/asm"
func (f *Compiler) AddLabel(label string) {
f.Assembler.Label(asm.LABEL, label)
f.postInstruction()
}

7
src/build/z/Call.go Normal file
View file

@ -0,0 +1,7 @@
package z
func (f *Compiler) Call(label string) {
f.Assembler.Call(label)
f.CurrentScope().Use(f.CPU.Output[0])
f.postInstruction()
}

8
src/build/z/Comment.go Normal file
View file

@ -0,0 +1,8 @@
package z
import "fmt"
func (f *Compiler) Comment(format string, args ...any) {
f.Assembler.Comment(fmt.Sprintf(format, args...))
f.postInstruction()
}

15
src/build/z/Compiler.go Normal file
View file

@ -0,0 +1,15 @@
package z
import (
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu"
"git.akyoto.dev/cli/q/src/build/scope"
)
// Compiler is a register usage aware assembler.
type Compiler struct {
scope.Stack
Assembler asm.Assembler
CPU cpu.CPU
RegisterHistory []uint64
}

8
src/build/z/Jump.go Normal file
View file

@ -0,0 +1,8 @@
package z
import "git.akyoto.dev/cli/q/src/build/asm"
func (f *Compiler) Jump(mnemonic asm.Mnemonic, label string) {
f.Assembler.Label(mnemonic, label)
f.postInstruction()
}

View file

@ -0,0 +1,8 @@
package z
import "git.akyoto.dev/cli/q/src/build/asm"
func (f *Compiler) MemoryNumber(mnemonic asm.Mnemonic, a asm.Memory, b int) {
f.Assembler.MemoryNumber(mnemonic, a, b)
f.postInstruction()
}

16
src/build/z/Register.go Normal file
View file

@ -0,0 +1,16 @@
package z
import (
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu"
)
func (f *Compiler) Register(mnemonic asm.Mnemonic, a cpu.Register) {
f.Assembler.Register(mnemonic, a)
if mnemonic == asm.POP {
f.CurrentScope().Use(a)
}
f.postInstruction()
}

View file

@ -0,0 +1,20 @@
package z
import (
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu"
)
func (f *Compiler) RegisterLabel(mnemonic asm.Mnemonic, register cpu.Register, label string) {
if f.CurrentScope().IsUsed(register) && isDestructive(mnemonic) {
f.SaveRegister(register)
}
f.Assembler.RegisterLabel(mnemonic, register, label)
if mnemonic == asm.MOVE {
f.CurrentScope().Use(register)
}
f.postInstruction()
}

View file

@ -0,0 +1,20 @@
package z
import (
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu"
)
func (f *Compiler) RegisterNumber(mnemonic asm.Mnemonic, a cpu.Register, b int) {
if f.CurrentScope().IsUsed(a) && isDestructive(mnemonic) {
f.SaveRegister(a)
}
f.Assembler.RegisterNumber(mnemonic, a, b)
if mnemonic == asm.MOVE {
f.CurrentScope().Use(a)
}
f.postInstruction()
}

View file

@ -0,0 +1,24 @@
package z
import (
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu"
)
func (f *Compiler) RegisterRegister(mnemonic asm.Mnemonic, a cpu.Register, b cpu.Register) {
if mnemonic == asm.MOVE && a == b {
return
}
if f.CurrentScope().IsUsed(a) && isDestructive(mnemonic) {
f.SaveRegister(a)
}
f.Assembler.RegisterRegister(mnemonic, a, b)
if mnemonic == asm.MOVE {
f.CurrentScope().Use(a)
}
f.postInstruction()
}

6
src/build/z/Return.go Normal file
View file

@ -0,0 +1,6 @@
package z
func (f *Compiler) Return() {
f.Assembler.Return()
f.postInstruction()
}

View file

@ -0,0 +1,30 @@
package z
import (
"git.akyoto.dev/cli/q/src/build/asm"
"git.akyoto.dev/cli/q/src/build/cpu"
)
// SaveRegister attempts to move a variable occupying this register to another register.
func (f *Compiler) SaveRegister(register cpu.Register) {
if !f.CurrentScope().IsUsed(register) {
return
}
for _, general := range f.CPU.General {
if register == general {
return
}
}
variable := f.VariableByRegister(register)
if variable == nil || variable.Alive == 0 {
return
}
newRegister := f.CurrentScope().MustFindFree(f.CPU.General)
f.CurrentScope().Reserve(newRegister)
f.RegisterRegister(asm.MOVE, newRegister, register)
variable.Register = newRegister
}

7
src/build/z/Syscall.go Normal file
View file

@ -0,0 +1,7 @@
package z
func (f *Compiler) Syscall() {
f.Assembler.Syscall()
f.CurrentScope().Use(f.CPU.Output[0])
f.postInstruction()
}

View file

@ -0,0 +1,12 @@
package z
import "git.akyoto.dev/cli/q/src/build/asm"
func isDestructive(mnemonic asm.Mnemonic) bool {
switch mnemonic {
case asm.MOVE, asm.ADD, asm.SUB, asm.MUL, asm.DIV:
return true
default:
return false
}
}

View file

@ -0,0 +1,11 @@
package z
import "git.akyoto.dev/cli/q/src/build/config"
func (f *Compiler) postInstruction() {
if !config.Assembler {
return
}
f.RegisterHistory = append(f.RegisterHistory, f.CurrentScope().Used)
}