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
|
||||
// {sign, bits.Len64(math.Abs())}
|
||||
func RandBiasedInt64() int64 {
|
||||
func RandBiasedInt64() uint64 {
|
||||
shift := rand.Intn(127)
|
||||
// [0,62]: positive
|
||||
// [63,63]: zero
|
||||
// [64,126]: negative
|
||||
if shift < 64 {
|
||||
return int64((rand.Uint64() | 0x8000000000000000) >> (shift + 1))
|
||||
return uint64(int64((rand.Uint64() | 0x8000000000000000) >> (shift + 1)))
|
||||
} 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{}
|
||||
|
||||
for i := 0; i < 1000000; i++ {
|
||||
val := gen.RandBiasedInt64()
|
||||
val := int64(gen.RandBiasedInt64())
|
||||
switch {
|
||||
case val == 0:
|
||||
buckets[63]++
|
||||
|
||||
Reference in New Issue
Block a user