Move operand type lists into the vm

This commit is contained in:
Ian Gulliver
2021-11-20 17:26:58 -10:00
parent 30ff003494
commit ae771823b0
4 changed files with 60 additions and 60 deletions

View File

@@ -65,7 +65,7 @@ func assembleInstruction(in instruction) (*vm.Instruction, error) {
instr.OpCode = opCode instr.OpCode = opCode
operands := in[1:] operands := in[1:]
pattern := operandsByOpCode[instr.OpCode] pattern := vm.OperandsByOpCode[instr.OpCode]
if len(operands) != len(pattern) { if len(operands) != len(pattern) {
return nil, fmt.Errorf("Incorrect number of operands: expected %d, found %d\n", len(pattern), len(operands)) return nil, fmt.Errorf("Incorrect number of operands: expected %d, found %d\n", len(pattern), len(operands))
} }
@@ -82,7 +82,7 @@ func assembleInstruction(in instruction) (*vm.Instruction, error) {
return instr, nil return instr, nil
} }
func assembleOperand(op string, t operandType) (*vm.Operand, error) { func assembleOperand(op string, t vm.OperandNumericType) (*vm.Operand, error) {
op = strings.ToLower(op) op = strings.ToLower(op)
ret := &vm.Operand{} ret := &vm.Operand{}
numStr := "" numStr := ""
@@ -96,7 +96,7 @@ func assembleOperand(op string, t operandType) (*vm.Operand, error) {
ret.Type = vm.GlobalMemoryIndex ret.Type = vm.GlobalMemoryIndex
numStr = strings.TrimPrefix(op, "g") numStr = strings.TrimPrefix(op, "g")
case t == s || t == u || t == us: case t == vm.OperandSigned || t == vm.OperandUnsigned || t == vm.OperandSignedOrUnsigned:
ret.Type = vm.Literal ret.Type = vm.Literal
numStr = op numStr = op
@@ -105,14 +105,14 @@ func assembleOperand(op string, t operandType) (*vm.Operand, error) {
} }
switch { switch {
case t == s || (t == us && (strings.HasPrefix(numStr, "+") || strings.HasPrefix(numStr, "-"))): case t == vm.OperandSigned || (t == vm.OperandSignedOrUnsigned && (strings.HasPrefix(numStr, "+") || strings.HasPrefix(numStr, "-"))):
num, err := strconv.ParseInt(numStr, 0, 64) num, err := strconv.ParseInt(numStr, 0, 64)
if err != nil { if err != nil {
return ret, errors.Wrapf(err, "While parsing operand value %s", numStr) return ret, errors.Wrapf(err, "While parsing operand value %s", numStr)
} }
ret.Value = uint64(num) ret.Value = uint64(num)
case t == u || t == us || t == r: case t == vm.OperandUnsigned || t == vm.OperandSignedOrUnsigned || t == vm.OperandReference:
num, err := strconv.ParseUint(numStr, 0, 64) num, err := strconv.ParseUint(numStr, 0, 64)
if err != nil { if err != nil {
return ret, errors.Wrapf(err, "While parsing operand value %s", numStr) return ret, errors.Wrapf(err, "While parsing operand value %s", numStr)

View File

@@ -44,7 +44,7 @@ func disassembleInstruction(in *vm.Instruction) (string, error) {
nameByOpCode[in.OpCode], nameByOpCode[in.OpCode],
} }
for i, t := range operandsByOpCode[in.OpCode] { for i, t := range vm.OperandsByOpCode[in.OpCode] {
op, err := disassembleOperand(in.Operands[i], t) op, err := disassembleOperand(in.Operands[i], t)
if err != nil { if err != nil {
return "", err return "", err
@@ -58,7 +58,7 @@ func disassembleInstruction(in *vm.Instruction) (string, error) {
return encoded, nil return encoded, nil
} }
func disassembleOperand(op *vm.Operand, t operandType) (string, error) { func disassembleOperand(op *vm.Operand, t vm.OperandNumericType) (string, error) {
switch op.Type { switch op.Type {
case vm.GlobalMemoryIndex: case vm.GlobalMemoryIndex:
return fmt.Sprintf("g%d", op.Value), nil return fmt.Sprintf("g%d", op.Value), nil
@@ -68,13 +68,13 @@ func disassembleOperand(op *vm.Operand, t operandType) (string, error) {
case vm.Literal: case vm.Literal:
switch t { switch t {
case u: case vm.OperandUnsigned:
return fmt.Sprintf("%d", op.Value), nil return fmt.Sprintf("%d", op.Value), nil
case s: case vm.OperandSigned:
return fmt.Sprintf("%+d", int64(op.Value)), nil return fmt.Sprintf("%+d", int64(op.Value)), nil
case us: case vm.OperandSignedOrUnsigned:
// Take our best guess // Take our best guess
if op.Value > math.MaxInt64 { if op.Value > math.MaxInt64 {
return fmt.Sprintf("%+d", int64(op.Value)), nil return fmt.Sprintf("%+d", int64(op.Value)), nil

View File

@@ -111,53 +111,3 @@ var nameByOpCode = map[vm.OpCodeType]string{
vm.OpRetT: "rett", vm.OpRetT: "rett",
vm.OpRetF: "retf", vm.OpRetF: "retf",
} }
type operandType int
const (
u operandType = 0
s = 1
us = 2
r = 3
)
var operandsByOpCode = map[vm.OpCodeType][]operandType{
vm.OpNop: []operandType{},
vm.OpMov: []operandType{r, us},
vm.OpAdd: []operandType{r, us},
vm.OpSub: []operandType{r, us},
vm.OpMul: []operandType{r, us},
vm.OpDivU: []operandType{r, u},
vm.OpDivS: []operandType{r, s},
vm.OpNot: []operandType{r},
vm.OpAnd: []operandType{r, u},
vm.OpOr: []operandType{r, u},
vm.OpXor: []operandType{r, u},
vm.OpShR: []operandType{r, u},
vm.OpShL: []operandType{r, u},
vm.OpEq: []operandType{us, us},
vm.OpLTU: []operandType{u, u},
vm.OpLTS: []operandType{s, s},
vm.OpGTU: []operandType{u, u},
vm.OpGTS: []operandType{s, s},
vm.OpLTEU: []operandType{u, u},
vm.OpLTES: []operandType{s, s},
vm.OpGTEU: []operandType{u, u},
vm.OpGTES: []operandType{s, s},
vm.OpJmp: []operandType{s},
vm.OpJmpT: []operandType{s},
vm.OpJmpF: []operandType{s},
vm.OpCal: []operandType{s},
vm.OpCalT: []operandType{s},
vm.OpCalF: []operandType{s},
vm.OpRet: []operandType{},
vm.OpRetT: []operandType{},
vm.OpRetF: []operandType{},
}

View File

@@ -69,3 +69,53 @@ const (
OpReturnIfFalse = 0x00000802 OpReturnIfFalse = 0x00000802
OpRetF = OpReturnIfFalse OpRetF = OpReturnIfFalse
) )
type OperandNumericType int
const (
OperandUnsigned OperandNumericType = 0
OperandSigned = 1
OperandSignedOrUnsigned = 2
OperandReference = 3
)
var OperandsByOpCode = map[OpCodeType][]OperandNumericType{
OpNop: []OperandNumericType{},
OpMov: []OperandNumericType{OperandReference, OperandSignedOrUnsigned},
OpAdd: []OperandNumericType{OperandReference, OperandSignedOrUnsigned},
OpSub: []OperandNumericType{OperandReference, OperandSignedOrUnsigned},
OpMul: []OperandNumericType{OperandReference, OperandSignedOrUnsigned},
OpDivU: []OperandNumericType{OperandReference, OperandUnsigned},
OpDivS: []OperandNumericType{OperandReference, OperandSigned},
OpNot: []OperandNumericType{OperandReference},
OpAnd: []OperandNumericType{OperandReference, OperandUnsigned},
OpOr: []OperandNumericType{OperandReference, OperandUnsigned},
OpXor: []OperandNumericType{OperandReference, OperandUnsigned},
OpShR: []OperandNumericType{OperandReference, OperandUnsigned},
OpShL: []OperandNumericType{OperandReference, OperandUnsigned},
OpEq: []OperandNumericType{OperandSignedOrUnsigned, OperandSignedOrUnsigned},
OpLTU: []OperandNumericType{OperandUnsigned, OperandUnsigned},
OpLTS: []OperandNumericType{OperandSigned, OperandSigned},
OpGTU: []OperandNumericType{OperandUnsigned, OperandUnsigned},
OpGTS: []OperandNumericType{OperandSigned, OperandSigned},
OpLTEU: []OperandNumericType{OperandUnsigned, OperandUnsigned},
OpLTES: []OperandNumericType{OperandSigned, OperandSigned},
OpGTEU: []OperandNumericType{OperandUnsigned, OperandUnsigned},
OpGTES: []OperandNumericType{OperandSigned, OperandSigned},
OpJmp: []OperandNumericType{OperandSigned},
OpJmpT: []OperandNumericType{OperandSigned},
OpJmpF: []OperandNumericType{OperandSigned},
OpCal: []OperandNumericType{OperandSigned},
OpCalT: []OperandNumericType{OperandSigned},
OpCalF: []OperandNumericType{OperandSigned},
OpRet: []OperandNumericType{},
OpRetT: []OperandNumericType{},
OpRetF: []OperandNumericType{},
}