Move operand type lists into the vm
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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{},
|
|
||||||
}
|
|
||||||
|
|||||||
50
vm/opcode.go
50
vm/opcode.go
@@ -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{},
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user