This program generates asm fuzz tests for the WISC-14 ISA for ECE552.
This isn't quite "random" input, but rather an intelligent fuzz tester - it keeps an expected state of the WISC processor and memory space while generating the fuzz tests, so it can insert branches and generate taken/not taken pass/failure paths. It also performs safe register and memory accesses (it will not attempt to read from uninitialized registers or invalid memory locations). (This may not be the exact spirit of fuzz testing, but this decision was made in the interest of generating useful tests for our processor.)
- Specifiy specific opcodes to test
- Generate tests of any length
- Export tests to a file
- Report expected state of memory and register file at end of execution
- Execute TheFuzz:
java io.kersten.thefuzz.Main
- Fill in the prompts for allowed opcodes, opcode count, memory offset, and file name
- Alternatively, run from the command line for batch mode:
java io.kersten .thefuzz.main "add addz lw" 30 0 "testname" 10
Here are three example programs generated by the fuzz tester.
LLB R4, 0 #; R4=0
LLB R12, 19 #; R12=19
LLB R3, 17 #; R3=17
B GT, taken0 #; branch on GT, take = yes
fail1: #
HLT #
taken0: #
B EQ, nottaken #; branch on EQ, take = no
B LTE, nottaken #; branch on LTE, take = no
LLB R4, 45 #; R4=45
ADD R6, R4, R4 #; (45+45=90); Z->0; N->0; V->0
B EQ, nottaken #; branch on EQ, take = no
ADD R1, R6, R12 #; (90+19=109); Z->0; N->0; V->0
nottaken: #failure case for wrongly taken branches
HLT #;
# R0 = 0
# R1 = 109
# R2 = xxxx
# R3 = 17
# R4 = 45
# R5 = xxxx
# R6 = 90
# R7 = xxxx
# R8 = xxxx
# R9 = xxxx
# R10 = xxxx
# R11 = xxxx
# R12 = 19
# R13 = xxxx
# R14 = xxxx
# R15 = xxxx
# Z = 0 N = 0 V = 0
SUB R10, R0, R0 #; (0-0=0); Z->1; N->0; V->0
LLB R6, 204 #; Load lower for sw; R6=204
LHB R6, 114 #; Load upper for sw; R6=29388
SW R0, R6, -7 #; R0=0->mem[29381]
ADD R10, R10, R10 #; (0+0=0); Z->1; N->0; V->0
SLL R13, R6, 1 #; (29388<<1=-6760); Z->0
LHB R10, 26 #; R10=6656
LLB R12, 42 #; R12=42
SRL R14, R6, 2 #; (29388>>2=7347); Z->0
LHB R5, 44 #; R5=11264
ADD R11, R5, R10 #; (11264+6656=17920); Z->0; N->0; V->0
AND R1, R5, R5 #; (11264&11264=11264); Z->0
LHB R14, 114 #; R14=29363
LLB R11, 164 #; Load lower for sw; R11=164
LHB R11, 124 #; Load upper for sw; R11=31908
SW R0, R11, -5 #; R0=0->mem[31903]
LLB R6, 119 #; R6=119
LLB R3, 103 #; R3=103
AND R1, R6, R12 #; (119&42=34); Z->0
HLT #;
# R0 = 0
# R1 = 34
# R2 = xxxx
# R3 = 103
# R4 = xxxx
# R5 = 11264
# R6 = 119
# R7 = xxxx
# R8 = xxxx
# R9 = xxxx
# R10 = 6656
# R11 = 31908
# R12 = 42
# R13 = -6760
# R14 = 29363
# R15 = xxxx
# Z = 0 N = 0 V = 0
# Valid memory addresses:
# mem[29381] = 0
# mem[31903] = 0
# Test Name: Overflow
# Generated by TheFuzz v0.9.4 written by Alex Kersten and Kenneth Siu for ECE552 (https://github.com/akersten/TheFuzz)
ADDZ R3, R0, R0 #; not executed
B EQ, nottaken #; branch on EQ, take = no
LHB R1, 111 #; R1=28416
B EQ, nottaken #; branch on EQ, take = no
LHB R5, 114 #; R5=29184
B GT, taken2 #; branch on GT, take = yes
fail3: #
HLT #
taken2: #
B UNCOND, taken4 #; branch on UNCOND, take = yes
fail5: #
HLT #
taken4: #
B EQ, nottaken #; branch on EQ, take = no
ADD R11, R5, R0 #; (29184+0=29184); Z->0; N->0; V->0
LHB R5, 107 #; R5=27392
B LT, nottaken #; branch on LT, take = no
ADDZ R1, R1, R11 #; not executed
B EQ, nottaken #; branch on EQ, take = no
B UNCOND, taken9 #; branch on UNCOND, take = yes
fail10: #
HLT #
taken9: #
B NEQ, taken11 #; branch on NEQ, take = yes
fail12: #
HLT #
taken11: #
ADD R4, R0, R11 #; (0+29184=29184); Z->0; N->0; V->0
B OVFL, nottaken #; branch on OVFL, take = no
B OVFL, nottaken #; branch on OVFL, take = no
ADDZ R1, R11, R5 #; not executed
B OVFL, nottaken #; branch on OVFL, take = no
LHB R13, 51 #; R13=13056
B GTE, taken16 #; branch on GTE, take = yes
fail17: #
HLT #
taken16: #
B GT, taken18 #; branch on GT, take = yes
fail19: #
HLT #
taken18: #
ADDZ R2, R0, R5 #; not executed
ADDZ R12, R5, R1 #; not executed
LHB R5, 75 #; R5=19200
B LTE, nottaken #; branch on LTE, take = no
ADDZ R9, R5, R11 #; not executed
ADDZ R5, R5, R13 #; not executed
ADD R12, R5, R11 #; (19200+29184=32767); Z->0; N->0; V->1
LHB R8, 98 #; R8=25088
B LT, nottaken #; branch on LT, take = no
ADD R10, R11, R4 #; (29184+29184=32767); Z->0; N->0; V->1
B NEQ, taken22 #; branch on NEQ, take = yes
fail23: #
HLT #
taken22: #
ADDZ R0, R0, R0 #; No change to R0
ADDZ R1, R13, R1 #; not executed
LHB R9, 79 #; R9=20224
LHB R1, 56 #; R1=14336
ADDZ R0, R4, R11 #; No change to R0
B OVFL, taken24 #; branch on OVFL, take = yes
fail25: #
HLT #
taken24: #
LHB R7, 5 #; R7=1280
LHB R11, 34 #; R11=8704
ADD R13, R8, R9 #; (25088+20224=32767); Z->0; N->0; V->1
B EQ, nottaken #; branch on EQ, take = no
B LT, nottaken #; branch on LT, take = no
B GT, taken28 #; branch on GT, take = yes
fail29: #
HLT #
taken28: #
ADD R4, R8, R9 #; (25088+20224=32767); Z->0; N->0; V->1
LHB R8, 68 #; R8=17408
B LTE, nottaken #; branch on LTE, take = no
B GTE, taken31 #; branch on GTE, take = yes
fail32: #
HLT #
taken31: #
nottaken: #; failure case for wrongly taken branches
HLT #;
# R0 = 0
# R1 = 14336
# R2 = xxxx
# R3 = xxxx
# R4 = 32767
# R5 = 19200
# R6 = xxxx
# R7 = 1280
# R8 = 17408
# R9 = 20224
# R10 = 32767
# R11 = 8704
# R12 = 32767
# R13 = 32767
# R14 = xxxx
# R15 = xxxx
# Z = 0 N = 0 V = 1
# Valid memory addresses: