# SPIM S20 MIPS simulator.
# The default trap handler for spim.
#
# Copyright (C) 1990-1995 James Larus, larus@cs.wisc.edu.
# ALL RIGHTS RESERVED.
#
# SPIM is distributed under the following conditions:
#
# You may make copies of SPIM for your own use and modify those copies.
#
# All copies of SPIM must retain my name and copyright notice.
#
# You may not sell SPIM or distributed SPIM in conjunction with a commerical
# product or service without the expressed written consent of James Larus.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE.
#
# $Header: /u/l/a/larus/Software/SPIM/RCS/trap.handler,v 1.23 1997/07/09 21:45:23 larus Exp $
# Define the exception handling code. This must go first!
.kdata
__m1_: .asciiz " Exception "
__m2_: .asciiz " occurred and ignored\n"
__e0_: .asciiz " [Interrupt] "
__e1_: .asciiz ""
__e2_: .asciiz ""
__e3_: .asciiz ""
__e4_: .asciiz " [Unaligned address in inst/data fetch] "
__e5_: .asciiz " [Unaligned address in store] "
__e6_: .asciiz " [Bad address in text read] "
__e7_: .asciiz " [Bad address in data/stack read] "
__e8_: .asciiz " [Error in syscall] "
__e9_: .asciiz " [Breakpoint] "
__e10_: .asciiz " [Reserved instruction] "
__e11_: .asciiz ""
__e12_: .asciiz " [Arithmetic overflow] "
__e13_: .asciiz " [Inexact floating point result] "
__e14_: .asciiz " [Invalid floating point result] "
__e15_: .asciiz " [Divide by 0] "
__e16_: .asciiz " [Floating point overflow] "
__e17_: .asciiz " [Floating point underflow] "
__excp: .word __e0_,__e1_,__e2_,__e3_,__e4_,__e5_,__e6_,__e7_,__e8_,__e9_
.word __e10_,__e11_,__e12_,__e13_,__e14_,__e15_,__e16_,__e17_
s1: .word 0
s2: .word 0
.ktext 0x80000080
.set noat
# Because we are running in the kernel, we can use $k0/$k1 without
# saving their old values.
move $k1 $at # Save $at
.set at
sw $v0 s1 # Not re-entrent and we can't trust $sp
sw $a0 s2
mfc0 $k0 $13 # Cause
sgt $v0 $k0 0x44 # ignore interrupt exceptions
bgtz $v0 ret
addu $0 $0 0
li $v0 4 # syscall 4 (print_str)
la $a0 __m1_
syscall
li $v0 1 # syscall 1 (print_int)
srl $a0 $k0 2 # shift Cause reg
syscall
li $v0 4 # syscall 4 (print_str)
lw $a0 __excp($k0)
syscall
bne $k0 0x18 ok_pc # Bad PC requires special checks
mfc0 $a0, $14 # EPC
and $a0, $a0, 0x3 # Is EPC word-aligned?
beq $a0, 0, ok_pc
li $v0 10 # Exit on really bad PC (out of text)
syscall
ok_pc:
li $v0 4 # syscall 4 (print_str)
la $a0 __m2_
syscall
mtc0 $0, $13 # Clear Cause register
ret: lw $v0 s1
lw $a0 s2
mfc0 $k0 $14 # EPC
.set noat
move $at $k1 # Restore $at
.set at
rfe # Return from exception handler
addiu $k0 $k0 4 # Return to next instruction
jr $k0
# Standard startup code. Invoke the routine main with no arguments.
.data 0x10000010
d1: .byte 9,2,3,4
.data 0x10000020
d2: .byte 4,3,2,7
.data 0x10000030
ad: .byte 0,0,0,0,0
.text
.globl __start
__start:
li $19, 3
li $20, 0
loop:
blt $19, 0, Exit
lb $4, d1($19)
lb $5, d2($19)
add $6, $4, $5
add $6, $6, $20
li $20, 0
blt $6, 10, sinon
li $20, 1
sub $6, $6, 10
sinon:
sb $6, ad+1($19)
sub $19, $19, 1
j loop
Exit:
sb $20, ad
li $v0 10
syscall # syscall 10 (exit)