Added other instructions to the instruction set + begun work on instructions behavior
This commit is contained in:
parent
866eebd43d
commit
5a47c7eb69
@ -5,7 +5,9 @@ import (
|
||||
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/cpu"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/instr"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/instrset"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/simcontext"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/siminstr"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -15,12 +17,7 @@ const (
|
||||
|
||||
func main() {
|
||||
cpu := cpu.New(simcontext.SimContext{}, nil)
|
||||
cpu.RegisterInstr(instr.InstrDesc{
|
||||
Mnemonic: "LDR",
|
||||
VariantName: "LDRIR",
|
||||
OpCode: 0x01,
|
||||
Format: instr.A,
|
||||
Formatter: func(i *instr.DecodedInstr) string { return "Hello" }})
|
||||
cpu.RegisterInstr(siminstr.SimInstrDesc{InstrDesc: &instrset.LDRIR, Behavior: nil})
|
||||
|
||||
fmt.Printf("MOV[6:0] = %#0x\n", cpu.GetOpCode(MOV_r1_r2))
|
||||
fmt.Printf("SVC[6:0] = %#0x\n", cpu.GetOpCode(SVC_ffffff))
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/breakcfg"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/events"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/instrset"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/sim"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/siminstrset"
|
||||
)
|
||||
|
||||
type SysoutEventLogger struct{}
|
||||
@ -30,7 +30,7 @@ func main() {
|
||||
|
||||
sim := sim.New(simConfig, schedulerConfig, eventLogger)
|
||||
|
||||
sim.RegisterInstructionSet(instrset.CentralInstructionSet)
|
||||
sim.RegisterInstructionSet(siminstrset.SimCentralInstructionSet[:])
|
||||
|
||||
/*
|
||||
sim.QueueStateAccess(func(s simstate.SimState) {
|
||||
|
@ -4,13 +4,14 @@ import (
|
||||
"log"
|
||||
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/instr"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/siminstr"
|
||||
)
|
||||
|
||||
const instrMask = 0x7f
|
||||
|
||||
func (cpu *Cpu) RegisterInstr(instrDesc instr.InstrDesc) {
|
||||
func (cpu *Cpu) RegisterInstr(desc siminstr.SimInstrDesc) {
|
||||
// TODO Implement it
|
||||
log.Printf("Registered: %+v\n", instrDesc)
|
||||
log.Printf("Registered: %s\n", desc.InstrDesc.VariantName)
|
||||
}
|
||||
|
||||
func (cpu *Cpu) GetOpCode(i instr.Instr) uint32 {
|
||||
|
@ -2,43 +2,39 @@ package instr
|
||||
|
||||
import (
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/register"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/simstate"
|
||||
)
|
||||
|
||||
type Instr uint32
|
||||
type InstrFormat uint32
|
||||
|
||||
const (
|
||||
A InstrFormat = iota
|
||||
B
|
||||
A1 InstrFormat = iota
|
||||
A2
|
||||
B1
|
||||
B2
|
||||
C
|
||||
D1
|
||||
D2
|
||||
E
|
||||
)
|
||||
|
||||
func (instrf InstrFormat) String() string {
|
||||
switch instrf {
|
||||
case A:
|
||||
return "A"
|
||||
|
||||
case B:
|
||||
return "B"
|
||||
|
||||
case C:
|
||||
return "C"
|
||||
|
||||
case D1:
|
||||
return "D1"
|
||||
|
||||
case D2:
|
||||
return "D2"
|
||||
|
||||
case E:
|
||||
return "E"
|
||||
var instrFormatNames = [...]string{
|
||||
"A1",
|
||||
"A2",
|
||||
"B1",
|
||||
"B2",
|
||||
"C",
|
||||
"D1",
|
||||
"D2",
|
||||
"E",
|
||||
}
|
||||
|
||||
panic("unknown format")
|
||||
func (instrf InstrFormat) String() string {
|
||||
if int(instrf) > len(instrFormatNames) {
|
||||
panic("unknown instruction format")
|
||||
}
|
||||
|
||||
return instrFormatNames[instrf]
|
||||
}
|
||||
|
||||
type Cond uint32
|
||||
@ -63,9 +59,35 @@ const (
|
||||
SLE // Signed Lower or Equal, Z==1 && N!=V
|
||||
)
|
||||
|
||||
type InstrFormatter func(*DecodedInstr) string
|
||||
var condNames = [...]string{
|
||||
"al",
|
||||
"eq",
|
||||
"neq",
|
||||
"uge",
|
||||
"cs",
|
||||
"ult",
|
||||
"cc",
|
||||
"neg",
|
||||
"pos",
|
||||
"vs",
|
||||
"vc",
|
||||
"ugt",
|
||||
"ule",
|
||||
"sge",
|
||||
"slt",
|
||||
"sgt",
|
||||
"sle",
|
||||
}
|
||||
|
||||
type InstrBehavior func(*DecodedInstr, simstate.SimState) error
|
||||
func (cond Cond) String() string {
|
||||
if int(cond) > len(condNames) {
|
||||
panic("unknown instruction condition")
|
||||
}
|
||||
|
||||
return condNames[cond]
|
||||
}
|
||||
|
||||
type InstrFormatter func(*DecodedInstr) string
|
||||
|
||||
type InstrDesc struct {
|
||||
VariantName string
|
||||
@ -73,7 +95,6 @@ type InstrDesc struct {
|
||||
OpCode uint32
|
||||
Format InstrFormat
|
||||
Formatter InstrFormatter
|
||||
Behavior InstrBehavior
|
||||
}
|
||||
|
||||
type StandardFormatFields struct {
|
||||
@ -92,8 +113,7 @@ type SubsystemFormatFields struct {
|
||||
}
|
||||
|
||||
type DecodedInstr struct {
|
||||
Format InstrFormat
|
||||
OpCode uint32
|
||||
InstrDesc InstrDesc
|
||||
// A, B, C, D1 and D2 formats fields
|
||||
StandardFormatFields
|
||||
// E format fields
|
||||
|
@ -1,14 +1,129 @@
|
||||
package instrset
|
||||
|
||||
import "git.elyanpoujol.fr/elyan/central-arch/pkg/instr"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/instr"
|
||||
)
|
||||
|
||||
var CentralInstructionSet = []instr.InstrDesc{
|
||||
{VariantName: "NOP", Mnemonic: "nop", OpCode: 0x0, Format: instr.D2, Formatter: nil, Behavior: nil},
|
||||
{VariantName: "LDRIR", Mnemonic: "ldr", OpCode: 0x1, Format: instr.A, Formatter: nil, Behavior: nil},
|
||||
{VariantName: "LDRIRW", Mnemonic: "ldr", OpCode: 0x2, Format: instr.A, Formatter: nil, Behavior: nil},
|
||||
{VariantName: "LDRIOW", Mnemonic: "ldr", OpCode: 0x3, Format: instr.A, Formatter: nil, Behavior: nil},
|
||||
{VariantName: "LDRR", Mnemonic: "ldr", OpCode: 0x4, Format: instr.A, Formatter: nil, Behavior: nil},
|
||||
{VariantName: "LDRRW", Mnemonic: "ldr", OpCode: 0x5, Format: instr.A, Formatter: nil, Behavior: nil},
|
||||
{VariantName: "LDROW", Mnemonic: "ldr", OpCode: 0x6, Format: instr.A, Formatter: nil, Behavior: nil},
|
||||
{VariantName: "SVC", Mnemonic: "svc", OpCode: 0x7f, Format: instr.D2, Formatter: nil, Behavior: nil},
|
||||
NOP,
|
||||
SVC,
|
||||
LDRIR,
|
||||
LDRIRW,
|
||||
LDRIOW,
|
||||
LDRR,
|
||||
LDRRW,
|
||||
LDROW,
|
||||
MOVR,
|
||||
MOVI,
|
||||
MOVNI,
|
||||
BIO,
|
||||
BAIO,
|
||||
BXI,
|
||||
BXR,
|
||||
SSR,
|
||||
SSW,
|
||||
}
|
||||
|
||||
// Miscellaneous Instructions
|
||||
|
||||
var NOP = instr.InstrDesc{VariantName: "NOP", Mnemonic: "nop", OpCode: 0x0, Format: instr.D2, Formatter: nopFormatter}
|
||||
var SVC = instr.InstrDesc{VariantName: "SVC", Mnemonic: "svc", OpCode: 0x7f, Format: instr.D2, Formatter: svcFormatter}
|
||||
|
||||
// Memory-Related Instructions
|
||||
// TODO Add "str" variants
|
||||
|
||||
var LDRIR = instr.InstrDesc{VariantName: "LDRIR", Mnemonic: "ldr", OpCode: 0x1, Format: instr.B1, Formatter: ldrirFormatter}
|
||||
var LDRIRW = instr.InstrDesc{VariantName: "LDRIRW", Mnemonic: "ldr", OpCode: 0x2, Format: instr.B1, Formatter: ldrirwFormatter}
|
||||
var LDRIOW = instr.InstrDesc{VariantName: "LDRIOW", Mnemonic: "ldr", OpCode: 0x3, Format: instr.B1, Formatter: ldriowFormatter}
|
||||
var LDRR = instr.InstrDesc{VariantName: "LDRR", Mnemonic: "ldr", OpCode: 0x4, Format: instr.A1, Formatter: ldrrFormatter}
|
||||
var LDRRW = instr.InstrDesc{VariantName: "LDRRW", Mnemonic: "ldr", OpCode: 0x5, Format: instr.A1, Formatter: ldrrwFormatter}
|
||||
var LDROW = instr.InstrDesc{VariantName: "LDROW", Mnemonic: "ldr", OpCode: 0x6, Format: instr.A1, Formatter: ldrowFormatter}
|
||||
|
||||
// Register Manipulation Instructions
|
||||
|
||||
var MOVR = instr.InstrDesc{VariantName: "MOVR", Mnemonic: "mov", OpCode: 0xd, Format: instr.B1, Formatter: movrFormatter}
|
||||
var MOVI = instr.InstrDesc{VariantName: "MOVI", Mnemonic: "mov", OpCode: 0xe, Format: instr.C, Formatter: moviFormatter}
|
||||
var MOVNI = instr.InstrDesc{VariantName: "MOVNI", Mnemonic: "movn", OpCode: 0x13, Format: instr.C, Formatter: movniFormatter}
|
||||
|
||||
// Branching Instructions
|
||||
|
||||
var BIO = instr.InstrDesc{VariantName: "BIO", Mnemonic: "b", OpCode: 0xf, Format: instr.D1, Formatter: bioFormatter}
|
||||
var BAIO = instr.InstrDesc{VariantName: "BAIO", Mnemonic: "b", OpCode: 0x10, Format: instr.D2, Formatter: baioFormatter}
|
||||
var BXI = instr.InstrDesc{VariantName: "BXI", Mnemonic: "bx", OpCode: 0x11, Format: instr.B2, Formatter: bxiFormatter}
|
||||
var BXR = instr.InstrDesc{VariantName: "BXR", Mnemonic: "bx", OpCode: 0x12, Format: instr.A2, Formatter: bxrFormatter}
|
||||
|
||||
// Subsystems Instructions
|
||||
|
||||
var SSR = instr.InstrDesc{VariantName: "SSR", Mnemonic: "ssr", OpCode: 0x7d, Format: instr.E, Formatter: ssrFormatter}
|
||||
var SSW = instr.InstrDesc{VariantName: "SSW", Mnemonic: "ssw", OpCode: 0x7e, Format: instr.E, Formatter: sswFormatter}
|
||||
|
||||
func nopFormatter(i *instr.DecodedInstr) string {
|
||||
return i.InstrDesc.Mnemonic
|
||||
}
|
||||
|
||||
func svcFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s 0x%06x", i.InstrDesc.Mnemonic, i.Imm)
|
||||
}
|
||||
|
||||
func ldrirFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %s, [%s, %#04x]", i.InstrDesc.Mnemonic, i.Condition, i.Rd, i.Rs1, int32(i.Imm)*4)
|
||||
}
|
||||
|
||||
func ldrirwFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %s, ![%s, %#04x]", i.InstrDesc.Mnemonic, i.Condition, i.Rd, i.Rs1, int32(i.Imm)*4)
|
||||
}
|
||||
|
||||
func ldriowFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %s, [%s, %#04x]!", i.InstrDesc.Mnemonic, i.Condition, i.Rd, i.Rs1, int32(i.Imm)*4)
|
||||
}
|
||||
|
||||
func ldrrFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %s, [%s, %s]", i.InstrDesc.Mnemonic, i.Condition, i.Rd, i.Rs1, i.Rs2)
|
||||
}
|
||||
|
||||
func ldrrwFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %s, ![%s, %s]", i.InstrDesc.Mnemonic, i.Condition, i.Rd, i.Rs1, i.Rs2)
|
||||
}
|
||||
|
||||
func ldrowFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %s, [%s, %s]!", i.InstrDesc.Mnemonic, i.Condition, i.Rd, i.Rs1, i.Rs2)
|
||||
}
|
||||
|
||||
func movrFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %s, %s", i.InstrDesc.Mnemonic, i.Condition, i.Rd, i.Rs1)
|
||||
}
|
||||
|
||||
func moviFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %s, %#04x", i.InstrDesc.Mnemonic, i.Condition, i.Rd, i.Imm)
|
||||
}
|
||||
|
||||
func movniFormatter(i *instr.DecodedInstr) string {
|
||||
val := int32(0xffff0000 + i.Imm&0xffff)
|
||||
return fmt.Sprintf("%s.%s %s, %#04x", i.InstrDesc.Mnemonic, i.Condition, i.Rd, val)
|
||||
}
|
||||
|
||||
func bioFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s %#06x", i.InstrDesc.Mnemonic, i.Condition, int32(i.Imm)*4)
|
||||
}
|
||||
|
||||
func baioFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s %#06x", i.InstrDesc.Mnemonic, int32(i.Imm))
|
||||
}
|
||||
|
||||
func bxiFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s [%s, %#06x]", i.InstrDesc.Mnemonic, i.Condition, i.Rs1, int32(i.Imm)*4)
|
||||
}
|
||||
|
||||
func bxrFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s.%s [%s, %s]", i.InstrDesc.Mnemonic, i.Condition, i.Rs1, i.Rs2)
|
||||
}
|
||||
|
||||
func ssrFormatter(i *instr.DecodedInstr) string {
|
||||
return fmt.Sprintf("%s ss%d, %s, sr%d, %#02x", i.InstrDesc.Mnemonic, i.Sid, i.Reg, i.Sre, i.Cmd)
|
||||
}
|
||||
|
||||
func sswFormatter(i *instr.DecodedInstr) string {
|
||||
return ssrFormatter(i)
|
||||
}
|
||||
|
@ -12,17 +12,75 @@ const (
|
||||
R5
|
||||
R6
|
||||
R7
|
||||
LR CpuRegister = iota + 15
|
||||
RESERVED_8
|
||||
RESERVED_9
|
||||
RESERVED_10
|
||||
RESERVED_11
|
||||
RESERVED_12
|
||||
RESERVED_13
|
||||
RESERVED_14
|
||||
RESERVED_15
|
||||
RESERVED_16
|
||||
RESERVED_17
|
||||
RESERVED_18
|
||||
RESERVED_19
|
||||
RESERVED_20
|
||||
RESERVED_21
|
||||
RESERVED_22
|
||||
LR
|
||||
PC
|
||||
SP
|
||||
PC_USER
|
||||
SP_USER
|
||||
PC_SYS
|
||||
SP_SYS
|
||||
PC_SVC
|
||||
SP_SVC
|
||||
PC_FAULT
|
||||
SP_FAULT
|
||||
)
|
||||
|
||||
var cpuRegisterNames = [...]string{
|
||||
"r0",
|
||||
"r1",
|
||||
"r2",
|
||||
"r3",
|
||||
"r4",
|
||||
"r5",
|
||||
"r6",
|
||||
"r7",
|
||||
"reserved_8",
|
||||
"reserved_9",
|
||||
"reserved_10",
|
||||
"reserved_11",
|
||||
"reserved_12",
|
||||
"reserved_13",
|
||||
"reserved_14",
|
||||
"reserved_15",
|
||||
"reserved_16",
|
||||
"reserved_17",
|
||||
"reserved_18",
|
||||
"reserved_19",
|
||||
"reserved_20",
|
||||
"reserved_21",
|
||||
"reserved_22",
|
||||
"lr",
|
||||
"pc",
|
||||
"sp",
|
||||
"pc_user",
|
||||
"sp_user",
|
||||
"pc_svc",
|
||||
"sp_svc",
|
||||
"pc_fault",
|
||||
"sp_fault",
|
||||
}
|
||||
|
||||
func (r CpuRegister) String() string {
|
||||
if int(r) > len(cpuRegisterNames) {
|
||||
panic("unknown register")
|
||||
}
|
||||
|
||||
return cpuRegisterNames[r]
|
||||
}
|
||||
|
||||
// General purpose registers count
|
||||
const GPR_COUNT = 8
|
||||
|
||||
|
@ -6,11 +6,11 @@ import (
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/cache"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/cpu"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/events"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/instr"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/memory"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/mmu"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/ram"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/simcontext"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/siminstr"
|
||||
)
|
||||
|
||||
type SimStatus struct {
|
||||
@ -111,7 +111,7 @@ func (s *Sim) Stop() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sim) RegisterInstructionSet(instrSet []instr.InstrDesc) {
|
||||
func (s *Sim) RegisterInstructionSet(instrSet []siminstr.SimInstrDesc) {
|
||||
for _, instr := range instrSet {
|
||||
s.cpu.RegisterInstr(instr)
|
||||
}
|
||||
|
13
pkg/siminstr/siminstr.go
Normal file
13
pkg/siminstr/siminstr.go
Normal file
@ -0,0 +1,13 @@
|
||||
package siminstr
|
||||
|
||||
import (
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/instr"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/simstate"
|
||||
)
|
||||
|
||||
type InstrBehavior func(*instr.DecodedInstr, simstate.SimState) error
|
||||
|
||||
type SimInstrDesc struct {
|
||||
InstrDesc *instr.InstrDesc
|
||||
Behavior InstrBehavior
|
||||
}
|
27
pkg/siminstrset/siminstrset.go
Normal file
27
pkg/siminstrset/siminstrset.go
Normal file
@ -0,0 +1,27 @@
|
||||
package siminstrset
|
||||
|
||||
import (
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/instrset"
|
||||
"git.elyanpoujol.fr/elyan/central-arch/pkg/siminstr"
|
||||
)
|
||||
|
||||
// TODO Add behaviors
|
||||
var SimCentralInstructionSet = [...]siminstr.SimInstrDesc{
|
||||
{InstrDesc: &instrset.NOP, Behavior: nil},
|
||||
{InstrDesc: &instrset.SVC, Behavior: nil},
|
||||
{InstrDesc: &instrset.LDRIR, Behavior: nil},
|
||||
{InstrDesc: &instrset.LDRIRW, Behavior: nil},
|
||||
{InstrDesc: &instrset.LDRIOW, Behavior: nil},
|
||||
{InstrDesc: &instrset.LDRR, Behavior: nil},
|
||||
{InstrDesc: &instrset.LDRRW, Behavior: nil},
|
||||
{InstrDesc: &instrset.LDROW, Behavior: nil},
|
||||
{InstrDesc: &instrset.MOVR, Behavior: nil},
|
||||
{InstrDesc: &instrset.MOVI, Behavior: nil},
|
||||
{InstrDesc: &instrset.MOVNI, Behavior: nil},
|
||||
{InstrDesc: &instrset.BIO, Behavior: nil},
|
||||
{InstrDesc: &instrset.BAIO, Behavior: nil},
|
||||
{InstrDesc: &instrset.BXI, Behavior: nil},
|
||||
{InstrDesc: &instrset.BXR, Behavior: nil},
|
||||
{InstrDesc: &instrset.SSR, Behavior: nil},
|
||||
{InstrDesc: &instrset.SSW, Behavior: nil},
|
||||
}
|
Loading…
Reference in New Issue
Block a user