central-arch/pkg/instr/instr.go

122 lines
2.1 KiB
Go

package instr
import (
"git.elyanpoujol.fr/elyan/central-arch/pkg/register"
)
type Instr uint32
type InstrFormat uint32
const (
A1 InstrFormat = iota
A2
B1
B2
C
D1
D2
E
)
var instrFormatNames = [...]string{
"A1",
"A2",
"B1",
"B2",
"C",
"D1",
"D2",
"E",
}
func (instrf InstrFormat) String() string {
if int(instrf) > len(instrFormatNames) {
panic("unknown instruction format")
}
return instrFormatNames[instrf]
}
type Cond uint32
const (
AL Cond = iota // Always
EQ // Equal, Z==1
NEQ // Not Equal, Z==0
UGE // Unsigned Greater or Equal, C==1
CS Cond = iota - 1 // Carry Set, C==1
ULT // Unsigned Lower Than, C==0
CC Cond = iota - 2 // Carry Clear, C==0
NEG // Negative, N==1
POS // Positive, N==0
VS // oVerflow Set, V==1
VC // oVerflow Clear, V==0
UGT // Unsigned Greater Than, C==1 && Z==0
ULE // Unsigned Lower Than, C==0 && Z==1
SGE // Signed Greater or Equal, N==V
SLT // Signed Lower Than, N!=V
SGT // Signed Greater Than, Z==0 && N==V
SLE // Signed Lower or Equal, Z==1 && N!=V
)
var condNames = [...]string{
"al",
"eq",
"neq",
"uge",
"cs",
"ult",
"cc",
"neg",
"pos",
"vs",
"vc",
"ugt",
"ule",
"sge",
"slt",
"sgt",
"sle",
}
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
Mnemonic string
OpCode uint32
Format InstrFormat
Formatter InstrFormatter
}
type StandardFormatFields struct {
Condition Cond
Rd register.CpuRegister
Rs1 register.CpuRegister
Rs2 register.CpuRegister
Imm uint32
}
type SubsystemFormatFields struct {
Reg register.CpuRegister
Sid uint32
Sre uint32
Cmd uint32
}
type DecodedInstr struct {
InstrDesc InstrDesc
// A, B, C, D1 and D2 formats fields
StandardFormatFields
// E format fields
SubsystemFormatFields
}