Generate random single instructions
This commit is contained in:
15
gen/instruction.go
Normal file
15
gen/instruction.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package gen
|
||||||
|
|
||||||
|
import "github.com/firestuff/subcoding/vm"
|
||||||
|
|
||||||
|
func randInstruction() *vm.Instruction {
|
||||||
|
instr := &vm.Instruction{
|
||||||
|
OpCode: randOpCode(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, t := range vm.OperandsByOpCode[instr.OpCode] {
|
||||||
|
instr.Operands[i] = randOperand(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return instr
|
||||||
|
}
|
||||||
52
gen/opcode.go
Normal file
52
gen/opcode.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package gen
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
import "github.com/firestuff/subcoding/vm"
|
||||||
|
|
||||||
|
var opCodes = []vm.OpCodeType{
|
||||||
|
vm.OpNop,
|
||||||
|
|
||||||
|
vm.OpMov,
|
||||||
|
|
||||||
|
vm.OpAdd,
|
||||||
|
vm.OpSub,
|
||||||
|
vm.OpMul,
|
||||||
|
vm.OpDivU,
|
||||||
|
vm.OpDivS,
|
||||||
|
|
||||||
|
vm.OpNot,
|
||||||
|
vm.OpAnd,
|
||||||
|
vm.OpOr,
|
||||||
|
vm.OpXor,
|
||||||
|
|
||||||
|
vm.OpShR,
|
||||||
|
vm.OpShL,
|
||||||
|
|
||||||
|
vm.OpEq,
|
||||||
|
vm.OpLTU,
|
||||||
|
vm.OpLTS,
|
||||||
|
vm.OpGTU,
|
||||||
|
vm.OpGTS,
|
||||||
|
vm.OpLTEU,
|
||||||
|
vm.OpLTES,
|
||||||
|
vm.OpGTEU,
|
||||||
|
vm.OpGTES,
|
||||||
|
|
||||||
|
vm.OpJmp,
|
||||||
|
vm.OpJmpT,
|
||||||
|
vm.OpJmpF,
|
||||||
|
|
||||||
|
vm.OpCal,
|
||||||
|
vm.OpCalT,
|
||||||
|
vm.OpCalF,
|
||||||
|
|
||||||
|
vm.OpRet,
|
||||||
|
vm.OpRetT,
|
||||||
|
vm.OpRetF,
|
||||||
|
}
|
||||||
|
|
||||||
|
func randOpCode() vm.OpCodeType {
|
||||||
|
// Uniform distribution
|
||||||
|
return opCodes[rand.Intn(len(opCodes))]
|
||||||
|
}
|
||||||
50
gen/operand.go
Normal file
50
gen/operand.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package gen
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
import "github.com/firestuff/subcoding/vm"
|
||||||
|
|
||||||
|
func randOperand(t vm.OperandNumericType) *vm.Operand {
|
||||||
|
for {
|
||||||
|
op := &vm.Operand{
|
||||||
|
Type: randOperandType(),
|
||||||
|
}
|
||||||
|
|
||||||
|
switch op.Type {
|
||||||
|
case vm.GlobalMemoryIndex:
|
||||||
|
op.Value = RandBiasedUint64()
|
||||||
|
|
||||||
|
case vm.FunctionMemoryIndex:
|
||||||
|
op.Value = RandBiasedUint64()
|
||||||
|
|
||||||
|
case vm.Literal:
|
||||||
|
switch t {
|
||||||
|
case vm.OperandUnsigned:
|
||||||
|
op.Value = RandBiasedUint64()
|
||||||
|
|
||||||
|
case vm.OperandSigned:
|
||||||
|
op.Value = RandBiasedInt64()
|
||||||
|
|
||||||
|
case vm.OperandSignedOrUnsigned:
|
||||||
|
op.Value = RandBiasedUSint64()
|
||||||
|
|
||||||
|
case vm.OperandReference:
|
||||||
|
// Invalid. Roll the dice again.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var operandTypes = []vm.OperandType{
|
||||||
|
vm.Literal,
|
||||||
|
vm.FunctionMemoryIndex,
|
||||||
|
vm.GlobalMemoryIndex,
|
||||||
|
}
|
||||||
|
|
||||||
|
func randOperandType() vm.OperandType {
|
||||||
|
// Uniform distribution
|
||||||
|
return operandTypes[rand.Intn(len(operandTypes))]
|
||||||
|
}
|
||||||
15
gen/program.go
Normal file
15
gen/program.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package gen
|
||||||
|
|
||||||
|
import "github.com/firestuff/subcoding/vm"
|
||||||
|
|
||||||
|
func RandProgram() *vm.Program {
|
||||||
|
return &vm.Program{
|
||||||
|
Functions: []*vm.Function{
|
||||||
|
&vm.Function{
|
||||||
|
Instructions: []*vm.Instruction{
|
||||||
|
randInstruction(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
16
gen/rand.go
16
gen/rand.go
@@ -11,14 +11,24 @@ func RandBiasedUint64() uint64 {
|
|||||||
|
|
||||||
// Generate a random int64 with an even distribution of the tuple
|
// Generate a random int64 with an even distribution of the tuple
|
||||||
// {sign, bits.Len64(math.Abs())}
|
// {sign, bits.Len64(math.Abs())}
|
||||||
func RandBiasedInt64() int64 {
|
func RandBiasedInt64() uint64 {
|
||||||
shift := rand.Intn(127)
|
shift := rand.Intn(127)
|
||||||
// [0,62]: positive
|
// [0,62]: positive
|
||||||
// [63,63]: zero
|
// [63,63]: zero
|
||||||
// [64,126]: negative
|
// [64,126]: negative
|
||||||
if shift < 64 {
|
if shift < 64 {
|
||||||
return int64((rand.Uint64() | 0x8000000000000000) >> (shift + 1))
|
return uint64(int64((rand.Uint64() | 0x8000000000000000) >> (shift + 1)))
|
||||||
} else {
|
} else {
|
||||||
return int64((rand.Uint64() | 0x8000000000000000) >> (shift - 63)) * -1
|
return uint64(int64((rand.Uint64() | 0x8000000000000000) >> (shift - 63)) * -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mixture of RandBiasedUint64() and RandBiasedInt64(), with probability shifted
|
||||||
|
// toward more unsigned values.
|
||||||
|
func RandBiasedUSint64() uint64 {
|
||||||
|
if rand.Intn(2) == 0 {
|
||||||
|
return RandBiasedUint64()
|
||||||
|
} else {
|
||||||
|
return RandBiasedInt64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
9
test/gen_test.go
Normal file
9
test/gen_test.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
import "github.com/firestuff/subcoding/gen"
|
||||||
|
|
||||||
|
func TestRandProgram(t *testing.T) {
|
||||||
|
gen.RandProgram()
|
||||||
|
}
|
||||||
@@ -43,7 +43,7 @@ func TestRandBiasedInt64(t *testing.T) {
|
|||||||
buckets := [127]uint64{}
|
buckets := [127]uint64{}
|
||||||
|
|
||||||
for i := 0; i < 1000000; i++ {
|
for i := 0; i < 1000000; i++ {
|
||||||
val := gen.RandBiasedInt64()
|
val := int64(gen.RandBiasedInt64())
|
||||||
switch {
|
switch {
|
||||||
case val == 0:
|
case val == 0:
|
||||||
buckets[63]++
|
buckets[63]++
|
||||||
|
|||||||
Reference in New Issue
Block a user