Commit 0df07d5f authored by George Hotz's avatar George Hotz

add full test suite

parent c20dde6b
......@@ -42,11 +42,12 @@ contract MIPS {
}
uint32 insn = m.ReadMemory(stateHash, pc);
uint32 opcode = insn >> 26; // 6-bits
uint32 func = insn & 0x3f; // 6-bits
// decode
// register fetch
uint32 storeAddr;
uint32 storeAddr = 0xFFFFFFFF;
uint32 rs;
uint32 rt;
if (opcode != 2 && opcode != 3) { // J-type: j and jal have no register fetch
......@@ -57,10 +58,18 @@ contract MIPS {
// R-type (stores rd)
rt = m.ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
storeAddr = REG_OFFSET + ((insn >> 9) & 0x7C);
} else {
} else if (opcode < 0x20) {
// rt is SignExtImm
uint32 SignExtImm = insn&0xFFFF | (insn&0x8000 != 0 ? 0xFFFF0000 : 0);
rt = SignExtImm;
uint32 ZeroExtImm = insn&0xFFFF;
if (opcode == 0xC || opcode == 0xD) {
rt = ZeroExtImm;
} else {
rt = SignExtImm;
}
} else if (opcode >= 0x28) {
// store rt
rt = m.ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
}
}
......@@ -78,12 +87,22 @@ contract MIPS {
}
}
if (opcode == 0 && func == 8) {
// jr
storeAddr = REG_PC;
}
// execute
uint32 val = execute(insn, rs, rt, mem);
// write back
stateHash = m.WriteMemory(stateHash, storeAddr, val);
stateHash = m.WriteMemory(stateHash, REG_PC, pc+4);
if (storeAddr != 0xFFFFFFFF) {
// does this ever not happen?
stateHash = m.WriteMemory(stateHash, storeAddr, val);
}
if (storeAddr != REG_PC) {
stateHash = m.WriteMemory(stateHash, REG_PC, pc+4);
}
return stateHash;
}
......@@ -96,17 +115,20 @@ contract MIPS {
// transform ArithLogI
// TODO: replace with table
if (opcode == 8) { opcode = 0; func = 0x20; }
else if (opcode == 9) { opcode = 0; func = 0x21; }
else if (opcode == 0xc) { opcode = 0; func = 0x24; }
if (opcode == 8) { opcode = 0; func = 0x20; } // addi
else if (opcode == 9) { opcode = 0; func = 0x21; } // addiu
else if (opcode == 0xc) { opcode = 0; func = 0x24; } // andi
else if (opcode == 0xd) { opcode = 0; func = 0x25; } // ori
else if (opcode == 0xe) { opcode = 0; func = 0x26; } // xori
if (opcode == 0) {
uint32 shamt = (insn >> 6) & 0x1f;
// R-type (ArithLog)
if (func == 0x20 || func == 0x21) { return rs+rt; // add or addu
} else if (func == 0x24) { return rs&rt; // and
} else if (func == 0x27) { return ~(rs|rt); // nor
} else if (func == 0x25) { return (rs|rt); // or
} else if (func == 0x26) { return (rs^rt); // xor
} else if (func == 0x27) { return ~(rs|rt); // nor
} else if (func == 0x22 || func == 0x23) {
return rs-rt; // sub or subu
} else if (func == 0x2a) {
......@@ -120,13 +142,15 @@ contract MIPS {
} else if (func == 0x07) { return rt >> rs; // srav
} else if (func == 0x02) { return rt >> shamt; // srl
} else if (func == 0x06) { return rt >> rs; // srlv
} else if (func == 8) { return rs; // jr
}
} else if (func == 0x20) { return mem; // lb
} else if (func == 0x24) { return mem; // lbu
} else if (func == 0x21) { return mem; // lh
} else if (func == 0x25) { return mem; // lhu
} else if (func == 0x23) { return mem; // lw
} else if (func&0x3c == 0x28) { return rt; // sb, sh, sw
} else if (opcode == 0x20) { return mem; // lb
} else if (opcode == 0x24) { return mem; // lbu
} else if (opcode == 0x21) { return mem; // lh
} else if (opcode == 0x25) { return mem; // lhu
} else if (opcode == 0x23) { return mem; // lw
} else if (opcode&0x3c == 0x28) { return rt; // sb, sh, sw
} else if (opcode == 0xf) { return rt<<16; // lui
}
}
......
......@@ -93,7 +93,8 @@ type jsoncontract struct {
//var ram []byte
//var regs [4096]byte
var ram = make(map[uint64](uint32))
var debug bool = false
var ram map[uint64](uint32)
func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeContext) ([]byte, error) {
// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
......@@ -117,12 +118,16 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
//scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
ret := common.BigToHash(big.NewInt(int64(nret))).Bytes()
fmt.Println("HOOKED READ!", fmt.Sprintf("%x = %x", addr, nret))
if debug {
fmt.Println("HOOKED READ! ", fmt.Sprintf("%x = %x", addr, nret))
}
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
} else if args[0] == 184 {
addr := common.BytesToHash(args[0x24:0x44]).Big().Uint64()
dat := common.BytesToHash(args[0x44:0x64]).Big().Uint64()
fmt.Println("HOOKED WRITE!", fmt.Sprintf("%x = %x", addr, dat))
if debug {
fmt.Println("HOOKED WRITE! ", fmt.Sprintf("%x = %x", addr, dat))
}
ram[addr] = uint32(dat)
// pass through stateRoot
......@@ -134,17 +139,39 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
return common.Hash{}.Bytes(), nil
}
func main() {
fmt.Println("hello")
dat, _ := ioutil.ReadFile("test/add.bin")
func runTest(fn string, steps int, interpreter *vm.EVMInterpreter, bytecode []byte) {
ram = make(map[uint64](uint32))
dat, _ := ioutil.ReadFile(fn)
for i := 0; i < len(dat); i += 4 {
ram[uint64(i)] = uint32(dat[i])<<24 |
uint32(dat[i+1])<<16 |
uint32(dat[i+2])<<8 |
uint32(dat[i+3])<<0
}
// 0xdb7df598
from := common.Address{}
to := common.HexToAddress("0x1337")
input := []byte{0xdb, 0x7d, 0xf5, 0x98} // Steps(bytes32, uint256)
input = append(input, common.BigToHash(common.Big0).Bytes()...)
input = append(input, common.BigToHash(big.NewInt(int64(steps))).Bytes()...)
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, 20000000)
//fmt.Println(bytecodehash, bytecode)
contract.SetCallCode(&to, crypto.Keccak256Hash(bytecode), bytecode)
start := time.Now()
ret, err := interpreter.Run(contract, input, false)
elapsed := time.Now().Sub(start)
fmt.Println(ret, err, contract.Gas, elapsed,
ram[0xbffffff4], ram[0xbffffff8], fmt.Sprintf("%x", ram[0xc0000080]), fn)
if err != nil {
log.Fatal(err)
}
}
func main() {
fmt.Println("hello")
/*var parent types.Header
database := state.NewDatabase(parent)
......@@ -155,7 +182,6 @@ func main() {
json.NewDecoder(bytes.NewReader(mipsjson)).Decode(&jj)
bytecode := common.Hex2Bytes(jj.DeployedBytecode[2:])
//fmt.Println(bytecode, jj.Bytecode)
bytecodehash := crypto.Keccak256Hash(bytecode)
statedb := &StateDB{Bytecode: bytecode}
bc := core.NewBlockChain()
......@@ -172,8 +198,6 @@ func main() {
evm := vm.NewEVM(blockContext, txContext, statedb, params.MainnetChainConfig, config)
fmt.Println(evm)
from := common.Address{}
to := common.HexToAddress("0x1337")
/*ret, gas, err := evm.Call(vm.AccountRef(from), to, []byte{}, 20000000, common.Big0)
fmt.Println(ret, gas, err)*/
......@@ -184,22 +208,11 @@ func main() {
input = append(input, common.Hash{}.Bytes()...)*/
// 1.26s for 100000 steps
steps := 10
//steps := 20
// 19.100079097s for 1_000_000 new steps
//steps := 1000000
//debug = true
runTest("test/add.bin", 20, interpreter, bytecode)
runTest("test/addiu.bin", 20, interpreter, bytecode)
// 0xdb7df598
input := []byte{0xdb, 0x7d, 0xf5, 0x98} // Steps(bytes32, uint256)
input = append(input, common.BigToHash(common.Big0).Bytes()...)
input = append(input, common.BigToHash(big.NewInt(int64(steps))).Bytes()...)
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, 20000000)
//fmt.Println(bytecodehash, bytecode)
contract.SetCallCode(&to, bytecodehash, bytecode)
start := time.Now()
ret, err := interpreter.Run(contract, input, false)
elapsed := time.Now().Sub(start)
fmt.Println(ret, err, contract.Gas, elapsed)
if err != nil {
log.Fatal(err)
}
}
......@@ -13,7 +13,8 @@ for d in os.listdir("test/"):
if not d.endswith(".asm"):
continue
print("building", d)
os.system("%s/mips-elf-as -o /tmp/mips/%s test/%s" % (path, d, d))
# which mips is go
os.system("%s/mips-elf-as -march=mips32 -o /tmp/mips/%s test/%s" % (path, d, d))
elffile = ELFFile(open("/tmp/mips/"+d, "rb"))
#print(elffile)
for sec in elffile.iter_sections():
......
###############################################################################
# File : addi.asm
# Project : MIPS32 MUX
# Author : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'addi' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xffff # A = 0xfffffffd (-3)
ori $t0, 0xfffd
addi $t1, $t0, 5 # B = A + 5 = 2
addi $t2, $t1, 0xfffe # C = B + -2 = 0
sltiu $v0, $t2, 1 # D = 1 if C == 0
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : addu.asm
# Project : MIPS32 MUX
# Author : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'addu' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xffff # A = 0xfffffffd (-3)
ori $t0, 0xfffd
ori $t1, $0, 0x3 # B = 0x3
addu $t2, $t0, $t1 # C = A + B = 0
sltiu $v0, $t2, 1 # D = 1 if C == 0
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : and.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'and' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xdeaf # A = 0xdeafbeef
lui $t1, 0xaaaa # B = 0xaaaaaaaa
lui $t2, 0x5555 # C = 0x55555555
ori $t0, 0xbeef
ori $t1, 0xaaaa
ori $t2, 0x5555
and $t3, $t0, $t1 # D = A & B = 0x8aaaaaaa
and $t4, $t2, $t3 # E = B & D = 0
sltiu $v0, $t4, 1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : andi.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'andi' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $t0, $0, 0xcafe # A = 0xcafe
andi $t1, $t0, 0xaaaa # B = A & 0xaaaa = 0x8aaa
andi $t2, $t1, 0x5555 # C = B & 0x5555 = 0
sltiu $v0, $t2, 1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : bds_mtc0.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'mtc0' instruction in a branch delay slot
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xc001
ori $t0, 0xcafe
j $check
mtc0 $t0, $11, 0
j $end
move $v0, $0
$check:
mfc0 $t1, $11, 0
subu $t2, $t0, $t1
sltiu $v0, $t2, 1
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : beq.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'beq' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $t0, $0, 0xcafe
ori $t1, $0, 0xcafe
ori $v0, $0, 0 # The test result starts as a failure
beq $t0, $v0, $finish # No branch
nop
beq $t0, $t1, $target
nop
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
beq $0, $0, $finish # Late-by-1 branch detection (result not stored)
nop
j $finish
nop
#### Test code end ####
.end test
###############################################################################
# File : beql.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'beql' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $t0, $0, 0xcafe
ori $t1, $0, 0xcafe
ori $v0, $0, 0 # The test result starts as a failure
ori $t2, $0, 0
ori $t3, $0, 0
beql $t0, $v0, $finish # Expect no branch, no BDS
ori $t2, $0, 0xcafe
beql $t0, $t1, $target # Expect branch and BDS
nop
$finish:
sw $v0, 8($s0) # Late-by-1 branch detection (result not stored)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
beql $0, $0, $likely
ori $t3, $0, 0xcafe
j $finish
nop
$likely:
subu $t4, $t3, $t2 # Should be t4 = 0xcafe - 0
subu $t5, $t4, $t0 # Should be t5 = 0xcafe - 0xcafe = 0
beql $0, $0, $finish
sltiu $v0, $t5, 1 # Set the result to pass
#### Test code end ####
.end test
###############################################################################
# File : bgez.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bgez' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xffff
bgez $t0, $finish # No branch
nop
bgez $s1, $target
nop
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
bgez $0, $finish # Late-by-1 branch detection (result not stored)
nop
j $finish # Broken branch recovery
nop
#### Test code end ####
.end test
###############################################################################
# File : bgezal.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bgezal' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v1, $ra, 0 # Save $ra
ori $v0, $0, 0 # The test result starts as a failure
lui $t0, 0xffff
bgezal $t0, $finish # No branch
nop
bgezal $s1, $target
nop
$finish:
sw $v0, 8($s0)
ori $ra, $v1, 0 # Restore $ra
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
jr $ra
nop
#### Test code end ####
.end test
###############################################################################
# File : bgezall.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bgezall' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v1, $ra, 0 # Save $ra
ori $v0, $0, 0 # The test result starts as a failure
lui $t0, 0xffff
ori $t1, $0, 0
ori $t2, $0, 0
bgezall $t0, $finish # No branch, no BDS
ori $t1, $0, 0x1
bgezall $s1, $target
ori $t2, $0, 0x1
j $likely
nop
$finish:
sw $v0, 8($s0)
ori $ra, $v1, 0 # Restore $ra
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
jr $ra
nop
$likely:
subu $t3, $t2, $t1 # Should be t3 = 1 - 0
addiu $t4, $t3, -1 # Should be t4 = 1 - 1 = 0
bgezall $s1, $finish
sltiu $v0, $t4, 1
#### Test code end ####
.end test
###############################################################################
# File : bgezl.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bgezl' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xffff
ori $t1, $0, 0
ori $t2, $0, 0
bgezl $t0, $finish # No branch, no BDS
ori $t1, $0, 0x1
bgezl $s1, $target
ori $t2, $0, 0x1
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
bgezl $0, $likely
nop
j $finish # Broken branch recovery
nop
$likely:
subu $t3, $t2, $t1 # Should be t3 = 1 - 0
subu $t4, $t3, $s1 # Should be t4 = 1 - 1 = 0
bgezl $s1, $finish
sltiu $v0, $t4, 1
j $finish
ori $v0, $0, 0
#### Test code end ####
.end test
###############################################################################
# File : bgtz.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bgtz' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 0 # The test result starts as a failure
lui $t0, 0xffff
bgtz $t0, $finish # No branch
nop
bgtz $s1, $target
nop
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
bgtz $s1, $finish # Late-by-1 branch detection (result not stored)
nop
j $finish # Broken branch recovery
nop
#### Test code end ####
.end test
###############################################################################
# File : bgtzl.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bgtzl' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 0 # The test result starts as a failure
lui $t0, 0xffff
ori $t1, $0, 0
ori $t2, $0, 0
bgtzl $t0, $finish # No branch, no BDS
ori $t1, $0, 0x1
bgtzl $s1, $target
ori $t2, $0, 0x1
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
bgtzl $s1, $likely # Late-by-1 branch detection (result not stored)
nop
j $finish # Broken branch recovery
nop
$likely:
subu $t3, $t2, $t1 # Should be t3 = 1 - 0
addiu $t4, $t3, -1 # Should be t4 = 1 - 1 = 0
bgtzl $s1, $finish
sltiu $v0, $t4, 1
j $finish
ori $v0, $0, 0
#### Test code end ####
.end test
###############################################################################
# File : blez.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'blez' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 0 # The test result starts as a failure
blez $s1, $finish # No branch
lui $t0, 0xffff
blez $t0, $target
nop
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
blez $0, $finish # Late-by-1 branch detection (result not stored)
nop
j $finish
nop
#### Test code end ####
.end test
###############################################################################
# File : blezl.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'blezl' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 0 # The test result starts as a failure
lui $t0, 0xffff
ori $t1, $0, 0
ori $t2, $0, 0
blezl $s1, $finish # No branch, no BDS
ori $t1, $0, 1
blezl $t0, $target
ori $t2, $0, 1
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
blezl $0, $likely
nop
j $finish
nop
$likely:
subu $t3, $t2, $t1 # Should be t3 = 1 - 0
addiu $t4, $t3, -1 # Should be t4 = 1 - 1 = 0
blezl $t0, $finish
sltiu $v0, $t4, 1
j $finish
ori $v0, $0, 0
#### Test code end ####
.end test
###############################################################################
# File : bltz.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bltz' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 0 # The test result starts as a failure
bltz $0, $finish # No branch
nop
bltz $s1, $finish # No branch
lui $t0, 0xffff
bltz $t0, $target
nop
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
bltz $t0, $finish # Late-by-1 branch detection (result not stored)
nop
j $finish # Broken branch recovery
nop
#### Test code end ####
.end test
###############################################################################
# File : bltzal.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bltzal' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 0 # The test result starts as a failure
ori $v1, $ra, 0 # Save $ra
lui $t0, 0xffff
bltzal $0, $finish # No branch
nop
bltzal $t0, $target
nop
$finish:
sw $v0, 8($s0)
ori $ra, $v1, 0 # Restore $ra
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
jr $ra
nop
#### Test code end ####
.end test
###############################################################################
# File : bltzall.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bltzall' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 0 # The test result starts as a failure
ori $v1, $ra, 0 # Save $ra
lui $t0, 0xffff
ori $t1, $0, 0
ori $t2, $0, 0
bltzall $0, $finish # No branch, no BDS
ori $t1, $0, 1
bltzall $t0, $target
ori $t2, $0, 1
j $likely
nop
$finish:
sw $v0, 8($s0)
ori $ra, $v1, 0 # Restore $ra
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
jr $ra
nop
$likely:
subu $t3, $t2, $t1 # Should be t3 = 1 - 0
addiu $t4, $t3, -1 # Should be t4 = 1 - 1 = 0
bltzall $t0, $finish
sltiu $v0, $t4, 1
j $finish
ori $v0, $0, 0
#### Test code end ####
.end test
###############################################################################
# File : bltzl.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bltzl' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 0 # The test result starts as a failure
lui $t0, 0xffff
ori $t1, $0, 0
ori $t2, $0, 0
bltzl $0, $finish # No branch, no BDS
ori $t1, $0, 1
bltzl $s1, $finish # No branch, no BDS
ori $t1, $0, 2
bltzl $t0, $target
ori $t2, $0, 1
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
bltzl $t0, $likely
nop
j $finish # Broken branch recovery
nop
$likely:
subu $t3, $t2, $t1 # Should be t3 = 1 - 0
addiu $t4, $t3, -1 # Should be t4 = 1 - 1 = 0
bltzl $t0, $finish
sltiu $v0, $t4, 1
j $finish
ori $v0, $0, 0
#### Test code end ####
.end test
###############################################################################
# File : bne.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bne' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $t0, $0, 0xcafe
ori $t1, $0, 0xcafe
ori $v0, $0, 0 # The test result starts as a failure
bne $t0, $t1, $finish # No branch
nop
bne $t0, $v0, $target
nop
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
bne $t0, $0, $finish # Late-by-1 branch detection (result not stored)
nop
j $finish
nop
#### Test code end ####
.end test
###############################################################################
# File : bnel.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'bnel' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $t0, $0, 0xcafe
ori $t1, $0, 0xcafe
ori $v0, $0, 0 # The test result starts as a failure
ori $t2, $0, 0
ori $t3, $0, 0
bnel $t0, $t1, $finish # No branch, no BDS
ori $t2, $0, 1
bnel $t0, $v0, $target
ori $t3, $0, 1
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
$done:
jr $ra
nop
j $finish # Early-by-1 branch detection
$target:
nop
bnel $t0, $0, $likely
nop
j $finish
nop
$likely:
subu $t4, $t3, $t2 # Should be t4 = 1 - 0
addiu $t5, $t4, -1 # Should be t5 = 1 - 1 = 0
bnel $t0, $v0, $finish
sltiu $v0, $t5, 1
j $finish
ori $v0, $0, 0
#### Test code end ####
.end test
###############################################################################
# File : clo.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'clo' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t2, 0xffff # 32
ori $t2, 0xffff
lui $t3, 0xffff # 18
ori $t3, 0xc000
lui $t4, 0xf800 # 5
lui $t5, 0xf000 # 4
lui $t6, 0x7fff # 0
ori $t7, $0, 0 # 0
clo $s2, $t2
clo $s3, $t3
clo $s4, $t4
clo $s5, $t5
clo $s6, $t6
clo $s7, $t7
addiu $s2, -32
addiu $s3, -18
addiu $s4, -5
addiu $s5, -4
addiu $s6, 0
addiu $s7, 0
or $v1, $s2, $s3
or $v1, $v1, $s4
or $v1, $v1, $s5
or $v1, $v1, $s6
or $v1, $v1, $s7
sltiu $v0, $v1, 1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : clz.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'clz' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t2, 0xffff # 0
ori $t2, 0xffff
ori $t3, $0, 0x0100 # 23
lui $t4, 0x0700 # 5
lui $t5, 0x0f00 # 4
lui $t6, 0x7fff # 1
ori $t7, $0, 0 # 32
clz $s2, $t2
clz $s3, $t3
clz $s4, $t4
clz $s5, $t5
clz $s6, $t6
clz $s7, $t7
addiu $s2, 0
addiu $s3, -23
addiu $s4, -5
addiu $s5, -4
addiu $s6, -1
addiu $s7, -32
or $v1, $s2, $s3
or $v1, $v1, $s4
or $v1, $v1, $s5
or $v1, $v1, $s6
or $v1, $v1, $s7
sltiu $v0, $v1, 1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : dcache_adrhinv.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the address hit invalidate operation on the dcache
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $t1, $cache_on # Run this code with the i-cache enabled by jumping to the cacheable address
lui $t0, 0xdfff
ori $t0, 0xffff
and $t1, $t1, $t0
jr $t1
li $v0, 1 # Initialize the test result (1 is pass)
$cache_on:
la $s2, word # Uncacheable address for 'word' in kseg1
la $s3, word # Cacheable address of 'word' in kseg0 (set below)
lui $t0, 0xdfff
ori $t0, 0xffff
and $s3, $s3, $t0 # Clearing bit 29 changes a kseg1 address to kseg0
jal test1
nop
jal test2
nop
jal test3
nop
j $end
nop
test1: # No Writeback: Load to cache, modify, invalidate => memory/uncached value should not be updated
lw $t1, 0($s3) # Load 'word' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v1, $v1, 1
and $v0, $v0, $v1
li $t0, 4321 # Modify 'word' in the cache
sw $t0, 0($s3)
lw $t0, 0($s3) # Sanity check that the store worked
addiu $v1, $t0, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
cache 0x11, 0($s3) # Invalidate 'word' in the cache (11 <=> {3'AdrHitInv, 2'L1-DCache})
lw $t2, 0($s2) # Check that the (uncached) memory word was not updated
addiu $v1, $t2, -1234
sltiu $v1, $v1, 1
and $v0, $v0, $v1
jr $ra
nop
test2: # Invalidate: Load to cache, invalidate, write uncached, load to cache => new value in cache
lw $t1, 0($s3) # Load 'word' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v1, $v1, 1
and $v0, $v0, $v1
cache 0x15, 0($s3) # Remove 'word' from the cache
li $t0, 4321 # Modify 'word' in memory
sw $t0, 0($s2)
lw $t1, 0($s3) # Load 'word' to the cache. It should have the new value
addiu $v1, $t1, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
li $t0, 1234 # Restore 'word' for the next test
sw $t0, 0($s2)
jr $ra
sw $t0, 0($s3)
test3: # Invalidate: Load to cache, modify, write uncached, invalidate, load to cache => new value in cache
lw $t1, 0($s3) # Load 'word' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v1, $v1, 1
and $v0, $v0, $v1
li $t0, 777 # Modify 'word' in the cache
sw $t0, 0($s3)
li $t0, 4321 # Modify 'word' in memory
sw $t0, 0($s2)
cache 0x11, 0($s3) # Remove 'word' from the cache
lw $t1, 0($s3) # Load 'word' to the cache. It should have the new uncached value
addiu $v1, $t1, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
jr $ra
nop
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.balign 4096 # Place this code at address 0xXXXXX{3,7,b,f}30, which is the arbitrary
.skip 0xaa0, 0 # index 0x33 (51) for a 2 KiB 2-way 16-byte-block cache
word:
.word 0x000004d2 # Arbitrary value (1234) indicating the data is unchanged
.end test
###############################################################################
# File : dcache_adrhwbinv.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the address hit writeback invalidate operation on the dcache
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $t1, $cache_on # Run this code with the i-cache enabled by jumping to the cacheable address
lui $t0, 0xdfff
ori $t0, 0xffff
and $t1, $t1, $t0
jr $t1
nop
$cache_on:
la $s2, word # Uncacheable address for 'word' in kseg1
la $s3, word # Cacheable address of 'word' in kseg0 (set below)
lui $t0, 0xdfff
ori $t0, 0xffff
and $s3, $s3, $t0 # Clearing bit 29 changes a kseg1 address to kseg0
jal test1
nop
jal test2
nop
jal test3
nop
j $end
nop
test1: # Writeback: Load to cache, modify, invalidate => memory/uncached value should be updated
lw $t1, 0($s3) # Load 'word' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v0, $v1, 1
li $t0, 4321 # Modify 'word' in the cache
sw $t0, 0($s3)
lw $t0, 0($s3) # Sanity check that the store worked
addiu $v1, $t0, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
cache 0x15, 0($s3) # Invalidate 'word' writing it back to memory (15 <=> {3'AdrHitWbInv, 2'L1-DCache})
lw $t2, 0($s2) # Check that the (uncached) memory word was updated
addiu $v1, $t2, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
li $t0, 1234 # Restore 'word' for the next test
jr $ra
sw $t0, 0($s2)
test2: # Invalidate: Load to cache, invalidate, write uncached, load to cache => new value in cache
lw $t1, 0($s3) # Load 'word' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v1, $v1, 1
and $v0, $v0, $v1
cache 0x15, 0($s3) # Remove 'word' from the cache
li $t0, 4321 # Modify 'word' in memory
sw $t0, 0($s2)
lw $t1, 0($s3) # Load 'word' to the cache. It should have the new value
addiu $v1, $t1, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
li $t0, 1234 # Restore 'word' for the next test
sw $t0, 0($s2)
jr $ra
sw $t0, 0($s3)
test3: # Invalidate: Load to cache, modify, invalidate, write uncached, load to cache => new value in cache
lw $t1, 0($s3) # Load 'word' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v1, $v1, 1
and $v0, $v0, $v1
li $t0, 777 # Modify 'word' in the cache
sw $t0, 0($s3)
cache 0x15, 0($s3) # Remove 'word' from the cache
li $t0, 4321 # Modify 'word' in memory
sw $t0, 0($s2)
lw $t1, 0($s3) # Load 'word' to the cache. It should have the new value
addiu $v1, $t1, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
jr $ra
nop
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.balign 4096 # Place this code at address 0xXXXXX{3,7,b,f}30, which is the arbitrary
.skip 0xaa0, 0 # index 0x33 (51) for a 2 KiB 2-way 16-byte-block cache
word:
.word 0x000004d2 # Arbitrary value (1234) indicating the data is unchanged
.end test
###############################################################################
# File : dcache_idxwbinv.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the index writeback invalidate operation on the dcache
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $s2, word # Uncacheable address for 'word' in kseg1
la $s3, word # Cacheable address of 'word' in kseg0
lui $t0, 0xdfff # (clear bit 29 to change from kseg1 to kseg0)
ori $t0, 0xffff
and $s3, $s3, $t0
lw $t1, 0($s3) # Load 'word' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v0, $v1, 1
li $t0, 4321 # Store a new value to 'word' in the cache
sw $t0, 0($s3)
lw $t2, 0($s3) # Sanity check that the store worked (new value)
addiu $v1, $t2, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lw $t3, 0($s2) # Verify that the uncached value did not update
addiu $v1, $t3, -1234
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lui $t0, 0x8000 # Invalidate index 0x33 (51) for both ways (1 KiB apart)
cache 0x1, 0x0330($t0) # 0x1 <=> {000, 01} <=> {IdxWbInv, L1-DCache}
cache 0x1, 0x0730($t0)
lw $t4, 0($s2) # Load 'word1' uncached (should have new value)
addiu $v1, $t4, -4321
sltiu $v1, $v1, 1
and $v0, $v1, $v1
j $end # Set the result and finish
nop
.balign 1024 # Place this code at address 0xXXXXX{3,7,b,f}30, which is the arbitrary
.skip 0x330, 0 # index 0x33 (51) for a 2 KiB 2-way 16-byte-block cache
word:
.word 0x000004d2 # Arbitrary value (1234) indicating the data is unchanged
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : dcache_stag1.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the index store tag operation on the dcache: Invalidate a block
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $t1, $cache_on # Run the rest of the code with the i-cache enabled (kseg0)
lui $t0, 0xdfff
ori $t0, 0xffff
and $t1, $t1, $t0 # Clearing bit 29 of a kseg1 address moves it to kseg0
j $t1
nop
$cache_on:
la $s2, word # Uncacheable address for 'word' in kseg1
la $s3, word # Cacheable address of 'word' in kseg0
and $s3, $s3, $t0 # Clearing bit 29 of a kseg1 address moves it to kseg0
lw $t1, 0($s3) # Load 'word' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v0, $v1, 1
li $t2, 4321 # Store a new value to 'word' in the cache
sw $t2, 0($s3)
lw $t1, 0($s3) # Sanity check that the store worked (new value)
addiu $v1, $t1, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
mtc0 $0, $28, 0 # Prepare TagHi/TagLo for invalidation
mtc0 $0, $29, 0
lui $t0, 0x8000 # Invalidate index 0x33 (51) for both ways (1 KiB apart)
cache 0x9, 0x0330($t0) # 0x9 <=> {010, 01} <=> {IdxStoreTag, L1-DCache}
cache 0x9, 0x0730($t0)
lw $t3, 0($s2) # Load 'word' from memory. It should be the old value
addiu $v1, $t3, -1234
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lw $t4, 0($s3) # Load again but cached. Expect the old value still
addiu $v1, $t4, -1234
sltiu $v1, $v1, 1
and $v0, $v0, $v1
j $end # Set the result and finish
nop
.balign 1024 # Place this code at address 0xXXXXX{3,7,b,f}30, which is the arbitrary
.skip 0x330, 0 # index 0x33 (51) for a 2 KiB 2-way 16-byte-block cache
word:
.word 0x000004d2 # Arbitrary value (1234) indicating the data is unchanged
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : dcache_stag2.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test index store tag operation on the dcache: Change a tag to a new address
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $s2, word1 # Uncacheable address of 'word1' in kseg1
la $s3, word1 # Cacheable address of 'word1' in kseg1 (set below)
la $s4, word2 # Uncacheable address of 'word2' in kseg1
la $s5, word2 # Cacheable address of 'word2' in kseg0 (set below)
lui $t0, 0xdfff
ori $t0, 0xffff
and $s3, $s3, $t0 # Clearing bit 29 changes a kseg1 address to kseg0
and $s5, $s5, $t0
lw $t1, 0($s3) # Load 'word1' into the cache
addiu $v1, $t1, -1234 # Sanity check that the load worked
sltiu $v0, $v1, 1
li $t0, 7777
sw $t0, 0($s3) # Change the value of 'word1' in the cache
lw $t2, 0($s3) # Sanity check that the store worked
addiu $v1, $t2, -7777
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lui $t0, 0x1fff # Compute the physical address of 'word2'
ori $t0, 0xffff
and $t3, $t0, $s4
srl $t3, $t3, 1 # TagLo format is {1'b0, 23'b(Tag), 2'b(State), 6'b0}
lui $t0, 0xffff
ori $t0, 0xff00
and $t3, $t3, $t0
ori $t3, 0x00c0 # If any bit of State (TagLo[7:6]) is high => valid (if both => dirty)
mtc0 $t3, $28, 0 # Send the tag to TagLo and zero TagHi
mtc0 $0, $29, 0
lui $t0, 0x8000 # Change the tag of 'word1' to 'word2' (assumes data is in set A!)
cache 0x9, 0x0730($t0) # 0x9 <=> {010, 01} <=> {IdxStoreTag, L1-DCache}
lw $t4, 0($s5) # Load 'word2' from the cache. It should contain '7777'
addiu $v1, $t4, -7777
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lw $t5, 0($s4) # Load 'word2' uncached. It should be the original value
addiu $v1, $t5, -4321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lw $t6, 0($s3) # Load 'word1' cached. It should be the original value
addiu $v1, $t6, -1234
sltiu $v1, $v1, 1
and $v0, $v0, $v1
j $end # Set the result and finish
nop
.balign 1024 # Place this code at address 0xXXXXX{3,7,b,f}30, which is the arbitrary
.skip 0x330, 0 # index 0x33 (51) for a 2 KiB 2-way 16-byte-block cache
word1:
.word 0x000004d2 # Arbitrary value (1234) indicating the data is unchanged
.balign 1024 # Move to another address with the same set index
.skip 0x330, 0
word2:
.word 0x000010e1 # Arbitrary value (4321)
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : div.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'div' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0x1234
ori $t0, 0x5678
lui $t1, 0xc001
ori $t1, 0xcafe
div $t1, $t0 # 0xfffffffd (q), 0xf69ece66 (r)
mfhi $t2
mflo $t3
lui $t4, 0xf69e
ori $t4, 0xce66
lui $t5, 0xffff
ori $t5, 0xfffd
subu $t6, $t2, $t4
subu $t7, $t3, $t5
sltiu $v0, $t6, 1
sltiu $v1, $t7, 1
and $v0, $v0, $v1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : divu.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'divu' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0x1234
ori $t0, 0x5678
lui $t1, 0xc001
ori $t1, 0xcafe
divu $t1, $t0 # 0xa (q), 0x09f66a4e (r)
mfhi $t2
mflo $t3
lui $t4, 0x09f6
ori $t4, 0x6a4e
lui $t5, 0x0000
ori $t5, 0x000a
subu $t6, $t2, $t4
subu $t7, $t3, $t5
sltiu $v0, $t6, 1
sltiu $v1, $t7, 1
and $v0, $v0, $v1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : icache_adrhinv.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the address hit invalidate operation on the icache
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $t0, $cache_on # Run the remainder of the code from the i-cache
lui $t1, 0xdfff
ori $t1, 0xffff
and $t0, $t0, $t1
jr $t0
nop
$cache_on:
la $s2, $mutable # Run the mutable code once in kseg0 to cache it
lui $t0, 0xdfff # (Clear bit 29 to change the address from kseg1 to kseg0)
ori $t0, 0xffff
and $s2, $s2, $t0
jalr $s2
nop
addiu $v1, $s7, -123 # Sanity check the call result
sltiu $v0, $v1, 1
la $t0, $mutable # Replace the mutable instruction with "li $s7, 321"
lui $s3, 0x2417
ori $s3, 0x0141
sw $s3, 0($t0) # This address is in kseg1, hence uncacheable so it will go to mem
jalr $s2 # Call the cacheable version again to verify it was actually
nop # cached--if so it will give the old value
addiu $v1, $s7, -123
sltiu $v1, $v1, 1
and $v0, $v0, $v1
cache 0x10, 0($t0) # Test 1: Invalidate via the kseg1 address
# 0x10 <=> {100, 00} <=> {AddrHitInvalidate, L1-ICache}
jalr $s2 # Call the cacheable version. If the invalidation worked it will
nop # pull the new instruction from memory which sets '321'. Otherwise
# the invalidation (or uncacheable store) failed.
addiu $v1, $s7, -321
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lui $s4, 0x2417 # Replace the new instruction with the original version
ori $s4, 0x007b
sw $s4, 0($t0)
cache 0x10, 0($t0) # Test 2: Invalidate via the kseg0 address
jalr $s2 # Cacheable version again. Should give '123'
nop
addiu $v1, $s7, -123
sltiu $v1, $v1, 1
and $v0, $v0, $v1
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.balign 4096 # Place this code at address 0xXXXXXaa0, which is the arbitrary
.skip 0xaa0, 0 # index 0xaa (170) for an 8 KiB 2-way 16-byte block cache
$mutable:
li $s7, 123 # The arbitrary number 123 indicates the instruction is unchanged
jr $ra
nop
.end test
###############################################################################
# File : icache_idxinv.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the index invalidate tag operation on the icache
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $t0, $cache_on # Run the remainder of the code from the i-cache
lui $t1, 0xdfff
ori $t1, 0xffff
and $t0, $t0, $t1
jr $t0
nop
$cache_on:
la $s2, $mutable # Run the mutable code once in kseg0 to cache it
lui $t0, 0xdfff # (Clear bit 29 to change the address from kseg1 to kseg0)
ori $t0, 0xffff
and $s2, $s2, $t0
jalr $s2
nop
addiu $v1, $s7, -123 # Sanity check the call result
sltiu $v0, $v1, 1
la $t0, $mutable # Replace the mutable instruction with "li $s7, 321"
lui $t1, 0x2417
ori $t1, 0x0141
sw $t1, 0($t0) # This address is in kseg1, hence uncacheable so it will go to mem
jalr $s2 # Call the cacheable version again to verify it was actually
nop # cached--if so it will give the old value
addiu $v1, $s7, -123
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lui $s3, 0x8000 # Invalidate the cache index 0xaa (170) for both sets (4 KiB apart)
cache 0x0, 0x0aa0($s3) # 0x8 <=> {010, 00} <=> {IndexStoreTag, L1-ICache}
cache 0x0, 0x1aa0($s3)
jalr $s2 # Call the cacheable version. If the invalidation worked it will
nop # pull the new instruction from memory which sets '321'. Otherwise
addiu $v1, $s7, -321 # the invalidation (or uncacheable store) failed.
sltiu $v1, $v1, 1
and $v0, $v0, $v1
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.balign 4096 # Place this code at address 0xXXXXXaa0, which is the arbitrary
.skip 0xaa0, 0 # index 0xaa (170) for an 8 KiB 2-way 16-byte block cache
$mutable:
li $s7, 123 # The arbitrary number 123 indicates the instruction is unchanged
jr $ra
nop
.end test
###############################################################################
# File : icache_stag1.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the index store tag operation on the icache: Invalidate a block
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
mtc0 $0, $28, 0 # Prepare the TagLo/TagHi invalidation value
mtc0 $0, $29, 0
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $t0, $cache_on # Run the remainder of the code from the i-cache
lui $t1, 0xdfff
ori $t1, 0xffff
and $t0, $t0, $t1
jr $t0
nop
$cache_on:
la $s2, $mutable # Run the mutable code once in kseg0 to cache it
lui $t0, 0xdfff # (Clear bit 29 to change the address from kseg1 to kseg0)
ori $t0, 0xffff
and $s2, $s2, $t0
jalr $s2
nop
addiu $v1, $s7, -123 # Sanity check the call result
sltiu $v0, $v1, 1
la $t0, $mutable # Replace the mutable instruction with "li $s7, 321"
lui $t1, 0x2417
ori $t1, 0x0141
sw $t1, 0($t0) # This address is in kseg1, hence uncacheable so it will go to mem
jalr $s2 # Call the cacheable version again to verify it was actually
nop # cached--if so it will give the old value
addiu $v1, $s7, -123
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lui $s3, 0x8000 # Invalidate the cache index 0xaa (170) for both sets (4 KiB apart)
cache 0x8, 0x0aa0($s3) # 0x8 <=> {010, 00} <=> {IndexStoreTag, L1-ICache}
cache 0x8, 0x1aa0($s3)
jalr $s2 # Call the cacheable version. If the invalidation worked it will
nop # pull the new instruction from memory which sets '321'. Otherwise
addiu $v1, $s7, -321 # the invalidation (or uncacheable store) failed.
sltiu $v1, $v1, 1
and $v0, $v0, $v1
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.balign 4096 # Place this code at address 0xXXXXXaa0, which is the arbitrary
.skip 0xaa0, 0 # index 0xaa (170) for an 8 KiB 2-way 16-byte block cache
$mutable:
li $s7, 123 # The arbitrary number 123 indicates the instruction is unchanged
jr $ra
nop
.end test
###############################################################################
# File : icache_stag2.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test index store tag operation on the icache: Change a tag to a new address
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
# Procedure: Load procA to cache, change tag to procB, jump to procB and it should execute procA.
mfc0 $t0, $16, 0 # Enable kseg0 caching (Config:K0 = 0x3)
lui $t1, 0xffff
ori $t1, 0xfff8
and $t0, $t0, $t1
ori $t0, 0x3
mtc0 $t0, $16, 0
la $t0, $cache_on # Run the remainder of the code from the i-cache
lui $t8, 0xdfff
ori $t8, 0xffff
and $t0, $t0, $t8
jr $t0
nop
$cache_on:
la $s2, $procedureA # Run procedure A once in kseg0 to cache it
lui $t0, 0xdfff # (Clear bit 29 to change the address from kseg1 to kseg0)
ori $t0, 0xffff
and $s2, $s2, $t0
jalr $s2
nop
addiu $v1, $s7, -123 # Sanity check the call result
sltiu $v0, $v1, 1
la $s3, $procedureB # Compute the physical tag of procedureB
lui $t0, 0xdfff
ori $t0, 0xffff
and $s3, $s3, $t0 # kseg0 address of procedureB
lui $t0, 0x1fff
ori $t0, 0xffff
and $t1, $t0, $s3 # Physical address of procedureB
srl $t2, $t1, 1 # TagLo format is {1'b0, 23'b(Tag), 2'b(State), 6'b0}
lui $t0, 0xffff
ori $t0, 0xff00
and $t2, $t2, $t0
ori $t2, 0x00c0 # If any bit of State (TagLo[7:6]) is high => valid
mtc0 $t2, $28, 0 # Send the tag to TagLo and zero TagHi
mtc0 $0, $29, 0
lui $t1, 0x8000 # Change the tag for procedureA to procedureB
cache 0x8, 0x1aa0($t1) # 0x8 <=> {010, 00} <=> {IndexStoreTag, L1-ICache}
# NOTE: Assumes the data is in set A! This could break.
nop # Inject NOPs to prevent the next jump target from entering
nop # the pipeline and being 'prefetched' into the cache
nop # before the 'cache' operation retires
jalr $s3 # Call procedureB, which should actually be procedureA
nop
addiu $v1, $s7, -123
sltiu $v1, $v1, 1
and $v0, $v0, $v1
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.balign 4096 # Place this code at address 0xXXXXXaa0, which is the arbitrary
.skip 0xaa0, 0 # index 0xaa (170) for an 8 KiB 2-way 16-byte block cache
$procedureA:
li $s7, 123 # The arbitrary number 123 indicates the instruction is unchanged
jr $ra
nop
.balign 4096
.skip 0xaa0, 0
$procedureB:
li $s7, 321
jr $ra
nop
.end test
###############################################################################
# File : icache_tlbl.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test that an icache operation causes a TLB exception when needed
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
jal $setup
nop
xor $v0, $v0, $v0
la $ra, $end
cache_inst:
j $end
cache 0x10, 0($0) # Cause a TLB miss for L1-ICache HitInv
nop
$setup:
mfc0 $k0, $12, 0 # Load the Status register for general setup
lui $k1, 0x1000 # Allow access to CP0
or $k0, $k0, $k1
lui $k1, 0x1dff # Disable CP3-1, No RE, BEV
ori $k1, 0x00e6 # Disable all interrupts, kernel mode
and $k0, $k0, $k1
mtc0 $k0, $12, 0 # Commit new Status register
mtc0 $ra, $30, 0 # Set ErrorEPC to the return address of this call
la $a0, cache_inst # Used by exception handler for verification
eret # Exit boot mode and return
$end:
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : interrupt_sw.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the basic functionality of software interrupts.
# This triggers SW Int 0 to the general exception vector (0x80000180)
# and then SW Int 1 to the interrupt vector (0x80000200), thus
# performing basic verification of the exception vectors and offsets too.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
j $setup # Enable interrupts and exit boot mode
nop
$run:
move $s2, $ra # Save $ra since we'll use it
sw $0, 12($s0) # Clear the scratch register
mfc0 $k0, $13, 0 # Fire sw interrupt 0 to 0x80000180 (general)
ori $k0, 0x0100
mtc0 $k0, $13, 0
jal busy
nop
lw $t0, 12($s0) # Check scratch register for 0x1
addiu $t1, $t0, -1
bne $t1, $0, $fail
nop
mfc0 $k0, $13, 0
lui $t2, 0x0080 # Enable the 'special' interrupt vector
ori $t2, 0x0200 # Fire sw interrupt 1 to 0x80000200 (iv)
or $k1, $k0, $t2
mtc0 $k1, $13, 0
jal busy
nop
lw $t3, 12($s0) # Check scratch register for 0x2
addiu $t4, $t3, -2
bne $t4, $0, $fail
nop
sw $s1, 8($s0) # Set the test to pass
sw $s1, 4($s0) # Set 'done'
jr $s2
$fail:
sw $0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
jr $s2
$setup:
mfc0 $k0, $12, 0 # Load the Status register
lui $k1, 0x1000 # Allow access to CP0
ori $k1, 0x0301 # Enable sw Int 0,1
or $k0, $k0, $k1
lui $k1, 0x1dbf # Disable CP3-1, No RE, No BEV
ori $k1, 0x03e7 # Disable hw ints, sw int 1-0, kernel mode, IE
and $k0, $k0, $k1
mtc0 $k0, $12, 0 # Commit the new Status register
la $k0, $run # Set ErrorEPC address to main test body
mtc0 $k0, $30, 0
eret
busy: # Allow time for an interrupt to be detected
nop
nop
nop
nop
nop
nop
nop
nop
nop
jr $ra
nop
#### Test code end ####
.end test
###############################################################################
# File : int_timer_cache.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the timer interrupt, i.e., hardware interrupt 5 with the interrupt
# vector running from the cache
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
j $setup # Enable interrupts and exit boot mode
nop
$run:
lw $t0, 0($a0) # Return success if the counter is >=30
sltiu $t1, $t0, 30
bne $t1, $0, $run
nop
sw $s1, 8($s0)
sw $s1, 4($s0)
$loop:
j $loop
nop
$setup:
mfc0 $k0, $16, 0 # Config: Enable kseg0 caching
lui $k1, 0xffff
ori $k1, 0xfff8
and $k0, $k0, $k1
ori $k0, 0x3
mtc0 $k0, $16, 0
mfc0 $k0, $12, 0 # Status: CP0, timer (int 5), ~CP3-1, ~RE, ~BEV, kernel, IE
lui $k1, 0x1dbf
ori $k1, 0x80e7
and $k0, $k0, $k1
lui $k1, 0x1000
ori $k1, 0x8001
or $k0, $k0, $k1
mtc0 $k0, $12, 0
mfc0 $k0, $13, 0 # Cause: Use the special interrupt vector
lui $k1, 0x0080
or $k0, $k0, $k1
mtc0 $k0, $13, 0
mfc0 $k0, $9, 0 # Set Compare to the near future (+200 cycles)
addiu $k0, 200
mtc0 $k0, $11, 0
la $k0, $run # Set ErrorEPC address to main test body (cached)
lui $k1, 0xdfff
ori $k1, 0xffff
and $k0, $k0, $k1
mtc0 $k0, $30, 0
la $a0, data # Use $a0 to hold the address of the iteration count
eret
data:
.word 0x0
#### Test code end ####
.end test
###############################################################################
# File : j.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'j' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
j $target
ori $v0, $0, 0 # The test result starts as a failure
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
jr $ra
nop
j $finish # Early-by-1 detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
j $finish # Late-by 1 detection (result not written)
nop
#### Test code end ####
.end test
###############################################################################
# File : jal.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'jal' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v1, $ra, 0 # Save $ra
jal $target
ori $v0, $0, 0 # The test result starts as a failure
$finish:
sw $v0, 8($s0)
ori $ra, $v1, 0 # Restore $ra
sw $s1, 4($s0)
jr $ra
nop
j $finish # Early-by-1 detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
jr $ra
nop
#### Test code end ####
.end test
###############################################################################
# File : jalr.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'jalr' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v1, $ra, 0 # Save $ra
la $t0, $target
jalr $t0
ori $v0, $0, 0 # The test result starts as a failure
$finish:
sw $v0, 8($s0)
ori $ra, $v1, 0 # Restore $ra
sw $s1, 4($s0)
jr $ra
nop
j $finish # Early-by-1 detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
jr $ra
nop
#### Test code end ####
.end test
###############################################################################
# File : jr.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'jr' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
la $t0, $target
jr $t0
ori $v0, $0, 0 # The test result starts as a failure
$finish:
sw $v0, 8($s0)
sw $s1, 4($s0)
jr $ra
nop
j $finish # Early-by-1 detection
$target:
nop
ori $v0, $0, 1 # Set the result to pass
j $finish
nop
#### Test code end ####
.end test
###############################################################################
# File : lb.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'lb' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting
ori $t0, 0x07fc # from 0xbfc00000)
lui $t1, 0xc001
ori $t1, 0x7afe
sw $t1, 0($t0)
lb $t2, 0($t0)
lb $t3, 1($t0)
lb $t4, 2($t0)
lb $t5, 3($t0)
.ifdef big_endian
lui $t6, 0xffff
ori $t6, 0xffc0
lui $t7, 0x0000
ori $t7, 0x0001
lui $t8, 0x0000
ori $t8, 0x007a
lui $t9, 0xffff
ori $t9, 0xfffe
.else
lui $t6, 0xffff
ori $t6, 0xfffe
lui $t7, 0x0000
ori $t7, 0x007a
lui $t8, 0x0000
ori $t8, 0x0001
lui $t9, 0xffff
ori $t9, 0xffc0
.endif
subu $v1, $t2, $t6
sltiu $v0, $v1, 1
subu $v1, $t3, $t7
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t4, $t8
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t5, $t9
sltiu $v1, $v1, 1
and $v0, $v0, $v1
# Repeat with halves swapped (sign extension corner cases)
lui $t1, 0x7afe
ori $t1, 0xc001
sw $t1, 0($t0)
lb $t2, 0($t0)
lb $t3, 1($t0)
lb $t4, 2($t0)
lb $t5, 3($t0)
.ifdef big_endian
lui $t6, 0x0000
ori $t6, 0x007a
lui $t7, 0xffff
ori $t7, 0xfffe
lui $t8, 0xffff
ori $t8, 0xffc0
lui $t9, 0x0000
ori $t9, 0x0001
.else
lui $t6, 0x0000
ori $t6, 0x0001
lui $t7, 0xffff
ori $t7, 0xffc0
lui $t8, 0xffff
ori $t8, 0xfffe
lui $t9, 0x0000
ori $t9, 0x007a
.endif
subu $v1, $t2, $t6
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t3, $t7
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t4, $t8
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t5, $t9
sltiu $v1, $v1, 1
and $v0, $v0, $v1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : lbu.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'lbu' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting
ori $t0, 0x07fc # from 0xbfc00000)
lui $t1, 0xc001
ori $t1, 0x7afe
sw $t1, 0($t0)
lbu $t2, 0($t0)
lbu $t3, 1($t0)
lbu $t4, 2($t0)
lbu $t5, 3($t0)
.ifdef big_endian
ori $t6, $0, 0x00c0
ori $t7, $0, 0x0001
ori $t8, $0, 0x007a
ori $t9, $0, 0x00fe
.else
ori $t6, $0, 0x00fe
ori $t7, $0, 0x007a
ori $t8, $0, 0x0001
ori $t9, $0, 0x00c0
.endif
subu $v1, $t2, $t6
sltiu $v0, $v1, 1
subu $v1, $t3, $t7
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t4, $t8
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t5, $t9
sltiu $v1, $v1, 1
and $v0, $v0, $v1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : lh.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'lh' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting
ori $t0, 0x07fc # from 0xbfc00000)
lui $t1, 0x7001
ori $t1, 0xcafe
sw $t1, 0($t0)
lh $t2, 0($t0)
lh $t3, 2($t0)
.ifdef big_endian
lui $t4, 0x0000
ori $t4, 0x7001
lui $t5, 0xffff
ori $t5, 0xcafe
.else
lui $t4, 0xffff
ori $t4, 0xcafe
lui $t5, 0x0000
ori $t5, 0x7001
.endif
subu $v1, $t2, $t4
sltiu $v0, $v1, 1
subu $v1, $t3, $t5
sltiu $v1, $v1, 1
and $v0, $v0, $v1
# Repeat with halves swapped (sign extension corner cases)
lui $t1, 0xcafe
ori $t1, 0x7001
sw $t1, 0($t0)
lh $t2, 0($t0)
lh $t3, 2($t0)
.ifdef big_endian
lui $t4, 0xffff
ori $t4, 0xcafe
lui $t5, 0x0000
ori $t5, 0x7001
.else
lui $t4, 0x0000
ori $t4, 0x7001
lui $t5, 0xffff
ori $t5, 0xcafe
.endif
subu $v1, $t2, $t4
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t3, $t5
sltiu $v1, $v1, 1
and $v0, $v0, $v1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : lhu.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'lhu' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting
ori $t0, 0x07fc # from 0xbfc00000)
lui $t1, 0x7001
ori $t1, 0xcafe
sw $t1, 0($t0)
lhu $t2, 0($t0)
lhu $t3, 2($t0)
.ifdef big_endian
ori $t4, $0, 0x7001
ori $t5, $0, 0xcafe
.else
ori $t4, $0, 0xcafe
ori $t5, $0, 0x7001
.endif
subu $v1, $t2, $t4
sltiu $v0, $v1, 1
subu $v1, $t3, $t5
sltiu $v1, $v1, 1
and $v0, $v0, $v1
# Repeat with halves swapped (sign extension corner cases)
lui $t1, 0xcafe
ori $t1, 0x7001
sw $t1, 0($t0)
lhu $t2, 0($t0)
lhu $t3, 2($t0)
.ifdef big_endian
ori $t4, $0, 0xcafe
ori $t5, $0, 0x7001
.else
ori $t4, $0, 0x7001
ori $t5, $0, 0xcafe
.endif
subu $v1, $t2, $t4
sltiu $v1, $v1, 1
and $v0, $v0, $v1
subu $v1, $t3, $t5
sltiu $v1, $v1, 1
and $v0, $v0, $v1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : llsc.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'll' and 'sc' instructions.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $s2, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting
ori $s2, 0x07fc # from 0xbfc00000)
lui $s3, 0xdeaf # Original memory word: 0xdeafbeef
ori $s3, 0xbeef
sw $s3, 0($s2)
lui $s4, 0xc001 # New memory word: 0xc001cafe
ori $s4, 0xcafe
### Test: Success
move $t0, $s3
move $t1, $s4
ll $t2, 0($s2)
sc $t1, 0($s2)
subu $v1, $t2, $s3 # Make sure the load worked
sltiu $v0, $v1, 1
lw $t3, 0($s2) # Memory should have the new value
subu $v1, $t3, $s4
sltiu $v1, $v1, 1
and $v0, $v0, $v1
addiu $v1, $t1, -1 # The sc dest reg should be 1
sltiu $v1, $v1, 1
and $v0, $v0, $v1
### Test: Failure
move $t4, $s4
sw $s3, 0($s2)
ll $t5, 0($s2)
sw $0, 0($s2)
sc $t4, 0($s2)
subu $v1, $t5, $s3 # Make sure the loads worked
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lw $t7, 0($s2) # Memory should have the old value
sltiu $v1, $t7, 1
and $v0, $v0, $v1
sltiu $v1, $t4, 1 # The sc dest reg should be 0
and $v0, $v0, $v1
### Test: Failure (Eret)
sw $s3, 0($s2)
move $t8, $s4
mfc0 $k0, $12, 0 # Load the Status register
lui $k1, 0x1dbf # Disable CP1-3, No RE, No BEV
ori $k1, 0x00e6 # Disable ints, kernel mode
and $k0, $k0, $k1
mtc0 $k0, $12, 0
la $k1, $post_eret
mtc0 $k1, $30, 0
ll $t9, 0($s2)
eret
$post_eret:
sc $t8, 0($s2)
subu $v1, $t9, $s3 # Make sure the load worked
sltiu $v1, $v1, 1
and $v0, $v0, $v1
lw $s5, 0($s2) # Memory should have the old value
subu $v1, $s5, $s3
sltiu $v1, $v1, 1
and $v0, $v0, $v1
sltiu $v1, $t8, 1 # The sc dest reg should be 0
and $v0, $v0, $v1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : lui.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'lui' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
ori $v0, $0, 1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : lw.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'lw' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xbfc0 # Load a valid address (last word in 2KB starting
ori $t0, 0x07fc # from 0xbfc00000)
sw $0, 0($t0)
ori $t1, $0, 1
sw $t1, 0($t0)
lw $v0, 0($t0)
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
###############################################################################
# File : lwl.asm
# Project : MIPS32 MUX
# Author: : Grant Ayers (ayers@cs.stanford.edu)
#
# Standards/Formatting:
# MIPS gas, soft tab, 80 column
#
# Description:
# Test the functionality of the 'lwl' instruction.
#
###############################################################################
.section .test, "x"
.balign 4
.set noreorder
.global test
.ent test
test:
lui $s0, 0xbfff # Load the base address 0xbffffff0
ori $s0, 0xfff0
ori $s1, $0, 1 # Prepare the 'done' status
#### Test code start ####
lui $t0, 0xbfc0 # Load address 0xbfc007fc (last word in 2KB starting
ori $t0, 0x07fc # from 0xbfc00000)
lui $t1, 0xc001 # Memory word is 0xc001cafe
ori $t1, 0xcafe
sw $t1, 0($t0)
lui $t2, 0xdeaf # Register word is 0xdeafbeef
ori $t2, 0xbeef
or $t3, $0, $t2
or $t4, $0, $t2
or $t5, $0, $t2
or $t6, $0, $t2
lwl $t3, 0($t0)
lwl $t4, 1($t0)
lwl $t5, 2($t0)
lwl $t6, 3($t0)
.ifdef big_endian
lui $s3, 0xc001 # 0xc001cafe
ori $s3, 0xcafe
lui $s4, 0x01ca # 0x01cafeef
ori $s4, 0xfeef
lui $s5, 0xcafe # 0xcafebeef
ori $s5, 0xbeef
lui $s6, 0xfeaf # 0xfeafbeef
ori $s6, 0xbeef
.else
lui $s3, 0xfeaf # 0xfeafbeef
ori $s3, 0xbeef
lui $s4, 0xcafe # 0xcafebeef
ori $s4, 0xbeef
lui $s5, 0x01ca # 0x01cafeef
ori $s5, 0xfeef
lui $s6, 0xc001 # 0xc001cafe
ori $s6, 0xcafe
.endif
subu $s2, $t3, $s3
sltiu $v0, $s2, 1
subu $s2, $t4, $s4
sltiu $v1, $s2, 1
and $v0, $v0, $v1
subu $s2, $t5, $s5
sltiu $v1, $s2, 1
and $v0, $v0, $v1
subu $s2, $t6, $s6
sltiu $v1, $s2, 1
and $v0, $v0, $v1
#### Test code end ####
sw $v0, 8($s0) # Set the test result
sw $s1, 4($s0) # Set 'done'
$done:
jr $ra
nop
.end test
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment