diff --git a/asm/assemble.go b/asm/assemble.go index 0e9dca8..4fd6e3b 100644 --- a/asm/assemble.go +++ b/asm/assemble.go @@ -65,7 +65,7 @@ func assembleInstruction(in instruction) (*vm.Instruction, error) { instr.OpCode = opCode operands := in[1:] - pattern := operandsByOpCode[instr.OpCode] + pattern := vm.OperandsByOpCode[instr.OpCode] if len(operands) != len(pattern) { 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 } -func assembleOperand(op string, t operandType) (*vm.Operand, error) { +func assembleOperand(op string, t vm.OperandNumericType) (*vm.Operand, error) { op = strings.ToLower(op) ret := &vm.Operand{} numStr := "" @@ -96,7 +96,7 @@ func assembleOperand(op string, t operandType) (*vm.Operand, error) { ret.Type = vm.GlobalMemoryIndex 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 numStr = op @@ -105,14 +105,14 @@ func assembleOperand(op string, t operandType) (*vm.Operand, error) { } 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) if err != nil { return ret, errors.Wrapf(err, "While parsing operand value %s", numStr) } 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) if err != nil { return ret, errors.Wrapf(err, "While parsing operand value %s", numStr) diff --git a/asm/disassemble.go b/asm/disassemble.go index 2b3a3b6..7e37a47 100644 --- a/asm/disassemble.go +++ b/asm/disassemble.go @@ -44,7 +44,7 @@ func disassembleInstruction(in *vm.Instruction) (string, error) { 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) if err != nil { return "", err @@ -58,7 +58,7 @@ func disassembleInstruction(in *vm.Instruction) (string, error) { 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 { case vm.GlobalMemoryIndex: return fmt.Sprintf("g%d", op.Value), nil @@ -68,13 +68,13 @@ func disassembleOperand(op *vm.Operand, t operandType) (string, error) { case vm.Literal: switch t { - case u: + case vm.OperandUnsigned: return fmt.Sprintf("%d", op.Value), nil - case s: + case vm.OperandSigned: return fmt.Sprintf("%+d", int64(op.Value)), nil - case us: + case vm.OperandSignedOrUnsigned: // Take our best guess if op.Value > math.MaxInt64 { return fmt.Sprintf("%+d", int64(op.Value)), nil diff --git a/asm/opcodes.go b/asm/opcodes.go index e8282b6..c3a3b9e 100644 --- a/asm/opcodes.go +++ b/asm/opcodes.go @@ -111,53 +111,3 @@ var nameByOpCode = map[vm.OpCodeType]string{ vm.OpRetT: "rett", 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{}, -} diff --git a/vm/opcode.go b/vm/opcode.go index 20809b9..1e7546b 100644 --- a/vm/opcode.go +++ b/vm/opcode.go @@ -69,3 +69,53 @@ const ( OpReturnIfFalse = 0x00000802 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{}, +}