Bit shift operators
This commit is contained in:
@@ -24,6 +24,11 @@ var opCodeByName = map[string]vm.OpCodeType{
|
||||
"or": vm.OpOr,
|
||||
"xor": vm.OpXor,
|
||||
|
||||
"shiftright": vm.OpShiftRight,
|
||||
"shr": vm.OpShR,
|
||||
"shiftleft": vm.OpShiftLeft,
|
||||
"shl": vm.OpShL,
|
||||
|
||||
"isequal": vm.OpIsEqual,
|
||||
"eq": vm.OpEq,
|
||||
"islessthanunsigned": vm.OpIsLessThanUnsigned,
|
||||
@@ -89,6 +94,9 @@ var operandsByOpCode = map[vm.OpCodeType][]operandType{
|
||||
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},
|
||||
|
||||
@@ -135,6 +135,26 @@ functions:
|
||||
expectGlobalMemory(t, state, 0, 21)
|
||||
}
|
||||
|
||||
func TestShR(t *testing.T) {
|
||||
state := assembleAndExecute(t, `
|
||||
functions:
|
||||
- - [mov, g0, 53]
|
||||
- [shr, g0, 2]
|
||||
`)
|
||||
|
||||
expectGlobalMemory(t, state, 0, 13)
|
||||
}
|
||||
|
||||
func TestShL(t *testing.T) {
|
||||
state := assembleAndExecute(t, `
|
||||
functions:
|
||||
- - [mov, g0, 53]
|
||||
- [shl, g0, 2]
|
||||
`)
|
||||
|
||||
expectGlobalMemory(t, state, 0, 212)
|
||||
}
|
||||
|
||||
func TestEq(t *testing.T) {
|
||||
state := assembleAndExecute(t, `
|
||||
functions:
|
||||
|
||||
41
vm/opcode.go
41
vm/opcode.go
@@ -24,43 +24,48 @@ const (
|
||||
OpOr = 0x00000302
|
||||
OpXor = 0x00000303
|
||||
|
||||
OpIsEqual = 0x00000400
|
||||
OpShiftRight = 0x00000400
|
||||
OpShR = OpShiftRight
|
||||
OpShiftLeft = 0x00000401
|
||||
OpShL = OpShiftLeft
|
||||
|
||||
OpIsEqual = 0x00000500
|
||||
OpEq = OpIsEqual
|
||||
OpIsLessThanUnsigned = 0x00000401
|
||||
OpIsLessThanUnsigned = 0x00000501
|
||||
OpLTU = OpIsLessThanUnsigned
|
||||
OpIsLessThanSigned = 0x00000402
|
||||
OpIsLessThanSigned = 0x00000502
|
||||
OpLTS = OpIsLessThanSigned
|
||||
OpIsGreaterThanUnsigned = 0x00000403
|
||||
OpIsGreaterThanUnsigned = 0x00000503
|
||||
OpGTU = OpIsGreaterThanUnsigned
|
||||
OpIsGreaterThanSigned = 0x00000404
|
||||
OpIsGreaterThanSigned = 0x00000504
|
||||
OpGTS = OpIsGreaterThanSigned
|
||||
OpIsLessThanOrEqualUnsigned = 0x00000405
|
||||
OpIsLessThanOrEqualUnsigned = 0x00000505
|
||||
OpLTEU = OpIsLessThanOrEqualUnsigned
|
||||
OpIsLessThanOrEqualSigned = 0x00000406
|
||||
OpIsLessThanOrEqualSigned = 0x00000506
|
||||
OpLTES = OpIsLessThanOrEqualSigned
|
||||
OpIsGreaterThanOrEqualUnsigned = 0x00000407
|
||||
OpIsGreaterThanOrEqualUnsigned = 0x00000507
|
||||
OpGTEU = OpIsGreaterThanOrEqualUnsigned
|
||||
OpIsGreaterThanOrEqualSigned = 0x00000408
|
||||
OpIsGreaterThanOrEqualSigned = 0x00000508
|
||||
OpGTES = OpIsGreaterThanOrEqualSigned
|
||||
|
||||
OpJump = 0x00000500
|
||||
OpJump = 0x00000600
|
||||
OpJmp = OpJump
|
||||
OpJumpIfTrue = 0x00000501
|
||||
OpJumpIfTrue = 0x00000601
|
||||
OpJmpT = OpJumpIfTrue
|
||||
OpJumpIfFalse = 0x00000502
|
||||
OpJumpIfFalse = 0x00000602
|
||||
OpJmpF = OpJumpIfFalse
|
||||
|
||||
OpCall = 0x00000600
|
||||
OpCall = 0x00000700
|
||||
OpCal = OpCall
|
||||
OpCallIfTrue = 0x00000601
|
||||
OpCallIfTrue = 0x00000701
|
||||
OpCalT = OpCallIfTrue
|
||||
OpCallIfFalse = 0x00000602
|
||||
OpCallIfFalse = 0x00000702
|
||||
OpCalF = OpCallIfFalse
|
||||
|
||||
OpReturn = 0x00000700
|
||||
OpReturn = 0x00000800
|
||||
OpRet = OpReturn
|
||||
OpReturnIfTrue = 0x00000701
|
||||
OpReturnIfTrue = 0x00000801
|
||||
OpRetT = OpReturnIfTrue
|
||||
OpReturnIfFalse = 0x00000702
|
||||
OpReturnIfFalse = 0x00000802
|
||||
OpRetF = OpReturnIfFalse
|
||||
)
|
||||
|
||||
@@ -18,6 +18,9 @@ var opHandlers = map[OpCodeType]opHandler{
|
||||
OpOr: (*State).handleOr,
|
||||
OpXor: (*State).handleXor,
|
||||
|
||||
OpShiftRight: (*State).handleShiftRight,
|
||||
OpShiftLeft: (*State).handleShiftLeft,
|
||||
|
||||
OpIsEqual: (*State).handleIsEqual,
|
||||
OpIsLessThanUnsigned: (*State).handleIsLessThanUnsigned,
|
||||
OpIsLessThanSigned: (*State).handleIsLessThanSigned,
|
||||
@@ -102,6 +105,18 @@ func (state *State) handleXor(instr *Instruction) {
|
||||
state.writeUnsigned(&instr.Operand1, in1^in2)
|
||||
}
|
||||
|
||||
func (state *State) handleShiftRight(instr *Instruction) {
|
||||
in1 := state.readUnsigned(&instr.Operand1)
|
||||
in2 := state.readUnsigned(&instr.Operand2)
|
||||
state.writeUnsigned(&instr.Operand1, in1>>in2)
|
||||
}
|
||||
|
||||
func (state *State) handleShiftLeft(instr *Instruction) {
|
||||
in1 := state.readUnsigned(&instr.Operand1)
|
||||
in2 := state.readUnsigned(&instr.Operand2)
|
||||
state.writeUnsigned(&instr.Operand1, in1<<in2)
|
||||
}
|
||||
|
||||
func (state *State) handleIsEqual(instr *Instruction) {
|
||||
in1 := state.readUnsigned(&instr.Operand1)
|
||||
in2 := state.readUnsigned(&instr.Operand2)
|
||||
|
||||
Reference in New Issue
Block a user