diff --git a/src/asm/unnecessary.go b/src/asm/CanSkip.go similarity index 67% rename from src/asm/unnecessary.go rename to src/asm/CanSkip.go index c3a915a..c707990 100644 --- a/src/asm/unnecessary.go +++ b/src/asm/CanSkip.go @@ -2,8 +2,12 @@ package asm import "git.akyoto.dev/cli/q/src/cpu" -// unnecessary returns true if the register/register operation can be skipped. -func (a *Assembler) unnecessary(mnemonic Mnemonic, left cpu.Register, right cpu.Register) bool { +// CanSkip returns true if the register/register operation can be skipped. +func (a *Assembler) CanSkip(mnemonic Mnemonic, left cpu.Register, right cpu.Register) bool { + if mnemonic == MOVE && left == right { + return true + } + if len(a.Instructions) == 0 { return false } diff --git a/src/asm/CanSkipReturn.go b/src/asm/CanSkipReturn.go new file mode 100644 index 0000000..0ce31cb --- /dev/null +++ b/src/asm/CanSkipReturn.go @@ -0,0 +1,16 @@ +package asm + +// CanSkipReturn returns true if the return operation can be skipped. +func (a *Assembler) CanSkipReturn() bool { + if len(a.Instructions) == 0 { + return false + } + + lastMnemonic := a.Instructions[len(a.Instructions)-1].Mnemonic + + if lastMnemonic == RETURN || lastMnemonic == JUMP { + return true + } + + return false +} diff --git a/src/asm/Instructions.go b/src/asm/Instructions.go index acfa639..ab6a510 100644 --- a/src/asm/Instructions.go +++ b/src/asm/Instructions.go @@ -32,14 +32,6 @@ func (a *Assembler) DLLCall(name string) { // Return returns back to the caller. func (a *Assembler) Return() { - if len(a.Instructions) > 0 { - lastMnemonic := a.Instructions[len(a.Instructions)-1].Mnemonic - - if lastMnemonic == RETURN || lastMnemonic == JUMP { - return - } - } - a.Instructions = append(a.Instructions, Instruction{Mnemonic: RETURN}) } diff --git a/src/asm/RegisterRegister.go b/src/asm/RegisterRegister.go index 8631fd6..c133e2c 100644 --- a/src/asm/RegisterRegister.go +++ b/src/asm/RegisterRegister.go @@ -19,10 +19,6 @@ func (data *RegisterRegister) String() string { // RegisterRegister adds an instruction using two registers. func (a *Assembler) RegisterRegister(mnemonic Mnemonic, left cpu.Register, right cpu.Register) { - if a.unnecessary(mnemonic, left, right) { - return - } - a.Instructions = append(a.Instructions, Instruction{ Mnemonic: mnemonic, Data: &RegisterRegister{ diff --git a/src/core/CompileReturn.go b/src/core/CompileReturn.go index 19d7963..87050e8 100644 --- a/src/core/CompileReturn.go +++ b/src/core/CompileReturn.go @@ -8,9 +8,8 @@ import ( // CompileReturn compiles a return instruction. func (f *Function) CompileReturn(node *ast.Return) error { - defer f.Return() - if len(node.Values) == 0 { + f.Return() return nil } @@ -27,12 +26,13 @@ func (f *Function) CompileReturn(node *ast.Return) error { if !types.Is(typ, f.Output[i].Type) { if f.Package == "mem" && f.Name == "alloc" { - return nil + continue } return errors.New(&errors.TypeMismatch{Encountered: typ.Name(), Expected: f.Output[i].Type.Name(), ParameterName: "", IsReturn: true}, f.File, node.Values[i].Token.Position) } } + f.Return() return nil } diff --git a/src/register/MemoryRegister.go b/src/register/MemoryRegister.go index 1a3c770..fa13e9f 100644 --- a/src/register/MemoryRegister.go +++ b/src/register/MemoryRegister.go @@ -7,5 +7,10 @@ import ( func (f *Machine) MemoryRegister(mnemonic asm.Mnemonic, a asm.Memory, b cpu.Register) { f.Assembler.MemoryRegister(mnemonic, a, b) + + if mnemonic == asm.LOAD { + f.UseRegister(b) + } + f.postInstruction() } diff --git a/src/register/RegisterNumber.go b/src/register/RegisterNumber.go index 23aa23f..f3986f5 100644 --- a/src/register/RegisterNumber.go +++ b/src/register/RegisterNumber.go @@ -27,7 +27,6 @@ func (f *Machine) RegisterNumber(mnemonic asm.Mnemonic, a cpu.Register, b int) { f.Assembler.RegisterNumber(asm.MOVE, tmp, b) f.UseRegister(tmp) f.postInstruction() - f.Assembler.RegisterRegister(mnemonic, a, tmp) - f.postInstruction() + f.RegisterRegister(mnemonic, a, tmp) f.FreeRegister(tmp) } diff --git a/src/register/RegisterRegister.go b/src/register/RegisterRegister.go index 98ac5ea..59208ae 100644 --- a/src/register/RegisterRegister.go +++ b/src/register/RegisterRegister.go @@ -6,7 +6,7 @@ import ( ) func (f *Machine) RegisterRegister(mnemonic asm.Mnemonic, a cpu.Register, b cpu.Register) { - if mnemonic == asm.MOVE && a == b { + if f.Assembler.CanSkip(mnemonic, a, b) { return } diff --git a/src/register/Return.go b/src/register/Return.go index b9e09b7..032b74c 100644 --- a/src/register/Return.go +++ b/src/register/Return.go @@ -1,6 +1,13 @@ package register func (f *Machine) Return() { + if f.Assembler.CanSkipReturn() { + return + } + f.Assembler.Return() + scope := f.CurrentScope() + scope.Reserved = 0 + scope.Used = 0 f.postInstruction() }