Improved assembler
This commit is contained in:
106
src/cpu/CPU.go
Normal file
106
src/cpu/CPU.go
Normal file
@ -0,0 +1,106 @@
|
||||
package cpu
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/register"
|
||||
|
||||
// CPU manages the allocation state of registers.
|
||||
type CPU struct {
|
||||
All List
|
||||
General List
|
||||
Call List
|
||||
Syscall List
|
||||
}
|
||||
|
||||
// New creates a new CPU state.
|
||||
func New() *CPU {
|
||||
// Rather than doing lots of mini allocations
|
||||
// we'll allocate memory for all registers at once.
|
||||
registers := [16]Register{
|
||||
{ID: register.R0},
|
||||
{ID: register.R1},
|
||||
{ID: register.R2},
|
||||
{ID: register.R3},
|
||||
{ID: register.R4},
|
||||
{ID: register.R5},
|
||||
{ID: register.R6},
|
||||
{ID: register.R7},
|
||||
{ID: register.R8},
|
||||
{ID: register.R9},
|
||||
{ID: register.R10},
|
||||
{ID: register.R11},
|
||||
{ID: register.R12},
|
||||
{ID: register.R13},
|
||||
{ID: register.R14},
|
||||
{ID: register.R15},
|
||||
}
|
||||
|
||||
rax := ®isters[0]
|
||||
rcx := ®isters[1]
|
||||
rdx := ®isters[2]
|
||||
rbx := ®isters[3]
|
||||
rsp := ®isters[4]
|
||||
rbp := ®isters[5]
|
||||
rsi := ®isters[6]
|
||||
rdi := ®isters[7]
|
||||
r8 := ®isters[8]
|
||||
r9 := ®isters[9]
|
||||
r10 := ®isters[10]
|
||||
r11 := ®isters[11]
|
||||
r12 := ®isters[12]
|
||||
r13 := ®isters[13]
|
||||
r14 := ®isters[14]
|
||||
r15 := ®isters[15]
|
||||
|
||||
// Register configuration
|
||||
return &CPU{
|
||||
All: List{
|
||||
rax,
|
||||
rcx,
|
||||
rdx,
|
||||
rbx,
|
||||
rsp,
|
||||
rbp,
|
||||
rsi,
|
||||
rdi,
|
||||
r8,
|
||||
r9,
|
||||
r10,
|
||||
r11,
|
||||
r12,
|
||||
r13,
|
||||
r14,
|
||||
r15,
|
||||
},
|
||||
General: List{
|
||||
rcx,
|
||||
rbx,
|
||||
rbp,
|
||||
r11,
|
||||
r12,
|
||||
r13,
|
||||
r14,
|
||||
r15,
|
||||
},
|
||||
Call: List{
|
||||
rdi,
|
||||
rsi,
|
||||
rdx,
|
||||
r10,
|
||||
r8,
|
||||
r9,
|
||||
},
|
||||
Syscall: List{
|
||||
rax,
|
||||
rdi,
|
||||
rsi,
|
||||
rdx,
|
||||
r10,
|
||||
r8,
|
||||
r9,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ByID returns the register with the given ID.
|
||||
func (cpu *CPU) ByID(id register.ID) *Register {
|
||||
return cpu.All[id]
|
||||
}
|
29
src/cpu/List.go
Normal file
29
src/cpu/List.go
Normal file
@ -0,0 +1,29 @@
|
||||
package cpu
|
||||
|
||||
// List is a list of registers.
|
||||
type List []*Register
|
||||
|
||||
// FindFree tries to find a free register
|
||||
// and returns nil when all are currently occupied.
|
||||
func (registers List) FindFree() *Register {
|
||||
for _, register := range registers {
|
||||
if register.IsFree() {
|
||||
return register
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// InUse returns a list of registers that are currently in use.
|
||||
func (registers List) InUse() List {
|
||||
var inUse List
|
||||
|
||||
for _, register := range registers {
|
||||
if !register.IsFree() {
|
||||
inUse = append(inUse, register)
|
||||
}
|
||||
}
|
||||
|
||||
return inUse
|
||||
}
|
39
src/cpu/Register.go
Normal file
39
src/cpu/Register.go
Normal file
@ -0,0 +1,39 @@
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/errors"
|
||||
"git.akyoto.dev/cli/q/src/register"
|
||||
)
|
||||
|
||||
// Register represents a single CPU register.
|
||||
type Register struct {
|
||||
ID register.ID
|
||||
user fmt.Stringer
|
||||
}
|
||||
|
||||
// Use marks the register as used by the given object.
|
||||
func (register *Register) Use(obj fmt.Stringer) error {
|
||||
if register.user != nil {
|
||||
return &errors.RegisterInUse{Register: register.ID.String(), User: register.user.String()}
|
||||
}
|
||||
|
||||
register.user = obj
|
||||
return nil
|
||||
}
|
||||
|
||||
// Free frees the register so that it can be used for new calculations.
|
||||
func (register *Register) Free() {
|
||||
register.user = nil
|
||||
}
|
||||
|
||||
// IsFree returns true if the register is not in use.
|
||||
func (register *Register) IsFree() bool {
|
||||
return register.user == nil
|
||||
}
|
||||
|
||||
// String returns a human-readable representation of the register.
|
||||
func (register *Register) String() string {
|
||||
return fmt.Sprintf("%s%s%v", register.ID, "=", register.user)
|
||||
}
|
Reference in New Issue
Block a user