Bitwise operators

This commit is contained in:
Ian Gulliver
2021-11-19 16:43:59 -10:00
parent 50f986fb13
commit cc8e4a8ccb
4 changed files with 102 additions and 18 deletions

View File

@@ -19,6 +19,11 @@ var opCodeByName = map[string]vm.OpCodeType{
"dividesigned": vm.OpDivideSigned, "dividesigned": vm.OpDivideSigned,
"divs": vm.OpDivS, "divs": vm.OpDivS,
"not": vm.OpNot,
"and": vm.OpAnd,
"or": vm.OpOr,
"xor": vm.OpXor,
"isequal": vm.OpIsEqual, "isequal": vm.OpIsEqual,
"eq": vm.OpEq, "eq": vm.OpEq,
"islessthanunsigned": vm.OpIsLessThanUnsigned, "islessthanunsigned": vm.OpIsLessThanUnsigned,
@@ -79,6 +84,11 @@ var operandsByOpCode = map[vm.OpCodeType][]operandType{
vm.OpDivU: []operandType{r, u}, vm.OpDivU: []operandType{r, u},
vm.OpDivS: []operandType{r, s}, 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.OpEq: []operandType{us, us}, vm.OpEq: []operandType{us, us},
vm.OpLTU: []operandType{u, u}, vm.OpLTU: []operandType{u, u},
vm.OpLTS: []operandType{s, s}, vm.OpLTS: []operandType{s, s},

View File

@@ -94,6 +94,47 @@ functions:
expectGlobalMemorySigned(t, state, 2, 1) expectGlobalMemorySigned(t, state, 2, 1)
} }
func TestNot(t *testing.T) {
state := assembleAndExecute(t, `
functions:
- - [mov, g0, 8]
- [not, g0]
- [and, g0, 15]
`)
expectGlobalMemory(t, state, 0, 7)
}
func TestAnd(t *testing.T) {
state := assembleAndExecute(t, `
functions:
- - [mov, g0, 7]
- [and, g0, 18]
`)
expectGlobalMemory(t, state, 0, 2)
}
func TestOr(t *testing.T) {
state := assembleAndExecute(t, `
functions:
- - [mov, g0, 7]
- [or, g0, 18]
`)
expectGlobalMemory(t, state, 0, 23)
}
func TestXor(t *testing.T) {
state := assembleAndExecute(t, `
functions:
- - [mov, g0, 7]
- [xor, g0, 18]
`)
expectGlobalMemory(t, state, 0, 21)
}
func TestEq(t *testing.T) { func TestEq(t *testing.T) {
state := assembleAndExecute(t, ` state := assembleAndExecute(t, `
functions: functions:

View File

@@ -19,43 +19,48 @@ const (
OpDivideSigned = 0x00000204 OpDivideSigned = 0x00000204
OpDivS = OpDivideSigned OpDivS = OpDivideSigned
OpIsEqual = 0x00000300 OpNot = 0x00000300
OpAnd = 0x00000301
OpOr = 0x00000302
OpXor = 0x00000303
OpIsEqual = 0x00000400
OpEq = OpIsEqual OpEq = OpIsEqual
OpIsLessThanUnsigned = 0x00000301 OpIsLessThanUnsigned = 0x00000401
OpLTU = OpIsLessThanUnsigned OpLTU = OpIsLessThanUnsigned
OpIsLessThanSigned = 0x00000302 OpIsLessThanSigned = 0x00000402
OpLTS = OpIsLessThanSigned OpLTS = OpIsLessThanSigned
OpIsGreaterThanUnsigned = 0x00000303 OpIsGreaterThanUnsigned = 0x00000403
OpGTU = OpIsGreaterThanUnsigned OpGTU = OpIsGreaterThanUnsigned
OpIsGreaterThanSigned = 0x00000304 OpIsGreaterThanSigned = 0x00000404
OpGTS = OpIsGreaterThanSigned OpGTS = OpIsGreaterThanSigned
OpIsLessThanOrEqualUnsigned = 0x00000305 OpIsLessThanOrEqualUnsigned = 0x00000405
OpLTEU = OpIsLessThanOrEqualUnsigned OpLTEU = OpIsLessThanOrEqualUnsigned
OpIsLessThanOrEqualSigned = 0x00000306 OpIsLessThanOrEqualSigned = 0x00000406
OpLTES = OpIsLessThanOrEqualSigned OpLTES = OpIsLessThanOrEqualSigned
OpIsGreaterThanOrEqualUnsigned = 0x00000307 OpIsGreaterThanOrEqualUnsigned = 0x00000407
OpGTEU = OpIsGreaterThanOrEqualUnsigned OpGTEU = OpIsGreaterThanOrEqualUnsigned
OpIsGreaterThanOrEqualSigned = 0x00000308 OpIsGreaterThanOrEqualSigned = 0x00000408
OpGTES = OpIsGreaterThanOrEqualSigned OpGTES = OpIsGreaterThanOrEqualSigned
OpJump = 0x00000400 OpJump = 0x00000500
OpJmp = OpJump OpJmp = OpJump
OpJumpIfTrue = 0x00000401 OpJumpIfTrue = 0x00000501
OpJmpT = OpJumpIfTrue OpJmpT = OpJumpIfTrue
OpJumpIfFalse = 0x00000402 OpJumpIfFalse = 0x00000502
OpJmpF = OpJumpIfFalse OpJmpF = OpJumpIfFalse
OpCall = 0x00000500 OpCall = 0x00000600
OpCal = OpCall OpCal = OpCall
OpCallIfTrue = 0x00000501 OpCallIfTrue = 0x00000601
OpCalT = OpCallIfTrue OpCalT = OpCallIfTrue
OpCallIfFalse = 0x00000502 OpCallIfFalse = 0x00000602
OpCalF = OpCallIfFalse OpCalF = OpCallIfFalse
OpReturn = 0x00000600 OpReturn = 0x00000700
OpRet = OpReturn OpRet = OpReturn
OpReturnIfTrue = 0x00000601 OpReturnIfTrue = 0x00000701
OpRetT = OpReturnIfTrue OpRetT = OpReturnIfTrue
OpReturnIfFalse = 0x00000602 OpReturnIfFalse = 0x00000702
OpRetF = OpReturnIfFalse OpRetF = OpReturnIfFalse
) )

View File

@@ -13,6 +13,11 @@ var opHandlers = map[OpCodeType]opHandler{
OpDivideUnsigned: (*State).handleDivideUnsigned, OpDivideUnsigned: (*State).handleDivideUnsigned,
OpDivideSigned: (*State).handleDivideSigned, OpDivideSigned: (*State).handleDivideSigned,
OpNot: (*State).handleNot,
OpAnd: (*State).handleAnd,
OpOr: (*State).handleOr,
OpXor: (*State).handleXor,
OpIsEqual: (*State).handleIsEqual, OpIsEqual: (*State).handleIsEqual,
OpIsLessThanUnsigned: (*State).handleIsLessThanUnsigned, OpIsLessThanUnsigned: (*State).handleIsLessThanUnsigned,
OpIsLessThanSigned: (*State).handleIsLessThanSigned, OpIsLessThanSigned: (*State).handleIsLessThanSigned,
@@ -74,6 +79,29 @@ func (state *State) handleDivideSigned(instr *Instruction) {
state.writeSigned(&instr.Operand1, in1/in2) state.writeSigned(&instr.Operand1, in1/in2)
} }
func (state *State) handleNot(instr *Instruction) {
in := state.readUnsigned(&instr.Operand1)
state.writeUnsigned(&instr.Operand1, in^uint64(0xffffffffffffffff))
}
func (state *State) handleAnd(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1&in2)
}
func (state *State) handleOr(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1|in2)
}
func (state *State) handleXor(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2)
state.writeUnsigned(&instr.Operand1, in1^in2)
}
func (state *State) handleIsEqual(instr *Instruction) { func (state *State) handleIsEqual(instr *Instruction) {
in1 := state.readUnsigned(&instr.Operand1) in1 := state.readUnsigned(&instr.Operand1)
in2 := state.readUnsigned(&instr.Operand2) in2 := state.readUnsigned(&instr.Operand2)