115 lines
2.2 KiB
Go
115 lines
2.2 KiB
Go
package core
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.akyoto.dev/cli/q/src/build/asm"
|
|
"git.akyoto.dev/cli/q/src/build/config"
|
|
"git.akyoto.dev/cli/q/src/build/cpu"
|
|
)
|
|
|
|
func (f *Function) AddLabel(label string) {
|
|
f.assembler.Label(asm.LABEL, label)
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) Call(label string) {
|
|
f.assembler.Call(label)
|
|
f.cpu.Use(f.cpu.Output[0])
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) Comment(format string, args ...any) {
|
|
f.assembler.Comment(fmt.Sprintf(format, args...))
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) Jump(mnemonic asm.Mnemonic, label string) {
|
|
f.assembler.Label(mnemonic, label)
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) Register(mnemonic asm.Mnemonic, a cpu.Register) {
|
|
f.assembler.Register(mnemonic, a)
|
|
|
|
if mnemonic == asm.POP {
|
|
f.cpu.Use(a)
|
|
}
|
|
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) RegisterNumber(mnemonic asm.Mnemonic, a cpu.Register, b int) {
|
|
if f.cpu.IsUsed(a) && isDestructive(mnemonic) {
|
|
f.SaveRegister(a)
|
|
}
|
|
|
|
f.assembler.RegisterNumber(mnemonic, a, b)
|
|
|
|
if mnemonic == asm.MOVE {
|
|
f.cpu.Use(a)
|
|
}
|
|
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) RegisterLabel(mnemonic asm.Mnemonic, register cpu.Register, label string) {
|
|
if f.cpu.IsUsed(register) && isDestructive(mnemonic) {
|
|
f.SaveRegister(register)
|
|
}
|
|
|
|
f.assembler.RegisterLabel(mnemonic, register, label)
|
|
|
|
if mnemonic == asm.MOVE {
|
|
f.cpu.Use(register)
|
|
}
|
|
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) RegisterRegister(mnemonic asm.Mnemonic, a cpu.Register, b cpu.Register) {
|
|
if mnemonic == asm.MOVE && a == b {
|
|
return
|
|
}
|
|
|
|
if f.cpu.IsUsed(a) && isDestructive(mnemonic) {
|
|
f.SaveRegister(a)
|
|
}
|
|
|
|
f.assembler.RegisterRegister(mnemonic, a, b)
|
|
|
|
if mnemonic == asm.MOVE {
|
|
f.cpu.Use(a)
|
|
}
|
|
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) Return() {
|
|
f.assembler.Return()
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) Syscall() {
|
|
f.assembler.Syscall()
|
|
f.cpu.Use(f.cpu.Output[0])
|
|
f.postInstruction()
|
|
}
|
|
|
|
func (f *Function) postInstruction() {
|
|
if !config.Assembler {
|
|
return
|
|
}
|
|
|
|
f.registerHistory = append(f.registerHistory, f.cpu.Used)
|
|
}
|
|
|
|
func isDestructive(mnemonic asm.Mnemonic) bool {
|
|
switch mnemonic {
|
|
case asm.MOVE, asm.ADD, asm.SUB, asm.MUL, asm.DIV:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|