#
# Blitz-64 ISA Validation Program
#
# Program Name: ISAValidator.s
#
# Harry Porter III - 11 May 2019
# Harry Porter III - 17 August 2019
# Harry Porter III - 18 August 2019    - Altered test_53 (csr_status unused bits)
# Harry Porter III -  6 November 2019  - Altered test_94 (csr_bad, remove sign-extension of upper bits)
# Harry Porter III - 18 September 2022 - Started mods to accommodate ISA version #2
# Harry Porter III - 30 November 2022  - Modified version for MicroBlitz hardware
# Harry Porter III -  9 February 2023  - ASID moved to csr_pgtable
# Harry Porter III - 11 December 2023  - Elimination of Kernel Exception

#
# STATUS: The MicroBlitz core passes all tests in this program.
#
# This program is intended to be loaded and executed by a Blitz-64 processor core, either
# emulated or physical. The purpose is to test and exercise the machine instructions
# reasonably thoroughly. If the processor passes the tests contained herein, then we can
# say it has reached the first level of validation.
#
# This program may be assembled into HEX format (for downloading to hardware) like this:
#
#     % asm ISAValidator.s -o ISAValidator.o -l > ISAValidator.listing
#     % link ISAValidator.o -o ISAValidator.exe -k
#     % hexify ISAValidator.exe -hex -silent > ISAValidator.hex
#
# It may also be assembled and executed with the emulator like this:
#
#     % asm ISAValidator.s -o ISAValidator.o -l > ISAValidator.listing
#     % link ISAValidator.o -o ISAValidator.exe -k
#     % blitz ISAValidator.hex -g -nowarn -fp -nodebug
# or
#     % blitz ISAValidator.exe -g -nowarn -fp
#
# The program terminates by going executing "CONTROLU HALT".
#
###
### The first level of validation is called "A-Level Validation".
###
### It is envisioned that (in the future) there will be additional levels of
### testing available, perhaps in similar form with names like ISAValidator_B.s, etc.
### However, such validation suites do not exist at the time of this writing.
###
### If your core passes all the tests in this program, you may claim
###    -- The core is "operational" and "functional."
###    -- The core has achieved "A-Level Validation."
### If your core cannot pass all tests here, you must be clear that
###    -- The core is "only partially operational."
###    -- The core is "not certified" and "not fully functional."
###    -- The core is "does not pass A-Level Validation."
###
### It may be that some instructions (such as floating point instructions and unaligned
### LOADs and STOREs) will be executed. On the other hand, they may cause Emulation
### Exceptions or Unaligned LOAD/STORE Exceptions instead. This program will function
### correctly either way. It will test to see whether the instructions cause exceptions
### or not and then will run the appropriate tests only if the instructions do not
### cause exceptions.
###
### If your core implements floating point instructions, this program will run a number
### of tests on these instructions, testing basic functionality. For example, "12.0 / 3.0"
### is tested, but "1.0 / 3.0" is not tested, since it requires rounding/truncation.
###
### If your core implements any floating point instructions, please realize that the
### testing here is only cursory. The following are not tested:
###    -- rounding, truncation, overflow, underflow, invalid
### In more detail
###    -- The setting of the FLOAT_STATUS bits in csr_status is not checked.
###    -- Whether the FLOAT_ROUND bits in csr_status are used is not checked.
###    -- Whether rounding/truncation is done properly is not checked.
###    -- Proper handling of NaN is not checked.
### As a result of this validation program, you must be clear that
###    -- The floating instructions are "partially functional, and not fully certified."
###
### If your core does not implement floating point instructions but signals Emulation
### Exceptions, and it passes all tests, then you may claim that Floating Point Emulation
### is A-Level certified.
###
#
# Here are some features which are not tested by this program:
#    -- Memory-Mapped I/O devices are not tested in any way.
#    -- Cache memories are not tested in any way.
#    -- The SLEEP1 and SLEEP2 are implementation dependent and not tested.
#    -- The CONTROLU instruction is use for I/O by this program. Otherwise CONTROL & CONTROLU
#         and implementation-dependent and not tested.
#    -- Some floating point behavior, as discussed above.
#    -- Multi-processor functionality is not required or tested.
#
# This program uses the following memory:
#      LOWEST ADDRESS USED:     0x 0_0000_0008
#      APPROX LENGTH OF CODE:   0x 0_0000_fb67  (about 62.8 KiBytes)
# This program requires the presence of RAM memory.
#
# Only this portion of memory needs to be functional for this test to be executed.
#
# Approximate number of instructions executed if all tests are passed: 865,886
#
# Each test is numbered sequentially from 1, 2, 3, ... The tests are performed in order... mostly.
# The program begins each test by placing the test number in register r9 (also known as "s0").
# If any test fails, this register is not updated. No further tests are attempted.
#
# In the case of success (i.e., all tests were passed):
#    -- Register r9 ("s0") will contain 0x1234,1234,1234,1234.
#    -- Optionally, this program infinite loops at location SUCCESS_LOOP.
#
# If one of the tests fails:
#    -- This program will stop, without attempting to run any more tests.
#    -- Register r9 ("s0") will contain the number of the failing test.
#    -- Optionally, this program infinite loops at location FAILURE (address 0x0,0000,0030)
#
# General outline of testing:
#    Test very basic instructions
#    Test arithmetic and logic instructions
#    Test remaining non-privileged instructions
#    Test LOAD and STORE memory instructions
#    Test basic CSR functionality
#    Test privileged instructions
#    Test exception processing
#
# This program is meant to be read more-or-less from top to bottom. The organization of
# this program is roughly one giant straight-line sequence of code. So you can start
# reading at the top and read only as much as you want to get the general idea.
# The very last few lines of this program may be of interest; these last lines
# are reached only after all tests have been passed.
#
# When executed on the Blitz Emulator, the option "-nowarn" might be useful. This program
# does a lot of very suspicious things (such as trying to store into read-only CSRs). The
# emulator will catch this malarkey and complain. This can be a nuisance, but -nowarn
# will suppress the emulator's tendency to interrupt execution.
#
# When executed on the Blitz Emulator, the option "-fp" might be useful. This flag tells
# the emulator whether floating point instructions should be executed or should cause
# Emulation Exceptions.
#
# NOTE: This program breaks almost every programming rule. It uses GOTOs in unstructured
# ways. It does instruction modification. In some cases, it will store a value into memory 
# into the location directly after the STORE instruction and then immediately attempt to
# execute that instruction. It uses exception processing to perform GOTOs; exception handling
# code never returns. It places code in one section of memory and uses the TLB to map that
# memory elsewhere. It relies heavily on the assembler/linker doing what is expected, such as
# synthesizing certain instructions with specific machine code sequences. It makes
# assumptions about exactly where in memory the assembler/linker will place instructions and
# data, and is highly sensitive to the insertion, deletion, or re-arrangement of instructions.
# This is a bizarre, fragile program. In short, this is a program that only its author could love.
# But doesn't.
#
# NOTE: This program uses r15 indiscriminately like any other register. This makes inserting code
# for debugging (such as calls to "print" functions) difficult. These calls will fail. I really
# need to go through this code and eliminate use of r15, or at least save and restore it when used. 
#
######
###### The testing of the DEBUG and BREAKPOINT instructions is problematic. In testing this program
###### on the emulator, it is very useful to use the DEBUG.
######
###### Test_107 makes sure that the DEBUG instruction causes a DEBUG exception.
######    The test is disabled because the DEBUG instruction is treated specially by the
######    emulator. If not being emulated, this test should be re-enabled in order to
######    verify the proper functioning of the DEBUG instruction.
######
###### Option 1 (for debugging this program on the emulator):
######           Test_107 is disabled (a jump around the test, i.e., JUMP skip_107: ... skip_107😀
######           The emulator is run without  "-nodebug".
######           Or EmulationParms can be configured with:
######             DEBUG_INVOKES_EMULATOR_K_MODE  1
######             DEBUG_INVOKES_EMULATOR_U_MODE  1
###### 
###### Option 2: (for testing the functioning of the DEBUG instruction):
######           Test_107 is re-enabled by modifying the jump.
######           The emulator is run with  "-nodebug".
######
###### Furthermore, before the CONTROLU instruction was implemented, DEBUG was used to terminate
###### execution. Must of this code is left in, but commented out with ######.
######


	.begin	startaddr = 0x000000008,kernel,gp=undefined
	.sourcefile	"ISAValidator", "hand-coded assembly"
	.function	"NamelessFunction",line=0,framesize=0


# Here is a rough log of errors this program has found in the emulator:
#
# --For unaligned LOAD/STORE, the address saved in csr_bad was the address
#     of the instruction, but should have been the following instruction.
# --The csr_timer CSR register was not getting decremented.
# --B.EQ, B.NE, B.LT, and B.LE which cause a NULL address exception
#     The test code has grown to make it too far from location 0 for such jumps.
# --For JALR, JAL, B.EQ, B.NE, B.LT, B.LE, on a NULL address exception
#     where the branch was taken, the csr_prevpc was set to -4. This was
#     because a null PC was checked during fetch; too late for PC-4 to work.
# --The remainder of the floating instructions were implemented.
# --The command options "-nowarn", "-fp", and "-nodebug" were added.
# --For FETCHES that cause exceptions, csr_prevpc was incorrectly set because
#     the PC was incremented after PC-4 was computed, not before.
# --For a branch to a physical address from user mode, csr_prevpc was
#     wrong. It was not the address of the offending instruction, but 4
#     before the current PC, so somewhere in physical space.
# --The emulator was not previously executing Singlestep exceptions.

# **********  THINGS THAT MAY NOT BE TESTED VERY WELL  **********
#
# -- When an exception occurs during a FETCH, is the last instruction
#      fully executed and the failing instruction not executed at all?
# -- When an exception occurs, is the previous instruction fully executed?
# -- When a FETCH exception occurs AND an exception on the following instruction,
#      is the FETCH exception preferred?
# -- Consider when an exception occurs for a fetch. We need to make sure the
#      previous instruction executed to completion (and loaded regs or
#      stored to memory). Consider an instruction at the end of a page;
#      it must execute to completion.
# -- The page table exceptions are tested only with the CAS instruction.
# -- Interrupts are not tested.
#


TRAP_CAUSE_ARITHMETIC:			.equ	0x2000		# 8192  Arithmetic Exception
TRAP_CAUSE_UNALIGNED_LOAD_STORE:	.equ	0x2008		# 8200  Unaligned LOAD/STORE Exception
TRAP_CAUSE_NULL_ADDRESS:		.equ	0x2010		# 8208  Null Address Exception
TRAP_CAUSE_ILLEGAL_INSTRUCTION:		.equ	0x2018		# 8216  Illegal Instruction, privilege violation

TRAP_CAUSE_PAGE_ILLEGAL_ADDRESS:	.equ	0x2020   	# 8224  Page Privilege Exception - attempt to access kernel space
TRAP_CAUSE_PAGE_TABLE:			.equ	0x2028   	# 8232  Page Table Exception - bad csr_pgtable
TRAP_CAUSE_PAGE_INVALID:		.equ	0x2030   	# 8240  Page Invalid Exception - either index page or PTE
TRAP_CAUSE_PAGE_WRITE:			.equ	0x2038   	# 8248  Page Write Exception
TRAP_CAUSE_PAGE_FETCH:			.equ	0x2040   	# 8256  Page Fetch Exception
TRAP_CAUSE_PAGE_COPY_ON_WRITE:		.equ	0x2048   	# 8264  Page Copy-On-Write Exception
TRAP_CAUSE_PAGE_FIRST_DIRTY:		.equ	0x2050   	# 8272  Page First Dirty Exception

TRAP_CAUSE_DEBUG:			.equ	0x2058		# 8280  Debug Exception
TRAP_CAUSE_BREAKPOINT:			.equ	0x2060		# 8288  Breakpoint Exception
TRAP_CAUSE_SINGLESTEP:			.equ	0x2068		# 8296  Singlestep Exception

TRAP_CAUSE_EMULATED_INSTRUCTION:	.equ	0x2070		# 8312  Emulated Instruction Exception
TRAP_CAUSE_HARDWARE_FAULT:		.equ	0x2078		# 8320  Hardware Fault Exception
TRAP_CAUSE_BAD_ARRAY_INDEX:		.equ	0x2080		# 8328  Bad Array Index Exception
TRAP_CAUSE_STACK_OVERFLOW:		.equ	0x2088		# 8328  Bad Array Index Exception

TRAP_CAUSE_TIMER:			.equ	0x2090		# 8336  Timer Interrupt




DIGITAL_READ:  .equ   0     # controlu   XXX,r0,DIGITAL_READ
DIGITAL_WRITE: .equ   1     # controlu   r0,XXX,DIGITAL_WRITE
HALT:          .equ   2     # controlu   r0,r0,HALT
SERIAL_STAT:   .equ   3     # controlu   XXX,r0,SERIAL_STAT
SERIAL_RECV:   .equ   4     # controlu   XXX,r0,SERIAL_RECV
SERIAL_SEND:   .equ   5     # controlu   r0,XXX,SERIAL_SEND
ENABLE_KERNEL: .equ   6     # controlu   XXX,r0,ENABLE_KERNEL  # grab csr_status; then set mode
SET_STATUS:    .equ   7     # controlu   r0,XXX,SET_STATUS     # set csr_status from reg.
TLB_DEBUG:     .equ   8     # controlu   regD,Reg1,TLB_DEBUG   # copy TLB[r1] to RegD



############################################################################
############################################################################
###
###  The testing begins with several very simple instructions.
###
###  We test the basic functionality of XORI, ADDI, B.NE, B.EQ first because we
###  rely on these instructions in all other tests.
###
############################################################################
############################################################################

_entry:
	.export	_entry

Test_1:
	xori	s0,r0,1			# s0 = 1

Test_2:
	addi	s0,s0,1			# s0 = 2

Test_3:
	xori	s0,s0,1			# s0 = 3

Test_4:
	movi	s0,4			# Small MOVI values use XORI
	bne	s0,s0,FAILURE		# Test b.ne (not taken)

Test_5:
	movi	s0,5
	movi	r1,0
	bne	r0,r1,FAILURE		# Test b.ne (not taken)

Test_6:
	movi	s0,6
	beq	s0,s0,Test_6_OK		# Test b.eq (taken)
					# If this jump fails, we fall into the FAILURE code





############################################################################
############################################################################
###
###  FAILURE: Come here if any test fails.
###
############################################################################
############################################################################

FAILURE:

######
###### The DEBUG and .COMMENT instructions are useful when the emulator executes
###### this program; However, the ISA specifies that DEBUG causes an exception
###### and this will cause major problems when this program is executed on
###### hardware that implements the ISA spec correctly.
######
###### So, you'll need to replace this DEBUG with the NOP.
######
###### THIS PROGRAM IS VERY SENSITIVE TO THE EXACT PLACEMENT OF INSTRUCTIONS
###### IN MEMORY. THE NOP INSTRUCTION REQUIRES THE SAME NUMBER OF BYTES, SO
###### THE NOP INSTRUCTION MUST BE COMMENTED WHENEVER THE DEBUG INSTRUCTION
###### IS UN-COMMENTED, AND VICE-VERSA.
######

	.comment	"\n\n-->-->-->-->-->-->-->\n-->-->-->-->-->-->-->   FAILURE: Check reg s0 to see which test failed\n-->-->-->-->-->-->-->\n\n"

######
###### Replace DEBUG with NOP, if using -nodebug:
######
#	debug
	nop
######

	jump	FAILURE_2

	bne	s0,r0,FAILURE		# Try to infinite loop, even if there
	beq	s0,s0,FAILURE		#    are problems with b.ne, b.eq
	bne	r0,s0,FAILURE

	.comment	"\n------   CHECK REG s0 TO SEE WHICH TEST IS RUNNING\n\n"


#
# The code is somewhat sensitive to alignment and location.
#



############################################################################
############################################################################
###
###  We have jumped around the above code and we will come here
###  to continue with more tests.
###
############################################################################
############################################################################

Test_6_OK:



###########################################################
#
# Perform more testing of the most basic instructions.
#
###########################################################

Test_7:
	movi	s0,7
	bne	s0,s0,FAILURE		# b.ne (not taken)

###########################################################

Test_8:
	movi	s0,8
	bne	s0,s0,FAILURE		# b.ne (not taken)

###########################################################

Test_9:
	movi	s0,9
	movi	r1,0
	bne	r1,r0,FAILURE		# b.ne (not taken)

###########################################################

Test_10:
	movi	s0,10
	bne	r0,r1,FAILURE		# b.ne (not taken)

###########################################################

Test_11:
	movi	s0,11
	movi	r1,1
	bne	r1,s0,Test_11_OK	# b.ne (taken)
	beq	s0,s0,FAILURE
Test_11_OK:

###########################################################

Test_12:
	movi	s0,12
	beq	s0,r0,FAILURE		# b.eq (not taken)

###########################################################

Test_13: movi	s0,13

	movi	r1,13
	beq	r1,s0,Test_13_OK	# b.eq (taken)
	beq	s0,s0,FAILURE
Test_13_OK:

###########################################################

Test_14: movi	s0,14

	movi	r1,0
Test_14_loop:
	addi	r1,r1,1			# executed 14 times (r1 = 1,2,3,...,14)
	bne	r1,s0,Test_14_loop

###########################################################

Test_15: movi	s0,15

	movi	r1,10
Test_15_loop:
	addi	r1,r1,5			# executed 2 times (r1 = 15, 20)
	beq	r1,s0,Test_15_loop
	movi	r2,20
	bne	r1,r2,FAILURE

###########################################################

Test_16: movi	s0,16

	movi	r1,0
	xori	r0,r0,0x7fff		# Try to update r0
	bne	r0,r1,FAILURE


#
# At this point, we assume that we have basic functionality of
#    ADDI, MOVI, BNE, BEQ, XORI.
#


###########################################################
#
# Test basic functionality of SRLI, SLLI
#
Test_17: movi	s0,17

	movi	r1,0x3a74		# 0011101001110100
	srli	r1,r1,5			# 00111010011---->
	movi	r2,0x01d3		# 0000000111010011
	bne	r1,r2,FAILURE
	beq	r1,r2,Test_17_OK
	beq	s0,s0,FAILURE
Test_17_OK:
	slli	r1,r1,3			# <--0000111010011
	movi	r3,0x0e98		# 0000111010011000
	bne	r1,r3,FAILURE
	beq	r1,r3,Test_17_OKb
	beq	s0,s0,FAILURE
Test_17_OKb:

###########################################################
#
# Test basic functionality of UPPER16, SHIFT16
#
Test_18: movi	s0,18

	movi	r1,0x123446688aacdef0
	srli	r1,r1,12
	movi	r2,0x000123446688aacd
	bne	r1,r2,FAILURE
	beq	r1,r2,Test_18_OK
	beq	s0,s0,FAILURE
Test_18_OK:
	movi	r1,0x1234567799bbdef0
	movi	r3,0x567799bbdef00000
	slli	r1,r1,16
	bne	r1,r3,FAILURE
	beq	r1,r3,Test_18_OKb
	beq	s0,s0,FAILURE
Test_18_OKb:



###########################################################
#
# Test the presence of all registers. Uses UPPER16, SHIFT16, and XORI.
#
Test_19: movi	s0,19

	movi	r2, 0x1222324252627282
	movi	r3, 0x1323334353637383
	movi	r4, 0x1424344454647484
	movi	r5, 0x1525354555657585
	movi	r6, 0x1626364656667686
	movi	r7, 0x1727374757677787
	movi	r8, 0x1828384858687888
#	movi	r9, 0x1929394959697989   # r9=s0 is done later
	movi	r10,0x1a2a3a4a5a6a7a8a
	movi	r11,0x1b2b3b4b5b6b7b8b
	movi	r12,0x1c2c3c4c5c6c7c8c
	movi	r13,0x1d2d3d4d5d6d7d8d
	movi	r14,0x1e2e3e4e5e6e7e8e
	movi	r15,0x1f2f3f4f5f6f7f8f

	movi	r1, 0x1222324252627282
	beq	r1,r2,Test_19_3
	bne	r1,r2,FAILURE

Test_19_3:
	movi	r1, 0x1323334353637383
	beq	r1,r3,Test_19_4
	bne	r1,r3,FAILURE

Test_19_4:
	movi	r1, 0x1424344454647484
	beq	r1,r4,Test_19_5
	bne	r1,r4,FAILURE

Test_19_5:
	movi	r1, 0x1525354555657585
	beq	r1,r5,Test_19_6
	bne	r1,r5,FAILURE

Test_19_6:
	movi	r1, 0x1626364656667686
	beq	r1,r6,Test_19_7
	bne	r1,r6,FAILURE

Test_19_7:
	movi	r1, 0x1727374757677787
	beq	r1,r7,Test_19_8
	bne	r1,r7,FAILURE

Test_19_8:
	movi	r1, 0x1828384858687888
	beq	r1,r8,Test_19_a
	bne	r1,r8,FAILURE

# r9=s0 is done below

Test_19_a:
	movi	r1, 0x1a2a3a4a5a6a7a8a
	beq	r1,r10,Test_19_b
	bne	r1,r10,FAILURE

Test_19_b:
	movi	r1, 0x1b2b3b4b5b6b7b8b
	beq	r1,r11,Test_19_c
	bne	r1,r11,FAILURE

Test_19_c:
	movi	r1, 0x1c2c3c4c5c6c7c8c
	beq	r1,r12,Test_19_d
	bne	r1,r12,FAILURE

Test_19_d:
	movi	r1, 0x1d2d3d4d5d6d7d8d
	beq	r1,r13,Test_19_e
	bne	r1,r13,FAILURE

Test_19_e:
	movi	r1, 0x1e2e3e4e5e6e7e8e
	beq	r1,r14,Test_19_f
	bne	r1,r14,FAILURE

Test_19_f:
	movi	r1, 0x1f2f3f4f5f6f7f8f
	beq	r1,r15,Test_19_9
	bne	r1,r15,FAILURE

# Test r9 last, since it overwrites r9=s0 (the test code number).

Test_19_9:
	movi	r9, 0x1929394959697989
	movi	r1, 0x1929394959697989
	beq	r1,r9,Test_19_OK
	bne	r1,r9,FAILURE

Test_19_OK:

	movi	s0,20		# r9=s0 was just trashed; restore it.


###########################################################
#
# Write a 1 into all bits in all registers and read it back.
# Write a 0 into all bits in all registers and read it back.
#
Test_20: movi	s0,20

	movi	r1,1
	slli	r1,r1,63
	srai	r1,r1,63
	bnei	r1,-1,FAILURE
	xor	r1,r1,r1
	bnez	r1,FAILURE

	movi	r2,1
	slli	r2,r2,63
	srai	r2,r2,63
	bnei	r2,-1,FAILURE
	xor	r2,r2,r2
	bnez	r2,FAILURE

	movi	r3,1
	slli	r3,r3,63
	srai	r3,r3,63
	bnei	r3,-1,FAILURE
	xor	r3,r3,r3
	bnez	r3,FAILURE

	movi	r4,1
	slli	r4,r4,63
	srai	r4,r4,63
	bnei	r4,-1,FAILURE
	xor	r4,r4,r4
	bnez	r4,FAILURE

	movi	r5,1
	slli	r5,r5,63
	srai	r5,r5,63
	bnei	r5,-1,FAILURE
	xor	r5,r5,r5
	bnez	r5,FAILURE

	movi	r6,1
	slli	r6,r6,63
	srai	r6,r6,63
	bnei	r6,-1,FAILURE
	xor	r6,r6,r6
	bnez	r6,FAILURE

	movi	r7,1
	slli	r7,r7,63
	srai	r7,r7,63
	bnei	r7,-1,FAILURE
	xor	r7,r7,r7
	bnez	r7,FAILURE

	movi	r8,1
	slli	r8,r8,63
	srai	r8,r8,63
	movi	r1,-1		# BNEI uses r8
	bne	r8,r1,FAILURE
	xor	r8,r8,r8
	bnez	r8,FAILURE

	movi	r9,1
	slli	r9,r9,63
	srai	r9,r9,63
	bnei	r9,-1,FAILURE
	xor	r9,r9,r9
	bnez	r9,FAILURE

	movi	s0,20		# r9=s0 was just used; restore it.

	movi	r10,1
	slli	r10,r10,63
	srai	r10,r10,63
	bnei	r10,-1,FAILURE
	xor	r10,r10,r10
	bnez	r10,FAILURE

	movi	r11,1
	slli	r11,r11,63
	srai	r11,r11,63
	bnei	r11,-1,FAILURE
	xor	r11,r11,r11
	bnez	r11,FAILURE

	movi	r12,1
	slli	r12,r12,63
	srai	r12,r12,63
	bnei	r12,-1,FAILURE
	xor	r12,r12,r12
	bnez	r12,FAILURE

	movi	r13,1
	slli	r13,r13,63
	srai	r13,r13,63
	bnei	r13,-1,FAILURE
	xor	r13,r13,r13
	bnez	r13,FAILURE

	movi	r14,1
	slli	r14,r14,63
	srai	r14,r14,63
	bnei	r14,-1,FAILURE
	xor	r14,r14,r14
	bnez	r14,FAILURE

	movi	r15,1
	slli	r15,r15,63
	srai	r15,r15,63
	bnei	r15,-1,FAILURE
	xor	r15,r15,r15
	bnez	r15,FAILURE

###########################################################
#
# Test UPPER16
#
Test_21: movi	s0,21

	movi	r1,0
	upper16	r3,r1,0x0000
	bnez	r3,FAILURE

	movi	r2,0x7fff
	slli	r2,r2,16
	addi	r2,r2,0x1234
	movi	r1,0x1234
	upper16	r3,r1,0x7fff
	bne	r2,r3,FAILURE

	movi	r2,1
	slli	r2,r2,63
	srai	r2,r2,32
	addi	r2,r2,0x789a
	movi	r1,0x789a
	upper16	r3,r1,0xFFFFFFFFFFFF8000
	bne	r2,r3,FAILURE

	movi	r2,1
	slli	r2,r2,63
	srai	r2,r2,47
	movi	r1,0
	upper16	r3,r1,0xFFFFFFFFFFFFFFFF
	bne	r2,r3,FAILURE

	# move the starting value into r1: 0x123456789abcdef0
	movi	r1,0x1234
	slli	r1,r1,16
	xori	r1,r1,0x5678	
	slli	r1,r1,8
	xori	r1,r1,0x9a	
	slli	r1,r1,8
	xori	r1,r1,0xbc	
	slli	r1,r1,8
	xori	r1,r1,0xde	
	slli	r1,r1,8
	xori	r1,r1,0xf0	

	upper16	r3,r1,0x2468		# test addition.

	# move the correct answer into r2: 0x12345678BF24DEF0
	movi	r2,0x1234
	slli	r2,r2,16
	xori	r2,r2,0x5678	
	slli	r2,r2,8
	xori	r2,r2,0xBF	
	slli	r2,r2,8
	xori	r2,r2,0x24	
	slli	r2,r2,8
	xori	r2,r2,0xde
	slli	r2,r2,8
	xori	r2,r2,0xf0
	
	bne	r2,r3,FAILURE

	upper16	r3,r1,0xFFFFFFFFFFFF8642	# test sign extension of immed-16

#   0x123456789abcdef0
# + 0xFFFFFFFF86420000
#   ------------------
#   0x1234567820fedef0

	# move the correct answer into r2: 0x1234567820fedef0
	movi	r2,0x1234
	slli	r2,r2,16
	xori	r2,r2,0x5678	
	slli	r2,r2,16
	xori	r2,r2,0x20fe	
	slli	r2,r2,8
	xori	r2,r2,0xde
	slli	r2,r2,8
	xori	r2,r2,0xf0
	
	bne	r2,r3,FAILURE

	# move the starting value into r1: 0x7fffffffdb981234
	movi	r1,0x7fff
	slli	r1,r1,8
	xori	r1,r1,0xff
	slli	r1,r1,8
	xori	r1,r1,0xff	
	slli	r1,r1,8
	xori	r1,r1,0xdb	
	slli	r1,r1,8
	xori	r1,r1,0x98	
	slli	r1,r1,16
	xori	r1,r1,0x1234	

	upper16	r3,r1,0x2468		# test that overflow is ignored

#   0x7fffffffdb981234
# + 0x0000000024680000
#   ------------------
#   0x8000000000001234

	# move the correct answer into r2: 0x8000000000001234
	movi	r2,0x1
	slli	r2,r2,63
	xori	r2,r2,0x1234	
	
	bne	r2,r3,FAILURE


###########################################################
#
# Test SHIFT16
#
Test_22: movi	s0,22

	# move the starting value into r1: 0x1234A6789abcdef0
	movi	r1,0x1234
	slli	r1,r1,8
	xori	r1,r1,0xA6	
	slli	r1,r1,8
	xori	r1,r1,0x78	
	slli	r1,r1,8
	xori	r1,r1,0x9a	
	slli	r1,r1,8
	xori	r1,r1,0xbc	
	slli	r1,r1,8
	xori	r1,r1,0xde	
	slli	r1,r1,8
	xori	r1,r1,0xf0

	shift16	r3,r1,0xfffffffffffffedc

#   0x1234A6789abcdef0
#   0x------------fedc
#   ------------------
#   0x1234A6789abcfedc
#   ------------------
#   0xA6789abcfedc0000  Note sign change, but nothing special occurs

	# move the correct answer into r2: 0xA678 9abc fedc 0000
	movi	r2,0xA6
	slli	r2,r2,8
	xori	r2,r2,0x78
	slli	r2,r2,8
	xori	r2,r2,0x9a	
	slli	r2,r2,8
	xori	r2,r2,0xbc	
	slli	r2,r2,8
	xori	r2,r2,0xfe
	slli	r2,r2,8
	xori	r2,r2,0xdc
	slli	r2,r2,16

	bne	r2,r3,FAILURE

		

###########################################################
#
# Test UPPER20
#
Test_23: movi	s0,23

	movi	r3,1
	slli	r3,r3,63
	srai	r3,r3,63

	upper20	r3,0x789ab    # No sign extension

	# move the correct answer into r2: 0x0000 0007 89ab 0000
	movi	r2,0x07
	slli	r2,r2,8
	xori	r2,r2,0x89
	slli	r2,r2,8
	xori	r2,r2,0xab	
	slli	r2,r2,16

	bne	r2,r3,FAILURE

	movi	r3,1
	slli	r3,r3,63
	srai	r3,r3,63

	upper20	r3,0xfffffffffff87654   # With sign extension

	# move the correct answer into r2: 0xFFFF FFF8 7654 0000
	movi	r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xf8
	slli	r2,r2,8
	xori	r2,r2,0x76
	slli	r2,r2,8
	xori	r2,r2,0x54	
	slli	r2,r2,16

	bne	r2,r3,FAILURE

###########################################################
#
# Test ADDPC
#
# This test relies on the the exact placement of this code. Any changes
# to any code above will require this test to be adjusted. 
#
Test_24: movi	s0,24


#
# Get the current PC into r5.
# NOTE: Changes to anything above will change the value and this will fail.
#
	addpc	r5,0
# debug

	# move the expected answer into r2: 0x000000000000074c
	movi	r2,0x074c

	bne	r2,r5,FAILURE

	addpc	r5,0x789ab	# Test the addition
 # debug

	# move the expected answer into r2: 0x0000000000079103
	movi	r2,0x07
	slli	r2,r2,8
	xori	r2,r2,0x91
	slli	r2,r2,8
	xori	r2,r2,0x03

	bne	r2,r5,FAILURE

	addpc	r5,0xfffffffffff89abc	# Test sign-extension
 # debug

	# move the expected answer into r2: 0xffff ffff fff8 a230
	movi	r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xf8
	slli	r2,r2,8
	xori	r2,r2,0xa2
	slli	r2,r2,8
	xori	r2,r2,0x30

	bne	r2,r5,FAILURE



###########################################################
#
# Test AUIPC
#
# ********** THIS TEST IS SENSITIVE TO THE LOCATION OF THE INSTRUCTIONS. **********
#
# This test relies on the the exact placement of this code. Any changes
# to any code above will require this test to be adjusted. 
#
Test_25: movi	s0,25

	auipc	r5,0
# debug

	# move the expected answer into r2: 0x00000000000007bc
	movi	r2,0x07bc

	bne	r2,r5,FAILURE

	auipc	r5,0x789ab	# Test the addition
# debug

	# move the expected answer into r2: 0x0000000789ab07c8
	movi	r2,0x07
	slli	r2,r2,8
	xori	r2,r2,0x89
	slli	r2,r2,8
	xori	r2,r2,0xab
	slli	r2,r2,8
	xori	r2,r2,0x07
	slli	r2,r2,8
	xori	r2,r2,0xc8

	bne	r2,r5,FAILURE

	auipc	r5,0xfffffffffff89abc	# Test sign-extension
# debug

	# move the expected answer into r2: 0xffff fff8 9abc 07f4
	movi	r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xff
	slli	r2,r2,8
	xori	r2,r2,0xf8
	slli	r2,r2,8
	xori	r2,r2,0x9a
	slli	r2,r2,8
	xori	r2,r2,0xbc
	slli	r2,r2,8
	xori	r2,r2,0x07
	slli	r2,r2,8
	xori	r2,r2,0xf4

	bne	r2,r5,FAILURE

#
# At this point we have tested XORI, SHIFT16, UPPER16, UPPER20, AUIPC, and ADDPC.
# Therefore, we can rely on MOVI, regardless of how it is synthesized.
# We can also rely on BEQI and BNEI.
#

###########################################################
#
# Test ADD and ADDI (no overflow)
#
Test_26: movi	s0,26

	movi	r1,0x1111222233334444
	movi	r2,0x5555666677778888
	add	r3,r1,r2
	bnei	r3,0x66668888aaaacccc,FAILURE

	movi	r1,0xf0123456789abcde
	movi	r2,0xe76543210fedcba9
	add	r3,r1,r2
	bnei	r3,0xd777777788888887,FAILURE

	movi	r1,0x4444333322221111
	movi	r2,0x8888666644442222
	add	r3,r1,r2
	bnei	r3,0xcccc999966663333,FAILURE

	movi	r1,0x9999999999999999
	movi	r2,0x2888888888888888
	add	r3,r1,r2
	bnei	r3,0xc222222222222221,FAILURE

	movi	r1,0x111122223333c444
	addi	r3,r1,         0x7654
	bnei	r3,0x1111222233343a98,FAILURE

	movi	r1,   0x111122223333c444
	addi	r3,r1,0xffffffffffff8765
	bnei	r3,   0x1111222233334ba9,FAILURE

###########################################################
#
# Test SUB (no overflow)
#
Test_27: movi	s0,27

	movi	r1,0x66668888aaaacccc
	movi	r2,0x1111222233334444
	sub	r3,r1,r2
	bnei	r3,0x5555666677778888,FAILURE

	movi	r1,0xd777777788888887
	movi	r2,0xe76543210fedcba9
	sub	r3,r1,r2
	bnei	r3,0xf0123456789abcde,FAILURE

	movi	r1,0xcccc999966663333
	movi	r2,0x8888666644442222
	sub	r3,r1,r2
	bnei	r3,0x4444333322221111,FAILURE

	movi	r1,0xc222222222222221
	movi	r2,0x2888888888888888
	sub	r3,r1,r2
	bnei	r3,0x9999999999999999,FAILURE

###########################################################
#
# Test AND, ANDI, OR, ORI, XOR, XORI
#
Test_28: movi	s0,28

	movi	r1,0xa3a3a3a3a3a3a3a3
	movi	r2,0x3a3a3a3a3a3a3a3a

	and	r3,r1,r2
	bnei	r3,0x2222222222222222,FAILURE
	or	r3,r1,r2
	bnei	r3,0xbbbbbbbbbbbbbbbb,FAILURE
	xor	r3,r1,r2
	bnei	r3,0x9999999999999999,FAILURE

	andi	r3,r1,0x3a3a
	bnei	r3,0x0000000000002222,FAILURE
	ori	r3,r1,0x3a3a
	bnei	r3,0xa3a3a3a3a3a3bbbb,FAILURE
	xori	r3,r1,0x3a3a
	bnei	r3,0xa3a3a3a3a3a39999,FAILURE

	andi	r3,r2,0xffffffffffffa3a3
	bnei	r3,0x3a3a3a3a3a3a2222,FAILURE
	ori	r3,r2,0xffffffffffffa3a3
	bnei	r3,0xffffffffffffbbbb,FAILURE
	xori	r3,r2,0xffffffffffffa3a3
	bnei	r3,0xc5c5c5c5c5c59999,FAILURE

###########################################################
#
# Test JAL and JALR
#
# NOTE: NullAddressException is not tested.
#
# This is only a basic test:
#    The full 20 bits of the immed-16 and immed-20 fields are not tested.
#    Null Address Exception is not tested.
#
# ********** THIS TEST IS SENSITIVE TO THE LOCATION OF THE INSTRUCTIONS. **********
#
Test_29: movi	s0,29

	nop
	nop
	nop
	nop
	nop
	nop
	nop
#	debug

# Check to make sure this code is at the location in memory where we expected it to be.
	addpc	r1,0
	bnei	r1,0x0_0000_0b54,FAILURE

# First test...
	jal	r2,+4
	beqz	r2,FAILURE
	movi	r3,0x0_0000_0b64	# This is the address of the above BEQZ	
	bne	r2,r3,FAILURE

# Second test...
	jal	r0,+12			# Jump to Test_29_Do_it

Test_29_Here:
	jal	r0,+16			# Jump to Test_29_Done
	bnez	r3,FAILURE

Test_29_Do_it:
	jal	r2,-8			# Jump to Test_29_Here, save ret addr in r2
	bnez	r3,FAILURE

Test_29_Done:
	movi	r3,0x0_0000_0b80	# This is the address of the above BNEZ statement
	bne	r2,r3,FAILURE		# Check to make sure we saved r2 okay

BasicTest_JALR:

	nop				# Slot for an optional DEBUG instruction
#	debug

	movi	r1,0xffff_ffff_ffff_9548
	jalr	r2,+0x7654(r1)		# Jumps to Test_29_OK at 0_0000_0b9c
	jump	FAILURE
Test_29_OK:
	movi	r3,0x0_0000_0b98	# This is the address of the above JUMP	
	bne	r2,r3,FAILURE

	nop				# Slot for an optional DEBUG instruction

	movi	r1,0x820c
	jalr	r2,-0x7654(r1)		# Jumps to Test_29_OK_2 at 0_0000_0bb8
	jump	FAILURE			# 
Test_29_OK_2:
	movi	r3,0x0_0000_0bb4	# This is the address of the above JUMP	
	bne	r2,r3,FAILURE






###########################################################
#
# Test ADD3
#
Test_30: movi	s0,30
	call	InitJumpTable

	movi	r1,3000
	movi	r2, 400
	movi	r3,  50
	add3	r4,r1,r2,r3
	bnei	r4,3450,FAILURE

	movi	r1,0xa41a_41a4_1a41_a41a
	movi	r2,0x41a4_1a41_a41a_41a4
	movi	r3,0x1a41_a41a_41a4_1a41
	add3	r4,r1,r2,r3
	bnei	r4,0xffff_ffff_ffff_ffff,FAILURE

# positive overflow on r1+r2
	movi	r1,0x7fff_ffff_ffff_0000
	movi	r2,0x0000_0000_1234_0000
	movi	r3,0x0000_0000_0000_5678
	add3	r4,r1,r2,r3
	bnei	r4,0x8000_0000_1233_5678,FAILURE

# positive overflow on r2+r3
	movi	r1,0x0000_0000_0000_5678
	movi	r2,0x7fff_ffff_ffff_0000
	movi	r3,0x0000_0000_1234_0000
	add3	r4,r1,r2,r3
	bnei	r4,0x8000_0000_1233_5678,FAILURE

# positive overflow on r1+r3
	movi	r1,0x7fff_ffff_ffff_0000
	movi	r2,0x0000_0000_0000_5678
	movi	r3,0x0000_0000_1234_0000
	add3	r4,r1,r2,r3
	bnei	r4,0x8000_0000_1233_5678,FAILURE

# negative overflow on r1+r2
	movi	r1,0x8000_0000_0000_0000
	movi	r2,0xffff_ffff_ffff_0000
	movi	r3,0x0000_0000_0000_5678
	add3	r4,r1,r2,r3
	bnei	r4,0x7fff_ffff_ffff_5678,FAILURE

# negative overflow on r2+r3
	movi	r1,0x0000_0000_0000_5678
	movi	r2,0x8000_0000_0000_0000
	movi	r3,0xffff_ffff_ffff_0000
	add3	r4,r1,r2,r3
	bnei	r4,0x7fff_ffff_ffff_5678,FAILURE

# negative overflow on r1+r3
	movi	r1,0x8000_0000_0000_0000
	movi	r2,0x0000_0000_0000_5678
	movi	r3,0xffff_ffff_ffff_0000
	add3	r4,r1,r2,r3
	bnei	r4,0x7fff_ffff_ffff_5678,FAILURE



###########################################################
#
# Test - Basic test of MULADD
#
Test_31: movi	s0,31

	movi		r4,300
	movi		r5,400
	movi		r6,3456
	muladd		r7,r4,r5,r6		# (300 * 400) + 3456 = 120000 + 3456
	bnei		r7,123456,FAILURE

	movi		r4,-500
	movi		r5,700
	movi		r6,-3456
	muladd		r7,r4,r5,r6		# (-500 * 700) + -3456 = -350000 - 3456
	bnei		r7,-353456,FAILURE


###########################################################
#
# Test SLL, SLLI, SRL, SRLI (overflow on the shift amount is not checked)
#
Test_32: movi	s0,32

	movi	r1,1
	slli	r2,r1,63
	bnei	r2,0x8000000000000000,FAILURE
	srli	r3,r2,63
	bnei	r3,1,FAILURE

	movi	r1,0x8000000000000000
	srli	r2,r1,63
	bnei	r2,1,FAILURE
	slli	r3,r2,63
	bnei	r3,0x8000000000000000,FAILURE

	movi	r1,0xcdef0123456789ab
	srli	r2,r1,32
	bnei	r2,0xcdef0123,FAILURE
	slli	r3,r2,32
	bnei	r3,0xcdef012300000000,FAILURE

	movi	r1,0xcdef0123456789ab
	slli	r2,r1,32
	bnei	r2,0x456789ab00000000,FAILURE
	srli	r3,r2,32
	bnei	r3,0x00000000456789ab,FAILURE

	movi	r1,0xcdef0123456789ab
	srli	r2,r1,1
# 1100 1101 1110 1111  0000 0001 0010 0011  0100 0101 0110 0111  1000 1001 1010 1011
# 0110 0110 1111 0111  1000 0000 1001 0001  1010 0010 1011 0011  1100 0100 1101 0101
	bnei	r2,0x66f78091a2b3c4d5,FAILURE
	slli	r3,r2,1
	bnei	r3,0xcdef0123456789aa,FAILURE

	movi	r1,0xcdef0123456789ab
	srli	r2,r1,0
	bnei	r2,0xcdef0123456789ab,FAILURE
	slli	r3,r2,0
	bnei	r3,0xcdef0123456789ab,FAILURE

#
	movi	r5,63

	movi	r1,1
	sll	r2,r1,r5
	bnei	r2,0x8000000000000000,FAILURE
	srl	r3,r2,r5
	bnei	r3,1,FAILURE

	movi	r1,0x8000000000000000
	srl	r2,r1,r5
	bnei	r2,1,FAILURE
	sll	r3,r2,r5
	bnei	r3,0x8000000000000000,FAILURE

	movi	r5,32

	movi	r1,0xcdef0123456789ab
	srl	r2,r1,r5
	bnei	r2,0xcdef0123,FAILURE
	sll	r3,r2,r5
	bnei	r3,0xcdef012300000000,FAILURE

	movi	r1,0xcdef0123456789ab
	sll	r2,r1,r5
	bnei	r2,0x456789ab00000000,FAILURE
	srl	r3,r2,r5
	bnei	r3,0x00000000456789ab,FAILURE

	movi	r5,1

	movi	r1,0xcdef0123456789ab
	srl	r2,r1,r5
# 1100 1101 1110 1111  0000 0001 0010 0011  0100 0101 0110 0111  1000 1001 1010 1011
# 0110 0110 1111 0111  1000 0000 1001 0001  1010 0010 1011 0011  1100 0100 1101 0101
	bnei	r2,0x66f78091a2b3c4d5,FAILURE
	sll	r3,r2,r5
	bnei	r3,0xcdef0123456789aa,FAILURE

	movi	r5,0

	movi	r1,0xcdef0123456789ab
	srl	r2,r1,r5
	bnei	r2,0xcdef0123456789ab,FAILURE
	sll	r3,r2,r5
	bnei	r3,0xcdef0123456789ab,FAILURE

###########################################################
#
# Test SLA, SLAI, SRA, SRAI
#
# Overflow on the shift amount is not checked.
# Overflow is not checked.
#
Test_33: movi	s0,33

	movi	r1,1
	slai	r2,r1,62
	bnei	r2,0x4000000000000000,FAILURE
	srai	r3,r2,62
	bnei	r3,1,FAILURE

	movi	r1,0x8000000000000000
	srai	r2,r1,63
	bnei	r2,-1,FAILURE
	slai	r3,r2,63
	bnei	r3,0x8000000000000000,FAILURE

	movi	r1,0xcdef0123456789ab
	srai	r2,r1,32
	bnei	r2,0xffffffffcdef0123,FAILURE
	slai	r3,r2,32
	bnei	r3,0xcdef012300000000,FAILURE

	movi	r1,0x00000000456789ab
	slai	r2,r1,32
	bnei	r2,0x456789ab00000000,FAILURE
	srai	r3,r2,32
	bnei	r3,0x00000000456789ab,FAILURE

	movi	r4,62

	movi	r1,1
	sla	r2,r1,r4
	bnei	r2,0x4000000000000000,FAILURE
	sra	r3,r2,r4
	bnei	r3,1,FAILURE

	movi	r4,63

	movi	r1,0x8000000000000000
	sra	r2,r1,r4
	bnei	r2,-1,FAILURE
	sla	r3,r2,r4
	bnei	r3,0x8000000000000000,FAILURE

	movi	r4,32

	movi	r1,0xcdef0123456789ab
	sra	r2,r1,r4
	bnei	r2,0xffffffffcdef0123,FAILURE
	sla	r3,r2,r4
	bnei	r3,0xcdef012300000000,FAILURE

	movi	r1,0x00000000456789ab
	sla	r2,r1,r4
	bnei	r2,0x456789ab00000000,FAILURE
	sra	r3,r2,r4
	bnei	r3,0x00000000456789ab,FAILURE

#

	movi	r1,0x4def0123456789ab
	srai	r2,r1,1
# 0100 1101 1110 1111  0000 0001 0010 0011  0100 0101 0110 0111  1000 1001 1010 1011
# 0010 0110 1111 0111  1000 0000 1001 0001  1010 0010 1011 0011  1100 0100 1101 0101
	bnei	r2,0x26f78091a2b3c4d5,FAILURE
	slai	r3,r2,1
	bnei	r3,0x4def0123456789aa,FAILURE

	movi	r1,0xcdef0123456789ab
	srai	r2,r1,0
	bnei	r2,0xcdef0123456789ab,FAILURE
	slai	r3,r2,0
	bnei	r3,0xcdef0123456789ab,FAILURE


	movi	r4,1

	movi	r1,0x4def0123456789ab
	sra	r2,r1,r4
# 0100 1101 1110 1111  0000 0001 0010 0011  0100 0101 0110 0111  1000 1001 1010 1011
# 0010 0110 1111 0111  1000 0000 1001 0001  1010 0010 1011 0011  1100 0100 1101 0101
	bnei	r2,0x26f78091a2b3c4d5,FAILURE
	sla	r3,r2,r4
	bnei	r3,0x4def0123456789aa,FAILURE

	movi	r4,0

	movi	r1,0xcdef0123456789ab
	sra	r2,r1,r4
	bnei	r2,0xcdef0123456789ab,FAILURE
	sla	r3,r2,r4
	bnei	r3,0xcdef0123456789ab,FAILURE


###########################################################
#
# Test ROTR, ROTRI
#
Test_34: movi	s0,34

	movi	r1,0xcdef0123456789ab
	rotri	r2,r1,32
	bnei	r2,0x456789abcdef0123,FAILURE
	rotri	r2,r2,32
	bnei	r2,0xcdef0123456789ab,FAILURE
	rotri	r2,r2,0
	bnei	r2,0xcdef0123456789ab,FAILURE

	movi	r4,32
	movi	r1,0xcdef0123456789ab
	rotr	r2,r1,r4
	bnei	r2,0x456789abcdef0123,FAILURE

	movi	r4,64+32
	rotr	r2,r1,r4
	bnei	r2,0x456789abcdef0123,FAILURE
	rotr	r2,r2,r0
	bnei	r2,0x456789abcdef0123,FAILURE

	# An example of rotating to the left...
	movi	r4,-32
	rotr	r2,r1,r4
	bnei	r2,0x456789abcdef0123,FAILURE

	# An example of rotating to the left...
	movi	r4,-12
	rotr	r2,r1,r4
	bnei	r2,0xf0123456789abcde,FAILURE

	# An example of rotating to the left...
	movi	r4,-(6400+12)
	rotr	r2,r1,r4
	bnei	r2,0xf0123456789abcde,FAILURE

###########################################################
#
# Test SEXTB, SEXTH, and SEXTW
#
Test_35: movi	s0,35

	movi	r1,0x1234567890abcdef
	sextb	r2,r1
	bnei	r2,0xffffffffffffffef,FAILURE
	sexth	r2,r1
	bnei	r2,0xffffffffffffcdef,FAILURE
	sextw	r2,r1
	bnei	r2,0xffffffff90abcdef,FAILURE

	movi	r1,0xffffffff12345678
	sextb	r2,r1
	bnei	r2,0x78,FAILURE
	sexth	r2,r1
	bnei	r2,0x5678,FAILURE
	sextw	r2,r1
	bnei	r2,0x12345678,FAILURE

###########################################################
#
# Test ENDIANH, ENDIANW, and ENDIAND
#
Test_36: movi	s0,36

	movi	r1,0x1234567890abcdef

	endianh	r2,r1
	bnei	r2,0x34127856ab90efcd,FAILURE
	endianw	r2,r1
	bnei	r2,0x78563412efcdab90,FAILURE
	endiand	r2,r1
	bnei	r2,0xefcdab9078563412,FAILURE


###########################################################
#
# Test TESTEQ, TESTNE, TESTLT, TESTLE
#
Test_37: movi	s0,37

	movi	r5,5
	movi	r6,6
	testeq	r1,r5,r6
	testne	r2,r5,r6
	testlt	r3,r5,r6
	testle	r4,r5,r6

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,1,FAILURE
	bnei	r4,1,FAILURE

	testeq	r1,r6,r5
	testne	r2,r6,r5
	testlt	r3,r6,r5
	testle	r4,r6,r5

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,0,FAILURE

#

	movi	r5,-5
	movi	r6,-6
	testeq	r1,r5,r6
	testne	r2,r5,r6
	testlt	r3,r5,r6
	testle	r4,r5,r6

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,0,FAILURE

	testeq	r1,r6,r5
	testne	r2,r6,r5
	testlt	r3,r6,r5
	testle	r4,r6,r5

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,1,FAILURE
	bnei	r4,1,FAILURE

#

	movi	r5,0x8000000000000000
	movi	r6,0x7fffffffffffffff
	testeq	r1,r5,r6
	testne	r2,r5,r6
	testlt	r3,r5,r6
	testle	r4,r5,r6

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,1,FAILURE
	bnei	r4,1,FAILURE

	testeq	r1,r6,r5
	testne	r2,r6,r5
	testlt	r3,r6,r5
	testle	r4,r6,r5

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,0,FAILURE

#

	movi	r5,437
	movi	r6,437

	testeq	r1,r6,r5
	testne	r2,r6,r5
	testlt	r3,r6,r5
	testle	r4,r6,r5

	bnei	r1,1,FAILURE
	bnei	r2,0,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,1,FAILURE

	movi	r5,0x8000000000000000
	movi	r6,0x8000000000000000

	testeq	r1,r6,r5
	testne	r2,r6,r5
	testlt	r3,r6,r5
	testle	r4,r6,r5

	bnei	r1,1,FAILURE
	bnei	r2,0,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,1,FAILURE

	movi	r5,0
	movi	r6,0

	testeq	r1,r6,r5
	testne	r2,r6,r5
	testlt	r3,r6,r5
	testle	r4,r6,r5

	bnei	r1,1,FAILURE
	bnei	r2,0,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,1,FAILURE

	movi	r5,0

	testeq	r1,r0,r5
	testne	r2,r0,r5
	testlt	r3,r0,r5
	testle	r4,r0,r5

	bnei	r1,1,FAILURE
	bnei	r2,0,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,1,FAILURE

	testeq	r1,r5,r0
	testne	r2,r5,r0
	testlt	r3,r5,r0
	testle	r4,r5,r0

	bnei	r1,1,FAILURE
	bnei	r2,0,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,1,FAILURE

	testeq	r1,r0,r0
	testne	r2,r0,r0
	testlt	r3,r0,r0
	testle	r4,r0,r0

	bnei	r1,1,FAILURE
	bnei	r2,0,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,1,FAILURE
#
	movi	r5,1
	testeq	r1,r5,r0
	testne	r2,r5,r0
	testlt	r3,r5,r0
	testle	r4,r5,r0

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,0,FAILURE

	testeq	r1,r0,r5
	testne	r2,r0,r5
	testlt	r3,r0,r5
	testle	r4,r0,r5

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,1,FAILURE
	bnei	r4,1,FAILURE


###########################################################
#
# Test TESTEQI, TESTNEI, TESTLTI, TESTLEI, TESTGTI, TESTGEI
#
Test_38: movi	s0,38

	movi	r7,0x1234

	testeqi	r1,r7,0x1234
	testnei	r2,r7,0x1234
	testlti	r3,r7,0x1234
	testlei	r4,r7,0x1234
	testgti	r5,r7,0x1234
	testgei	r6,r7,0x1234

	bnei	r1,1,FAILURE
	bnei	r2,0,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,1,FAILURE
	bnei	r5,0,FAILURE
	bnei	r6,1,FAILURE

	movi	r7,0x1233

	testeqi	r1,r7,0x1234
	testnei	r2,r7,0x1234
	testlti	r3,r7,0x1234
	testlei	r4,r7,0x1234
	testgti	r5,r7,0x1234
	testgei	r6,r7,0x1234

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,1,FAILURE
	bnei	r4,1,FAILURE
	bnei	r5,0,FAILURE
	bnei	r6,0,FAILURE

	movi	r7,0x1235

	testeqi	r1,r7,0x1234
	testnei	r2,r7,0x1234
	testlti	r3,r7,0x1234
	testlei	r4,r7,0x1234
	testgti	r5,r7,0x1234
	testgei	r6,r7,0x1234

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,0,FAILURE
	bnei	r5,1,FAILURE
	bnei	r6,1,FAILURE
#
	movi	r7,-0x1234

	testeqi	r1,r7,-0x1234
	testnei	r2,r7,-0x1234
	testlti	r3,r7,-0x1234
	testlei	r4,r7,-0x1234
	testgti	r5,r7,-0x1234
	testgei	r6,r7,-0x1234

	bnei	r1,1,FAILURE
	bnei	r2,0,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,1,FAILURE
	bnei	r5,0,FAILURE
	bnei	r6,1,FAILURE

	movi	r7,-0x1233

	testeqi	r1,r7,-0x1234
	testnei	r2,r7,-0x1234
	testlti	r3,r7,-0x1234
	testlei	r4,r7,-0x1234
	testgti	r5,r7,-0x1234
	testgei	r6,r7,-0x1234

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,0,FAILURE
	bnei	r4,0,FAILURE
	bnei	r5,1,FAILURE
	bnei	r6,1,FAILURE

	movi	r7,-0x1235

	testeqi	r1,r7,-0x1234
	testnei	r2,r7,-0x1234
	testlti	r3,r7,-0x1234
	testlei	r4,r7,-0x1234
	testgti	r5,r7,-0x1234
	testgei	r6,r7,-0x1234

	bnei	r1,0,FAILURE
	bnei	r2,1,FAILURE
	bnei	r3,1,FAILURE
	bnei	r4,1,FAILURE
	bnei	r5,0,FAILURE
	bnei	r6,0,FAILURE

###########################################################
#
# Test B.EQ and B.NE
#
# Each of these synthetic BEQ instructions will assemble as a
# single B.EQ instruction since the targets are always 	quite close. 
# The same for the BNE instructions.
#
Test_39: movi	s0,39

	movi	r1,0x123
	movi	r2,0x456
	beq	r1,r2,FAILURE
	bne	r1,r2,OK_39_1
	jump	FAILURE
OK_39_1:

	movi	r1,0x0000000000000001
	movi	r2,0x0000000000000000
	beq	r1,r2,FAILURE
	bne	r1,r2,OK_39_2
	jump	FAILURE
OK_39_2:

	movi	r1,0x0000000000000000
	movi	r2,0x0000000000000001
	beq	r1,r2,FAILURE
	bne	r1,r2,OK_39_3
	jump	FAILURE
OK_39_3:

	movi	r1,0x0000000000000001
	movi	r2,0x0000000000000001
	bne	r1,r2,FAILURE
	beq	r1,r2,OK_39_4
	jump	FAILURE
OK_39_4:

	movi	r1,0x1000000000000000
	movi	r2,0x0000000000000000
	beq	r1,r2,FAILURE
	bne	r1,r2,OK_39_5
	jump	FAILURE
OK_39_5:

	movi	r1,0x0000000000000000
	movi	r2,0x1000000000000000
	beq	r1,r2,FAILURE
	bne	r1,r2,OK_39_6
	jump	FAILURE
OK_39_6:

	movi	r1,0x1000000000000000
	movi	r2,0x1000000000000000
	bne	r1,r2,FAILURE
	beq	r1,r2,OK_39_7
	jump	FAILURE
OK_39_7:

	movi	r1,0x0000004000000000
	movi	r2,0x0000000000000000
	beq	r1,r2,FAILURE
	bne	r1,r2,OK_39_8
	jump	FAILURE
OK_39_8:

	movi	r1,0x0000000000000000
	movi	r2,0x0000000000400000
	beq	r1,r2,FAILURE
	bne	r1,r2,OK_39_9
	jump	FAILURE
OK_39_9:

	movi	r1,0x0004000000000000
	movi	r2,0x0004000000000000
	bne	r1,r2,FAILURE
	beq	r1,r2,OK_39_a
	jump	FAILURE
OK_39_a:

	movi	r1,0
	movi	r2,0
	bne	r1,r2,FAILURE
	beq	r1,r2,OK_39_b
	jump	FAILURE
OK_39_b:


###########################################################
#
# Unused test
#
Test_40: movi	s0,40


###########################################################
#
# Unused test
#
Test_41: movi	s0,41

###########################################################
#
# Test B.LT and B.LE
#
Test_42: movi	s0,42

	movi	r1,0x123
	movi	r2,0x456
	blt	r1,r2,OK_40_1
	jump	FAILURE
OK_40_1:
	ble	r1,r2,OK_40_2
	jump	FAILURE
OK_40_2:

	movi	r1,0x8000000000000000
	movi	r2,0x8000000000000001
	blt	r1,r2,OK_40_3
	jump	FAILURE
OK_40_3:
	ble	r1,r2,OK_40_4
	jump	FAILURE
OK_40_4:

	movi	r1,0x7ffffffffffffffe
	movi	r2,0x7fffffffffffffff
	blt	r1,r2,OK_40_5
	jump	FAILURE
OK_40_5:
	ble	r1,r2,OK_40_6
	jump	FAILURE
OK_40_6:

	movi	r2,1
	blt	r0,r2,OK_40_7
	jump	FAILURE
OK_40_7:
	ble	r0,r2,OK_40_8
	jump	FAILURE
OK_40_8:

	movi	r1,-0x456
	movi	r2,-0x123
	blt	r1,r2,OK_40_9
	jump	FAILURE
OK_40_9:
	ble	r1,r2,OK_40_10
	jump	FAILURE
OK_40_10:

	movi	r1,0x456
	movi	r2,0x123
	blt	r1,r2,FAILURE
	ble	r1,r2,FAILURE

	movi	r1,0x124
	movi	r2,0x123
	blt	r1,r2,FAILURE
	ble	r1,r2,FAILURE

	movi	r1,0x8000000000000001
	movi	r2,0x8000000000000000
	blt	r1,r2,FAILURE
	ble	r1,r2,FAILURE

	movi	r1,0x7fffffffffffffff
	movi	r2,0x7ffffffffffffffe
	blt	r1,r2,FAILURE
	ble	r1,r2,FAILURE

	movi	r1,0x7fffffffffffffff
	movi	r2,0x8000000000000000
	blt	r1,r2,FAILURE
	ble	r1,r2,FAILURE

	movi	r1,0
	movi	r2,-1
	blt	r1,r2,FAILURE
	ble	r1,r2,FAILURE

	movi	r1,1
	movi	r2,0
	blt	r1,r2,FAILURE
	ble	r1,r2,FAILURE

	movi	r1,1
	blt	r1,r0,FAILURE
	ble	r1,r0,FAILURE

#
	movi	r1,123
	movi	r2,123
	blt	r1,r2,FAILURE
	ble	r1,r2,OK_40_11
	jump	FAILURE
OK_40_11:

	movi	r1,123
	movi	r2,123
	blt	r1,r2,FAILURE
	ble	r1,r2,OK_40_12
	jump	FAILURE
OK_40_12:

	movi	r1,0x8000000000000000
	movi	r2,0x8000000000000000
	blt	r1,r2,FAILURE
	ble	r1,r2,OK_40_13
	jump	FAILURE
OK_40_13:

	movi	r1,0x7fffffffffffffff
	movi	r2,0x7fffffffffffffff
	blt	r1,r2,FAILURE
	ble	r1,r2,OK_40_14
	jump	FAILURE
OK_40_14:

	movi	r1,0
	blt	r1,r0,FAILURE
	ble	r1,r0,OK_40_15
	jump	FAILURE
OK_40_15:

	movi	r2,0
	blt	r0,r2,FAILURE
	ble	r0,r2,OK_40_16
	jump	FAILURE
OK_40_16:

###########################################################
#
# Test ADDOK
#
Test_43: movi	s0,43

	movi	r1,123
	movi	r2,456
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,1,FAILURE
	movi	r3,0xabab
	addok	r3,r2,r1
	bnei	r3,1,FAILURE

	movi	r1,0x7ffffffffffffffe
	movi	r2,1
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,1,FAILURE
	movi	r3,0xabab
	addok	r3,r2,r1
	bnei	r3,1,FAILURE

	movi	r1,0x7fffffffffffffff
	movi	r2,1
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,0,FAILURE
	movi	r3,0xabab
	addok	r3,r2,r1
	bnei	r3,0,FAILURE

	movi	r1,0x7ffffffffffffffe
	movi	r2,2
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,0,FAILURE
	movi	r3,0xabab
	addok	r3,r2,r1
	bnei	r3,0,FAILURE

	movi	r1,0x8000000000000001
	movi	r2,-1
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,1,FAILURE
	movi	r3,0xabab
	addok	r3,r2,r1
	bnei	r3,1,FAILURE

	movi	r1,0x8000000000000000
	movi	r2,-1
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,0,FAILURE
	movi	r3,0xabab
	addok	r3,r2,r1
	bnei	r3,0,FAILURE

	movi	r1,0x8000000000000001
	movi	r2,-2
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,0,FAILURE
	movi	r3,0xabab
	addok	r3,r2,r1
	bnei	r3,0,FAILURE

	movi	r1,0x8000000000000000
	movi	r2,0x7fffffffffffffff
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,1,FAILURE
	movi	r3,0xabab
	addok	r3,r2,r1
	bnei	r3,1,FAILURE

	movi	r1,0x8000000000000000
	movi	r3,0xabab
	addok	r3,r1,r0
	bnei	r3,1,FAILURE
	movi	r3,0xabab
	addok	r3,r0,r1
	bnei	r3,1,FAILURE

	movi	r1,0x7fffffffffffffff
	movi	r3,0xabab
	addok	r3,r1,r0
	bnei	r3,1,FAILURE
	movi	r3,0xabab
	addok	r3,r0,r1
	bnei	r3,1,FAILURE

	movi	r1,0x7fffffffffffffff
	movi	r2,0x7fffffffffffffff
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,0,FAILURE

	movi	r1,0x8000000000000000
	movi	r2,0x8000000000000000
	movi	r3,0xabab
	addok	r3,r1,r2
	bnei	r3,0,FAILURE

	movi	r3,0xabab
	addok	r3,r0,r0
	bnei	r3,1,FAILURE

###########################################################
#
# Test ALIGNW
#
Test_44: movi	s0,44

	movi	r1,0x1234567890abcdef
	movi	r2,0xfedcba0987654321

	movi	r3,0
	alignw	r4,r1,r2,r3
	bnei	r4,0xffffffff90abcdef,FAILURE

	alignw	r4,r1,r2,r0
	bnei	r4,0xffffffff90abcdef,FAILURE

	movi	r3,1
	alignw	r4,r1,r2,r3
	bnei	r4,0xffffffffabcdef87,FAILURE

	movi	r3,2
	alignw	r4,r1,r2,r3
	bnei	r4,0xffffffffcdef8765,FAILURE

	movi	r3,3
	alignw	r4,r1,r2,r3
	bnei	r4,0xffffffffef876543,FAILURE

	movi	r3,0xfffffffffffffffc+0
	alignw	r4,r1,r2,r3
	bnei	r4,0xffffffff90abcdef,FAILURE

	movi	r3,0xfffffffffffffffc+1
	alignw	r4,r1,r2,r3
	bnei	r4,0xffffffffabcdef87,FAILURE

	movi	r3,0xfffffffffffffffc+2
	alignw	r4,r1,r2,r3
	bnei	r4,0xffffffffcdef8765,FAILURE

	movi	r3,0xfffffffffffffffc+3
	alignw	r4,r1,r2,r3
	bnei	r4,0xffffffffef876543,FAILURE

	bnei	r1,0x1234567890abcdef,FAILURE
	bnei	r2,0xfedcba0987654321,FAILURE


	movi	r1,0x90abcdef12345678
	movi	r2,0xfedcba0987654321

	movi	r3,0
	alignw	r4,r1,r2,r3
	bnei	r4,0x0000000012345678,FAILURE

	movi	r3,1
	alignw	r4,r1,r2,r3
	bnei	r4,0x0000000034567887,FAILURE

	movi	r3,2
	alignw	r4,r1,r2,r3
	bnei	r4,0x0000000056788765,FAILURE

	movi	r3,3
	alignw	r4,r1,r2,r3
	bnei	r4,0x0000000078876543,FAILURE

###########################################################
#
# Test ALIGND
#
Test_45: movi	s0,45

	movi	r1,0x1234567890abcdef
	movi	r2,0xfedcba0987654321

	movi	r3,0
	alignd	r4,r1,r2,r3
	bnei	r4,0x1234567890abcdef,FAILURE

	alignd	r4,r1,r2,r0
	bnei	r4,0x1234567890abcdef,FAILURE

	movi	r3,1
	alignd	r4,r1,r2,r3
	bnei	r4,0x34567890abcdeffe,FAILURE

	movi	r3,2
	alignd	r4,r1,r2,r3
	bnei	r4,0x567890abcdeffedc,FAILURE

	movi	r3,3
	alignd	r4,r1,r2,r3
	bnei	r4,0x7890abcdeffedcba,FAILURE

	movi	r3,4
	alignd	r4,r1,r2,r3
	bnei	r4,0x90abcdeffedcba09,FAILURE

	movi	r3,5
	alignd	r4,r1,r2,r3
	bnei	r4,0xabcdeffedcba0987,FAILURE

	movi	r3,6
	alignd	r4,r1,r2,r3
	bnei	r4,0xcdeffedcba098765,FAILURE

	movi	r3,7
	alignd	r4,r1,r2,r3
	bnei	r4,0xeffedcba09876543,FAILURE


	movi	r3,0xff345678ffee37f8 + 0
	alignd	r4,r1,r2,r3
	bnei	r4,0x1234567890abcdef,FAILURE

	movi	r3,0xff345678ffee37f8 + 1
	alignd	r4,r1,r2,r3
	bnei	r4,0x34567890abcdeffe,FAILURE

	movi	r3,0xff345678ffee37f8 + 2
	alignd	r4,r1,r2,r3
	bnei	r4,0x567890abcdeffedc,FAILURE

	movi	r3,0xff345678ffee37f8 + 3
	alignd	r4,r1,r2,r3
	bnei	r4,0x7890abcdeffedcba,FAILURE

	movi	r3,0xff345678ffee37f8 + 4
	alignd	r4,r1,r2,r3
	bnei	r4,0x90abcdeffedcba09,FAILURE

	movi	r3,0xff345678ffee37f8 + 5
	alignd	r4,r1,r2,r3
	bnei	r4,0xabcdeffedcba0987,FAILURE

	movi	r3,0xff345678ffee37f8 + 6
	alignd	r4,r1,r2,r3
	bnei	r4,0xcdeffedcba098765,FAILURE

	movi	r3,0xff345678ffee37f8 + 7
	alignd	r4,r1,r2,r3
	bnei	r4,0xeffedcba09876543,FAILURE


	bnei	r1,0x1234567890abcdef,FAILURE
	bnei	r2,0xfedcba0987654321,FAILURE


###########################################################
#
# Test ALIGNH
#
Test_46: movi	s0,46


	movi	r1,0x1234567890abcdef
	movi	r2,0xfedcba0987654321

	movi	r3,0
	alignh	r4,r1,r2,r3
	bnei	r4,0xffffffffffffcdef,FAILURE

	alignh	r4,r1,r2,r0
	bnei	r4,0xffffffffffffcdef,FAILURE

	movi	r3,1
	alignh	r4,r1,r2,r3
	bnei	r4,0xffffffffffffef43,FAILURE

	movi	r3,0xfffffffffffffffe + 0
	alignh	r4,r1,r2,r3
	bnei	r4,0xffffffffffffcdef,FAILURE

	movi	r3,0xfffffffffffffffe + 1
	alignh	r4,r1,r2,r3
	bnei	r4,0xffffffffffffef43,FAILURE

	bnei	r1,0x1234567890abcdef,FAILURE
	bnei	r2,0xfedcba0987654321,FAILURE


	movi	r1,0x1234567890ab1234
	movi	r2,0xfedcba0987655678

	movi	r3,0
	alignh	r4,r1,r2,r3
	bnei	r4,0x1234,FAILURE

	alignh	r4,r1,r2,r0
	bnei	r4,0x1234,FAILURE

	movi	r3,0xfffffffffffffffe + 1
	alignh	r4,r1,r2,r3
	bnei	r4,0x3456,FAILURE

	bnei	r1,0x1234567890ab1234,FAILURE
	bnei	r2,0xfedcba0987655678,FAILURE

###########################################################
#
# Test INJECT1D and INJECT2D
#
Test_47: movi	s0,47

	movi		r1,0x1234567890abcdef
	movi		r2,0xfedcba0987654321

	movi		r3,0
	inject1d	r4,r1,r2,r3
	bnei		r4,0xfedcba0987654321,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x1234567890abcdef,FAILURE

	movi		r3,1
	inject1d	r4,r1,r2,r3
	bnei		r4,0x12fedcba09876543,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x2134567890abcdef,FAILURE

	movi		r3,2
	inject1d	r4,r1,r2,r3
	bnei		r4,0x1234fedcba098765,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x4321567890abcdef,FAILURE

	movi		r3,3
	inject1d	r4,r1,r2,r3
	bnei		r4,0x123456fedcba0987,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x6543217890abcdef,FAILURE

	movi		r3,4
	inject1d	r4,r1,r2,r3
	bnei		r4,0x12345678fedcba09,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x8765432190abcdef,FAILURE

	movi		r3,5
	inject1d	r4,r1,r2,r3
	bnei		r4,0x1234567890fedcba,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x0987654321abcdef,FAILURE

	movi		r3,6
	inject1d	r4,r1,r2,r3
	bnei		r4,0x1234567890abfedc,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0xba0987654321cdef,FAILURE

	movi		r3,7
	inject1d	r4,r1,r2,r3
	bnei		r4,0x1234567890abcdfe,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0xdcba0987654321ef,FAILURE

	# Same thing, but make sure upper bits of r3 are ignored.

	movi		r3,0xfffffffffffffff8 + 0
	inject1d	r4,r1,r2,r3
	bnei		r4,0xfedcba0987654321,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x1234567890abcdef,FAILURE

	movi		r3,0xfffffffffffffff8 + 1
	inject1d	r4,r1,r2,r3
	bnei		r4,0x12fedcba09876543,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x2134567890abcdef,FAILURE

	movi		r3,0xfffffffffffffff8 + 2
	inject1d	r4,r1,r2,r3
	bnei		r4,0x1234fedcba098765,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x4321567890abcdef,FAILURE

	movi		r3,0xfffffffffffffff8 + 3
	inject1d	r4,r1,r2,r3
	bnei		r4,0x123456fedcba0987,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x6543217890abcdef,FAILURE

	movi		r3,0xfffffffffffffff8 + 4
	inject1d	r4,r1,r2,r3
	bnei		r4,0x12345678fedcba09,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x8765432190abcdef,FAILURE

	movi		r3,0xfffffffffffffff8 + 5
	inject1d	r4,r1,r2,r3
	bnei		r4,0x1234567890fedcba,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0x0987654321abcdef,FAILURE

	movi		r3,0xfffffffffffffff8 + 6
	inject1d	r4,r1,r2,r3
	bnei		r4,0x1234567890abfedc,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0xba0987654321cdef,FAILURE

	movi		r3,0xfffffffffffffff8 + 7
	inject1d	r4,r1,r2,r3
	bnei		r4,0x1234567890abcdfe,FAILURE
	inject2d	r5,r1,r2,r3
	bnei		r5,0xdcba0987654321ef,FAILURE


	bnei		r1,0x1234567890abcdef,FAILURE
	bnei		r2,0xfedcba0987654321,FAILURE

###########################################################
#
# Test INJECT1W and INJECT2W
#
Test_48: movi	s0,48

	movi		r1,0x1234567890abcdef
	movi		r2,0xfedcba0987654321

	movi		r3,0
	inject1w	r4,r1,r2,r3
	bnei		r4,0x1234567887654321,FAILURE
	inject2w	r5,r1,r2,r3
	bnei		r5,0x1234567890abcdef,FAILURE

	movi		r3,1
	inject1w	r4,r1,r2,r3
	bnei		r4,0x1234567890876543,FAILURE
	inject2w	r5,r1,r2,r3
	bnei		r5,0x1234567821abcdef,FAILURE

	movi		r3,2
	inject1w	r4,r1,r2,r3
	bnei		r4,0x1234567890ab8765,FAILURE
	inject2w	r5,r1,r2,r3
	bnei		r5,0x123456784321cdef,FAILURE

	movi		r3,3
	inject1w	r4,r1,r2,r3
	bnei		r4,0x1234567890abcd87,FAILURE
	inject2w	r5,r1,r2,r3
	bnei		r5,0x12345678654321ef,FAILURE

	bnei		r1,0x1234567890abcdef,FAILURE
	bnei		r2,0xfedcba0987654321,FAILURE

###########################################################
#
# Test INJECT1H and INJECT2H
#
Test_49: movi	s0,49


	movi		r1,0x1234567890abcdef
	movi		r2,0xfedcba0987654321

	movi		r3,0
	inject1h	r4,r1,r2,r3
	bnei		r4,0x1234567890ab4321,FAILURE
	inject2h	r5,r1,r2,r3
	bnei		r5,0x1234567890abcdef,FAILURE

	movi		r3,1
	inject1h	r4,r1,r2,r3
	bnei		r4,0x1234567890abcd43,FAILURE
	inject2h	r5,r1,r2,r3
	bnei		r5,0x1234567890ab21ef,FAILURE

	movi		r3,0xfffffffffffffffe + 0
	inject1h	r4,r1,r2,r3
	bnei		r4,0x1234567890ab4321,FAILURE
	inject2h	r5,r1,r2,r3
	bnei		r5,0x1234567890abcdef,FAILURE

	movi		r3,0xfffffffffffffffe + 1
	inject1h	r4,r1,r2,r3
	bnei		r4,0x1234567890abcd43,FAILURE
	inject2h	r5,r1,r2,r3
	bnei		r5,0x1234567890ab21ef,FAILURE

	bnei		r1,0x1234567890abcdef,FAILURE
	bnei		r2,0xfedcba0987654321,FAILURE


############################################################################
############################################################################
###
###   BEGIN TESTING LOAD AND STORE INSTRUCTIONS
###
###   We only test properly aligned instructions here.
###   This is a test of the instructions, not of memory. We do not verify
###   that memory exists outside of this memory containing this program.
###
############################################################################
############################################################################


###########################################################
#
# Test LOAD.B, LOAD.H, LOAD.W, and LOAD.D
#
# This only tests properly aligned loads.
#
Test_50: movi	s0,50

	jump	Test_50_Continue

	.align	8
addr0:	.byte	0x12
addr1:	.byte	0x34
addr2:	.byte	0x56
addr3:	.byte	0x78
addr4:	.byte	0xffffffffffffff90
addr5:	.byte	0xffffffffffffffab
addr6:	.byte	0xffffffffffffffcd
addr7:	.byte	0xffffffffffffffef
addr8:

Test_50_Continue:

# Check that the assumed alignment of the memory array is met...
	movi	r1,addr0
	andi	r1,r1,0x7
	bnez	r1,FAILURE

	movi	r1,addr0
	movi	r2,addr8

	load.b	r3,3(r1)
	bnei	r3,0x0000000000000078,FAILURE

	load.b	r3,6(r1)
	bnei	r3,0xffffffffffffffcd,FAILURE

	load.b	r3,-8(r2)
	bnei	r3,0x0000000000000012,FAILURE
#
	load.h	r3,2(r1)
	bnei	r3,0x0000000000005678,FAILURE

	load.h	r3,6(r1)
	bnei	r3,0xffffffffffffcdef,FAILURE

	load.h	r3,-8(r2)
	bnei	r3,0x0000000000001234,FAILURE
#
	load.w	r3,0(r1)
	bnei	r3,0x0000000012345678,FAILURE

	load.w	r3,4(r1)
	bnei	r3,0xffffffff90abcdef,FAILURE

	load.w	r3,-8(r2)
	bnei	r3,0x0000000012345678,FAILURE
#
	load.d	r3,0(r1)
	bnei	r3,0x1234567890abcdef,FAILURE

	load.d	r3,-8(r2)
	bnei	r3,0x1234567890abcdef,FAILURE


###########################################################
#
# Test STORE.B, STORE.H, STORE.W, and STORE.D
#
# This only tests properly aligned stores.
#
Test_51: movi	s0,51

	jump	Test_51_Continue

# A memory array in which we will store values

		.align	8
addr_0:		.byte	-1
addr_1:		.byte	-1	# 0x68  will go here
addr_2:		.byte	-1
addr_3:		.byte	-1
addr_4:		.byte	-1	# 0x65666868  will go here
addr_5:		.byte	-1	#
addr_6:		.byte	-1	#
addr_7:		.byte	-1	#
addr_8:		.byte	-1
addr_9:		.byte	-1
addr_a:		.byte	-1	# 0x6768  will go here
addr_b:		.byte	-1	#
addr_c:		.byte	-1
addr_d:		.byte	-1
addr_e:		.byte	-1
addr_f:		.byte	-1
addr_10:	.byte	-1	# 0x6162636465666768  will go here
addr_11:	.byte	-1	#
addr_12:	.byte	-1	#
addr_13:	.byte	-1	#
addr_14:	.byte	-1	#
addr_15:	.byte	-1	#
addr_16:	.byte	-1	#
addr_17:	.byte	-1	#
addr_18:	.byte	-1
addr_19:	.byte	-1
addr_1a:	.byte	-1
addr_1b:	.byte	-1
addr_1c:	.byte	-1
addr_1d:	.byte	-1
addr_1e:	.byte	-1
addr_1f:	.byte	-1
addr_20:	.byte	0
addr_21:	.byte	0	# 0xb8 will go here
addr_22:	.byte	0
addr_23:	.byte	0
addr_24:	.byte	0	# 0xb5b6b7b8 will go here
addr_25:	.byte	0	#
addr_26:	.byte	0	#
addr_27:	.byte	0	#
addr_28:	.byte	0
addr_29:	.byte	0
addr_2a:	.byte	0	# 0xb7b8 will go here
addr_2b:	.byte	0	#
addr_2c:	.byte	0
addr_2d:	.byte	0
addr_2e:	.byte	0
addr_2f:	.byte	0
addr_30:	.byte	0	# 0xb1b2b3b4b5b6b7b8 will go here
addr_31:	.byte	0	#
addr_32:	.byte	0	#
addr_33:	.byte	0	#
addr_34:	.byte	0	#
addr_35:	.byte	0	#
addr_36:	.byte	0	#
addr_37:	.byte	0	#
addr_38:	.byte	0
addr_39:	.byte	0
addr_3a:	.byte	0
addr_3b:	.byte	0
addr_3c:	.byte	0
addr_3d:	.byte	0
addr_3e:	.byte	0
addr_3f:	.byte	0
addr_40:

Test_51_Continue:

# Check that the assumed alignment of the memory array is met...
	movi	r1,addr_0
	andi	r1,r1,0x7
	bnez	r1,FAILURE

# Store positive values among lots of 0xFFs...

	movi	r2,0x6162636465666768
	movi	r1,addr_0
	store.b	0x01(r1),r2
	store.w	0x04(r1),r2
	store.h	0x0a(r1),r2
	store.d	0x10(r1),r2

# Store negative values among lots of 0x00s...
# Use negative offsets for good measure...

	movi	r2,0xb1b2b3b4b5b6b7b8
	movi	r7,addr_40		# Previous used r15, but this messed up stack ptr sp.
	store.b	-31(r7),r2
	store.w	-28(r7),r2
	store.h	-22(r7),r2
	store.d	-16(r7),r2

# Check that every byte in the above memory array is correct...
	load.b	r3,0x00(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x01(r1)			#
	bnei	r3,0x68,FAILURE
	load.b	r3,0x02(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x03(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x04(r1)			#
	bnei	r3,0x65,FAILURE
	load.b	r3,0x05(r1)			#
	bnei	r3,0x66,FAILURE
	load.b	r3,0x06(r1)			#
	bnei	r3,0x67,FAILURE
	load.b	r3,0x07(r1)			#
	bnei	r3,0x68,FAILURE
	load.b	r3,0x08(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x09(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x0a(r1)			#
	bnei	r3,0x67,FAILURE
	load.b	r3,0x0b(r1)			#
	bnei	r3,0x68,FAILURE
	load.b	r3,0x0c(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x0d(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x0e(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x0f(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x10(r1)			#
	bnei	r3,0x61,FAILURE
	load.b	r3,0x11(r1)			#
	bnei	r3,0x62,FAILURE
	load.b	r3,0x12(r1)			#
	bnei	r3,0x63,FAILURE
	load.b	r3,0x13(r1)			#
	bnei	r3,0x64,FAILURE
	load.b	r3,0x14(r1)			#
	bnei	r3,0x65,FAILURE
	load.b	r3,0x15(r1)			#
	bnei	r3,0x66,FAILURE
	load.b	r3,0x16(r1)			#
	bnei	r3,0x67,FAILURE
	load.b	r3,0x17(r1)			#
	bnei	r3,0x68,FAILURE
	load.b	r3,0x18(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x19(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x1a(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x1b(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x1c(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x1d(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x1e(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x1f(r1)
	bnei	r3,-1,FAILURE
	load.b	r3,0x20(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x21(r1)			#
	bnei	r3,0xffffffffffffffb8,FAILURE
	load.b	r3,0x22(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x23(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x24(r1)			#
	bnei	r3,0xffffffffffffffb5,FAILURE
	load.b	r3,0x25(r1)			#
	bnei	r3,0xffffffffffffffb6,FAILURE
	load.b	r3,0x26(r1)			#
	bnei	r3,0xffffffffffffffb7,FAILURE
	load.b	r3,0x27(r1)			#
	bnei	r3,0xffffffffffffffb8,FAILURE
	load.b	r3,0x28(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x29(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x2a(r1)			#
	bnei	r3,0xffffffffffffffb7,FAILURE
	load.b	r3,0x2b(r1)			#
	bnei	r3,0xffffffffffffffb8,FAILURE
	load.b	r3,0x2c(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x2d(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x2e(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x2f(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x30(r1)			#
	bnei	r3,0xffffffffffffffb1,FAILURE
	load.b	r3,0x31(r1)			#
	bnei	r3,0xffffffffffffffb2,FAILURE
	load.b	r3,0x32(r1)			#
	bnei	r3,0xffffffffffffffb3,FAILURE
	load.b	r3,0x33(r1)			#
	bnei	r3,0xffffffffffffffb4,FAILURE
	load.b	r3,0x34(r1)			#
	bnei	r3,0xffffffffffffffb5,FAILURE
	load.b	r3,0x35(r1)			#
	bnei	r3,0xffffffffffffffb6,FAILURE
	load.b	r3,0x36(r1)			#
	bnei	r3,0xffffffffffffffb7,FAILURE
	load.b	r3,0x37(r1)			#
	bnei	r3,0xffffffffffffffb8,FAILURE
	load.b	r3,0x38(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x39(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x3a(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x3b(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x3c(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x3d(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x3e(r1)
	bnei	r3,0,FAILURE
	load.b	r3,0x3f(r1)
	bnei	r3,0,FAILURE

############################################################################
############################################################################
###
###   BEGIN TESTING PRIVILEGED INSTRUCTIONS
###
############################################################################
############################################################################




###########################################################
#
# Move the the address of UnexpectedException into csr_trapvec, so future
# exceptions will print a message instead of freeze up in an exception loop.
#
	movi		t,UnexpectedException
	csrwrite	csr_trapvec,t

#	movi		r1,0x7fff_ffff_ffff_ffff	# Test it
#	addi		r1,r1,1

###########################################################
#
# Test CSRREAD, CSRSWAP, CSRSET, CSRCLR
#
Test_52: movi	s0,52


	movi		r1,0x1234567890abcdef
	csrwrite	csr_temp,r1
	csrread		r2, csr_temp
	bnei		r2,0x1234567890abcdef,FAILURE

	movi		r1,0xfedcba0987654321
	csrwrite	csr_temp,r1
	csrread		r2, csr_temp
	bnei		r2,0xfedcba0987654321,FAILURE

	movi		r3,0x1111222233334444
	csrswap		r4,csr_temp,r3
	csrread		r2, csr_temp
	bnei		r2,0x1111222233334444,FAILURE
	bnei		r3,0x1111222233334444,FAILURE
	bnei		r4,0xfedcba0987654321,FAILURE

	csrwrite	csr_temp,r0
	csrread		r2, csr_temp
	bnei		r2,0,FAILURE

	csrset		csr_temp,0x789a
	csrread		r2, csr_temp
	bnei		r2,0x000000000000789a,FAILURE

	csrwrite	csr_temp,r0
	csrset		csr_temp,0xffffffffffff8765
	csrread		r2, csr_temp
	bnei		r2,0xffffffffffff8765,FAILURE

	csrset		csr_temp,0x789a
	csrread		r2, csr_temp
	bnei		r2,0xffffffffffffffff,FAILURE

	csrclr		csr_temp,0x789a
	csrread		r2, csr_temp
	bnei		r2,0xffffffffffff8765,FAILURE

	csrclr		csr_temp,0xffffffffffff8765
	csrread		r2, csr_temp
	bnei		r2,0x0000000000000000,FAILURE


###########################################################
#
# Verify that CSR_STATUS is properly initialized on
# startup to 0x0000_0000_0000_0001.
#    Kernel mode = 1
#    All other bits = 0
# Verify that all USED bits of CSR_STATUS are writable and that
# all UNUSED bits are not writable.
#
Test_53: movi		s0,53

	csrread		r1,csr_status		# Make sure the startup value is correct.
	bnei		r1,0x0000000000000001,FAILURE

	movi		r1,0x7fffffffffffffff	# Make sure we don't get a timer interrupt next
	csrwrite	csr_timer,r1

	movi		r1,0xfffffffffffffffb	# Singlestep = 0, Interrupts=1, Kernel=1
	csrwrite	csr_status,r1
	csrread		r2,csr_status
	bnei		r2,0xfffffffff00003fb,FAILURE

# Avoid setting SingleStep at the same time that interrupts are enabled.

	csrclr		csr_status,2		# clear interrupts enabled
	csrset		csr_status,4		# set single step
	csrread		r2,csr_status
	bnei		r2,0xfffffffff00003fd,FAILURE	# Check: Singlestep = 1, Interrupts=0, Kernel=1

	movi		r1,0xa234567890abcfeb	# Note: Singlestep = 0, Interrupts=1, Kernel=1
	csrwrite	csr_status,r1
	csrread		r2,csr_status
	bnei		r2,0xa2345678900003eb,FAILURE
	
	movi		r1,0x0000000000000001	# ASID=0000, Singlestep = 0, Interrupts=0, Kernel=1
	csrwrite	csr_status,r1
	csrread		r1,csr_status
	bnei		r1,0x0000000000000001,FAILURE

	

###########################################################
#
# Make sure the following are read-only:
#     csr_version, csr_core, csr_prod
# Also check:
#     csr_version, csr_core
# The following is unchecked since it is fully implementation-defined:
#     csr_prod
#
Test_54: movi	s0,54

# csr_version
	csrread		r1,csr_version
	movi		r2,0x1234567890abcdef

	csrwrite	csr_version,r2

	csrread		r3,csr_version
	bne		r1,r3,FAILURE

# csr_core
	csrread		r1,csr_core
	movi		r2,0x1234567890abcdef

	csrwrite	csr_core,r2

	csrread		r3, csr_core
	bne		r1,r3,FAILURE

# csr_prod
	csrread		r1,csr_prod
	movi		r2,0x1234567890abcdef

	csrwrite	csr_prod,r2

	csrread		r3, csr_prod
	bne		r1,r3,FAILURE

# Make sure the csr_version has CyclesPerMillisec > 0, ConformsToOfficialISA=1, and Version=0x0002
	csrread		r1,csr_version
	movi		r2,0xffff_ffff_0000_0000
	and		r2,r1,r2
	beqz		r2,FAILURE

	movi		r2,0x0000_0000_FFFF_0000
	and		r2,r1,r2
	bnei		r2,0x0000_0000_8002_0000,FAILURE

# Make sure csr_core is correct.
	csrread		r1,csr_core
	srli		r2,r1,48		# number of rows (will be 0...65,535)

	slli		r3,r1,16
	srli		r3,r3,48		# number of columns (will be 0...65,535)

	slli		r4,r1,32
	srli		r4,r4,48		# number of planes (will be 0...65,535)
		
	slli		r5,r1,48
	srli		r5,r5,48		# core number (will be 0...65,535)

	mul		r6,r2,r3
	mul		r6,r6,r4		# number of cores (cannot overflow)

	beqz		r2,FAILURE		# numberOfRows must be positive
	beqz		r3,FAILURE		# numberOfColumns must be positive
	beqz		r4,FAILURE		# numberOfPlanes must be positive
	bge		r5,r6,FAILURE		# If CoreNumber < NumCores then OK



###########################################################
#
# Test csr_instr. Make sure it is getting incremented correctly.
#
#   We are not testing to see if it is properly initialized to zero on startup.
#
Test_55: movi	s0,55

	csrread		r1,csr_instr
	movi		r2,0x1234567890abcdef	# inst 1-4 (Synthetic; this is expanded to 4 instructions)

	csrwrite	csr_instr,r2		# inst 5

	csrread		r3,csr_instr		# inst 6
	addi		r1,r1,6			# Number of instructions since first csrread: 6
	bne		r1,r3,FAILURE
	blez		r1,FAILURE

###########################################################
#
# Test csr_cycle. Make sure it is getting incremented.
#
#   We are not testing to see if it is properly initialized to zero on startup.
#
Test_56: movi	s0,56

	csrread		r1,csr_cycle
	movi		r2,0x1234567890abcdef

	csrwrite	csr_cycle,r2

	csrread		r3,csr_cycle
	bge		r1,r3,FAILURE
	blez		r1,FAILURE

###########################################################
#
# Test csr_timer. Make sure it is getting decremented reasonably.
# Leave csr_timer with a large value so it won't cause an interrupt in the future.
#
Test_57: movi	s0,57

	movi		r2,0x1234567890abcdef
	csrwrite	csr_timer,r2
	csrread		r1,csr_timer
	csrread		r3,csr_timer
	ble		r1,r3,FAILURE			# Make sure it got decremented
	andi		r1,r1,0xFFFFFFFFFFFFFF00	# Should be fewer than 0xEF cycles since the csrwrite
	andi		r3,r3,0xFFFFFFFFFFFFFF00
	bne		r1,r3,FAILURE
	blez		r1,FAILURE

	movi		r2,0x8000000000000000
	csrwrite	csr_timer,r2
	nop
	nop
	nop
	nop
	csrread		r1,csr_timer
	blez		r1,FAILURE		# Make sure it overflows as expected
	movi		r2,0x7fffffffffffff00
	blt		r1,r2,FAILURE		# Make sure it is very positive now

###########################################################
#
# Test other CSRs to make sure they are present and writable.
#
# The following CSRs are read-only and not tested here:
#
#   csr_version, csr_instr, csr_cycle, csr_prod, csr_core
#
#
Test_58: movi	s0,58

# csr_stat2
	movi		r2,0x1234567890abcdef
	csrwrite	csr_stat2,r2
	csrread		r3, csr_stat2
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_stat2,r2
	csrread		r3, csr_stat2
	bnei		r3,0xfedcba0987654321,FAILURE
# csr_prevpc
	movi		r2,0x1234567890abcdef
	csrwrite	csr_prevpc,r2
	csrread		r3, csr_prevpc
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_prevpc,r2
	csrread		r3, csr_prevpc
	bnei		r3,0xfedcba0987654321,FAILURE
# csr_cause
	movi		r2,0x1234567890abcdef
	csrwrite	csr_cause,r2
	csrread		r3, csr_cause
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_cause,r2
	csrread		r3, csr_cause
	bnei		r3,0xfedcba0987654321,FAILURE
# csr_bad
	movi		r2,0x1234567890abcdef
	csrwrite	csr_bad,r2
	csrread		r3, csr_bad
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_bad,r2
	csrread		r3, csr_bad
	bnei		r3,0xfedcba0987654321,FAILURE
# csr_addr
	movi		r2,0x1234567890abcdef
	csrwrite	csr_addr,r2
	csrread		r3, csr_addr
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_addr,r2
	csrread		r3, csr_addr
	bnei		r3,0xfedcba0987654321,FAILURE
# csr_ptr
	movi		r2,0x1234567890abcdef
	csrwrite	csr_ptr,r2
	csrread		r3, csr_ptr
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_ptr,r2
	csrread		r3, csr_ptr
	bnei		r3,0xfedcba0987654321,FAILURE
# csr_temp
	movi		r2,0x1234567890abcdef
	csrwrite	csr_temp,r2
	csrread		r3, csr_temp
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_temp,r2
	csrread		r3, csr_temp
	bnei		r3,0xfedcba0987654321,FAILURE
# csr_trapvec
	movi		r2,0x1234567890abcdef
	csrwrite	csr_trapvec,r2
	csrread		r3, csr_trapvec
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_trapvec,r2
	csrread		r3, csr_trapvec
	bnei		r3,0xfedcba0987654321,FAILURE
# csr_pgtable
	movi		r2,0x1234567890abcdef
	csrwrite	csr_pgtable,r2
	csrread		r3, csr_pgtable
	bnei		r3,0x1234567890abcdef,FAILURE

	movi		r2,0xfedcba0987654321
	csrwrite	csr_pgtable,r2
	csrread		r3, csr_pgtable
	bnei		r3,0xfedcba0987654321,FAILURE


# For fun, trying looping back and repeating the entire program, forever.
# This is useful for seeing how many instructions per second are executed.
# On my MAC laptop: 55 million IPS (instructions/sec)
#
#	movi		r1,0x0000000000000001
#	csrwrite	csr_status,r1
#	jump		_entry


############################################################################
############################################################################
###
###   Tests 59-64 check the following instructions. These tests are no longer included.
###
###   TLBREAD, TLBWRITE, TLBPUSH, TLBSET, TLBCLR, TLBDELETE, TLBCHECK
###
############################################################################
############################################################################


############################################################################
############################################################################
###
###   At this point, we are ready to start testing exception processing
###
############################################################################
############################################################################



###########################################################
#
# This "test" is not really a test; we are just making sure that we have no more than
# 4 pages of code.
#
Test_65: movi	s0,65

# Make sure this program fits entirely before location 0x0000_0000_0001_0000  (=4 pages)
	movi		r1,EndOfCode
	bgei		r1,0x0000_0000_0001_0000,FAILURE



###########################################################
#
# Test to see if the most basic exception processing is implemented.
#
Test_66: movi	s0,66


# ----- Test an instruction which causes an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test66_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Do the thing causing an exception
	movi		r1,0x7fffffffffffffff
Test66_Loc_1:
	addi		r1,r1,1

# Make sure all is good after the exception
	jump		FAILURE
Test66_OK_1:
	movi		r1,Test66_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test66_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr
	call		CheckCSRs


# ----- Test an instruction which causes an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test66_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Do the thing causing an exception
	movi		r1,0x8000000000000000
Test66_Loc_2:
	addi		r1,r1,-1

# Make sure all is good after the exception
	jump		FAILURE
Test66_OK_2:
	movi		r1,Test66_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test66_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr
	call		CheckCSRs



###########################################################
#
# Test: The following instructions can be executed or may cause an
# Emulation or Unaligned LOAD/STORE Exception. Determine which
# instructions are implemented and which are not. Set these variables.
#
#   Unaligned LOADs     Unaligned_Load_Is_Implemented
#   Unaligned STOREs    Unaligned_Store_Is_Implemented
#   DIV and REM         Divide_Is_Implemented
#   FADD                Floating_Is_Implemented
#   FMUL                FMUL_Is_Implemented
#   FDIV                FDIV_Is_Implemented
#   FSQRT               FSQRT_Is_Implemented
#   FCVTFI              FCVTFI_Is_Implemented
#   FCVTIF              FCVTIF_Is_Implemented
#
Test_67: movi	s0,67



# ----- Test whether an unaligned LOAD will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_1
	stored		Jump_UnalignedLoadStore,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
Test67_Loc_1:
	loadd		r1,9(r0)		# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		Unaligned_Load_Is_Implemented,r1
	jump		Test67_Done_1

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_1:
	movi		r1,Test67_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_UNALIGNED_LOAD_STORE	# r2 = expected csr_cause  (Unaligned LOAD/STORE code)
	loadw		r3,Test67_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,9			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_1:

#	movi		r1,0xee01
#	controlu	r0,r1,DIGITAL_WRITE

# ----- Test whether an unaligned STORE will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_2
	stored		Jump_UnalignedLoadStore,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
Test67_Loc_2:
	stored		9(r0),r1		# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		Unaligned_Store_Is_Implemented,r1
	jump		Test67_Done_2

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_2:
	movi		r1,Test67_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_UNALIGNED_LOAD_STORE	# r2 = expected csr_cause  (Unaligned LOAD/STORE code)
	loadw		r3,Test67_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,9			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_2:


#	movi		r1,0xee02
#	controlu	r0,r1,DIGITAL_WRITE



# ----- Test whether DIV will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_4
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
	movi		r1,1
Test67_Loc_4:
	div		r1,r0,r1		# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		Divide_Is_Implemented,r1
	jump		Test67_Done_4

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_4:
	movi		r1,Test67_Loc_4+4			# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3,Test67_Loc_4				# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0					# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_4:



# ----- Test whether FADD will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_5
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
Test67_Loc_5:
	fadd		r1,r0,r0		# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		Floating_Is_Implemented,r1
	jump		Test67_Done_5

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_5:
	movi		r1,Test67_Loc_5+4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3,Test67_Loc_5		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_5:



# ----- Test whether FMUL will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_6
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
Test67_Loc_6:
	fmul		r1,r0,r0		# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		FMUL_Is_Implemented,r1
	jump		Test67_Done_6

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_6:
	movi		r1,Test67_Loc_6+4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3,Test67_Loc_6		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_6:



# ----- Test whether FDIV will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_7
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
Test67_Loc_7:
	fdiv		r1,r0,r0		# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		FDIV_Is_Implemented,r1
	jump		Test67_Done_7

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_7:
	movi		r1,Test67_Loc_7+4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3,Test67_Loc_7		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_7:



# ----- Test whether FSQRT will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_8
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
Test67_Loc_8:
	fsqrt		r1,r0			# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		FSQRT_Is_Implemented,r1
	jump		Test67_Done_8

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_8:
	movi		r1,Test67_Loc_8+4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3,Test67_Loc_8		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_8:



# ----- Test whether FCVTFI will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_9
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
Test67_Loc_9:
	fcvtfi		r1,r0			# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		FCVTFI_Is_Implemented,r1
	jump		Test67_Done_9

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_9:
	movi		r1,Test67_Loc_9+4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3,Test67_Loc_9		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_9:



# ----- Test whether FCVTIF will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test67_OK_10
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
Test67_Loc_10:
	fcvtif		r1,r0			# The instruction

# If no exception, then make a note of it. Set to 1=TRUE
	movi		r1,1
	storeb		FCVTIF_Is_Implemented,r1
	jump		Test67_Done_10

# If an exception occurred, then leave the value as 0=FALSE.
# Also, make sure all is good after the exception
Test67_OK_10:
	movi		r1,Test67_Loc_10+4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3,Test67_Loc_10	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
Test67_Done_10:


	call		InitJumpTable


###########################################################
#
# Test MUL (no overflow testing)
#
Test_68: movi	s0,68

	movi	r1,3
	movi	r2,4
	mul	r3,r1,r2
	bnei	r3,12,FAILURE

	movi	r1,-3
	movi	r2,4
	mul	r3,r1,r2
	bnei	r3,-12,FAILURE

	movi	r1,3
	movi	r2,-4
	mul	r3,r1,r2
	bnei	r3,-12,FAILURE

	movi	r1,-3
	movi	r2,-4
	mul	r3,r1,r2
	bnei	r3,12,FAILURE

	movi	r1,0x7a345678
	movi	r2,0x3579bdf1
	mul	r3,r1,r2
	bnei	r3,0x1986f34f65d3fef8,FAILURE

	movi	r1,-0x7a345678
	movi	r2,-0x3579bdf1
	mul	r3,r1,r2
	bnei	r3,0x1986f34f65d3fef8,FAILURE

	movi	r1,-0x7a345678
	movi	r2,0x3579bdf1
	mul	r3,r1,r2
	bnei	r3,-0x1986f34f65d3fef8,FAILURE

	movi	r1,0x7a345678
	movi	r2,-0x3579bdf1
	mul	r3,r1,r2
	bnei	r3,-0x1986f34f65d3fef8,FAILURE

	movi	r1,1
	movi	r2, 0x7fffffffffffffff
	mul	r3,r1,r2
	bnei	r3, 0x7fffffffffffffff,FAILURE

	movi	r1, 0x7fffffffffffffff
	movi	r2, 1
	mul	r3,r1,r2
	bnei	r3, 0x7fffffffffffffff,FAILURE

	movi	r1, 1
	movi	r2, 0x8000000000000000
	mul	r3,r1,r2
	bnei	r3, 0x8000000000000000,FAILURE

	movi	r1, 0x8000000000000000
	movi	r2, 1
	mul	r3,r1,r2
	bnei	r3, 0x8000000000000000,FAILURE



	movi	r1, -1
	movi	r2, 0x7fffffffffffffff
	mul	r3,r1,r2
	bnei	r3, -0x7fffffffffffffff,FAILURE

	movi	r1, 0x7fffffffffffffff
	movi	r2, -1
	mul	r3,r1,r2
	bnei	r3, -0x7fffffffffffffff,FAILURE

	movi	r1, -1
	movi	r2, 0x8000000000000001
	mul	r3,r1,r2
	bnei	r3, 0x7fffffffffffffff,FAILURE

	movi	r1, 0x8000000000000001
	movi	r2, -1
	mul	r3,r1,r2
	bnei	r3, 0x7fffffffffffffff,FAILURE


	movi	r1, 0
	movi	r2, 0x7fffffffffffffff
	mul	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0x7fffffffffffffff
	movi	r2, 0
	mul	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0
	movi	r2, 0x8000000000000000
	mul	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0x8000000000000000
	movi	r2, 0
	mul	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0
	movi	r2, 0
	mul	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, -1
	movi	r2, 0
	mul	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0
	movi	r2, -1
	mul	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, -1
	movi	r2, -1
	mul	r3,r1,r2
	bnei	r3, 1,FAILURE

	movi	r1, 0x3fffffffffffffff
	movi	r2, 2
	mul	r3,r1,r2
	bnei	r3, 0x7ffffffffffffffe,FAILURE

	movi	r1, 2
	movi	r2, 0x3fffffffffffffff
	mul	r3,r1,r2
	bnei	r3, 0x7ffffffffffffffe,FAILURE


	movi	r1, -0x3fffffffffffffff
	movi	r2, 2
	mul	r3,r1,r2
	bnei	r3, -0x7ffffffffffffffe,FAILURE

	movi	r1, -2
	movi	r2, 0x3fffffffffffffff
	mul	r3,r1,r2
	bnei	r3, -0x7ffffffffffffffe,FAILURE

	movi	r1, -0x4000000000000000
	movi	r2, 2
	mul	r3,r1,r2
	bnei	r3, 0x8000000000000000,FAILURE

	movi	r1, -2
	movi	r2, 0x4000000000000000
	mul	r3,r1,r2
	bnei	r3, 0x8000000000000000,FAILURE


	movi	r1, 0x3fffffffffffffff
	movi	r2, -2
	mul	r3,r1,r2
	bnei	r3, -0x7ffffffffffffffe,FAILURE

	movi	r1, 2
	movi	r2, -0x3fffffffffffffff
	mul	r3,r1,r2
	bnei	r3, -0x7ffffffffffffffe,FAILURE

	movi	r1, 0x4000000000000000
	movi	r2, -2
	mul	r3,r1,r2
	bnei	r3, 0x8000000000000000,FAILURE

	movi	r1, 2
	movi	r2, -0x4000000000000000
	mul	r3,r1,r2
	bnei	r3, 0x8000000000000000,FAILURE


###########################################################
#
# Test DIV and REM to make sure we implement truncated division.
#
Test_69: movi	s0,69

# If DIV is emulated, then skip this test
	loadb	r1,Divide_Is_Implemented
	beqz	r1,Test_69_Skip

#####  Basic test of DIV - positive values

	movi	r1,7
	movi	r2,3
	div	r3,r1,r2
	bnei	r3,2,FAILURE

	movi	r1,0x1101
	controlu	r1,r1,DIGITAL_WRITE

	movi	r1,123123123
	movi	r2,10
	div	r3,r1,r2
	bnei	r3,12312312,FAILURE

	movi	r1,0x1102
	controlu	r1,r1,DIGITAL_WRITE

	movi	r1,0x7fff_ffff_ffff_ffff
	movi	r2,1
	div	r3,r1,r2
	bnei	r3,0x7fff_ffff_ffff_ffff,FAILURE

	movi	r1,0x1103
	controlu	r1,r1,DIGITAL_WRITE

	movi	r1,0x7fff_ffff_ffff_ffff
	movi	r2,0x7fff_ffff_ffff_ffff
	div	r3,r1,r2
	bnei	r3,1,FAILURE

	movi	r1,0x1104
	controlu	r1,r1,DIGITAL_WRITE



#####  Basic test of DIV - negative values

	movi	r1,-7
	movi	r2,3
	div	r3,r1,r2
	bnei	r3,-2,FAILURE

	movi	r1,0x1106
	controlu	r1,r1,DIGITAL_WRITE

	movi	r1,7
	movi	r2,-3
	div	r3,r1,r2
	bnei	r3,-2,FAILURE

	movi	r1,0x1107
	controlu	r1,r1,DIGITAL_WRITE

	movi	r1,-7
	movi	r2,-3
	div	r3,r1,r2
	bnei	r3,2,FAILURE

	movi	r1,0x1108
	controlu	r1,r1,DIGITAL_WRITE


#####  Basic test of REM - positive values

	movi	r1,7
	movi	r2,3
	rem	r3,r1,r2
	bnei	r3,1,FAILURE

	movi	r1,0x1201
	controlu	r1,r1,DIGITAL_WRITE

	movi	r1,123123123
	movi	r2,10
	rem	r3,r1,r2
	bnei	r3,3,FAILURE

	movi	r1,0x1202
	controlu	r1,r1,DIGITAL_WRITE

	movi	r1,0x7fff_ffff_ffff_ffff
	movi	r2,1
	rem	r3,r1,r2
	bnei	r3,0,FAILURE

	movi	r1,0x1203
	controlu	r1,r1,DIGITAL_WRITE

	movi	r1,0x7fff_ffff_ffff_ffff
	movi	r2,0x7000_0000_0000_0000
	rem	r3,r1,r2
	bnei	r3,0x0fff_ffff_ffff_ffff,FAILURE

	movi	r1,0x1204
	controlu	r1,r1,DIGITAL_WRITE


#####  Basic test of REM - negative values

	movi	r1,-7
	movi	r2,3
	rem	r3,r1,r2
	bnei	r3,-1,FAILURE

	movi	r1,7
	movi	r2,-3
	rem	r3,r1,r2
	bnei	r3,1,FAILURE

	movi	r1,-7
	movi	r2,-3
	rem	r3,r1,r2
	bnei	r3,-1,FAILURE

	movi	r1,0x2222
	controlu	r1,r1,DIGITAL_WRITE

Test_69_Skip:


###########################################################
#
# Test DIV and REM (no overflow testing)
#
Test_70: movi	s0,70


# If DIV is emulated, then skip this test
	loadb	r1,Divide_Is_Implemented
	beqz	r1,Test_70_Skip

	movi	r1,12
	movi	r2,3

	div	r3,r1,r2
	bnei	r3,4,FAILURE
	rem	r3,r1,r2
	bnei	r3,0,FAILURE

	movi	r1,-12
	movi	r2,3

	div	r3,r1,r2
	bnei	r3,-4,FAILURE
	rem	r3,r1,r2
	bnei	r3,0,FAILURE

	movi	r1,12
	movi	r2,-3

	div	r3,r1,r2
	bnei	r3,-4,FAILURE
	rem	r3,r1,r2
	bnei	r3,0,FAILURE

	movi	r1,-12
	movi	r2,-3

	div	r3,r1,r2
	bnei	r3,4,FAILURE
	rem	r3,r1,r2
	bnei	r3,0,FAILURE


	movi	r1, 0x7fffffffffffffff
	movi	r2, 1

	div	r3,r1,r2
	bnei	r3, 0x7fffffffffffffff,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0x8000000000000000
	movi	r2, 1

	div	r3,r1,r2
	bnei	r3, 0x8000000000000000,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0
	movi	r2, 1

	div	r3,r1,r2
	bnei	r3, 0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0x567812349abcdef0
	movi	r2, 1

	div	r3,r1,r2
	bnei	r3, 0x567812349abcdef0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0x9abcdef056781234
	movi	r2, 1

	div	r3,r1,r2
	bnei	r3, 0x9abcdef056781234,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE
#
	movi	r1, 0x1986f34f65d3fef8
	movi	r2, 0x7a345678

	div	r3,r1,r2
	bnei	r3, 0x3579bdf1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, -0x1986f34f65d3fef8
	movi	r2, 0x7a345678

	div	r3,r1,r2
	bnei	r3, -0x3579bdf1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 0x1986f34f65d3fef8
	movi	r2, -0x7a345678

	div	r3,r1,r2
	bnei	r3, -0x3579bdf1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, -0x1986f34f65d3fef8
	movi	r2, -0x7a345678

	div	r3,r1,r2
	bnei	r3, 0x3579bdf1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE
#
	movi	r1, 0x1986f34f65d3fef7
	movi	r2, 0x7a345678

	div	r3,r1,r2
	bnei	r3, 0x3579bdf0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0x7a345677,FAILURE

	movi	r1, -0x1986f34f65d3fef7
	movi	r2, 0x7a345678

	div	r3,r1,r2
	bnei	r3, -0x3579bdf0,FAILURE		# 3 instructions
	rem	r3,r1,r2
	bnei	r3, -0x7a345677,FAILURE		# 3 instructions

	movi	r1, 0x1986f34f65d3fef7
	movi	r2, -0x7a345678

	div	r3,r1,r2
	bnei	r3, -0x3579bdf0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0x7a345677,FAILURE

	movi	r1, -0x1986f34f65d3fef7
	movi	r2, -0x7a345678

	div	r3,r1,r2
	bnei	r3, 0x3579bdf0,FAILURE		# 3 instructions
	rem	r3,r1,r2
	bnei	r3, -0x7a345677,FAILURE 	# 3 instructions

#
	movi	r1, 0
	movi	r2, 3

	div	r3,r1,r2
	bnei	r3, 0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 1
	movi	r2, 3

	div	r3,r1,r2
	bnei	r3, 0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 1,FAILURE

	movi	r1, 2
	movi	r2, 3

	div	r3,r1,r2
	bnei	r3, 0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 2,FAILURE

	movi	r1, 3
	movi	r2, 3

	div	r3,r1,r2
	bnei	r3, 1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 4
	movi	r2, 3

	div	r3,r1,r2
	bnei	r3, 1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 1,FAILURE

	movi	r1, 5
	movi	r2, 3

	div	r3,r1,r2
	bnei	r3, 1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 2,FAILURE

	movi	r1, 6
	movi	r2, 3

	div	r3,r1,r2
	bnei	r3, 2,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 7
	movi	r2, 3

	div	r3,r1,r2
	bnei	r3, 2,FAILURE
	rem	r3,r1,r2
	bnei	r3, 1,FAILURE
#
	movi	r1, 0
	movi	r2, -3

	div	r3,r1,r2
	bnei	r3, 0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 1
	movi	r2, -3

	div	r3,r1,r2
	bnei	r3, 0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 1,FAILURE

	movi	r1, 2
	movi	r2, -3

	div	r3,r1,r2
	bnei	r3, 0,FAILURE
	rem	r3,r1,r2
	bnei	r3, 2,FAILURE

	movi	r1, 3
	movi	r2, -3

	div	r3,r1,r2
	bnei	r3, -1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 4
	movi	r2, -3

	div	r3,r1,r2
	bnei	r3, -1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 1,FAILURE

	movi	r1, 5
	movi	r2, -3

	div	r3,r1,r2
	bnei	r3, -1,FAILURE
	rem	r3,r1,r2
	bnei	r3, 2,FAILURE

	movi	r1, 6
	movi	r2, -3

	div	r3,r1,r2
	bnei	r3, -2,FAILURE
	rem	r3,r1,r2
	bnei	r3, 0,FAILURE

	movi	r1, 7
	movi	r2, -3

	div	r3,r1,r2
	bnei	r3, -2,FAILURE
	rem	r3,r1,r2
	bnei	r3, 1,FAILURE

Test_70_Skip:

###########################################################
#
# Test ADD - with overflow
#
Test_71: movi	s0,71

	jump	Test71_begin

	.align		8
Test71_Testdata:

	.doubleword	0x7fffffffffffffff
	.doubleword	0x0000000000000001

	.doubleword	0x8000000000000000
	.doubleword	0xffffffffffffffff

	.doubleword	0x7fffffffffffffff
	.doubleword	0x7fffffffffffffff

	.doubleword	0x8000000000000000
	.doubleword	0x8000000000000000

	.doubleword	0x1234567890abcdef
	.doubleword	0x6dcca9876f543210

	.doubleword	0x7ffffffffffffffd
	.doubleword	0x0000000000000003

Test71_count:	.equ	6

Test71_begin:

# LOOP: Each iteration does one test.
	movi		r6,Test71_Testdata
	movi		r7,Test71_count
Test71_loop:


# ----- Test that ADD with overflow will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test71_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...

#Grab the next pair of arguments to test.
	loadd		r1,0(r6)
	loadd		r2,8(r6)
	addi		r6,r6,16
#	debug

Test71_Loc_1:
	add		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test71_OK_1:
	movi		r1,Test71_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test71_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

# decrement counter and repeat loop
	addi		r7,r7,-1
	bnez		r7,Test71_loop


##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test71_OK_7
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
	movi		r1,0x8000000000000000
	movi		r2,-1
Test71_Loc_7:
	add		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test71_OK_7:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test71_Loc_7		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2, TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test71_Loc_7		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop


	call		InitJumpTable


###########################################################
#
# Test SUB - with overflow
#
Test_72: movi	s0,72
	jump	Test72_begin

	.align		8

Test72_Testdata:

	.doubleword	0x7fffffffffffffff
	.doubleword	0xffffffffffffffff

	.doubleword	0x8000000000000000
	.doubleword	0x0000000000000001

	.doubleword	0x7fffffffffffffff
	.doubleword	0xffffffffffffffff

	.doubleword	0x8000000000000000
	.doubleword	0x0000000000000001

	.doubleword	0x7ffffffffffffffd
	.doubleword	0xffffFFFFFFFFFFFD

	.doubleword	0x3fffffffffff1234
	.doubleword	0xbfffffffffff1234

Test72_count:	.equ	6

Test72_begin:

# LOOP: Each iteration does one test.
	movi		r6,Test72_Testdata
	movi		r7,Test72_count
Test72_loop:

# ----- Test that SUB with overflow will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test72_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...

#Grab the next pair of arguments to test.
	loadd		r1,0(r6)
	loadd		r2,8(r6)
	addi		r6,r6,16
#	debug

Test72_Loc_1:
	sub		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test72_OK_1:
	movi		r1,Test72_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test72_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

# decrement counter and repeat loop
	addi		r7,r7,-1
	bnez		r7,Test72_loop



##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test72_OK_7
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
	movi		r1,0x7fffffffffffffff
	movi		r2,-1

Test72_Loc_7:
	sub		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test72_OK_7:


# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test72_Loc_7		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2, TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test72_Loc_7		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop					# To maintain doubleword alignment of instructions


	call		InitJumpTable

###########################################################
#
# Test ADDI - with overflow
#
Test_73: movi	s0,73


# ----- Test that ADDI with overflow will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test73_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
	movi		r1,0x7fffffffffffffff

Test73_Loc_1:
	addi		r3,r1,1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test73_OK_1:
	movi		r1,Test73_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test73_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# ----- Test that ADDI with overflow will cause an exception -----
#
# Setup before the exception
	call		InitJumpTable
	movi		r1,Test73_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction, which may cause an exception...
	movi		r1,0x8000000000000000

Test73_Loc_2:
	addi		r3,r1,-1		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test73_OK_2:
	movi		r1,Test73_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test73_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test73_OK_7
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
	movi		r1,0x7fffffffffffffff

Test73_Loc_7:
	addi		r3,r1,1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test73_OK_7:


# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test73_Loc_7		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test73_Loc_7		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop					# To maintain doubleword alignment of instructions


	call		InitJumpTable

###########################################################
#
# Test SLA - with overflow
#
Test_74: movi	s0,74



#####    8000000000000000  <<<  1

# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x8000000000000000
	movi		r2,1

Test74_Loc_1:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_1:
	movi		r1,Test74_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    7fffffffffffffff  <<<  1


# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x7fffffffffffffff
	movi		r2,1

Test74_Loc_2:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_2:
	movi		r1,Test74_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    f000000000000000  <<<  4


# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_3
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0xf000000000000000
	movi		r2,4

Test74_Loc_3:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_3:
	movi		r1,Test74_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    4000000000000000  <<<  2


# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_4
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x4000000000000000
	movi		r2,2

Test74_Loc_4:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_4:
	movi		r1,Test74_Loc_4		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_4		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    0000000000000000  <<<  64


# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_5
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0
	movi		r2,64

Test74_Loc_5:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_5:
	movi		r1,Test74_Loc_5		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_5		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    0000000000000000  <<<  -1


# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_6
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0
	movi		r2,-1

Test74_Loc_6:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_6:
	movi		r1,Test74_Loc_6		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_6		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    0000000000000001  <<<  63


# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_7
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x0000000000000001
	movi		r2,63

Test74_Loc_7:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_7:
	movi		r1,Test74_Loc_7		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_7		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    fffffffffffffffe  <<<  63


# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_8
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0xfffffffffffffffe
	movi		r2,63

Test74_Loc_8:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_8:
	movi		r1,Test74_Loc_8		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_8		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs





##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test74_OK_9
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
	movi		r1,0xfffffffffffffffe
	movi		r2,63

Test74_Loc_9:
	sla		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test74_OK_9:


# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test74_Loc_9		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test74_Loc_9		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop					# To maintain doubleword alignment of instructions


	call		InitJumpTable

###########################################################
#
# Test SLAI - with overflow
#
Test_75: movi	s0,75


#####    0x8000000000000000  <<<  1

# Setup
	call		InitJumpTable
	movi		r1,Test75_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1, 0x8000000000000000

Test75_Loc_1:
	slai		r3,r1,1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test75_OK_1:
	movi		r1,Test75_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test75_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#####    0x7fffffffffffffff  <<<  1

# Setup
	call		InitJumpTable
	movi		r1,Test75_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1, 0x7fffffffffffffff

Test75_Loc_2:
	slai		r3,r1,1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test75_OK_2:
	movi		r1,Test75_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test75_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    0xf000000000000000  <<<  4

# Setup
	call		InitJumpTable
	movi		r1,Test75_OK_3
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1, 0xf000000000000000
Test75_Loc_3:
	slai		r3,r1,4			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test75_OK_3:
	movi		r1,Test75_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test75_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    0x4000000000000000  <<<  2

# Setup
	call		InitJumpTable
	movi		r1,Test75_OK_4
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1, 0x4000000000000000

Test75_Loc_4:
	slai		r3,r1,2			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test75_OK_4:
	movi		r1,Test75_Loc_4		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test75_Loc_4		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    0x0000000000000001  <<<  63

# Setup
	call		InitJumpTable
	movi		r1,Test75_OK_5
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1, 0x0000000000000001

Test75_Loc_5:
	slai		r3,r1,63		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test75_OK_5:
	movi		r1,Test75_Loc_5		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test75_Loc_5		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#####    0xfffffffffffffffe  <<<  63

# Setup
	call		InitJumpTable
	movi		r1,Test75_OK_6
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1, 0xfffffffffffffffe

Test75_Loc_6:
	slai		r3,r1,63		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test75_OK_6:
	movi		r1,Test75_Loc_6		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test75_Loc_6		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



	call		InitJumpTable

###########################################################
#
# Test SRA - with overflow
#
Test_76: movi	s0,76


##### Check 0x0 >>> 64

# Setup
	call		InitJumpTable
	movi		r1,Test76_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0
	movi		r2,64

Test76_Loc_1:
	sra		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test76_OK_1:
	movi		r1,Test76_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test76_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check 0x0 >>> -1

# Setup
	call		InitJumpTable
	movi		r1,Test76_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0
	movi		r2,-1

Test76_Loc_2:
	sra		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test76_OK_2:
	movi		r1,Test76_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test76_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


	call		InitJumpTable

###########################################################
#
# Test SLL - with overflow
#
Test_77: movi	s0,77


##### Check 0x0 << 64

# Setup
	call		InitJumpTable
	movi		r1,Test77_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0
	movi		r2,64

Test77_Loc_1:
	sll		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test77_OK_1:
	movi		r1,Test77_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test77_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check 0x0 << -1

# Setup
	call		InitJumpTable
	movi		r1,Test77_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0
	movi		r2,-1

Test77_Loc_2:
	sll		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test77_OK_2:
	movi		r1,Test77_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test77_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



	call		InitJumpTable

###########################################################
#
# Test SRL - with overflow
#
Test_78: movi	s0,78


##### Check 0x0 >> 64

# Setup
	call		InitJumpTable
	movi		r1,Test78_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0
	movi		r2,64

Test78_Loc_1:
	srl		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test78_OK_1:
	movi		r1,Test78_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test78_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check 0x0 >> 0x8000000000000003

# Setup
	call		InitJumpTable
	movi		r1,Test78_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0
	movi		r2,0xfffffffffffffff3

Test78_Loc_2:
	srl		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test78_OK_2:
	movi		r1,Test78_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test78_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

	call		InitJumpTable

###########################################################
#
# Test CHECKB
#
Test_79: movi	s0,79

# Try some values that do not cause exceptions

	call		InitJumpTable
	movi		r1,0x7f
	checkb		r1
	movi		r1,0xffffffffffffff80
	checkb		r1
	movi		r1,0
	checkb		r1
	movi		r1,-1
	checkb		r1



##### Check 0x0000000000000080

# Setup
	call		InitJumpTable
	movi		r1,Test79_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x0000000000000080

Test79_Loc_1:
	checkb		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test79_OK_1:
	movi		r1,Test79_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test79_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check 0xffffffffffffff7f

# Setup
	call		InitJumpTable
	movi		r1,Test79_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0xffffffffffffff7f

Test79_Loc_2:
	checkb		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test79_OK_2:
	movi		r1,Test79_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test79_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check 0x0001000000000000

# Setup
	call		InitJumpTable
	movi		r1,Test79_OK_3
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x0001000000000000

Test79_Loc_3:
	checkb		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test79_OK_3:
	movi		r1,Test79_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test79_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs





##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test79_OK_9
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
	movi		r1,0x0001000000000000

Test79_Loc_9:
	checkb		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test79_OK_9:


# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test79_Loc_9		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test79_Loc_9		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop					# To maintain doubleword alignment of instructions


	call		InitJumpTable



###########################################################
#
# Test CHECKH
#
Test_80: movi	s0,80

# Try some values that do not cause exceptions

	call		InitJumpTable
	movi		r1,0x7fff
	checkh		r1
	movi		r1,0xffffffffffff8000
	checkh		r1
	movi		r1,0
	checkh		r1
	movi		r1,-1
	checkh		r1



##### Check 0x0000000000008000

# Setup
	call		InitJumpTable
	movi		r1,Test80_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x0000000000008000

Test80_Loc_1:
	checkh		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test80_OK_1:
	movi		r1,Test80_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test80_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check 0xffffffffffff7fff

# Setup
	call		InitJumpTable
	movi		r1,Test80_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0xffffffffffff7fff

Test80_Loc_2:
	checkh		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test80_OK_2:
	movi		r1,Test80_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test80_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check 0x0001000000000000

# Setup
	call		InitJumpTable
	movi		r1,Test80_OK_3
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x0001000000000000

Test80_Loc_3:
	checkh		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test80_OK_3:
	movi		r1,Test80_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test80_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


	call		InitJumpTable

###########################################################
#
# Test CHECKW
#
Test_81: movi	s0,81

# Try some values that do not cause exceptions

	call		InitJumpTable
	movi		r1,0x7fffffff
	checkw		r1
	movi		r1,0xffffffff80000000
	checkw		r1
	movi		r1,0
	checkw		r1
	movi		r1,-1
	checkw		r1



##### Check 0x0000,0000,8000,0000

# Setup
	call		InitJumpTable
	movi		r1,Test81_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x0000000080000000

Test81_Loc_1:
	checkw		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test81_OK_1:
	movi		r1,Test81_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test81_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check 0xffff,ffff,7fff,ffff

# Setup
	call		InitJumpTable
	movi		r1,Test81_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0xffffffff7fffffff

Test81_Loc_2:
	checkw		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test81_OK_2:
	movi		r1,Test81_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test81_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check 0x0001000000000000

# Setup
	call		InitJumpTable
	movi		r1,Test81_OK_3
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x0001000000000000

Test81_Loc_3:
	checkw		r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test81_OK_3:
	movi		r1,Test81_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test81_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


	call		InitJumpTable



###########################################################
#
# Test MUL - with overflow
#
Test_82: movi	s0,82

	call		InitJumpTable
	movi		r1,5
	movi		r2,25
	mul		r3,r1,r2
	bnei		r3,125,FAILURE


##### Check BIG_POS * 2

# Setup
	call		InitJumpTable
	movi		r1,Test82_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x7fffffffffffffff
	movi		r2,2			# result is 0xFFFF,FFFF,FFFF,FFFE

Test82_Loc_1:
	mul		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test82_OK_1:
	movi		r1,Test82_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test82_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check positive overflow where result is also positive

# Setup
	call		InitJumpTable
	movi		r1,Test82_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x4000000000000001
	movi		r2,0x4			# Result is 0x1,0000,0000,0000,0004

Test82_Loc_2:
	mul		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test82_OK_2:
	movi		r1,Test82_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test82_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check MAX_NEG * -1

# Setup
	call		InitJumpTable
	movi		r1,Test82_OK_3
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x8000000000000000
	movi		r2,-1

Test82_Loc_3:
	mul		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test82_OK_3:
	movi		r1,Test82_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test82_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check -1 * MAX_NEG

# Setup
	call		InitJumpTable
	movi		r1,Test82_OK_4
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,-1
	movi		r2,0x8000000000000000

Test82_Loc_4:
	mul		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test82_OK_4:
	movi		r1,Test82_Loc_4		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test82_Loc_4		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check 2 * BIG_POS

# Setup
	call		InitJumpTable
	movi		r1,Test82_OK_5
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,2
	movi		r2,0x7fffffffffffffff

Test82_Loc_5:
	mul		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test82_OK_5:
	movi		r1,Test82_Loc_5		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test82_Loc_5		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check neg * neg where result is negative

# Setup
	call		InitJumpTable
	movi		r1,Test82_OK_6
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,-0x4
	movi		r2,0x8fffffffffffffff
						# Result is -0x2,3FFF,FFFF,FFFF,FFFC
						# Result is  0xD,C000,0000,0000,0004

Test82_Loc_6:
	mul		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test82_OK_6:
	movi		r1,Test82_Loc_6		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test82_Loc_6		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test82_OK_7
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
	movi		r1,0x8000000000000000
	movi		r2,-1

Test82_Loc_7:
	mul		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test82_OK_7:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test82_Loc_7		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test82_Loc_7		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


###########################################################
#
# Test DIV & REM with overflow
#
Test_83: movi	s0,83

# If DIV is emulated, then skip this test
	loadb	r1,Divide_Is_Implemented
	beqz	r1,Test_83_Skip



##### Check that divide-by -zero causes an exception.

# Setup
	call		InitJumpTable
	movi		r1,Test83_OK_1
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,123
	movi		r2,0

Test83_Loc_1:
	div		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test83_OK_1:
	movi		r1,Test83_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test83_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



##### Check that divide-by-zero for REM causes an exception.

# Setup
	call		InitJumpTable
	movi		r1,Test83_OK_2
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,123
	movi		r2,0

Test83_Loc_2:
	rem		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test83_OK_2:
	movi		r1,Test83_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test83_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### Check that MAX_NEG / -1 causes an exception.

# Setup
	call		InitJumpTable
	movi		r1,Test83_OK_3
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x8000000000000000
	movi		r2,-1

Test83_Loc_3:
	div		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test83_OK_3:
	movi		r1,Test83_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test83_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



##### Check that MAX_NEG / -1 for REM causes an exception.

# Setup
	call		InitJumpTable
	movi		r1,Test83_OK_4
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0x8000000000000000
	movi		r2,-1

Test83_Loc_4:
	rem		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test83_OK_4:
	movi		r1,Test83_Loc_4		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test83_Loc_4		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test83_OK_7
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
	movi		r1,123
	movi		r2,0

Test83_Loc_7:
	div		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test83_OK_7:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test83_Loc_7		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test83_Loc_7		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check that with interrupts disabled, it works the same way.
#####    MAX_NEW/-1 for REM

# Setup
	call		InitJumpTable
	movi		r1,Test83_OK_8
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
	movi		r1,0x8000000000000000
	movi		r2,-1

Test83_Loc_8:
	rem		r3,r1,r2		# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test83_OK_8:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test83_Loc_8		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test83_Loc_8		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

	call		InitJumpTable


Test_83_Skip:

###########################################################
#
# Test - Check that these assumptions are correct:
#
# We assume that if Floating_Is_Implemented is true, then the following
# instructions are all implemented, and if not, then they are all emulated:
#   FADD  (This instruction was used to set Floating_Is_Implemented)
#   FSUB
#   FMIN
#   FMAX
#   FNEG
#   FABS
#   FEQ
#   FLT
#   FLE
#
# We assume that if FMUL_Is_Implemented is true, then the following
# instructions are all implemented, and if not, then they are all emulated:
#   FMUL  (This instruction was used to set FMUL_Is_Implemented)
#   FMADD
#   FNMADD
#   FMSUB
#   FNMSUB
#
# We assume that the following instructions may or may not be implemented,
# but this is independent of the others, so we don't check them here.
#   FDIV        FDIV_Is_Implemented
#   FSQRT       FSQRT_Is_Implemented
#   FCVTFI      FCVTFI_Is_Implemented
#   FCVTIF      FCVTIF_Is_Implemented
#
# If the instruction is emulated, then we verify that it will cause an
# Emulation Exception if executed with interrupts enabled and that it will
# also work properly if executed when interrupts are disabled.
#
Test_84: movi	s0,84
	call	InitJumpTable

# If Floating_Is_Implemented...

	loadb	r1,Floating_Is_Implemented
	beqz	r1,Test_84_FADD_emul

# Make sure these instructions do not cause exceptions.
# Use r0 = +0.0 as an operand.
	call	InitJumpTable
	fsub	r7,r0,r0		# r7 = r0 - r0 = 0.0 - 0.0
	fmin	r7,r0,r0		# r7 = MIN (0.0, 0.0)
	fmax	r7,r0,r0		# r7 = MAX (0.0, 0.0)
	fneg	r7,r0			# r7 = -0.0
	fabs	r7,r0			# r7 = +0.0
	feq	r7,r0,r0		# r7 = (Reg1 == Reg2) ? 1 : 0
	flt	r7,r0,r0		# r7 = (Reg1 <  Reg2) ? 1 : 0
	fle	r7,r0,r0		# r7 = (Reg1 <= Reg2) ? 1 : 0
#	fclass	r7,r0			# r7 = classify(Reg1) || FLOAT_STATUS	

	jump	Test84_FADD_done
Test_84_FADD_emul:

# If Floating_Is_Implemented == FALSE...


#################  Check that FSUB causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_1
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_1:
	fsub		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_1:
	movi		r1, Test84_Loc_1 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_1	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_1
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_1:
	fsub		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_1:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_1 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_1	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FMIN causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_2
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_2:
	fmin		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_2:
	movi		r1, Test84_Loc_2 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_2	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_2
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_2:
	fmin		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_2:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_2 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_2	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FMAX causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_3
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_3:
	fmax		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_3:
	movi		r1, Test84_Loc_3 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_3	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_3
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_3:
	fmax		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_3:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_3 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_3	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FNEG causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_4
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_4:
	fneg		r7,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_4:
	movi		r1, Test84_Loc_4 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_4	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_4
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_4:
	fneg		r7,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_4:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_4 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_4	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FABS causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_5
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_5:
	fabs		r7,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_5:
	movi		r1, Test84_Loc_5 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_5	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_5
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_5:
	fabs		r7,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_5:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_5 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_5	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FEQ causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_6
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_6:
	feq		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_6:
	movi		r1, Test84_Loc_6 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_6	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_6
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_6:
	feq		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_6:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_6 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_6	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FLT causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_7
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_7:
	flt		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_7:
	movi		r1, Test84_Loc_7 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_7	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_7
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_7:
	flt		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_7:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_7 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_7	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FLE causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_8
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_8:
	fle		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_8:
	movi		r1, Test84_Loc_8 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_8	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_8
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_8:
	fle		r7,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_8:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_8 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_8	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

###  #################  Check that FCLASS causes an emulation exception...
###  
###  # Setup
###  	call		InitJumpTable
###  	movi		r1,Test84_OK_9
###  	stored		Jump_EmulatedInstruction,r1
###  	call		InitCSRs
###  
###  # Perform the instruction
###  Test84_Loc_9:
###  	fclass		r7,r0
###  	jump		FAILURE
###  
###  # Make sure all is good after the exception
###  Test84_OK_9:
###  	movi		r1, Test84_Loc_9 +4	# r1 = expected csr_prevpc (Addr after the instruction)
###  	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
###  	loadw		r3, Test84_Loc_9	# r3 = expected csr_bad    (The offending instruction)
###  	movi		r4,0			# r4 = expected csr_addr   (The bad address)
###  	call		CheckCSRs
###  
###  ##### Check that with interrupts disabled, it works the same way.
###  
###  # Setup
###  	call		InitJumpTable
###  	movi		r1,Test84_OKb_9
###  	stored		Jump_EmulatedInstruction,r1
###  	call		InitCSRs
###  
###  	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
###  	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1
###  
###  # Perform the instruction
###  Test84_Loc_B_9:
###  	fclass		r7,r0
###  	jump		FAILURE
###  
###  # Make sure all is good after the exception
###  Test84_OKb_9:
###  
###  # Check csr_stat2
###  	csrread		r5,csr_stat2
###  	bnei		r5,0x00000000000001A9,FAILURE
###  # Store value into it so CheckCSRs will not fail.
###  	movi		r5,0x00000000000001AB
###  	csrwrite	csr_stat2,r5
###  
###  	movi		r1, Test84_Loc_B_9 +4	# r1 = expected csr_prevpc (Addr after the instruction)
###  	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
###  	loadw		r3, Test84_Loc_B_9	# r3 = expected csr_bad    (The offending instruction)
###  	movi		r4,0			# r4 = expected csr_addr   (The bad address)
###  	call		CheckCSRs



Test84_FADD_done:



# If FMUL_Is_Implemented...
	loadb	r1, FMUL_Is_Implemented
	beqz	r1,Test_84_FMUL_emul

# Make sure these instructions do not cause exceptions.
	call	InitJumpTable
	fmadd	r7,r0,r0,r0		# r7 = (Reg1 × Reg2) + Reg3
	fnmadd	r7,r0,r0,r0		# r7 = (-(Reg1 × Reg2)) + Reg3
	fmsub	r7,r0,r0,r0		# r7 = (Reg1 × Reg2) - Reg3
	fnmsub	r7,r0,r0,r0		# r7 = (-(Reg1 × Reg2)) - Reg3

	jump	Test84_FMUL_done

# If FMUL is emulated...
Test_84_FMUL_emul:



#################  Check that FMADD causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_10
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_10:
	fmadd		r7,r0,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_10:
	movi		r1, Test84_Loc_10 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_10	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_10
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_10:
	fmadd		r7,r0,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_10:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_10 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_10	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


#################  Check that FNMADD causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_11
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_11:
	fnmadd		r7,r0,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_11:
	movi		r1, Test84_Loc_11 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_11	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_11
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_11:
	fnmadd		r7,r0,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_11:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_11 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_11	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FMSUB causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_12
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_12:
	fmsub		r7,r0,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_12:
	movi		r1, Test84_Loc_12 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_12	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_12
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_12:
	fmsub		r7,r0,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_12:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_12 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_12	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

#################  Check that FNMSUB causes an emulation exception...

# Setup
	call		InitJumpTable
	movi		r1,Test84_OK_13
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

# Perform the instruction
Test84_Loc_13:
	fnmsub		r7,r0,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OK_13:
	movi		r1, Test84_Loc_13 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_13	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Check that with interrupts disabled, it works the same way.

# Setup
	call		InitJumpTable
	movi		r1,Test84_OKb_13
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs

	movi		r1,0x00000000000001A9	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Perform the instruction
Test84_Loc_B_13:
	fnmsub		r7,r0,r0,r0
	jump		FAILURE

# Make sure all is good after the exception
Test84_OKb_13:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test84_Loc_B_13 +4	# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, Test84_Loc_B_13	# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


Test84_FMUL_done:

	call		InitJumpTable


###########################################################
#
# Test - Basic tests of:
#
#   FADD
#   FSUB
#   FMIN
#   FMAX
#   FNEG
#   FABS
#   FEQ
#   FLT
#   FLE
#
# NOT TESTED: NaN, +inf, -inf
# NOT TESTED: Overflow, rounding

Test_85: movi	s0,85




# If these instructions are emulated, then skip this test

	loadb	r1,Floating_Is_Implemented
	beqz	r1,Test_85_skip

# We do not expect any exceptions
	call		InitJumpTable
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

#########################  test FADD

# Basic test of FADD
	loadd	r1,three
	loadd	r2,four
	fadd	r3,r1,r2
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FADD
	loadd	r1,three
	loadd	r2,zero
	fadd	r3,r1,r2
	loadd	r4,three
	bne	r3,r4,FAILURE

# Basic test of FADD
	loadd	r1,three
	loadd	r2,neg_zero
	fadd	r3,r1,r2
	loadd	r4,three
	bne	r3,r4,FAILURE

# Basic test of FADD
	loadd	r1,zero
	loadd	r2,zero
	fadd	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FADD
	loadd	r1,zero
	loadd	r2,neg_zero
	fadd	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FADD
	loadd	r1,neg_zero
	loadd	r2,zero
	fadd	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FADD
	loadd	r1,neg_zero
	loadd	r2,neg_zero
	fadd	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE


#########################  test FSUB

# Basic test of FSUB...  7.0 - 4.0 = 12.0
	loadd	r1,seven
	loadd	r2,four
	fsub	r3,r1,r2
	loadd	r4,three
	bne	r3,r4,FAILURE

# Basic test of FSUB...  7.0 - +0.0 = 7.0
	loadd	r1,seven
	loadd	r2,zero
	fsub	r3,r1,r2
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FSUB...  7.0 - -0.0 = 7.0
	loadd	r1,seven
	loadd	r2,neg_zero
	fsub	r3,r1,r2
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FSUB...  +0.0 - +0.0 = +0.0
	loadd	r1,zero
	loadd	r2,zero
	fsub	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FSUB...  -0.0 - +0.0 = -0.0
	loadd	r1,neg_zero
	loadd	r2,zero
	fsub	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

# Basic test of FSUB...  -0.0 - -0.0 = +0.0
	loadd	r1,neg_zero
	loadd	r2,neg_zero
	fsub	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE


#########################  test FMIN

# Basic test of FMIN
	loadd	r1,seven
	loadd	r2,four
	fmin	r3,r1,r2
	loadd	r4,four
	bne	r3,r4,FAILURE

# Basic test of FMIN
	loadd	r1,four
	loadd	r2,seven
	fmin	r3,r1,r2
	loadd	r4,four
	bne	r3,r4,FAILURE

# Basic test of FMIN
	loadd	r1,neg_seven
	loadd	r2,neg_four
	fmin	r3,r1,r2
	loadd	r4, neg_seven
	bne	r3,r4,FAILURE

# Basic test of FMIN
	loadd	r1,neg_four
	loadd	r2,neg_seven
	fmin	r3,r1,r2
	loadd	r4, neg_seven
	bne	r3,r4,FAILURE

# Basic test of FMIN
	loadd	r1,four
	loadd	r2,four
	fmin	r3,r1,r2
	loadd	r4,four
	bne	r3,r4,FAILURE

# Basic test of FMIN
	loadd	r1,zero
	loadd	r2,zero
	fmin	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FMIN
	loadd	r1,neg_zero	# What is FMIN (+0.0, -0.0)? This test looks for -0.0.
	loadd	r2,zero
	fmin	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

# Basic test of FMIN
	loadd	r1,zero
	loadd	r2,neg_zero
	fmin	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

# Basic test of FMIN
	loadd	r1,neg_zero
	loadd	r2,neg_zero
	fmin	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE


#########################  test FMAX

# Basic test of FMAX
	loadd	r1,seven
	loadd	r2,four
	fmax	r3,r1,r2
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FMAX
	loadd	r1,four
	loadd	r2,seven
	fmax	r3,r1,r2
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FMAX
	loadd	r1,neg_seven
	loadd	r2,neg_four
	fmax	r3,r1,r2
	loadd	r4, neg_four
	bne	r3,r4,FAILURE

# Basic test of FMAX
	loadd	r1,neg_four
	loadd	r2,neg_seven
	fmax	r3,r1,r2
	loadd	r4, neg_four
	bne	r3,r4,FAILURE

# Basic test of FMAX
	loadd	r1,seven
	loadd	r2,seven
	fmax	r3,r1,r2
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FMAX
	loadd	r1,zero
	loadd	r2,zero
	fmax	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FMAX
	loadd	r1,zero
	loadd	r2,neg_zero	# What is FMAX (+0.0, -0.0)? This test looks for +0.0.
	fmax	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FMAX
	loadd	r1,neg_zero
	loadd	r2,zero
	fmax	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FMAX
	loadd	r1,neg_zero
	loadd	r2,neg_zero
	fmax	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE


#########################  test FNEG

# Basic test of FNEG
	loadd	r1,seven
	fneg	r3,r1
	loadd	r4,neg_seven
	bne	r3,r4,FAILURE

# Basic test of FNEG
	loadd	r1,neg_seven
	fneg	r3,r1
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FNEG
	loadd	r1,neg_zero
	fneg	r3,r1
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FNEG
	loadd	r1,zero
	fneg	r3,r1
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE


# Basic test of FNEG... FNEG(+inf) = -inf
	loadd	r1,pos_inf
	fneg	r3,r1
	loadd	r4,neg_inf
	bne	r3,r4,FAILURE

# Basic test of FNEG... FNEG(-inf) = +inf
	loadd	r1,neg_inf
	fneg	r3,r1
	loadd	r4,pos_inf
	bne	r3,r4,FAILURE

# Basic test of FNEG... FNEG(NaN) = NaN
	loadd	r1,NaN
	fneg	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FNEG... FNEG(sNaN) = NaN
	loadd	r1,sNaN
	fneg	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FNEG... FNEG(qNaN) = NaN
	loadd	r1,qNaN
	fneg	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FNEG... FNEG(strange_sNaN) = NaN
	loadd	r1,strange_sNaN
	fneg	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FNEG... FNEG(weird_qNaN) = NaN
	loadd	r1, weird_qNaN
	fneg	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN



#########################  test FABS

# Basic test of FABS... ABS(-7.0) = +7.0
	loadd	r1,neg_seven
	fabs	r3,r1
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FABS... ABS(+7.0) = +7.0
	loadd	r1,seven
	fabs	r3,r1
	loadd	r4,seven
	bne	r3,r4,FAILURE

# Basic test of FABS... ABS(+inf) = +inf
	loadd	r1,pos_inf
	fabs	r3,r1
	loadd	r4,pos_inf
	bne	r3,r4,FAILURE

# Basic test of FABS... ABS(-inf) = +inf
	loadd	r1,neg_inf
	fabs	r3,r1
	loadd	r4,pos_inf
	bne	r3,r4,FAILURE

# Basic test of FABS... ABS(NaN) = NaN
	loadd	r1,NaN
	fabs	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FABS... ABS(sNaN) = NaN
	loadd	r1,sNaN
	fabs	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FABS... ABS(qNaN) = NaN
	loadd	r1,qNaN
	fabs	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FABS... ABS(strange_sNaN) = NaN
	loadd	r1,strange_sNaN
	fabs	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FABS... ABS(weird_qNaN) = NaN
	loadd	r1, weird_qNaN
	fabs	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

# Basic test of FABS... ABS(+0.0) = +0.0
	loadd	r1,zero
	fabs	r3,r1
	loadd	r4,zero
	bne	r3,r4,FAILURE

# Basic test of FABS
	loadd	r1,neg_zero	# FABS(-0.0) is +0.0, not -0.0
	fabs	r3,r1
	loadd	r4,zero
	bne	r3,r4,FAILURE


#########################  test FEQ

# Basic test of FEQ
	loadd	r1,seven
	loadd	r2,four
	feq	r3,r1,r2
	bnei	r3,0,FAILURE

# Basic test of FEQ
	loadd	r1,seven
	loadd	r2,seven
	feq	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FEQ
	loadd	r1,zero
	loadd	r2,zero
	feq	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FEQ
	loadd	r1,zero
	loadd	r2,neg_zero
	feq	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FEQ
	loadd	r1,neg_zero
	loadd	r2,zero
	feq	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FEQ
	loadd	r1,neg_zero
	loadd	r2,neg_zero
	feq	r3,r1,r2
	bnei	r3,1,FAILURE


#########################  test FLT

# Basic test of FLT
	loadd	r1,three
	loadd	r2,four
	flt	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FLT
	loadd	r1,four
	loadd	r2,three
	flt	r3,r1,r2
	bnei	r3,0,FAILURE

# Basic test of FLT
	loadd	r1,three
	loadd	r2,three
	flt	r3,r1,r2
	bnei	r3,0,FAILURE

# Basic test of FLT
	loadd	r1,zero
	loadd	r2,zero
	flt	r3,r1,r2
	bnei	r3,0,FAILURE

# Basic test of FLT
	loadd	r1,neg_zero
	loadd	r2,neg_zero
	flt	r3,r1,r2
	bnei	r3,0,FAILURE

# Basic test of FLT
	loadd	r1,zero
	loadd	r2,neg_zero
	flt	r3,r1,r2
	bnei	r3,0,FAILURE

# This next test is problematic: Is FLT(-0.0,+0.0) true or false?
# This test says false, since -0.0 == +0.0.

# Basic test of FLT
	loadd	r1,neg_zero
	loadd	r2,zero
	flt	r3,r1,r2
	bnei	r3,0,FAILURE


#########################  test FLE

# Basic test of FLE
	loadd	r1,three
	loadd	r2,four
	fle	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FLE
	loadd	r1,four
	loadd	r2,three
	fle	r3,r1,r2
	bnei	r3,0,FAILURE

# Basic test of FLE
	loadd	r1,three
	loadd	r2,three
	fle	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FLE
	loadd	r1,zero
	loadd	r2,zero
	fle	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FLE
	loadd	r1,neg_zero
	loadd	r2,neg_zero
	fle	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FLE
	loadd	r1,neg_zero
	loadd	r2,zero
	fle	r3,r1,r2
	bnei	r3,1,FAILURE

# Basic test of FLE
	loadd	r1,zero
	loadd	r2,neg_zero
	fle	r3,r1,r2
	bnei	r3,1,FAILURE

# Verify that csr_status is unchanged.
	csrread	r1,csr_status
# But ignore the FLOAT_STATUS bits, which should have been set (but aren't in the emulator)
	andi	r1,r1,0xFFFFFFFFFFFFFF07	# Zero out FLOAT_STATUS bits
	bnei	r1,0x0000000000000001,FAILURE

Test_85_skip:

###########################################################
###########################################################
##
##  Jump around this function
##
###########################################################
###########################################################

	jump	afterMustBeNaN

###########################################################
#
# r3MustBeNaN
#
# This function verifies that the contents of r3 is some form of NaN.
#
# Args:      r3 = input value (NOT STANDARD CALLING CONVENTIONS)
# Regs used: r1
# Stack:     Not used; this is a leaf function
#
r3MustBeNaN:
# Verify that all exponent bits are 1
	movi	r1,0x7ff0000000000000
	and	r1,r3,r1
	bnei	r1,0x7ff0000000000000,FAILURE
# Verify that the fraction is not all zeros
	movi	r1,0x000fffffffffffff
	and	r1,r3,r1
	beqz	r1,FAILURE
	ret
	
afterMustBeNaN:


###########################################################
#
# Test - Basic tests of FMUL
#
# Tested: Arguments such as: 3.0, 4.0, -3.0, -4.0, +0.0, -0.0, +inf, -inf, NaN
# Not tested: rounding, overflow, underflow
#
Test_86: movi	s0,86

# If FMUL emulated, then skip this test.

	loadb	r1,FMUL_Is_Implemented
	beqz	r1,Test_86_skip

# We do not expect any exceptions
	call		InitJumpTable
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

# pos * pos
	loadd	r1,three
	loadd	r2,four
	fmul	r3,r1,r2
	loadd	r4,twelve
	bne	r3,r4,FAILURE

# neg * pos
	loadd	r1,neg_three
	loadd	r2,four
	fmul	r3,r1,r2
	loadd	r4,neg_twelve
	bne	r3,r4,FAILURE

# pos * neg
	loadd	r1,three
	loadd	r2,neg_four
	fmul	r3,r1,r2
	loadd	r4,neg_twelve
	bne	r3,r4,FAILURE

# neg * neg
	loadd	r1,neg_three
	loadd	r2,neg_four
	fmul	r3,r1,r2
	loadd	r4,twelve
	bne	r3,r4,FAILURE

#### Test +0.0

# +0.0 * pos --> +0.0
	loadd	r1,zero
	loadd	r2,twelve
	fmul	r3,r1,r2
	loadd	r4, zero
	bne	r3,r4,FAILURE

# pos * +0.0 --> +0.0
	loadd	r1, twelve
	loadd	r2, zero
	fmul	r3,r1,r2
	loadd	r4, zero
	bne	r3,r4,FAILURE

# +0.0 * neg --> -0.0
	loadd	r1,zero
	loadd	r2,neg_twelve
	fmul	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

# neg * +0.0 --> -0.0
	loadd	r1, neg_twelve
	loadd	r2, zero
	fmul	r3,r1,r2
	loadd	r4, neg_zero
	bne	r3,r4,FAILURE

#### test -0.0

# -0.0 * pos --> -0.0
	loadd	r1,neg_zero
	loadd	r2, twelve
	fmul	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

# -0.0 * neg --> +0.0
	loadd	r1,neg_zero
	loadd	r2, neg_twelve
	fmul	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# neg * -0.0 --> +0.0
	loadd	r1, neg_twelve
	loadd	r2,neg_zero
	fmul	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE

# pos * -0.0 --> -0.0
	loadd	r1, twelve
	loadd	r2,neg_zero
	fmul	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

# +0.0 * -0.0 --> -0.0
	loadd	r1, zero
	loadd	r2,neg_zero
	fmul	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

# -0.0 * +0.0 --> -0.0
	loadd	r1,neg_zero
	loadd	r2,zero
	fmul	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

####  TEST POS-INF: pos, neg, +0.0, -0.0, +inf

# +inf * pos --> +inf
	loadd	r1,pos_inf
	loadd	r2,twelve
	fmul	r3,r1,r2
	loadd	r4, pos_inf
	bne	r3,r4,FAILURE

# +inf * neg --> -inf
	loadd	r1,pos_inf
	loadd	r2, neg_twelve
	fmul	r3,r1,r2
	loadd	r4, neg_inf
	bne	r3,r4,FAILURE

# +inf * +0.0 --> NaN!
	loadd	r1,pos_inf
	loadd	r2,zero
	fmul	r3,r1,r2
	call	r3MustBeNaN

#	loadd	r4, weird_qNaN  ####### The emulator actually produces this strange NaN
#	bne	r3,r4,FAILURE

# +inf * -0.0 --> NaN!
	loadd	r1,pos_inf
	loadd	r2,neg_zero
	fmul	r3,r1,r2
	call	r3MustBeNaN

#	loadd	r4, weird_qNaN  ####### The emulator actually produces this strange NaN
#	bne	r3,r4,FAILURE

# +inf * +inf --> +inf
	loadd	r1,pos_inf
	loadd	r2,pos_inf
	fmul	r3,r1,r2
	loadd	r4, pos_inf
	bne	r3,r4,FAILURE


# pos * +inf --> +inf
	loadd	r1,twelve
	loadd	r2,pos_inf
	fmul	r3,r1,r2
	loadd	r4, pos_inf
	bne	r3,r4,FAILURE

# neg * +inf --> -inf
	loadd	r1, neg_twelve
	loadd	r2,pos_inf
	fmul	r3,r1,r2
	loadd	r4, neg_inf
	bne	r3,r4,FAILURE

# +0.0 * +inf --> NaN!
	loadd	r1,zero
	loadd	r2,pos_inf
	fmul	r3,r1,r2
	call	r3MustBeNaN

#	loadd	r4, weird_qNaN  ####### The emulator actually produces this strange NaN
#	bne	r3,r4,FAILURE

# -0.0 * +inf --> NaN!
	loadd	r1,neg_zero
	loadd	r2,pos_inf
	fmul	r3,r1,r2
	call	r3MustBeNaN

#	loadd	r4, weird_qNaN  ####### The emulator actually produces this strange NaN
#	bne	r3,r4,FAILURE

# +inf * +inf --> +inf
	loadd	r1,pos_inf
	fmul	r3,r1,r2
	loadd	r4, pos_inf
	bne	r3,r4,FAILURE


####  TEST NEG-INF: pos, neg, +0.0, -0.0, +inf, -inf


# -inf * pos --> -inf
	loadd	r1,neg_inf
	loadd	r2,twelve
	fmul	r3,r1,r2
	loadd	r4, neg_inf
	bne	r3,r4,FAILURE

# -inf * neg --> +inf
	loadd	r1,neg_inf
	loadd	r2, neg_twelve
	fmul	r3,r1,r2
	loadd	r4, pos_inf
	bne	r3,r4,FAILURE

# -inf * +0.0 --> NaN!
	loadd	r1,neg_inf
	loadd	r2,zero
	fmul	r3,r1,r2
	call	r3MustBeNaN

#	loadd	r4, weird_qNaN  ####### The emulator actually produces this strange NaN
#	bne	r3,r4,FAILURE

# -inf * -0.0 --> NaN!
	loadd	r1,neg_inf
	loadd	r2,neg_zero
	fmul	r3,r1,r2
	call	r3MustBeNaN

#	loadd	r4, weird_qNaN  ####### The emulator actually produces this strange NaN
#	bne	r3,r4,FAILURE

# -inf * +inf --> -inf
	loadd	r1,pos_inf
	loadd	r2,neg_inf
	fmul	r3,r1,r2
	loadd	r4, neg_inf
	bne	r3,r4,FAILURE


# pos * -inf --> -inf
	loadd	r1,twelve
	loadd	r2,neg_inf
	fmul	r3,r1,r2
	loadd	r4, neg_inf
	bne	r3,r4,FAILURE

# neg * -inf --> +inf
	loadd	r1, neg_twelve
	loadd	r2,neg_inf
	fmul	r3,r1,r2
	loadd	r4, pos_inf
	bne	r3,r4,FAILURE

# +0.0 * -inf --> NaN!
	loadd	r1,zero
	loadd	r2,neg_inf
	fmul	r3,r1,r2
	call	r3MustBeNaN

#	loadd	r4, weird_qNaN  ####### The emulator actually produces this strange NaN
#	bne	r3,r4,FAILURE

# -0.0 * -inf --> NaN!
	loadd	r1,neg_zero
	loadd	r2,neg_inf
	fmul	r3,r1,r2
	call	r3MustBeNaN

#	loadd	r4, weird_qNaN  ####### The emulator actually produces this strange NaN
#	bne	r3,r4,FAILURE



# +inf * -inf --> -inf
	loadd	r1,pos_inf
	loadd	r2,neg_inf
	fmul	r3,r1,r2
	loadd	r4, neg_inf
	bne	r3,r4,FAILURE



# +12.0 * NaN --> NaN!
	loadd	r1,twelve
	loadd	r2,NaN
	fmul	r3,r1,r2
	call	r3MustBeNaN


# +12.0 * sNaN --> NaN!
	loadd	r1,twelve
	loadd	r2,sNaN
	fmul	r3,r1,r2
	call	r3MustBeNaN


# +12.0 * qNaN --> NaN!
	loadd	r1,twelve
	loadd	r2,qNaN
	fmul	r3,r1,r2
	call	r3MustBeNaN


# +12.0 * strange_sNaN --> NaN!
	loadd	r1,twelve
	loadd	r2,strange_sNaN
	fmul	r3,r1,r2
	call	r3MustBeNaN


# +12.0 * weird_qNaN --> NaN!
	loadd	r1,twelve
	loadd	r2,weird_qNaN
	fmul	r3,r1,r2
	call	r3MustBeNaN


# NaN * +12.0 --> NaN!
	loadd	r1,NaN
	loadd	r2,twelve
	fmul	r3,r1,r2
	call	r3MustBeNaN


# sNaN * +12.0 --> NaN!
	loadd	r1,sNaN
	loadd	r2,twelve
	fmul	r3,r1,r2
	call	r3MustBeNaN


# qNaN * +12.0 --> NaN!
	loadd	r1,qNaN
	loadd	r2,twelve
	fmul	r3,r1,r2
	call	r3MustBeNaN


# strange_sNaN * +12.0 --> NaN!
	loadd	r1,strange_sNaN
	loadd	r2,twelve
	fmul	r3,r1,r2
	call	r3MustBeNaN


# weird_qNaN * +12.0 --> NaN!
	loadd	r1,weird_qNaN
	loadd	r2,twelve
	fmul	r3,r1,r2
	call	r3MustBeNaN

# Verify that csr_status is unchanged.
	csrread	r1,csr_status
# But ignore the FLOAT_STATUS bits, which should have been set (but aren't in the emulator)
	andi	r1,r1,0xFFFFFFFFFFFFFF07	# Zero out FLOAT_STATUS bits
	bnei	r1,0x0000000000000001,FAILURE

Test_86_skip:

###########################################################
#
# Test - Basic tests of:
#
#   FMADD
#   FNMADD
#   FMSUB
#   FNMSUB
#
# Not tested: any arguments such as +0.0, -0.0, +inf, -inf, NaN
# Not tested: rounding, overflow, underflow
#
Test_87: movi	s0,87

# If FMUL emulated, then we assume these are emulated and skip this test.

	loadb	r1,FMUL_Is_Implemented
	beqz	r1,Test_87_skip

# We do not expect any exceptions
	call		InitJumpTable
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

##### FMADD

# (3 * 4) + 7 --> 19
	loadd	r1, three
	loadd	r2, four
	loadd	r6, seven
	fmadd	r3,r1,r2,r6
	loadd	r4, nineteen
	bne	r3,r4,FAILURE

# (3 * -4) + 7 --> -5
	loadd	r1, three
	loadd	r2, neg_four
	loadd	r6, seven
	fmadd	r3,r1,r2,r6
	loadd	r4, neg_five
	bne	r3,r4,FAILURE

# (-3 * 4) + -7 --> -19
	loadd	r1, neg_three
	loadd	r2, four
	loadd	r6, neg_seven
	fmadd	r3,r1,r2,r6
	loadd	r4, neg_nineteen
	bne	r3,r4,FAILURE

##### FNMADD

# -(3 * 4) + 7 --> -5
	loadd	r1, three
	loadd	r2, four
	loadd	r6, seven
	fnmadd	r3,r1,r2,r6
	loadd	r4, neg_five
	bne	r3,r4,FAILURE

# -(3 * -4) + 7 --> 19
	loadd	r1, three
	loadd	r2, neg_four
	loadd	r6, seven
	fnmadd	r3,r1,r2,r6
	loadd	r4, nineteen
	bne	r3,r4,FAILURE

# -(-3 * 4) + -7 --> 5
	loadd	r1, neg_three
	loadd	r2, four
	loadd	r6, neg_seven
	fnmadd	r3,r1,r2,r6
	loadd	r4, five
	bne	r3,r4,FAILURE

##### FMSUB

# (3 * 4) - 7 --> 5
	loadd	r1, three
	loadd	r2, four
	loadd	r6, seven
	fmsub	r3,r1,r2,r6
	loadd	r4, five
	bne	r3,r4,FAILURE

# (3 * -4) - 7 --> -19
	loadd	r1, three
	loadd	r2, neg_four
	loadd	r6, seven
	fmsub	r3,r1,r2,r6
	loadd	r4, neg_nineteen
	bne	r3,r4,FAILURE

# (-3 * 4) - -7 --> -5
	loadd	r1, neg_three
	loadd	r2, four
	loadd	r6, neg_seven
	fmsub	r3,r1,r2,r6
	loadd	r4, neg_five
	bne	r3,r4,FAILURE

##### FNMSUB

# -(3 * 4) - 7 --> -19
	loadd	r1, three
	loadd	r2, four
	loadd	r6, seven
	fnmsub	r3,r1,r2,r6
	loadd	r4, neg_nineteen
	bne	r3,r4,FAILURE

# -(3 * -4) - 7 --> 5
	loadd	r1, three
	loadd	r2, neg_four
	loadd	r6, seven
	fnmsub	r3,r1,r2,r6
	loadd	r4, five
	bne	r3,r4,FAILURE

# -(-3 * 4) - -7 --> 19
	loadd	r1, neg_three
	loadd	r2, four
	loadd	r6, neg_seven
	fnmsub	r3,r1,r2,r6
	loadd	r4, nineteen
	bne	r3,r4,FAILURE

# Verify that csr_status is unchanged.
	csrread	r1,csr_status
# But ignore the FLOAT_STATUS bits, which should have been set (but aren't in the emulator)
	andi	r1,r1,0xFFFFFFFFFFFFFF07	# Zero out FLOAT_STATUS bits
	bnei	r1,0x0000000000000001,FAILURE

Test_87_skip:

###########################################################
#
# Test FCVTFI
#
# Not tested: Proper rounding/truncation of large integers which cannot be
# represented accurately with double precision.
#
Test_88: movi	s0,88

# If FCVTFI emulated, then skip this test.

	loadb	r1,FCVTFI_Is_Implemented
	beqz	r1,Test_88_skip

# We do not expect any exceptions
	call		InitJumpTable
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

##### 12  -->  +12.0

	movi	r1,12
	fcvtfi	r3,r1
	loadd	r4, twelve
	bne	r3,r4,FAILURE

##### -12  -->  -12.0

	movi	r1,-12
	fcvtfi	r3,r1
	loadd	r4, neg_twelve
	bne	r3,r4,FAILURE

##### 0  -->  +0.0

	movi	r1,0
	fcvtfi	r3,r1
	loadd	r4, zero
	bne	r3,r4,FAILURE

# Verify that csr_status is unchanged.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000001,FAILURE

##### 0x7fffffffffffffff  -->  +9.22337203685477581e+18

	movi	r1,0x7fffffffffffffff
	fcvtfi	r3,r1
	loadd	r4,f_max_pos
	bne	r3,r4,FAILURE

##### 0x8000000000000000  -->   -9.22337203685477581e+18

	movi	r1,0x8000000000000000
	fcvtfi	r3,r1
	loadd	r4,f_min_neg
	bne	r3,r4,FAILURE

# Verify that INEXACT (NX) bit was set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000009,FAILURE



Test_88_skip:

###########################################################
#
# Test FCVTIF - Thorough testing
#
# Tested: Arguments +0.0, -0.0, +inf, -inf, various NaNs
# Overflow (OV) is set properly and this is tested.
#

# If FCVTIF emulated, then skip this test.
Test_89: movi	s0,89

	loadb	r1,FCVTIF_Is_Implemented
	beqz	r1,Test_89_skip

# We do not expect any exceptions
	call		InitJumpTable
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

##### 12.0 --> 12

	loadd	r1,twelve
	fcvtif	r3,r1
	bnei	r3,12,FAILURE

##### -12.0 --> -12

	loadd	r1,neg_twelve
	fcvtif	r3,r1
	bnei	r3,-12,FAILURE

##### +0.0 --> 0

	loadd	r1,zero
	fcvtif	r3,r1
	bnei	r3,0,FAILURE

##### -0.0 --> 0

	loadd	r1,neg_zero
	fcvtif	r3,r1
	bnei	r3,0,FAILURE

# Verify no changes to csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000001,FAILURE


##### -1.79769313486231571e+308 --> 0x8000,0000,0000,0000

	loadd	r1,f_min
	fcvtif	r3,r1
	bnei	r3,0x8000000000000000,FAILURE

# Verify that OF and NX were set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000049,FAILURE

# Reset csr_status.
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1


##### 1.79769313486231571e+308 --> 0x7fff,ffff,ffff,ffff

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r2,f_max
	fcvtif	r3,r2
	bnei	r3,0x7fffffffffffffff,FAILURE

# Verify that OF and NX were set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000049,FAILURE

# Reset csr_status.
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1


##### + 9,223,372,036,854,774,784.0 --> 0x7FFFFFFFFFFFFC00 = 9,223,372,036,854,774,784

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r2,f_max_pos_2
	fcvtif	r3,r2
	bnei	r3,0x7FFFFFFFFFFFFC00,FAILURE

# Verify that csr_status is unchanged.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000001,FAILURE


##### + 9,223,372,036,854,775,808.0 --> 0x7fff,ffff,ffff,ffff

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r2,f_max_pos
	fcvtif	r3,r2
	bnei	r3,0x7fffffffffffffff,FAILURE

# Verify that OF and NX were set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000049,FAILURE

# Reset csr_status.
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	

##### + 9,223,372,036,854,777,856  --> 0x7fff,ffff,ffff,ffff and OVERFLOW

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r2,f_max_pos_1
	fcvtif	r3,r2
	bnei	r3,0x7fffffffffffffff,FAILURE

# Verify that OF and NX were set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000049,FAILURE

# Reset csr_status.
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	

##### - 9,223,372,036,854,774,784.0 --> 0x8000000000000400 = -9,223,372,036,854,774,784

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r2,f_min_neg_2
	fcvtif	r3,r2
	bnei	r3,0x8000000000000400,FAILURE

# Verify that csr_status is unchanged.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000001,FAILURE


##### - 9,223,372,036,854,775,808.0 --> 0x8000,0000,0000,0000

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,f_min_neg
	fcvtif	r3,r1
	bnei	r3,0x8000000000000000,FAILURE

# Verify that csr_status is unchanged.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000001,FAILURE
	

##### - 9,223,372,036,854,777,856.0 --> 0x8000,0000,0000,0000 and OVERFLOW

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,f_min_neg_1
	fcvtif	r3,r1
	bnei	r3,0x8000000000000000,FAILURE

# Verify that OF and NX were set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000049,FAILURE

# Reset csr_status.
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1


##### +inf --> 0x7FFFFFFFFFFFFFFF (and sets OF, NX)

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,pos_inf
	fcvtif	r3,r1
	bnei	r3,0x7FFFFFFFFFFFFFFF,FAILURE

# Verify that OF and NX were set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000049,FAILURE

# Reset csr_status.
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1


##### -inf --> min (and sets OF, NX)

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,neg_inf
	fcvtif	r3,r1
	bnei	r3,0x8000000000000000,FAILURE

# Verify that OF and NX were set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000049,FAILURE

# Reset csr_status.
	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1


##### sNaN --> 0  (and sets NV)

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,sNaN
	fcvtif	r3,r1
	bnei	r3,0,FAILURE

# Verify that NV was set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000081,FAILURE

# Clear NV flag.
	csrclr	csr_status,0x0080	


##### qNaN --> 0  (and sets NV)

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,qNaN
	fcvtif	r3,r1
	bnei	r3,0,FAILURE

# Verify that NV was set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000081,FAILURE

# Clear NV flag.
	csrclr	csr_status,0x0080	


##### NaN --> 0  (and sets NV)

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,NaN
	fcvtif	r3,r1
	bnei	r3,0,FAILURE

# Verify that NV was set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000081,FAILURE

# Clear NV flag.
	csrclr	csr_status,0x0080	


##### weird_qNaN --> 0  (and sets NV)

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,weird_qNaN
	fcvtif	r3,r1
	bnei	r3,0,FAILURE

# Verify that NV was set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000081,FAILURE

# Clear NV flag.
	csrclr	csr_status,0x0080	


##### strange_sNaN --> 0  (and sets NV)

	movi		r1,0x0000000000000001	# IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1

	loadd	r1,strange_sNaN
	fcvtif	r3,r1
	bnei	r3,0,FAILURE

# Verify that NV was set in csr_status.
	csrread	r1,csr_status
	bnei	r1,0x0000000000000081,FAILURE

# Clear NV flag.
	csrclr	csr_status,0x0080	


Test_89_skip:




###########################################################
#
# Test that the following exceptions work properly, even if
# they occur with interrupts disabled:
#
#    Illegal                - DONE   Tested: Canonical ILLEGAL only
#    SYSCALL                - DONE
#    Unaligned LOAD/STORE   - DONE   Tested: LOADD/W/H, STORED/W/H
#    NullAddress            - DONE   Tested: LOADD/W/H/B, STORED/W/H/B, JAL, JALR,
#                                    Not tested: B.EQ, B.NE, B.LT, B.LE

#    Emulated               - DONE   Tested: FSQRT (only if emulated)
#                                    Not tested: other emulated instructions
#
Test_96: movi	s0,96

##### Check that if interrupts are disabled, ILLEGAL exception still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_a_OK
	stored		Jump_Illegal,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_a_Loc:
	illegal
	jump		FAILURE

# Make sure all is good after a "Kernel Instruction" exception.
T96_a_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_a_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION	# r2 = expected csr_cause  (Illegal Instruction Exception code)
	loadw		r3, T96_a_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, SYSCALL exception still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_b_OK
	stored		Jump_SyscallHandler,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_b_Loc:
	syscall		5		# Note: This is exception code 5*8 = 40 
	jump		FAILURE

# Make sure all is good after the exception.
T96_b_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_b_Loc + 4		# r1 = expected csr_prevpc (Addr of the instruction+4)
	movi		r2,5 * 8			# r2 = expected csr_cause  (Syscall code = N * 8)
	loadw		r3, T96_b_Loc			# r3 = expected csr_bad    (SYSCALL instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, Unaligned LOADD exception still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_c_OK
	stored		Jump_UnalignedLoadStore,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_c_Loc:
	loadd		r1,123(r0)
	jump		FAILURE

# Make sure all is good after the exception.
T96_c_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_c_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_UNALIGNED_LOAD_STORE	# r2 = expected csr_cause  (Unaligned LOAD/STORE code)
	loadw		r3, T96_c_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,123			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, Unaligned LOADW exception still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_d_OK
	stored		Jump_UnalignedLoadStore,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_d_Loc:
	loadw		r1,123(r0)
	jump		FAILURE

# Make sure all is good after the exception.
T96_d_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_d_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_UNALIGNED_LOAD_STORE	# r2 = expected csr_cause  (Unaligned LOAD/STORE code)
	loadw		r3, T96_d_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,123			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, Unaligned LOADH exception still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_e_OK
	stored		Jump_UnalignedLoadStore,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_e_Loc:
	loadh		r1,123(r0)
	jump		FAILURE

# Make sure all is good after the exception.
T96_e_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_e_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_UNALIGNED_LOAD_STORE	# r2 = expected csr_cause  (Unaligned LOAD/STORE code)
	loadw		r3, T96_e_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,123			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, Unaligned STORED exception still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_f_OK
	stored		Jump_UnalignedLoadStore,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_f_Loc:
	stored		123(r0),r1
	jump		FAILURE

# Make sure all is good after the exception.
T96_f_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_f_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_UNALIGNED_LOAD_STORE	# r2 = expected csr_cause  (Unaligned LOAD/STORE code)
	loadw		r3, T96_f_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,123			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, Unaligned STOREW exception still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_g_OK
	stored		Jump_UnalignedLoadStore,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_g_Loc:
	storew		123(r0),r1
	jump		FAILURE

# Make sure all is good after the exception.
T96_g_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_g_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_UNALIGNED_LOAD_STORE	# r2 = expected csr_cause  (Unaligned LOAD/STORE code)
	loadw		r3, T96_g_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,123			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, Unaligned STOREH exception still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_h_OK
	stored		Jump_UnalignedLoadStore,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_h_Loc:
	storeh		123(r0),r1
	jump		FAILURE

# Make sure all is good after the exception.
T96_h_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_h_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_UNALIGNED_LOAD_STORE	# r2 = expected csr_cause  (Unaligned LOAD/STORE code)
	loadw		r3, T96_h_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,123			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, NullAddress for LOADD still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_i_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_i_Loc:
	loadd		r1,0(r0)
	jump		FAILURE

# Make sure all is good after the exception.
T96_i_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_i_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_i_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop


##### Check that if interrupts are disabled, NullAddress for LOADW still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_j_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_j_Loc:
	loadw		r1,0(r0)
	jump		FAILURE

# Make sure all is good after the exception.
T96_j_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_j_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_j_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, NullAddress for LOADH still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_k_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_k_Loc:
	loadh		r1,0(r0)
	jump		FAILURE

# Make sure all is good after the exception.
T96_k_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_k_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_k_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, NullAddress for LOADB still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_l_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_l_Loc:
	loadb		r1,0(r0)
	jump		FAILURE

# Make sure all is good after the exception.
T96_l_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_l_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_l_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, NullAddress for STORED still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_m_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_m_Loc:
	stored		0(r0),r1
	jump		FAILURE

# Make sure all is good after the exception.
T96_m_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_m_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_m_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, NullAddress for STOREW still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_n_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_n_Loc:
	storew		0(r0),r1
	jump		FAILURE

# Make sure all is good after the exception.
T96_n_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_n_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_n_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, NullAddress for STOREH still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_o_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_o_Loc:
	storeh		0(r0),r1
	jump		FAILURE

# Make sure all is good after the exception.
T96_o_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_o_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_o_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, NullAddress for STOREB still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_p_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_p_Loc:
	storeb		0(r0),r1
	jump		FAILURE

# Make sure all is good after the exception.
T96_p_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_p_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_p_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop





##### Check that if interrupts are disabled, NullAddress for JAL still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_1_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Build a JAL instruction that adds -x to the PC, where x is the address of the instruction. This
# will then be a jump to location 0.
	movi		r1,T96_1_Loc		# This is the address of the JAL
	neg		r1,r1			# Make it negative
	slai		r1,r1,4			# Shift into correct position for a Format-D instruction
	movi		t,0x00fffff0		# Isolate the 20 bit field
	and		r1,r1,t			# .
	loadw		r2,T96_1_Loc		# Get the JAL instruction
	movi		t,0xff00000f		# Clear the 20 bit field
	and		r2,r2,t			# .
	or		r1,r1,r2		# Put them together
	storew		T96_1_Loc,r1		# Replace the JAL
	nop					
	nop					
	nop					
	nop					
	nop

# Attempt the instruction.
T96_1_Loc:
	jal		r0,0			# PC+offset. Offset of 0 just got replaced.
	jump		FAILURE

# Make sure all is good after the exception.
T96_1_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_1_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_1_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop



##### Check that if interrupts are disabled, NullAddress for JALR still works.

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_2_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_2_Loc:
	jalr		r0,0(r0)
	jump		FAILURE

# Make sure all is good after the exception.
T96_2_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_2_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3, T96_2_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop




########  We can't check B.EQ, B.NE, B.LT, or B.LE because we are too far away from location 0. The 16-bit offset
########  is not large enough to reach location 0 from this code, so we can't have the exception in this code.
####  
####  ##### Check that if interrupts are disabled, NullAddress for B.EQ still works.
####  
####  # Disable interrupts, expecting a "Kernel" exception.
####  	call		InitJumpTable
####  	movi		r1,T96_4_OK
####  	stored		Jump_NullAddress,r1
####  	call		InitCSRs
####  	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
####  	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1
####  
####  # Build a B.EQ instruction that adds -x to the PC, where x is the address of the instruction. This
####  # will then be a jump to location 0.
####  debug
####  	movi		r1,T96_4_Loc		# This is the address of the instruction
####  	neg		r1,r1			# Make it negative
####  	movi		t,0x0000ffff		# Isolate the 16 bit field: r1 = ---- ---- ---- ---- VVVV VVVV VVVV VVVV
####  	and		r1,r1,t			# .
####  	andi		r2,r1,0x0000000f	# r2 =  ---- ---- ---- ---- ---- ---- ---- VVVV
####  	srli		r1,r1,8			# .
####  	slli		r1,r1,12		# r1 =  ---- ---- VVVV VVVV VVVV ---- ---- ----
####  	or		r1,r1,r2		# Combine into format-c  ---- ---- VVVV VVVV VVVV ---- ---- VVVV
####  	loadw		r2,T96_4_Loc		# Get the instruction instruction
####  	movi		t,0xff000ff0		# Clear the 16 bit field
####  	and		r2,r2,t			# .
####  	or		r1,r1,r2		# Put them together
####  	storew		T96_4_Loc,r1		# Replace the JAL
####  	nop					
####  	nop					
####  	nop					
####  	nop					
####  	nop
####  
####  # Attempt the instruction.
####  T96_4_Loc:
####  	b.eq		r1,r2,0
####  	jump		FAILURE
####  
####  # Make sure all is good after a "Kernel Instruction" exception.
####  T96_4_OK:
####  #   Check csr_stat2
####  	csrread		r5,csr_stat2
####  	bnei		r5,0x0000_0000_0000_0001,FAILURE
####  #   Store value into csr_stat2 so CheckCSRs will not fail.
####  	movi		r5,0x0000_0000_0000_01AB
####  	csrwrite	csr_stat2,r5
####  #   Check csr_status
####  	csrread		r5, csr_status
####  	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
####  #   Store value into csr_status so CheckCSRs will not fail.
####  	movi		r5,0x0000_0000_0000_01A9
####  	csrwrite	csr_status,r5
####  #   Check all CSRs
####  	movi		r1, T96_4_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
####	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
####	loadw		r3, T96_4_Loc		# r3 = expected csr_bad    (The offending instruction)
####  	movi		r4,0			# r4 = expected csr_addr   (The bad address)
####  	call		CheckCSRs
####  	nop





##### Check that if interrupts are disabled, an Emulated Instruction Exception still works.

### To perform this check, we need to execute an instruction that is emulated.
### We assume that if any instructions at all are emulated, then FSQRT is most likely to be.
### So, if FSQRT is emulated, we will perform this test. If FSQRT is not emulated, this
### check is skipped.

###
### NOTE: To test the emulator, you must run it WITHOUT OPTION -fp.
###

	loadb		r1,FSQRT_Is_Implemented
	bnez		r1,Test96_SKIP_SQRT

# Disable interrupts, expecting a "Kernel" exception.
	call		InitJumpTable
	movi		r1,T96_8_OK
	stored		Jump_EmulatedInstruction,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_0001	# FloatRound=00, FloatStat=00000,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=0, KernelMode=1

# Attempt the instruction.
T96_8_Loc:
	fsqrt		r1,r1
	jump		FAILURE

# Make sure all is good after a "Kernel Instruction" exception.
T96_8_OK:
#   Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000_0000_0001,FAILURE
#   Store value into csr_stat2 so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01AB
	csrwrite	csr_stat2,r5
#   Check csr_status
	csrread		r5, csr_status
	bnei		r5,0x0000_0000_0000_0001,FAILURE		# InterruptsEnabled=0, KernelMode=1
#   Store value into csr_status so CheckCSRs will not fail.
	movi		r5,0x0000_0000_0000_01A9
	csrwrite	csr_status,r5
#   Check all CSRs
	movi		r1, T96_8_Loc +4			# r1 = expected csr_prevpc (Addr after the instruction)
	movi		r2,TRAP_CAUSE_EMULATED_INSTRUCTION	# r2 = expected csr_cause  (Emulated Instruction code)
	loadw		r3, T96_8_Loc				# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs
	nop

Test96_SKIP_SQRT:
	call		InitJumpTable





###########################################################
#
# Initialize the page table
#
	call	InitPageTable




###########################################################
#
# Test GETSTAT and PUTSTAT
#

Test_90: movi	s0,90


# We do not expect any exceptions
	call		InitJumpTable


##### Test GETSTAT

# Check bit all bits besides FlRound and FloatStatus
	movi		r1,0xffff_ffff_ffff_fc01	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

# Check bit [9] FlRound = 10
	movi		r1,0x0000_0000_0000_0201	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0200,FAILURE

	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

# Check bit [8] FlRound = 01
	movi		r1,0x0000_0000_0000_0101	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0100,FAILURE

	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

# Check bit [7] (the NV-Invalid bit)
	movi		r1,0x0000_0000_0000_0081	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0080,FAILURE

	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

# Check bit [6] (the OF-Overflow bit)
	movi		r1,0x0000_0000_0000_0041	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0040,FAILURE

	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

# Check bit [5] (the UF-Underflow bit)
	movi		r1,0x0000_0000_0000_0021	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0020,FAILURE

	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

# Check bit [4] (the DZ-DivideByZero bit)
	movi		r1,0x0000_0000_0000_0011	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0010,FAILURE

	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

# Check bit [3] (the NX-Inexact bit)
	movi		r1,0x0000_0000_0000_0009	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0008,FAILURE

	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

#	movi		r1,0x4420
#	controlu	r0,r1,DIGITAL_WRITE

##### Test PUTSTAT

# Check bit [9] FlRound = 10
	movi		r1,0x0000_0000_0000_fff1	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	movi		r2,0xffff_ffff_ffff_f203
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0201,FAILURE

	movi		r2,0xffff_ffff_ffff_f003
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0001,FAILURE

#	movi		r1,0x4421
#	controlu	r0,r1,DIGITAL_WRITE

# Check bit [8] FlRound = 01
	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	movi		r2,0xffff_ffff_ffff_f103
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0101,FAILURE

	movi		r2,0xffff_ffff_ffff_f003
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0001,FAILURE

# Check bit [7] (the NV-Invalid bit)
	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	movi		r2,0xffff_ffff_ffff_f083
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0081,FAILURE

	movi		r2,0xffff_ffff_ffff_f003
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0001,FAILURE

# Check bit [6] (the OF-Overflow)
	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	movi		r2,0xffff_ffff_ffff_f043
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0041,FAILURE

	movi		r2,0xffff_ffff_ffff_f003
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0001,FAILURE

# Check bit [5] (the UF-Underflow)
	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	movi		r2,0xffff_ffff_ffff_f023
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0021,FAILURE

	movi		r2,0xffff_ffff_ffff_f003
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0001,FAILURE

# Check bit [4] (the DZ-DivideByZero)
	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	movi		r2,0xffff_ffff_ffff_f013
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0011,FAILURE

	movi		r2,0xffff_ffff_ffff_f003
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0001,FAILURE

# Check bit [3] (the NX-Inexact)
	movi		r1,0x0000_0000_0000_0001	# SingleStep=0; IntEnabled=0; Kernel=1
	csrwrite	csr_status,r1
	movi		r2,0xffff_ffff_ffff_f00b
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0009,FAILURE

	movi		r2,0xffff_ffff_ffff_f003
	putstat		r2
	csrread		r1,csr_status
	bnei		r1,0x0000_0000_0000_0001,FAILURE




####################################################################################################
####################################################################################################
####################################################################################################
####################################################################################################
####################################################################################################
####################################################################################################
#
# Stop here and print some info. After this, we will go into user mode and use the page tables.
#

	movi		sp,StackRegionX	
	movi		r1,GoodSoFarMessage
	call		PrintString

	loadb		r1,Unaligned_Load_Is_Implemented
	beqz		r1,PVa_1
	movi		r1,PVc_1	# print "impl"
	call		PrintString
	jump		PVb_1
PVa_1:	movi		r1,PVd_1	# print "not impl"
	call		PrintString
PVb_1:

	loadb		r1, Unaligned_Store_Is_Implemented
	beqz		r1,PVa_2
	movi		r1,PVc_2	# print "impl"
	call		PrintString
	jump		PVb_2
PVa_2:	movi		r1,PVd_2	# print "not impl"
	call		PrintString
PVb_2:

	loadb		r1, Divide_Is_Implemented
	beqz		r1,PVa_3
	movi		r1,PVc_3	# print "impl"
	call		PrintString
	jump		PVb_3
PVa_3:	movi		r1,PVd_3	# print "not impl"
	call		PrintString
PVb_3:

	loadb		r1, Floating_Is_Implemented
	beqz		r1,PVa_4
	movi		r1,PVc_4	# print "impl"
	call		PrintString
	jump		PVb_4
PVa_4:	movi		r1,PVd_4	# print "not impl"
	call		PrintString
PVb_4:

	loadb		r1, FMUL_Is_Implemented
	beqz		r1,PVa_5
	movi		r1,PVc_5	# print "impl"
	call		PrintString
	jump		PVb_5
PVa_5:	movi		r1,PVd_5	# print "not impl"
	call		PrintString
PVb_5:

	loadb		r1, FDIV_Is_Implemented
	beqz		r1,PVa_6
	movi		r1,PVc_6	# print "impl"
	call		PrintString
	jump		PVb_6
PVa_6:	movi		r1,PVd_6	# print "not impl"
	call		PrintString
PVb_6:

	loadb		r1, FSQRT_Is_Implemented
	beqz		r1,PVa_7
	movi		r1,PVc_7	# print "impl"
	call		PrintString
	jump		PVb_7
PVa_7:	movi		r1,PVd_7	# print "not impl"
	call		PrintString
PVb_7:

	loadb		r1, FCVTFI_Is_Implemented
	beqz		r1,PVa_8
	movi		r1,PVc_8	# print "impl"
	call		PrintString
	jump		PVb_8
PVa_8:	movi		r1,PVd_8	# print "not impl"
	call		PrintString
PVb_8:

	loadb		r1, FCVTIF_Is_Implemented
	beqz		r1,PVa_9
	movi		r1,PVc_9	# print "impl"
	call		PrintString
	jump		PVb_9
PVa_9:	movi		r1,PVd_9	# print "not impl"
	call		PrintString
PVb_9:

	jump		continue_testing


GoodSoFarMessage:
	.string		"\nBasic Tests Complete\n\0"

PVc_1:	.string		"  Unaligned_Load: implemented\n\0"
PVd_1:	.string		"  Unaligned_Load: causes exception\n\0"
PVc_2:	.string		"  Unaligned_Store: implemented\n\0"
PVd_2:	.string		"  Unaligned_Store: causes exception\n\0"
PVc_3:	.string		"  Divide: implemented\n\0"
PVd_3:	.string		"  Divide: causes exception\n\0"
PVc_4:	.string		"  Floating: implemented\n\0"
PVd_4:	.string		"  Floating: causes exception\n\0"
PVc_5:	.string		"  FMUL: implemented\n\0"
PVd_5:	.string		"  FMUL: causes exception\n\0"
PVc_6:	.string		"  FDIV: implemented\n\0"
PVd_6:	.string		"  FDIV: causes exception\n\0"
PVc_7:	.string		"  FSQRT: implemented\n\0"
PVd_7:	.string		"  FSQRT: causes exception\n\0"
PVc_8:	.string		"  FCVTFI: implemented\n\0"
PVd_8:	.string		"  FCVTFI: causes exception\n\0"
PVc_9:	.string		"  FCVTIF: implemented\n\0"
PVd_9:	.string		"  FCVTIF: causes exception\n\0"
	.align		4


continue_testing:

####################################################################################################
####################################################################################################
####################################################################################################
####################################################################################################
####################################################################################################
####################################################################################################




####### Make sure GETSTAT and PUTSTAT will work in user mode


#####
##### Prepare to enter User Mode.
#####
# We will use an Arithmetic Exception to return to Kernel Mode
	call		InitJumpTable
	movi		r1,Test90_ReturnToKernel
	stored		Jump_ArithmeticException,r1
	call		InitCSRs
# Go into user mode
	call		goIntoUserMode


# Now perform the instructions to make sure they work in user mode.

# Set all bits in FL_ROUND and FL_STATUS
	movi		r1,0xffff_ffff_ffff_ffff
	putstat		r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_03f8,FAILURE

# Clear all bits in FL_ROUND and FL_STATUS
	movi		r1,0xffff_ffff_ffff_fc07
	putstat		r1
	getstat		r2
	bnei		r2,0x0000_0000_0000_0000,FAILURE

#	csrwrite	csr_ptr,r0		# This instruction is privileged and will cause FAILURE


#	movi		r1,0x4413
#	controlu	r0,r1,DIGITAL_WRITE

#####
##### Get back into Kernel Mode.
#####
	movi		r1,0x7fff_ffff_ffff_ffff
Test90_IllegalInst:
	addi		r1,r1,1				# Cause an Arithmetic Exception.
Test90_ReturnToKernel:					# GlobalTrapHandler will jump to here, now in Kernel Mode
	movi		r1, Test90_IllegalInst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ARITHMETIC		# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3, Test90_IllegalInst		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2			# Make sure all CSRs are as-expected



#	movi		r1,0x4414
#	controlu	r0,r1,DIGITAL_WRITE


###########################################################
#
# Test FDIV - basic tests
#
# Tested on: ±12.0 / ±3.0, +0.0, -0.0, +inf, -inf, NaNs
#
# NOT TESTED ON: un-even divisions
# NOT TESTED: rounding, underflow, inexact, overflow
#
Test_91: movi	s0,91

# If FDIV is emulated, then skip this test...

	loadb	r1, FDIV_Is_Implemented
	beqz	r1,Test_91_skip

# We do not expect any interrupts
	call		InitJumpTable

# Initialize csr_status, Interrupt Enabled=0, Kernel Mode=1
	movi		r1,0x0000000000000001
	csrwrite	csr_status,r1


##### Useful for copy-and-paste...

# Verify that DZ was SET in csr_status.
#	csrread	r1,csr_status
#	bnei	r1,0x0000000000000011,FAILURE

# Verify that DZ was NOT SET in csr_status.
#	csrread	r1,csr_status
#	bnei	r1,0x0000000000000001,FAILURE

# Clear FLOAT_ROUND and FLOAT_STATUS before each:  RR SSSSS XXX  ==>  0011,1111,1000  ==>  0x03f8
	csrclr	csr_status,0x03f8	


##### Test ±12.0 / ±3.0


# +12.0 / +3.0 --> +4.0
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,three
	fdiv	r3,r1,r2
	loadd	r4,four
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that no status bits were set
	bnei	r1,0x0000000000000001,FAILURE

# -12.0 / +3.0 --> -4.0
	csrclr	csr_status,0x03f8	
	loadd	r1,neg_twelve
	loadd	r2,three
	fdiv	r3,r1,r2
	loadd	r4,neg_four
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that no status bits were set
	bnei	r1,0x0000000000000001,FAILURE

# +12.0 / -3.0 --> -4.0
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,neg_three
	fdiv	r3,r1,r2
	loadd	r4,neg_four
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that no status bits were set
	bnei	r1,0x0000000000000001,FAILURE

# -12.0 / -3.0 --> +4.0
	csrclr	csr_status,0x03f8	
	loadd	r1,neg_twelve
	loadd	r2,neg_three
	fdiv	r3,r1,r2
	loadd	r4,four
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that no status bits were set
	bnei	r1,0x0000000000000001,FAILURE

##### Test ±0.0 / ±3.0

# +0.0 / +3.0 --> +0.0
	csrclr	csr_status,0x03f8	
	loadd	r1,zero
	loadd	r2,three
	fdiv	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that no status bits were set
	bnei	r1,0x0000000000000001,FAILURE

# -0.0 / +3.0 --> -0.0
	csrclr	csr_status,0x03f8	
	loadd	r1,neg_zero
	loadd	r2,three
	fdiv	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that no status bits were set
	bnei	r1,0x0000000000000001,FAILURE

# +0.0 / -3.0 --> +0.0
	csrclr	csr_status,0x03f8	
	loadd	r1,zero
	loadd	r2,neg_three
	fdiv	r3,r1,r2
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that no status bits were set
	bnei	r1,0x0000000000000001,FAILURE

# -0.0 / -3.0 --> -0.0
	csrclr	csr_status,0x03f8	
	loadd	r1,neg_zero
	loadd	r2,neg_three
	fdiv	r3,r1,r2
	loadd	r4,zero
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that no status bits were set
	bnei	r1,0x0000000000000001,FAILURE

##### Test divide-by-zero... ±12.0 / ±0.0

# +12.0 / +0.0 --> +inf
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,zero
	fdiv	r3,r1,r2
	loadd	r4,pos_inf
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that DZ was set
	bnei	r1,0x0000000000000011,FAILURE

# +12.0 / -0.0 --> -inf
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,neg_zero
	fdiv	r3,r1,r2
	loadd	r4,neg_inf
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that DZ was set
	bnei	r1,0x0000000000000011,FAILURE

# -12.0 / +0.0 --> -inf
	csrclr	csr_status,0x03f8	
	loadd	r1,neg_twelve
	loadd	r2,zero
	fdiv	r3,r1,r2
	loadd	r4,neg_inf
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that DZ was set
	bnei	r1,0x0000000000000011,FAILURE

# -12.0 / -0.0 --> +inf
	csrclr	csr_status,0x03f8	
	loadd	r1,neg_twelve
	loadd	r2,neg_zero
	fdiv	r3,r1,r2
	loadd	r4,pos_inf
	bne	r3,r4,FAILURE
	csrread	r1,csr_status			# Check that DZ was set
	bnei	r1,0x0000000000000011,FAILURE

##### Test NaNs ... +12.0 / NaN, NaN / +12.0

# +12.0 / NaN --> NaN  (NaN is quiet)
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,NaN
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

# +12.0 / sNaN --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,sNaN
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# NOTE: NV (invalid) gets set when signaling NaN is encountered.
	bnei	r1,0x0000000000000081,FAILURE

# +12.0 / qNaN --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,qNaN
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

# +12.0 / strange_sNaN --> NaN  (strange_sNaN is signalling)
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,strange_sNaN
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# NOTE: NV (invalid) gets set when signaling NaN is encountered.
	bnei	r1,0x0000000000000081,FAILURE

# +12.0 / weird_qNaN --> NaN  (weirdNaN is quiet)
	csrclr	csr_status,0x03f8	
	loadd	r1,twelve
	loadd	r2,weird_qNaN
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

# NaN / +12.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,NaN
	loadd	r2,twelve
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

# sNaN / +12.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,sNaN
	loadd	r2,twelve
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# NOTE: NV (invalid) gets set when signaling NaN is encountered.
	bnei	r1,0x0000000000000081,FAILURE

# qNaN / +12.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,qNaN
	loadd	r2,twelve
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

# strange_sNaN / +12.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,strange_sNaN
	loadd	r2,twelve
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# NOTE: NV (invalid) gets set when signaling NaN is encountered.
	bnei	r1,0x0000000000000081,FAILURE

# weird_qNaN / +12.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,weird_qNaN
	loadd	r2,twelve
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

##### Test NaNs divided by positive zero... NaN / +0.0


# NaN / +0.0 --> NaN  (NaN is quiet)
	csrclr	csr_status,0x03f8	
	loadd	r1,NaN
	loadd	r2,zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000011,FAILURE

# sNaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,sNaN
	loadd	r2, zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Check that NV and DZ were set
	bnei	r1,0x0000000000000091,FAILURE

# qNaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,qNaN
	loadd	r2, zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000011,FAILURE

# strange_sNaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,strange_sNaN
	loadd	r2, zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Check that NV and DZ were set
	bnei	r1,0x0000000000000091,FAILURE

# weird_qNaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,weird_qNaN
	loadd	r2, zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000011,FAILURE


##### Test NaNs divided by negative zero... NaN / -0.0


# NaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,NaN
	loadd	r2,neg_zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000011,FAILURE

# sNaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,sNaN
	loadd	r2, neg_zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Check that NV and DZ were set
	bnei	r1,0x0000000000000091,FAILURE

# qNaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,qNaN
	loadd	r2, neg_zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000011,FAILURE

# strange_sNaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,strange_sNaN
	loadd	r2, neg_zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Check that NV and DZ were set
	bnei	r1,0x0000000000000091,FAILURE

# weird_qNaN / +0.0 --> NaN
	csrclr	csr_status,0x03f8	
	loadd	r1,weird_qNaN
	loadd	r2, neg_zero
	fdiv	r3,r1,r2
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quietNan so NV-Invalid is not set
	bnei	r1,0x0000000000000011,FAILURE

Test_91_skip:





###########################################################
#
# Test FSQRT - basic testing
#
# Tested on: +25, -25, +0.0, -0.0, +inf, -inf, NaNs
#
# NOT TESTED ON: non-square numbers
# NOT TESTED: rounding and underflow, inexact
#
Test_92: movi	s0,92

# If FSQRT is emulated, then skip this test...

	loadb	r1, FSQRT_Is_Implemented
	beqz	r1,Test_92_skip

# We do not expect any interrupts
	call		InitJumpTable


##### Perform tests that do not set any flags...


# Initialize csr_status, Interrupt Enabled=0, Kernel Mode=1
	movi		r1,0x0000000000000001
	csrwrite	csr_status,r1

# SQRT(+25.0) --> +5.0
	loadd	r1,twenty_five
	fsqrt	r3,r1
	loadd	r4,five
	bne	r3,r4,FAILURE

# SQRT(+0.0) --> +0.0
	loadd	r1,zero
	fsqrt	r3,r1
	loadd	r4,zero
	bne	r3,r4,FAILURE

# The next test checks
#    SQRT (-0.0) == -0.0
# I believe the IEEE spec requires this result, although this result seems questionable.

# SQRT (-0.0) --> -0.0
	loadd	r1,neg_zero
	fsqrt	r3,r1
	loadd	r4,neg_zero
	bne	r3,r4,FAILURE

# SQRT(+inf) --> +inf
	loadd	r1,pos_inf
	fsqrt	r3,r1
	loadd	r4,pos_inf
	bne	r3,r4,FAILURE

# Check the csr_status is unchanged
	csrread		r1,csr_status
	bnei		r1,0x0000000000000001,FAILURE


##### Perform tests that set flags...


# SQRT(+2.0) --> +1.4142135624  (inexact)
	csrclr	csr_status,0x03f8		# clear flags

	loadd	r1,two
	fsqrt	r3,r1
	loadd	r4,root_two
	bne	r3,r4,FAILURE

	csrread	r1,csr_status			# Check that NX-Inexact is set
	bnei	r1,0x0000000000000009,FAILURE


# SQRT(-25.0) --> NaN
	csrclr	csr_status,0x03f8		# clear flags

	loadd	r1, neg_twenty_five
	fsqrt	r3,r1
	call	r3MustBeNaN

	csrread	r1,csr_status			# Check that NV-Invalid is set
	bnei	r1,0x0000000000000081,FAILURE

# SQRT(-inf) --> NaN
	csrclr	csr_status,0x03f8		# clear flags

	loadd	r1,neg_inf
	fsqrt	r3,r1
	call	r3MustBeNaN

	csrread	r1,csr_status			# Check that NV-Invalid is set
	bnei	r1,0x0000000000000081,FAILURE

# SQRT(NaN) --> NaN
	csrclr	csr_status,0x03f8		# clear flags

	loadd	r1,NaN
	fsqrt	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quiet NaN so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

# SQRT(sNaN) --> NaN
	csrclr	csr_status,0x03f8		# clear flags

	loadd	r1,sNaN
	fsqrt	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is signaling NaN so NV-Invalid is not set
	bnei	r1,0x0000000000000081,FAILURE

# SQRT(qNaN) --> NaN
	csrclr	csr_status,0x03f8		# clear flags

	loadd	r1,qNaN
	fsqrt	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quiet NaN so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

# SQRT(strange_sNaN) --> NaN
	csrclr	csr_status,0x03f8		# clear flags

	loadd	r1,strange_sNaN
	fsqrt	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is signaling NaN so NV-Invalid is not set
	bnei	r1,0x0000000000000081,FAILURE

# SQRT(weird_qNaN) --> NaN
	csrclr	csr_status,0x03f8		# clear flags

	loadd	r1, weird_qNaN
	fsqrt	r3,r1
	loadd	r4,pos_inf
	call	r3MustBeNaN

	csrread	r1,csr_status			# Operand is quiet NaN so NV-Invalid is not set
	bnei	r1,0x0000000000000001,FAILURE

Test_92_skip:



###########################################################
#
# Test INDEX0...INDEX32 
#
# For the Index instruction...
#	r1 = ptr to array
#	r2 = array header: MAX[63:32] CURRENT[31:0]
#	r3 = index
#       r7 = result:   r7 <-- r1 + 8 + (r3 * scale)
#       Exception if (r3 < 0) || (r3 >= CURRENT)
#       Exception if MAX = 0
# For the Bad Array Index Exception...
#       csr_cause = 0x2078
#	csr_prevpc = the address of the INDEX_ instruction
#	csr_bad = the INDEX_ instruction
#	csr_addr = 0
#
Test_93: movi	s0,93

# Try some values that do not cause exceptions

	call		InitJumpTable

##### index=7, MAX=8, CURRENT=8

	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,7
	index0		r7,r1,r2,r3
	bnei		r7,1000+8+(7*0),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,7
	index1		r7,r1,r2,r3
	bnei		r7,1000+8+(7*1),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,7
	index2		r7,r1,r2,r3
	bnei		r7,1000+8+(7*2),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,7
	index4		r7,r1,r2,r3
	bnei		r7,1000+8+(7*4),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,7
	index8		r7,r1,r2,r3
	bnei		r7,1000+8+(7*8),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,7
	index16		r7,r1,r2,r3
	bnei		r7,1000+8+(7*16),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,7
	index24		r7,r1,r2,r3
	bnei		r7,1000+8+(7*24),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,7
	index32		r7,r1,r2,r3
	bnei		r7,1000+8+(7*32),FAILURE


##### index=0, MAX=1, CURRENT=1

	movi		r1,1000
	movi		r2,0x0000_0001_0000_0001
	movi		r3,0
	index0		r7,r1,r2,r3
	bnei		r7,1000+8+(0*0),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0001_0000_0001
	movi		r3,0
	index1		r7,r1,r2,r3
	bnei		r7,1000+8+(0*1),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0001_0000_0001
	movi		r3,0
	index2		r7,r1,r2,r3
	bnei		r7,1000+8+(0*2),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0001_0000_0001
	movi		r3,0
	index4		r7,r1,r2,r3
	bnei		r7,1000+8+(0*4),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0001_0000_0001
	movi		r3,0
	index8		r7,r1,r2,r3
	bnei		r7,1000+8+(0*8),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0001_0000_0001
	movi		r3,0
	index16		r7,r1,r2,r3
	bnei		r7,1000+8+(0*16),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0001_0000_0001
	movi		r3,0
	index24		r7,r1,r2,r3
	bnei		r7,1000+8+(0*24),FAILURE

	movi		r1,1000
	movi		r2,0x0000_0001_0000_0001
	movi		r3,0
	index32		r7,r1,r2,r3
	bnei		r7,1000+8+(0*32),FAILURE


##### index=4294967294, MAX=4294967295, CURRENT=4294967295

	movi		r1,1000
	movi		r2,0xffff_ffff_ffff_ffff
	movi		r3, 4294967294
	index0		r7,r1,r2,r3
	bnei		r7,1000+8+(4294967294*0),FAILURE

	movi		r1,1000
	movi		r2,0xffff_ffff_ffff_ffff
	movi		r3, 4294967294
	index1		r7,r1,r2,r3
	bnei		r7,1000+8+(4294967294*1),FAILURE

	movi		r1,1000
	movi		r2,0xffff_ffff_ffff_ffff
	movi		r3, 4294967294
	index2		r7,r1,r2,r3
	bnei		r7,1000+8+(4294967294*2),FAILURE

	movi		r1,1000
	movi		r2,0xffff_ffff_ffff_ffff
	movi		r3, 4294967294
	index4		r7,r1,r2,r3
	bnei		r7,1000+8+(4294967294*4),FAILURE

	movi		r1,1000
	movi		r2,0xffff_ffff_ffff_ffff
	movi		r3, 4294967294
	index8		r7,r1,r2,r3
	bnei		r7,1000+8+(4294967294*8),FAILURE

	movi		r1,1000
	movi		r2,0xffff_ffff_ffff_ffff
	movi		r3, 4294967294
	index16		r7,r1,r2,r3
	bnei		r7,1000+8+(4294967294*16),FAILURE

	movi		r1,1000
	movi		r2,0xffff_ffff_ffff_ffff
	movi		r3, 4294967294
	index24		r7,r1,r2,r3
	bnei		r7,1000+8+(4294967294*24),FAILURE

	movi		r1,1000
	movi		r2,0xffff_ffff_ffff_ffff
	movi		r3, 4294967294
	index32		r7,r1,r2,r3
	bnei		r7,1000+8+(4294967294*32),FAILURE


##### Check index>=CURRENT. This should cause an exception.
#####
##### index=8, MAX=9, CURRENT=8


# Setup
	call		InitJumpTable
	movi		r1,T93_a_OK_1
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,8
T93_a_Loc_1:
	index0		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_a_OK_1:
	movi		r1,T93_a_Loc_1			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_a_Loc_1			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_a_OK_2
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,8
T93_a_Loc_2:
	index1		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_a_OK_2:
	movi		r1,T93_a_Loc_2			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_a_Loc_2			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_a_OK_3
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,8
T93_a_Loc_3:
	index2		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_a_OK_3:
	movi		r1,T93_a_Loc_3			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_a_Loc_3			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_a_OK_4
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,8
T93_a_Loc_4:
	index4		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_a_OK_4:
	movi		r1,T93_a_Loc_4			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_a_Loc_4			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_a_OK_5
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,8
T93_a_Loc_5:
	index8		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_a_OK_5:
	movi		r1,T93_a_Loc_5			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_a_Loc_5			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_a_OK_6
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,8
T93_a_Loc_6:
	index16		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_a_OK_6:
	movi		r1,T93_a_Loc_6			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_a_Loc_6			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_a_OK_7
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,8
T93_a_Loc_7:
	index24		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_a_OK_7:
	movi		r1,T93_a_Loc_7			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_a_Loc_7			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_a_OK_8
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,8
T93_a_Loc_8:
	index32		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_a_OK_8:
	movi		r1,T93_a_Loc_8			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_a_Loc_8			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check r3<0. This should cause an exception.
#####
##### index=-1, MAX=9, CURRENT=8


# Setup
	call		InitJumpTable
	movi		r1,T93_b_OK_1
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,-1
T93_b_Loc_1:
	index0		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_b_OK_1:
	movi		r1,T93_b_Loc_1			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_b_Loc_1			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_b_OK_2
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,-1
T93_b_Loc_2:
	index1		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_b_OK_2:
	movi		r1,T93_b_Loc_2			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_b_Loc_2			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_b_OK_3
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,-1
T93_b_Loc_3:
	index2		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_b_OK_3:
	movi		r1,T93_b_Loc_3			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_b_Loc_3			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_b_OK_4
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,-1
T93_b_Loc_4:
	index4		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_b_OK_4:
	movi		r1,T93_b_Loc_4			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_b_Loc_4			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_b_OK_5
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,-1
T93_b_Loc_5:
	index8		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_b_OK_5:
	movi		r1,T93_b_Loc_5			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_b_Loc_5			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_b_OK_6
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,-1
T93_b_Loc_6:
	index16		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_b_OK_6:
	movi		r1,T93_b_Loc_6			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_b_Loc_6			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_b_OK_7
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0009_0000_0008
	movi		r3,-1
T93_b_Loc_7:
	index24		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_b_OK_7:
	movi		r1,T93_b_Loc_7			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_b_Loc_7			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_b_OK_8
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0008_0000_0008
	movi		r3,-1
T93_b_Loc_8:
	index32		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_b_OK_8:
	movi		r1,T93_b_Loc_8			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_b_Loc_8			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check MAX=0. This should cause an exception.
#####
##### index=7, MAX=0, CURRENT=8


# Setup
	call		InitJumpTable
	movi		r1,T93_c_OK_1
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0000_0000_0008
	movi		r3,7
T93_c_Loc_1:
	index0		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_c_OK_1:
	movi		r1,T93_c_Loc_1			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_c_Loc_1			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_c_OK_2
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0000_0000_0008
	movi		r3,7
T93_c_Loc_2:
	index1		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_c_OK_2:
	movi		r1,T93_c_Loc_2			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_c_Loc_2			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_c_OK_3
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0000_0000_0008
	movi		r3,7
T93_c_Loc_3:
	index2		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_c_OK_3:
	movi		r1,T93_c_Loc_3			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_c_Loc_3			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_c_OK_4
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0000_0000_0008
	movi		r3,7
T93_c_Loc_4:
	index4		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_c_OK_4:
	movi		r1,T93_c_Loc_4			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_c_Loc_4			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_c_OK_5
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0000_0000_0008
	movi		r3,7
T93_c_Loc_5:
	index8		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_c_OK_5:
	movi		r1,T93_c_Loc_5			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_c_Loc_5			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_c_OK_6
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0000_0000_0008
	movi		r3,7
T93_c_Loc_6:
	index16		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_c_OK_6:
	movi		r1,T93_c_Loc_6			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_c_Loc_6			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_c_OK_7
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0000_0000_0008
	movi		r3,7
T93_c_Loc_7:
	index24		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_c_OK_7:
	movi		r1,T93_c_Loc_7			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_c_Loc_7			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Setup
	call		InitJumpTable
	movi		r1,T93_c_OK_8
	stored		Jump_BadArrayIndex,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,1000
	movi		r2,0x0000_0000_0000_0008
	movi		r3,7
T93_c_Loc_8:
	index32		r7,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T93_c_OK_8:
	movi		r1,T93_c_Loc_8			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_BAD_ARRAY_INDEX	# r2 = expected csr_cause  (Bad Array Index Exception code)
	loadw		r3,T93_c_Loc_8			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

# Reset the jump table
	call		InitJumpTable




###########################################################
#
# Test all ILLEGAL instruction opcodes.
#
# If additional instructions are added to the ISA, the following
# constant will require changes:

LastGoodFormatAInstruction:	.equ	0x004f0000	# Current range is 0..79.  NOTE: 79 = 0x4f
LastGoodFormatNonAInstruction:	.equ	0x2a000000	# Current range is 1..42.  NOTE: 42 = 0x2a


Test_94: movi	s0,94


##### Test that ILLEGAL causes an exception

# Setup
	call		InitJumpTable
	movi		r1,Test94_OK_1
	stored		Jump_Illegal,r1
	call		InitCSRs

# Perform the canonical ILLEGAL instruction, i.e., 0x00000000

Test94_Loc_1:
	illegal
	jump		FAILURE

# Make sure all is good after the exception
Test94_OK_1:
	movi		r1,Test94_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION	# r2 = expected csr_cause  (Illegal Instruction Exception code)
	loadw		r3,Test94_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


	movi		s1,0x6604


### LOOP through all illegal format A instructions

	movi		r6, LastGoodFormatAInstruction
Test94_loop_1:
	movi		r1,0x0000000000010000
	add		r6,r6,r1
	bgti		r6,0x0000000000ff0000,Test94_loop_1_exit

# Setup
	call		InitJumpTable
	movi		r1,Test94_OK_2
	stored		Jump_Illegal,r1
	call		InitCSRs

# Store the next illegal instruction into where the syscall now is. 
	storew		Test94_Loc_2,r6
	nop					# We are modifying the next instruction.
	nop					# There may be pipeline issues here.
	nop					# These NOPs are inserted in case they are needed.
	nop					# The emulator does not need them.
	nop
Test94_Loc_2:
	syscall		0			# This dummy instruction will cause FAILURE if executed
	jump		FAILURE

# Make sure all is good after the exception
Test94_OK_2:
	movi		r1,Test94_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION	# r2 = expected csr_cause  (Illegal Instruction Exception code)
	loadw		r3,Test94_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


### ENDLOOP
	jump		Test94_loop_1
Test94_loop_1_exit:





# Loop through all illegal non-format-A instructions

	movi		r6, LastGoodFormatNonAInstruction
Test94_loop_3:
	movi		r1,0x0000000001000000
	add		r6,r6,r1
	bgti		r6,0x00000000ff000000,Test94_loop_3_exit

# Setup
	call		InitJumpTable
	movi		r1,Test94_OK_3
	stored		Jump_Illegal,r1
	call		InitCSRs

# Store the next illegal instruction into where the syscall now is. 
	storew		Test94_Loc_3,r6
	nop					# We are modifying the next instruction.
	nop					# There may be pipeline issues here.
	nop					# These NOPs are inserted in case they are needed.
	nop					# The emulator does not need them.
	nop

Test94_Loc_3:
	syscall		0			# This dummy instruction will cause FAILURE if executed
	jump		FAILURE

# Make sure all is good after the exception
Test94_OK_3:
	movi		r1,Test94_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION	# r2 = expected csr_cause  (Illegal Instruction Exception code)
	loadw		r3,Test94_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32		# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32		# . This is needed for illegal instructions like 0x80000000
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


	jump		Test94_loop_3
Test94_loop_3_exit:

# Reset the jump table
	call		InitJumpTable


###########################################################
#
# Make sure the following instructions cause an exception if executed in USER MODE.
#
#       sysret
#       sleep1
#       sleep2
#       control
#
#	csrswap
#	csrread
#	csrset
#	csrclr
#
#       others???
#
Test_95: movi	s0,95


###
### Test sysret.
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_a_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_a_inst:
	sysret
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_a_OK:
	movi		r1, T95_a_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_a_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2

###
### Test sleep1.
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_b_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_b_inst:
	sleep1
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_b_OK:
	movi		r1, T95_b_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_b_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test sleep2.
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_c_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_c_inst:
	sleep2
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_c_OK:
	movi		r1, T95_c_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_c_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test that CONTROL causes an exception in User Mode.
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_d_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_d_inst:
	control		r7,r1,1234		# even though some codes are implemented, this one is illegal
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_d_OK:
	movi		r1, T95_d_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_d_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test that CONTROLU with random control code causes an exception
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_m_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_m_inst:
	controlu	r7,r1,1234		# even though some codes are implemented, this one is illegal
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_m_OK:
	movi		r1, T95_m_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_m_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test csrswap.
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_e_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_e_inst:
	csrswap		r1,csr_bad,r0
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_e_OK:
	movi		r1, T95_e_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_e_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test csrread.
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_f_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_f_inst:
	csrread		r1,csr_bad
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_f_OK:
	movi		r1, T95_f_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_f_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test csrset.
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_g_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_g_inst:
	csrset		csr_bad,0x1234
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_g_OK:
	movi		r1, T95_g_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_g_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test csrclr.
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_h_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_h_inst:
	csrclr		csr_bad,0x1234
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_h_OK:
	movi		r1, T95_h_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_h_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test TLBCLEAR
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_i_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_i_inst:
	tlbclear
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_i_OK:
	movi		r1, T95_i_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_i_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test TLBFLUSH
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_j_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_j_inst:
	tlbflush	r1
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_j_OK:
	movi		r1, T95_j_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_j_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###
### Test CHECKADDR
###

# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T95_k_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Attempt the instruction.
T95_k_inst:
	checkaddr	r2,r1,5
	jump		FAILURE

# Make sure all is good after an "Illegal/Privileged Instruction" exception.
T95_k_OK:
	movi		r1, T95_k_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION		# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, T95_k_inst			# r3 = expected csr_bad    (The offending instruction)
	slli		r3,r3,32			# The upper bits of CSR_BAD are always zero.
	srli		r3,r3,32			# . This is needed for illegal instructions like 0x80000000
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


###########################################################
#
# Test SYSCALL
#
Test_97: movi	s0,97


##### Test SYSCALL(3) exception, when in Kernel Mode, interrupts ENABLED.

# Setup
	call		InitJumpTable
	movi		r1,Test97_OK_5
	stored		Jump_SyscallHandler,r1
	call		InitCSRs

# Perform the instruction
Test97_Loc_5:
	syscall		3			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test97_OK_5:

	movi		r1,Test97_Loc_5 + 4	# r1 = expected csr_prevpc (Addr of the instruction+4)
	movi		r2,3 * 8		# r2 = expected csr_cause  (Syscall code = N * 8)
	loadw		r3,Test97_Loc_5		# r3 = expected csr_bad    (SYSCALL instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### Test SYSCALL(3) exception, when in Kernel Mode, interrupts DISABLED.

# Setup
	call		InitJumpTable
	movi		r1,Test97_OK_7
	stored		Jump_SyscallHandler,r1
	call		InitCSRs
	movi		r1,0x00000000000001A9	# Interrupts=DISABLED, mode=KERNEL
	csrwrite	csr_status,r1

# Perform the instruction
Test97_Loc_7:
	syscall		3			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test97_OK_7:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001A9,FAILURE
# Store the value into it that CheckCSRs expects, so it will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, Test97_Loc_7 + 4	# r1 = expected csr_prevpc (Addr of the instruction+4)
	movi		r2,3 * 8		# r2 = expected csr_cause  (Syscall code = N * 8)
	loadw		r3, Test97_Loc_7		# r3 = expected csr_bad    (SYSCALL instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Test SYSCALL(1023) exception, when in Kernel Mode.

# Setup
	call		InitJumpTable
	movi		r1,Test97_OK_6
	stored		Jump_SyscallHandler,r1
	call		InitCSRs

# Perform the instruction
Test97_Loc_6:
	syscall		1023			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test97_OK_6:

	movi		r1,Test97_Loc_6 + 4	# r1 = expected csr_prevpc (Addr of the instruction+4)
	movi		r2,1023 * 8		# r2 = expected csr_cause  (Syscall code = N * 8)
	loadw		r3,Test97_Loc_6		# r3 = expected csr_bad    (SYSCALL instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Test SYSCALL(123) exception, when in User Mode

# Go into user mode, expecting an "SYSCALL" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T97_a_OK
	stored		Jump_SyscallHandler,r1
	call		goIntoUserMode

# Attempt the instruction.
T97_a_inst:
	syscall		123
	jump		FAILURE

# Make sure all is good after an "syscall" exception.
T97_a_OK:
	movi		r1, T97_a_inst + 4		# r1 = expected csr_prevpc (Addr of the instruction+4)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,123 * 8			# r2 = expected csr_cause  (Syscall code = N * 8)
	loadw		r3, T97_a_inst			# r3 = expected csr_bad    (SYSCALL instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Test SYSCALL(1023) exception, when in User Mode


# Go into user mode, expecting an "Illegal/Privileged Instruction" exception.
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T97_b_OK
	stored		Jump_SyscallHandler,r1
	call		goIntoUserMode

# Attempt the instruction.
T97_b_inst:
	syscall		1023
	jump		FAILURE

# Make sure all is good after an "syscall" exception.
T97_b_OK:
	movi		r1, T97_b_inst + 4		# r1 = expected csr_prevpc (Addr of the instruction+4)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2,1023 * 8			# r2 = expected csr_cause  (Syscall code = N * 8)
	loadw		r3, T97_b_inst			# r3 = expected csr_bad    (SYSCALL instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


	call		InitJumpTable




###########################################################
#
# Test SYSRET
#
Test_98: movi	s0,98

##### Test SYSRET, when in Kernel Mode, interrupts ENABLED.

# Setup
	call		InitJumpTable
	call		InitCSRs
	movi		r1,Test98_OK_1
	csrwrite	csr_prevpc,r1
	movi		r1,0x0000_0000000001A9	# After SYSRET, we'll be in KERNEL MODE, but with interrupts DISABLED.
	csrwrite	csr_stat2,r1

# Perform the instruction
	sysret
	jump		FAILURE

# Make sure all is good after the SYSRET
Test98_OK_1:

# Check csr_status
	csrread		r5,csr_status
	bnei		r5,0x0000_0000000001A9,FAILURE
# Store the value into it that CheckCSRs expects, so it will not fail.
	movi		r5,0x00000000000001A9
	csrwrite	csr_status,r5

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000000001A9,FAILURE
# Store the value into it that CheckCSRs expects, so it will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

# We haven't had an exception, so just set these regs so CheckCSRs will not complain.
	movi		r1,Test98_OK_1			# r1 = expected csr_prevpc
	movi		r2,0x7777777777777777		# r2 = expected csr_cause
	movi		r3,0x8888888888888888		# r3 = expected csr_bad
	movi		r4,0x9999999999999999		# r4 = expected csr_addr
	call		CheckCSRs



##### Test SYSRET, when in Kernel Mode, interrupts DISABLED.

# Setup
	call		InitJumpTable
	call		InitCSRs
	movi		r1,0x0000_0000000001A9		# mode=KERNEL, interrupts=DISABLED
	csrwrite	csr_status,r1
	movi		r1,Test98_OK_2
	csrwrite	csr_prevpc,r1
	movi		r1,0x0000_0000000001AB	# After SYSRET, we'll be in KERNEL MODE, but with interrupts ENABLED.
	csrwrite	csr_stat2,r1

# Perform the instruction
	sysret
	jump		FAILURE

# Make sure all is good after the SYSRET
Test98_OK_2:

# Check csr_status
	csrread		r5,csr_status
	bnei		r5,0x0000_0000000001AB,FAILURE
# Store the value into it that CheckCSRs expects, so it will not fail.
	movi		r5,0x00000000000001A9
	csrwrite	csr_status,r5

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x0000_0000000001AB,FAILURE
# Store the value into it that CheckCSRs expects, so it will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

# We haven't had an exception, so just set these regs so CheckCSRs will not complain.
	movi		r1,Test98_OK_2			# r1 = expected csr_prevpc
	movi		r2,0x7777777777777777		# r2 = expected csr_cause
	movi		r3,0x8888888888888888		# r3 = expected csr_bad
	movi		r4,0x9999999999999999		# r4 = expected csr_addr
	call		CheckCSRs




###########################################################
#
# Test - MULADD, MULADDU
#
Test_99: movi	s0,99

# TABLE: Each group of 5 dwords is a single test
MUL_entry_size:		.equ	5*8
	jump		MUL_table_x
	.align		8
MUL_table:
	.doubleword	300	# op 1
	.doubleword	400	# op 2
	.doubleword	3456	# op 3
	.doubleword	123456	# expected result
	.doubleword	0	# 1=overflow for MULADD, 0=no overflow

	.doubleword	0	# op 1
	.doubleword	0	# op 2
	.doubleword	0	# op 3
	.doubleword	0	# expected result
	.doubleword	0	# 1=overflow for MULADD, 0=no overflow

	.doubleword	-1	# op 1
	.doubleword	-1	# op 2
	.doubleword	-1	# op 3
	.doubleword	0	# expected result
	.doubleword	0	# 1=overflow for MULADD, 0=no overflow

	.doubleword	2	# op 1
	.doubleword	3	# op 2  mul = +6
	.doubleword	4	# op 3
	.doubleword	10	# expected result
	.doubleword	0	# 1=overflow for MULADD, 0=no overflow

	.doubleword	-2	# op 1
	.doubleword	-3	# op 2  mul = +6
	.doubleword	-4	# op 3
	.doubleword	2	# expected result
	.doubleword	0	# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x8000_0000_0000_0000	# op 1
	.doubleword	2			# op 2  -- Overflow on mul, gives 0
	.doubleword	100			# op 3  -- Add is ok
	.doubleword	100			# expected result
	.doubleword	1			# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x8000_0000_0000_0000	# op 1
	.doubleword	2			# op 2  -- Overflow on mul, gives 0
	.doubleword	-3			# op 3  -- Add is ok
	.doubleword	-3			# expected result
	.doubleword	1			# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x8000_0000_0000_0000	# op 1
	.doubleword	1			# op 2
	.doubleword	0			# op 3
	.doubleword	0x8000_0000_0000_0000	# expected result
	.doubleword	0			# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x8000_0000_0000_0000	# op 1
	.doubleword	1			# op 2
	.doubleword	-1			# op 3   -- overflow on add
	.doubleword	0x7fff_ffff_ffff_ffff	# expected result
	.doubleword	1			# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x8000_0000_0000_0000	# op 1
	.doubleword	1			# op 2
	.doubleword	-1			# op 3
	.doubleword	0x7fff_ffff_ffff_ffff	# expected result
	.doubleword	1			# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x7fff_ffff_ffff_ffff	# op 1
	.doubleword	2			# op 2  -- Overflow on mul, gives ffff_ffff_ffff_fffe = -2
	.doubleword	0			# op 3  -- Add is ok
	.doubleword	0xffff_ffff_ffff_fffe	# expected result
	.doubleword	1			# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x7fff_ffff_ffff_ffff	# op 1
	.doubleword	2			# op 2  -- Overflow on mul, gives ffff_ffff_ffff_fffe = -2
	.doubleword	3			# op 3  -- Add is ok
	.doubleword	1			# expected result
	.doubleword	1			# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x7fff_ffff_ffff_ffff	# op 1
	.doubleword	1			# op 2
	.doubleword	0			# op 3
	.doubleword	0x7fff_ffff_ffff_ffff	# expected result
	.doubleword	0			# 1=overflow for MULADD, 0=no overflow

	.doubleword	0x7fff_ffff_ffff_ffff	# op 1
	.doubleword	1			# op 2
	.doubleword	1			# op 3  -- Overflow on add
	.doubleword	0x8000_0000_0000_0000	# expected result
	.doubleword	1			# 1=overflow for MULADD, 0=no overflow

	.doubleword	-500	# op 1
	.doubleword	700	# op 2
	.doubleword	-3456	# op 3
	.doubleword	-353456	# expected result
	.doubleword	0	# 1=overflow for MULADD, 0=no overflow
MUL_table_x:

	#r1 = op1
	#r2 = op2
	#r3 = op3
	#r4 = expected result
	#r5 = 1=overflow for MULADD, 0=no overflow
	#r6 = result
	#r7 = index

# Loop thru the table and run each test...
	movi		r7,MUL_table
mul_loop:
	loadd		r1,0(r7)
	loadd		r2,8(r7)
	loadd		r3,16(r7)
	loadd		r4,24(r7)
	loadd		r5,32(r7)

# Test MULADDU on these values
	muladdu		r6,r1,r2,r3
	bne		r4,r6,FAILURE

# If no overflow expected for MULADD, test it...

	bnez		r5,MUL_test_overflow
	muladd		r6,r1,r2,r3
	bne		r4,r6,FAILURE
	jump		MUL_endloop

# Else, if overflow expected...
MUL_test_overflow:

# Setup before the exception
	call		InitJumpTable
	movi		r1,MUL_OK
	stored		Jump_ArithmeticException,r1
	call		InitCSRs

# Reload r1-r2, which got trashed...
	loadd		r1,0(r7)
	loadd		r2,8(r7)

MUL_inst:
	muladd		r6,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
MUL_OK:
	movi		r1, MUL_inst			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3, MUL_inst			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr
	call		CheckCSRs			# Trashes r1-r4

MUL_endloop:
	addi		r7,r7,MUL_entry_size
	blti		r7,MUL_table_x,mul_loop




###########################################################
#
# Test NULLTEST
#
Test_100: movi	s0,100

# Try some values that do not cause exceptions

	call		InitJumpTable
	movi		r1,0xffff_ffff_ffff_ffff
	nulltest	r1
	movi		r2,0x0000_0000_0000_0008
	nulltest	r2
	movi		s2,0x0000_0008_0000_0000
	nulltest	s2


##### TRY NULLTEST 0

# Setup
	call		InitJumpTable
	movi		r1,Test100_OK_1
	stored		Jump_NullAddress,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0

Test100_Loc_1:
	nulltest	r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test100_OK_1:
	movi		r1,Test100_Loc_1		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3,Test100_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### TRY NULLTEST 0 with high bits set

# Setup
	call		InitJumpTable
	movi		r1,Test100_OK_2
	stored		Jump_NullAddress,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0xffff_fff0_0000_0000

Test100_Loc_2:
	nulltest	r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test100_OK_2:
	movi		r1,Test100_Loc_2		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3,Test100_Loc_2		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### TRY NULLTEST 7

# Setup
	call		InitJumpTable
	movi		r1,Test100_OK_3
	stored		Jump_NullAddress,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,7

Test100_Loc_3:
	nulltest	r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test100_OK_3:
	movi		r1,Test100_Loc_3		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3,Test100_Loc_3		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

##### TRY NULLTEST 7 with high bits set

# Setup
	call		InitJumpTable
	movi		r1,Test100_OK_4
	stored		Jump_NullAddress,r1
	call		InitCSRs

# Perform the instruction
	movi		r1,0xffff_fff0_0000_0007

Test100_Loc_4:
	nulltest	r1			# The instruction
	jump		FAILURE

# Make sure all is good after the exception
Test100_OK_4:
	movi		r1,Test100_Loc_4		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Exception code)
	loadw		r3,Test100_Loc_4		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

	call		InitJumpTable


###########################################################
#
# Unused test numbers
#
Test_101: movi	s0,101
Test_102: movi	s0,102
Test_103: movi	s0,103
Test_104: movi	s0,104
Test_105: movi	s0,105




###########################################################
#
# Test Null Address Exception
#
# Test LOADD/W/H/B, STORED/W/H/B, JALR, JAL with address 7.
#
# These are tested in both KERNEL MODE and USER MODE.
#
# NOTE: B.EQ, B.NE, B.LT, and B.LE should be tested in KERNEL MODE, but they are not tested.
#
# NOTE: B.EQ, B.NE, B.LT, B.LE, and JAL can never cause the exception when in USER MODE.
#
# NOTE: Using address 7 also causes Unaligned LOAD/STORE Exception, but
# the Null Address Exception has priority.
#
Test_106: movi	s0,106


##### Check LOADD, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_1_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_1_Loc:
	loadd		r1,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_1_OK:
	movi		r1, T106_1_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_1_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



##### Check LOADW, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_2_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_2_Loc:
	loadw		r1,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_2_OK:
	movi		r1, T106_2_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_2_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check LOADH, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_3_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_3_Loc:
	loadh		r1,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_3_OK:
	movi		r1, T106_3_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_3_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check LOADB, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_4_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_4_Loc:
	loadb		r1,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_4_OK:
	movi		r1, T106_4_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_4_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check STORED, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_5_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_5_Loc:
	stored		7(r0),r1
	jump		FAILURE

# Make sure all is good after the exception
T106_5_OK:
	movi		r1, T106_5_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_5_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check STOREW, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_6_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_6_Loc:
	storew		7(r0),r1
	jump		FAILURE

# Make sure all is good after the exception
T106_6_OK:
	movi		r1, T106_6_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_6_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check STOREH, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_7_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_7_Loc:
	storeh		7(r0),r1
	jump		FAILURE

# Make sure all is good after the exception
T106_7_OK:
	movi		r1, T106_7_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_7_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check STOREB, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_8_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_8_Loc:
	storeb		7(r0),r1
	jump		FAILURE

# Make sure all is good after the exception
T106_8_OK:
	movi		r1, T106_8_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_8_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### Check JAL, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_9_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Modify the JAL instruction. Place -offset into it, so the jump is to location 7.
	movi		r1, T106_9_Loc
	neg		r1,r1
	addi		r1,r1,7
	movi		r2,0x000FFFFF
	and		r1,r1,r2
	slli		r1,r1,4
	loadw		r2, T106_9_Loc
	or		r2,r1,r2
	storew		T106_9_Loc,r2
	nop
	nop
	nop
	nop
	nop
	nop

# Perform the instruction
T106_9_Loc:
	jal		r0,0
	jump		FAILURE

# Make sure all is good after the exception
T106_9_OK:
	movi		r1, T106_9_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_9_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check JALR, when in Kernel Mode

# Setup
	call		InitJumpTable
	movi		r1,T106_10_OK
	stored		Jump_NullAddress,r1
	call		InitCSRs
	movi		r1,0x0000_0000_0000_01AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1			# SingleStep=0, InterruptsEnabled=1, KernelMode=1

# Perform the instruction
T106_10_Loc:
	jalr		r0,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_10_OK:
	movi		r1, T106_10_Loc		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2,TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause  (Null Address Exception code)
	loadw		r3, T106_10_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Check B.EQ, B.NE, B.LT, B.LE, when in Kernel Mode

### Unfortunately, these instructions are already located too high in memory for a B.EQ
### (which uses a PC-relative offset) to be able to reach location 7.
###
### Thus, we are failing to test B.EQ, B.NE, B.LT, and B.LE when they cause Null Address Exception
###




##### Check LOADD, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_11_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_11_inst:
	loadd		r1,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_11_OK:
	movi		r1, T106_11_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_11_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Check LOADW, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_12_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_12_inst:
	loadw		r1,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_12_OK:
	movi		r1, T106_12_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_12_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Check LOADH, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_13_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_13_inst:
	loadh		r1,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_13_OK:
	movi		r1, T106_13_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_13_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Check LOADB, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_14_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_14_inst:
	loadb		r1,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_14_OK:
	movi		r1, T106_14_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_14_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Check STORED, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_15_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_15_inst:
	stored		7(r0),r4
	jump		FAILURE

# Make sure all is good after the exception
T106_15_OK:
	movi		r1, T106_15_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_15_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Check STOREW, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_16_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_16_inst:
	storew		7(r0),r4
	jump		FAILURE

# Make sure all is good after the exception
T106_16_OK:
	movi		r1, T106_16_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_16_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Check STOREH, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_17_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_17_inst:
	storeh		7(r0),r4
	jump		FAILURE

# Make sure all is good after the exception
T106_17_OK:
	movi		r1, T106_17_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_17_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Check STOREB, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_18_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_18_inst:
	storeb		7(r0),r4
	jump		FAILURE

# Make sure all is good after the exception
T106_18_OK:
	movi		r1, T106_18_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_18_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Concerning a Null Address Exception for the JAL instruction, when in User Mode.
#
# This cannot occur. The 20-bit offset is relative to the PC. Since we are in User Mode, we
# must be executing in a virtual address space and thus PC >= 0x8_0000_0000. There is no
# way the JAL can reach address 0...7.
#


##### Check JALR, when in User Mode


# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1, T106_20_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Perform the instruction
T106_20_inst:
	jalr		r0,7(r0)
	jump		FAILURE

# Make sure all is good after the exception
T106_20_OK:
	movi		r1, T106_20_inst		# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause  (Null Address Exception)
	loadw		r3, T106_20_inst		# r3 = expected csr_bad    (offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2




###########################################################
#
# Test the BREAKPOINT and DEBUG instructions and exceptions in KERNEL MODE and USER MODE.
#
# This test requires the emulator to be run with option "-nodebug"
#
Test_107: movi	s0,107

######
######    TO PERFORM THE TEST,YOU INCLUDE THE FOLLOWING JUMP. ALSO, YOU MUST DISABLE THE
######    "debug" INSTRUCTIONS AT "SUCCESS_LOOP" AND "FAILURE". THEN USE Ctrl-C TO SEE
######    IF EXECUTION ENDS AT "SUCCESS_LOOP" OR "FAILURE".
######

#	jump	skip_107_begin

	movi	r1,TestingDebug_mess3		# Print "test not performed"
	call	PrintString
	jump	skip_107
skip_107_begin:
	movi	r1,TestingDebug_mess1		# Print "test beginning"
	call	PrintString



##### Check that the BREAKPOINT instruction and Breakpoint Exception are handled properly (in KERNEL MODE).

# Setup
	call		InitJumpTable
	movi		r1,T107_1_OK
	stored		Jump_Breakpoint,r1
	call		InitCSRs

# Perform the instruction
T107_1_Loc:
	breakpoint
	jump		FAILURE

# Make sure all is good after the exception
T107_1_OK:
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AB,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, T107_1_Loc			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		r2, TRAP_CAUSE_BREAKPOINT	# r2 = expected csr_cause  (BreakpointException code)
	loadw		r3, T107_1_Loc			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



##### Check that the DEBUG instruction and Debug Exception are handled properly (in KERNEL MODE).

# Setup
	call		InitJumpTable
	movi		r1,T107_2_OK
	stored		Jump_Debug,r1
	call		InitCSRs

# Perform the instruction
T107_2_Loc:
	debug
	jump		FAILURE

# Make sure all is good after the exception
T107_2_OK:

# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AB,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1, T107_2_Loc+4	# r1 = expected csr_prevpc (Addr of the instruction + 4!)
	movi		r2, TRAP_CAUSE_DEBUG	# r2 = expected csr_cause  (Debug Exception code)
	loadw		r3, T107_2_Loc		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0			# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



##### Check that the BREAKPOINT instruction and Breakpoint Exception are handled properly (in USER MODE).

# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T107_3_OK
	stored		Jump_Breakpoint,r1
	call		goIntoUserMode

# Perform the instruction
T107_3_Loc:
	breakpoint
	jump		FAILURE

# Make sure all is good after the exception
T107_3_OK:
	movi		r1, T107_3_Loc			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_BREAKPOINT	# r2 = expected csr_cause  (Breakpoint Exception code)
	loadw		r3, T107_3_Loc			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



##### Check that the DEBUG instruction and Debug Exception are handled properly (in USER MODE).

# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T107_4_OK
	stored		Jump_Debug,r1
	call		goIntoUserMode

# Perform the instruction
T107_4_Loc:
	debug
	jump		FAILURE

# Make sure all is good after the exception
T107_4_OK:
	movi		r1, T107_4_Loc + 4		# r1 = expected csr_prevpc (Addr of the instruction + 4)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_DEBUG		# r2 = expected csr_cause  (Debug Exception code)
	loadw		r3, T107_4_Loc			# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



# All done. Restore the Jump Table.
	call		InitJumpTable


	movi	r1,TestingDebug_mess2
	call	PrintString
	jump	skip_107

TestingDebug_mess1:	.string		"Testing DEBUG and BREAKPOINT... beginning\n\0"
TestingDebug_mess2:	.string		"Testing DEBUG and BREAKPOINT... completed\n\0"
TestingDebug_mess3:	.string		"Testing DEBUG and BREAKPOINT... COMMENTED OUT & NOT PERFORMED\n\0"
	.align	4

skip_107:



###########################################################
#
# Test the Singlestep Exception
#
# Conditions tested:
#   Kernel Mode, Interrupts Enabled
#   User Mode, Interrupts Enabled
#   User Mode, Interrupts Enabled -- but overridden by Arithmetic Exception
#   User Mode, Interrupts Disabled -- The exception is ignored
#
Test_108: movi	s0,108


	movi		r1,Test108_WelcomeMess
	call		PrintString
	jump		Test108_WelcomeMess_X
Test108_WelcomeMess:
	.string		"Beginning Test 108 (Singlestep Trap)...\n\0"
	.align		4
Test108_WelcomeMess_X:


##### Check that the Singlestep Exception is handled properly (in KERNEL MODE).

# Setup
	call		InitJumpTable
	movi		r1,Test108_OK_1
	stored		Jump_Singlestep,r1
	call		InitCSRs
	movi		r1,0x00000000000001AF	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=1, InterruptsEnabled=1, KernelMode=1



# Here is the instruction sequence that we will single step through:
Test108_Loc_1:
	movi		r1,4321		# The instruction
Test108_Loc_1a:
	movi		r1,1234		# The instruction
Test108_Loc_1b:
	movi		r1,0x1234	# The instruction
Test108_Loc_1c:
	movi		r1,0x4321	# The instruction
Test108_Loc_1d:
	addi		r1,r1,0x4321	# The instruction
	jump		FAILURE



Test108_OK_1:
# Make sure the instruction executed.
	bnei		r1,4321,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AF,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5

	movi		r1,Test108_Loc_1+4		# r1 = expected csr_prevpc (Addr AFTER the instruction)
	movi		r2, TRAP_CAUSE_SINGLESTEP	# r2 = expected csr_cause  (Singlestep Exception code)
	loadw		r3,Test108_Loc_1		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


##### Now return and get another Singlestep exception.  THIS TIME WE USE SYSRET TO EXECUTE THE TARGET INSTRUCTION.

	movi		r1,Test108_OK_1a
	stored		Jump_Singlestep,r1
	movi		r5,0x00000000000001AF
	csrwrite	csr_stat2,r5
	sysret
	jump		FAILURE

Test108_OK_1a:
# Make sure the instruction executed.
	bnei		r1,1234,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AF,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Loc_1a+4		# r1 = expected csr_prevpc (Addr AFTER the instruction)
	movi		r2, TRAP_CAUSE_SINGLESTEP	# r2 = expected csr_cause  (Singlestep Exception code)
	loadw		r3,Test108_Loc_1a		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### Now return and get another Singlestep exception. THIS TIME IN USER MODE AND IN VIRTUAL SPACE.

	movi		r1,Test108_OK_1b
	stored		Jump_Singlestep,r1
	csrread		r1,csr_prevpc		# Adjust csr_prevpc to a user address
	movi		t,0x0000_0008_0000_0000	#
	or		r1,r1,t			#
	csrwrite	csr_prevpc,r1		#
	movi		r5,0x00000000000001AE	# SingleStep=1, InterruptsEnabled=1, KernelMode=0
	csrwrite	csr_stat2,r5
	sysret
	jump		FAILURE

Test108_OK_1b:
# Make sure the instruction executed.
	bnei		r1,0x1234,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AE,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Loc_1b+4		# r1 = expected csr_prevpc (Addr AFTER the instruction)
	movi		t,0x0000_0008_0000_0000		#   modify to user space
	or		r1,r1,t				#
	movi		r2, TRAP_CAUSE_SINGLESTEP	# r2 = expected csr_cause  (Singlestep Exception code)
	loadw		r3,Test108_Loc_1b		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### Now return and get YET ANOTHER another Singlestep exception. ALSO IN USER MODE.

	movi		r1,Test108_OK_1c
	stored		Jump_Singlestep,r1
# No need to adjust csr_prevpc, since we were in user space
	movi		r5,0x00000000000001AE	# SingleStep=1, InterruptsEnabled=1, KernelMode=0
	csrwrite	csr_stat2,r5
	sysret
	jump		FAILURE

Test108_OK_1c:
# Make sure the instruction executed.
	bnei		r1,0x4321,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AE,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Loc_1c+4		# r1 = expected csr_prevpc (Addr AFTER the instruction)
	movi		t,0x0000000800000000		#   modify to user space
	or		r1,r1,t				#
	movi		r2, TRAP_CAUSE_SINGLESTEP	# r2 = expected csr_cause  (Singlestep Exception code)
	loadw		r3,Test108_Loc_1c		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



##### Now return and get YET ANOTHER another Singlestep exception. ALSO IN USER MODE.
##### But this time, there will be an Arithmetic Exception that will override it.

	movi		r1,Test108_OK_1d
	stored		Jump_ArithmeticException,r1
# No need to adjust csr_prevpc, since we were in user space
	movi		r5,0x00000000000001AE
	csrwrite	csr_stat2,r5
# First, put a big number in reg r1 so the ADDI will overflow.
	movi		r1,0x7fffffffffffffff
	sysret
	jump		FAILURE

Test108_OK_1d:
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AE,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Loc_1d		# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		t,0x0000000800000000		#   modify to user space
	or		r1,r1,t				#
	movi		r2,TRAP_CAUSE_ARITHMETIC	# r2 = expected csr_cause  (Arithmetic Exception code)
	loadw		r3,Test108_Loc_1d		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs

# All done. Restore the Jump Table.
	call		InitJumpTable




##### USER MODE: Singlestep will be set, but interrupts will be disabled. The instructions should
#####            execute without problem, until we attempt to execute ILLEGAL.

	call		InitCSRs
	movi		r1,Test108_OK_1e
	stored		Jump_Illegal,r1
	movi		r1,Test108_Loc_1e	# Set csr_prevpc to point to the instructions
	movi		t,0x0000000800000000	#   which are virtual
	or		r1,r1,t			#
	csrwrite	csr_prevpc,r1		#
	movi		r5,0x00000000000001AC	# SingleStep=1, InterruptsEnabled=0, KernelMode=0
	csrwrite	csr_stat2,r5
	movi		r3,0
	sysret
	jump		FAILURE

Test108_Loc_1e:
	movi		r1,4		# The instruction sequence
	movi		r2,5
	add		r3,r1,r2
Test108_Loc_1e_ill:
	illegal
	jump		FAILURE

Test108_OK_1e:
# Check r3 to make sure the single step exception was ignored and we reached ILLEGAL.
	bnei		r3,9,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AC,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1, Test108_Loc_1e_ill			# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000			#   modify to user space
	add		r1,r1,t					#
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION	# r2 = expected csr_cause  (Illegal/Privileged Instruction Exception code)
	loadw		r3, Test108_Loc_1e_ill			# r3 = expected csr_bad    (The offending instruction)

	movi		r4,0					# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### USER MODE AND IN VIRTUAL SPACE. Execute a WRITE instruction. Make sure exactly one instruction executes.

	movi		r1,Test108_OK_1f
	stored		Jump_Singlestep,r1
	movi		r1,Test108_Loc_1f		# Make csr_prevpc point to the target (in virt space)
	movi		r4,0x0000_0008_0000_0000	#
	or		r1,r1,r4			#
	csrwrite	csr_prevpc,r1			#
	movi		r5,0x00000000000001AE		# SingleStep=1, InterruptsEnabled=1, KernelMode=0
	csrwrite	csr_stat2,r5
	movi		r2,Test108_var			# Store 0 in the memory location
	store.d		0(r2),r0			# .
	or		r2,r2,r4			# Make r2 point to this location in virtual space
	movi		r1,0x1234_1234_1234_1234	# Put a number in r1
	sysret
	jump		FAILURE


Test108_Loc_1f:
	store.d		0(r2),r1
	mov		r1,r0
	.align		8
Test108_var:
	.doubleword	0


Test108_OK_1f:
# Make sure the STORE executed, but not the MOV.
	bnei		r1,0x1234_1234_1234_1234,FAILURE
	load.d		r3,0(r2)
	bnei		r3,0x1234_1234_1234_1234,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AE,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Loc_1f+4		# r1 = expected csr_prevpc (Addr AFTER the instruction)
	movi		t,0x0000_0008_0000_0000		#   modify to user space
	or		r1,r1,t				#
	movi		r2, TRAP_CAUSE_SINGLESTEP	# r2 = expected csr_cause  (Singlestep Exception code)
	loadw		r3,Test108_Loc_1f		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### USER MODE AND IN VIRTUAL SPACE. Execute a BRANCH instruction (not taken).

	movi		r1,Test108_OK_1g
	stored		Jump_Singlestep,r1
	movi		r1,Test108_Loc_1g		# Make csr_prevpc point to the target (in virt space)
	movi		r4,0x0000_0008_0000_0000	#
	or		r1,r1,r4			#
	csrwrite	csr_prevpc,r1			#
	movi		r5,0x00000000000001AE		# SingleStep=1, InterruptsEnabled=1, KernelMode=0
	csrwrite	csr_stat2,r5
	movi		r2,Test108_var			# Store 0 in the memory location
	store.d		0(r2),r0			# .
	or		r2,r2,r4			# Make r2 point to this location in virtual space
	movi		r1,0x1234_1234_1234_1234	# Put a number in r1
	sysret
	jump		FAILURE

Test108_Loc_1g:
	beq		r1,r0,Test108_Targ_1g		# Branch not taken; next instruction is the MOV.
	mov		r1,r0
Test108_Targ_1g:
	illegal

Test108_OK_1g:
# Make sure the MOV did not execute.
	bnei		r1,0x1234_1234_1234_1234,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AE,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Loc_1g+4		# r1 = expected csr_prevpc (Addr AFTER the instruction)
	movi		t,0x0000_0008_0000_0000		#   modify to user space
	or		r1,r1,t				#
	movi		r2, TRAP_CAUSE_SINGLESTEP	# r2 = expected csr_cause  (Singlestep Exception code)
	loadw		r3,Test108_Loc_1g		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### USER MODE AND IN VIRTUAL SPACE. Execute a BRANCH instruction (taken).

	movi		r1,Test108_OK_1h
	stored		Jump_Singlestep,r1
	movi		r1,Test108_Loc_1h		# Make csr_prevpc point to the target (in virt space)
	movi		r4,0x0000_0008_0000_0000	#
	or		r1,r1,r4			#
	csrwrite	csr_prevpc,r1			#
	movi		r5,0x00000000000001AE		# SingleStep=1, InterruptsEnabled=1, KernelMode=0
	csrwrite	csr_stat2,r5
	movi		r1,0x1234_1234_1234_1234	# Put a number in r1
	sysret
	jump		FAILURE

Test108_Loc_1h:
	bne		r1,r0,Test108_Targ_1h		# Branch taken; next instruction is the ILLEGAL.
	mov		r1,r0
	nop
	nop
Test108_Targ_1h:
	illegal

Test108_OK_1h:
# Make sure the MOV did not execute.
	bnei		r1,0x1234_1234_1234_1234,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AE,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Targ_1h		# r1 = expected csr_prevpc (target of the branch)
	movi		t,0x0000_0008_0000_0000		#   modify to user space
	or		r1,r1,t				#
	movi		r2, TRAP_CAUSE_SINGLESTEP	# r2 = expected csr_cause  (Singlestep Exception code)
	loadw		r3,Test108_Loc_1h		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs




##### USER MODE AND IN VIRTUAL SPACE. Execute a JALR instruction (taken).

	movi		r1,Test108_OK_1i
	stored		Jump_Singlestep,r1
	movi		r1,Test108_Loc_1i		# Make csr_prevpc point to the target (in virt space)
	movi		r4,0x0000_0008_0000_0000	#
	or		r1,r1,r4			#
	csrwrite	csr_prevpc,r1			#
	movi		r5,0x00000000000001AE		# SingleStep=1, InterruptsEnabled=1, KernelMode=0
	csrwrite	csr_stat2,r5
	movi		r2,Test108_Targ_1i		# Make r2 point to the target (in virtual space)
	or		r2,r2,r4			# 
	movi		r1,0x1234_1234_1234_1234	# Put a number in r1
	sysret
	jump		FAILURE

Test108_Loc_1i:
	jalr		r3,0(r2)			# Branch taken; next instruction is the ILLEGAL.
Test108_Ret_1i:
	mov		r1,r0
	nop
	nop
Test108_Targ_1i:
	illegal

Test108_OK_1i:
# Make sure the MOV did not execute.
	bnei		r1,0x1234_1234_1234_1234,FAILURE
# Make sure the ret addr was stored in r3
	movi		r2,Test108_Ret_1i		# Make r2 point to the return addr 
	or		r2,r2,r4			# 
	bne		r3,r2,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AE,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Targ_1i		# r1 = expected csr_prevpc (target of the branch)
	movi		t,0x0000_0008_0000_0000		#   modify to user space
	or		r1,r1,t				#
	movi		r2, TRAP_CAUSE_SINGLESTEP	# r2 = expected csr_cause  (Singlestep Exception code)
	loadw		r3,Test108_Loc_1i		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs





##### USER MODE AND IN VIRTUAL SPACE. Execute a JALR instruction (NULL ADDRESS EXCEPTION).

	movi		r1,Test108_OK_1j
	stored		Jump_NullAddress,r1
	movi		r1,Test108_Loc_1j		# Make csr_prevpc point to the target (in virt space)
	movi		r4,0x0000_0008_0000_0000	#
	or		r1,r1,r4			#
	csrwrite	csr_prevpc,r1			#
	movi		r5,0x00000000000001AE		# SingleStep=1, InterruptsEnabled=1, KernelMode=0
	csrwrite	csr_stat2,r5
	movi		r2,0				# Make r2 point to the target (ZERO!)
	movi		r1,0x1234_1234_1234_1234	# Put a number in r1
	movi		r3,0x1234_1234_1234_1234	# Put a number in r3
	sysret
	jump		FAILURE

Test108_Loc_1j:
	jalr		r3,0(r2)			# Exception overrides singlestep
Test108_Ret_1j:
	mov		r1,r0
	nop
	nop
Test108_Targ_1j:
	illegal

Test108_OK_1j:
# Make sure the MOV did not execute.
	bnei		r1,0x1234_1234_1234_1234,FAILURE
# Make sure the ret addr was not stored in r3
	bnei		r3,0x1234_1234_1234_1234,FAILURE
# Check csr_stat2
	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AE,FAILURE
# Store value into it so CheckCSRs will not fail.
	movi		r5,0x00000000000001AB
	csrwrite	csr_stat2,r5
	movi		r1,Test108_Loc_1j		# r1 = expected csr_prevpc (address of offending instruction)
	movi		t,0x0000_0008_0000_0000		#   modify to user space
	or		r1,r1,t				#
	movi		r2, TRAP_CAUSE_NULL_ADDRESS	# r2 = expected csr_cause
	loadw		r3,Test108_Loc_1j		# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0				# r4 = expected csr_addr
	call		CheckCSRs



	call		InitJumpTable




###########################################################
#
# Test CHECKADDR when in KERNEL MODE.
#
Test_109: movi	s0,109

	movi		r1,Test109_WelcomeMess
	call		PrintString
	jump		Test109_WelcomeMess_X
Test109_WelcomeMess:
	.string		"Beginning Test 109 (CHECKADDR)...\n\0"
	.align		4
Test109_WelcomeMess_X:


LOAD1:	.equ	0
LOAD2:	.equ	1
LOAD4:	.equ	2
LOAD8:	.equ	3
STORE1:	.equ	4
STORE2:	.equ	5
STORE4:	.equ	6
STORE8:	.equ	7
	
CODE_SUCCESS:		.equ		0
CODE_NULL_ADDRESS:	.equ		1
CODE_UNALIGNED:		.equ		2
CODE_PAGE_ILLEGAL_ADDR:	.equ		3
CODE_PAGE_TABLE:	.equ		4
CODE_PAGE_INVALID:	.equ		5
CODE_PAGE_WRITE:	.equ		6
CODE_COPY_ON_WRITE:	.equ		7
CODE_FIRST_DIRTY:	.equ		8


# Prepare for PAGE_TABLE Exception
	movi		r1,0
	csrwrite	csr_pgtable,r1

	movi		r1,0
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_NULL_ADDRESS,FAILURE		# NULL_ADDRESS overrides PAGE_TABLE

	movi		r1,0x800000001
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_UNALIGNED,FAILURE	# UNALIGNED_LOAD_STORE overrides PAGE_TABLE

	movi		r1,8
	checkaddr	r2,r1,LOAD1
	bnei		r2, CODE_PAGE_ILLEGAL_ADDR,FAILURE		# PAGE_PRIVILEGE overrides PAGE_TABLE

	movi		r1,0x800000002
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_PAGE_TABLE,FAILURE		# And this causes PAGE_TABLE

# Restore csr_pgtable
	movi		r1,PageTable
	csrwrite	csr_pgtable,r1

	movi		r1,0x800000002
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE					# Now OK

	movi		r1,0
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_NULL_ADDRESS,FAILURE		# NULL_ADDRESS overrides PAGE_PRIVILEGE

	movi		r1,7
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_NULL_ADDRESS,FAILURE

	movi		r1,8
	checkaddr	r2,r1,LOAD1
	bnei		r2, CODE_PAGE_ILLEGAL_ADDR,FAILURE

	movi		r1,9
	checkaddr	r2,r1,LOAD1
	bnei		r2, CODE_PAGE_ILLEGAL_ADDR,FAILURE

	movi		r1,0
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_NULL_ADDRESS,FAILURE

	movi		r1,7
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_NULL_ADDRESS,FAILURE		# NULL_ADDRESS overrides UNALIGNED_LOAD_STORE

	movi		r1,8
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_PAGE_ILLEGAL_ADDR,FAILURE

	movi		r1,9
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_UNALIGNED,FAILURE	# UNALIGNED_LOAD_STORE overrides PAGE_PRIVILEGE

	movi		r1,0
	checkaddr	r2,r1,STORE8
	bnei		r2,CODE_NULL_ADDRESS,FAILURE

	movi		r1,7
	checkaddr	r2,r1,STORE8
	bnei		r2,CODE_NULL_ADDRESS,FAILURE		# NULL_ADDRESS overrides UNALIGNED_LOAD_STORE

	movi		r1,8
	checkaddr	r2,r1,STORE8
	bnei		r2,CODE_PAGE_ILLEGAL_ADDR,FAILURE

	movi		r1,9
	checkaddr	r2,r1,STORE8
	bnei		r2,CODE_UNALIGNED,FAILURE	# UNALIGNED_LOAD_STORE overrides PAGE_PRIVILEGE

	movi		r1,0x800000000					# Maps to location 0, but not problem
	checkaddr	r2,r1,STORE2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0x800000000					# Maps to location 0, but not problem
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0x800000001
	checkaddr	r2,r1,STORE2
	bnei		r2,CODE_UNALIGNED,FAILURE

	movi		r1,0x800000001
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_UNALIGNED,FAILURE


# This page is read-only

	movi		r1,0xaaaaa0000
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa0007
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa0006
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa0007
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaaa0004
	checkaddr	r2,r1,LOAD4
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa0005
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaaa0000
	checkaddr	r2,r1,LOAD8
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa0004
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaaa0000
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaaa0007
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaaa0006
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaaa0007
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

	movi		r1,0xaaaaa0004
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaaa0005
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

	movi		r1,0xaaaaa0000
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaaa0004
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

# This page is invalid

	movi		r1,0xbbbbb0000
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0007
	checkaddr	r2,r1,LOAD1
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0006
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0007
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xbbbbb0004
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0005
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xbbbbb0000
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0004
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xbbbbb0000
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0007
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0006
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0007
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

	movi		r1,0xbbbbb0004
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0005
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

	movi		r1,0xbbbbb0000
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_PAGE_INVALID,FAILURE

	movi		r1,0xbbbbb0004
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

# This page is read/ write; STORES should cause PAGE_FIRST_DIRTY


	movi		r1,0xaaaaa8000
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa8007
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa8006
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa8007
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaaa8004
	checkaddr	r2,r1,LOAD4
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa8005
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaaa8000
	checkaddr	r2,r1,LOAD8
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaaa8004
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaaa8000
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_FIRST_DIRTY,FAILURE

	movi		r1,0xaaaaa8007
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_FIRST_DIRTY,FAILURE

	movi		r1,0xaaaaa8006
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_FIRST_DIRTY,FAILURE

	movi		r1,0xaaaaa8007
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides FIRST_DIRTY

	movi		r1,0xaaaaa8004
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_FIRST_DIRTY,FAILURE

	movi		r1,0xaaaaa8005
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides FIRST_DIRTY

	movi		r1,0xaaaaa8000
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_FIRST_DIRTY,FAILURE

	movi		r1,0xaaaaa8004
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides FIRST_DIRTY

# This page is read/write/dirty; STORES should be ok.

	movi		r1,0xaaaab8000
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8007
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8006
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8007
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaab8004
	checkaddr	r2,r1,LOAD4
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8005
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaab8000
	checkaddr	r2,r1,LOAD8
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8004
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_UNALIGNED,FAILURE

# Store a value in this location
	movi		r1,0xaaaab8000
	movi		r2,0x5656_5656_5656_5656
	store.d		0(r1),r2
	movi		r2,0

	movi		r1,0xaaaab8000
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8007
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8006
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8007
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaab8004
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8005
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaab8000
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaab8004
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_UNALIGNED,FAILURE

# Verify that the location was unchanged.
	movi		r1,0xaaaab8000
	load.d		r2,0(r1)
	bnei		r2,0x5656_5656_5656_5656,FAILURE


# This page is read/copy-on-write; STORES should cause WRITE exception.

	movi		r1,0xaaaac0000
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac0007
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac0006
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac0007
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaac0004
	checkaddr	r2,r1,LOAD4
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac0005
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaac0000
	checkaddr	r2,r1,LOAD8
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac0004
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaac0000
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaac0007
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaac0006
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaac0007
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

	movi		r1,0xaaaac0004
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaac0005
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

	movi		r1,0xaaaac0000
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaac0004
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE


# This page is read/write/copy-on-write; STORES should cause COPY_ON_WRITE exception.

	movi		r1,0xaaaac8000
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac8007
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac8006
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac8007
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaac8004
	checkaddr	r2,r1,LOAD4
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac8005
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaac8000
	checkaddr	r2,r1,LOAD8
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaac8004
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaac8000
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_COPY_ON_WRITE,FAILURE

	movi		r1,0xaaaac8007
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_COPY_ON_WRITE,FAILURE

	movi		r1,0xaaaac8006
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_COPY_ON_WRITE,FAILURE

	movi		r1,0xaaaac8007
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides COPY_ON_WRITE

	movi		r1,0xaaaac8004
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_COPY_ON_WRITE,FAILURE

	movi		r1,0xaaaac8005
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides COPY_ON_WRITE

	movi		r1,0xaaaac8000
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_COPY_ON_WRITE,FAILURE

	movi		r1,0xaaaac8004
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides COPY_ON_WRITE

# This page is read/copy-on-write/dirty; STORES should cause WRITE exception.

	movi		r1,0xaaaad0000
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad0007
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad0006
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad0007
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaad0004
	checkaddr	r2,r1,LOAD4
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad0005
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaad0000
	checkaddr	r2,r1,LOAD8
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad0004
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaad0000
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaad0007
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaad0006
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaad0007
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

	movi		r1,0xaaaad0004
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaad0005
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

	movi		r1,0xaaaad0000
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_PAGE_WRITE,FAILURE

	movi		r1,0xaaaad0004
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_UNALIGNED,FAILURE	# UNALIGNED overrides WRITE

# This page is read/write/copy-on-write/dirty; STORES shouldbe ok.

	movi		r1,0xaaaad8000
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8007
	checkaddr	r2,r1,LOAD1
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8006
	checkaddr	r2,r1,LOAD2
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8007
	checkaddr	r2,r1,LOAD2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaad8004
	checkaddr	r2,r1,LOAD4
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8005
	checkaddr	r2,r1,LOAD4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaad8000
	checkaddr	r2,r1,LOAD8
	bnei		r2,CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8004
	checkaddr	r2,r1,LOAD8
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaad8000
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8007
	checkaddr	r2,r1,STORE1
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8006
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8007
	checkaddr	r2,r1,STORE2
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaad8004
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8005
	checkaddr	r2,r1,STORE4
	bnei		r2, CODE_UNALIGNED,FAILURE

	movi		r1,0xaaaad8000
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_SUCCESS,FAILURE

	movi		r1,0xaaaad8004
	checkaddr	r2,r1,STORE8
	bnei		r2, CODE_UNALIGNED,FAILURE


	call		goIntoKernelMode



###########################################################
#
# Test TLBCLEAR
#
# This test requires that at least 2 TLB registers exist (plus several more for the code and the stack). It will
# be using these entries in the page table, which are initialized as follows:
#
#
#    Addr of PTE           PTE          Virt Page   VirtPageAddr     Phys Page      PhysPageAddr     C   D   W   X   V
#    ===========   ==================   =========  ==============  =============  ================  === === === === ===
#    0x000019570:  0x000000300000000d     699054     0xaaaab8000             12    0x000000030000        D   W       V
#    0x000019578:  0x000000340000000f     699055     0xaaaabc000             13    0x000000034000        D   W   X   V
#
Test_110:
	movi		s0,110

# Verify that we have at least 256 Kbytes. Note 0x0_0004_0000 = 262,144 = 256K
	movi		r1,0x1234_5555_6789_aaaa
	stored		0x0_0003_fff8,r1
	loadd		r2,0x0_0003_fff8
	bnei		r2,0x1234_5555_6789_aaaa,FAILURE

# This will fail if memory is limited to 256K.
#	movi		r1,0x1234_5555_6789_aaaa
#	stored		0x0_0004_0000,r1
#	loadd		r2,0x0_0004_0000
#	bnei		r2,0x1234_5555_6789_aaaa,FAILURE



	movi		r1,Test110_WelcomeMess
	call		PrintString
	jump		Test110_WelcomeMess_X
Test110_WelcomeMess:
	.string		"Beginning Test 110 (TLBCLEAR)...\n\0"
	.align		4
Test110_WelcomeMess_X:

#	call		InitJumpTable

# Set the ASID to 1111.

	movi		r1,0x1111000000000000 | PageTable
	csrwrite	csr_pgtable,r1

# Store into virtual addresses. This will have the effect of loading two TLB registers

	movi		r1,0x1234567812345678
	stored		0xa_aaab_8000,r1
	movi		r1,0x8787656543432121
	stored		0xa_aaab_c008,r1

#	call		PrintTLBs

# Now load from the virtual addresses and verify that this works.

	loadd		r1,0xa_aaab_8000
	bnei		r1,0x1234567812345678,FAILURE

	loadd		r1,0xa_aaab_c008
	bnei		r1,0x8787656543432121,FAILURE

# Set the ASID to 2222.

	movi		r1,0x2222_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

# Store into virtual addresses. This will have the effect of loading two TLB registers
	movi		r1,0x1234567812345678
	stored		0xa_aaab_8000,r1
	movi		r1,0x8787656543432121
	stored		0xa_aaab_c008,r1

# Now modify the relevant PTEs to mark these pages as invalid.
	loadd		r1,0x0_0001_9570
	bnei		r1,0x000000300000000d,FAILURE
	andi		r1,r1,0xffff_ffff_ffff_fffe
	stored		0x0_0001_9570,r1

	loadd		r1,0x0_0001_9578
	bnei		r1,0x000000340000000f,FAILURE
	andi		r1,r1,0xffff_ffff_ffff_fffe
	stored		0x0_0001_9578,r1

# Now load from these virtual addresses and verify that this works.
# ----- This will cause a Page_Invalid_Exception if there are no TLB registers. -----

	loadd		r1,0xa_aaab_8000
	bnei		r1,0x1234567812345678,FAILURE
	loadd		r1,0xa_aaab_c008
	bnei		r1,0x8787656543432121,FAILURE

# Clear the TLBs for ASID 2222.
 
	tlbclear

# Set the ASID to 1111.

	movi		r1,0x1111_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

# Load from the virtual addresses and verify that they are still there.
# ----- This will cause a Page_Invalid_Exception if there are fewer than 4 TLB registers. -----

	loadd		r1,0xa_aaab_8000
	bnei		r1,0x1234567812345678,FAILURE
	loadd		r1,0xa_aaab_c008
	bnei		r1,0x8787656543432121,FAILURE

# Set the ASID to 2222.

	movi		r1,0x2222_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

# Load from the virtual address and verify that this causes a Page_Invalid_Exception -- KERNEL MODE

# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T110_1_OK
	stored		Jump_PageInvalid,r1
#	call		goIntoUserMode

# Perform the instruction
	movi		r2,0xa_aaab_8000		# With this address, a LOADD will become 2 instructions.
T110_1_Loc:
	loadd		r1,0(r2)
	jump		FAILURE

# Make sure all is good after the exception
T110_1_OK:
	movi		r1, T110_1_Loc			# r1 = expected csr_prevpc (Addr of offending instruction)
#	movi		t,0x0000_0008_0000_0000		#   which is in
#	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_PAGE_INVALID	# r2 = expected csr_cause  (Debug Exception code)
	movi		r3, 0				# r3 = expected csr_bad
	movi		r4,0xa_aaab_8000		# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs


# Load from the virtual address and verify that this causes a Page_Invalid_Exception -- USER MODE

# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T110_2_OK
	stored		Jump_PageInvalid,r1
	call		goIntoUserMode

# Perform the instruction
	movi		r2,0xa_aaab_8000		# With this address, a LOADD will become 2 instructions.
T110_2_Loc:
	loadd		r1,0(r2)
	jump		FAILURE

# Make sure all is good after the exception
T110_2_OK:
	movi		r1, T110_2_Loc			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_PAGE_INVALID	# r2 = expected csr_cause  (Debug Exception code)
	movi		r3, 0				# r3 = expected csr_bad
	movi		r4,0xa_aaab_8000		# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2



# Restore the relevant PTEs to mark these pages as valid.
	loadd		r1,0x0_0001_9570
	bnei		r1,0x000000300000000c,FAILURE
	ori		r1,r1,0x0000_0000_0000_0001
	stored		0x0_0001_9570,r1

	loadd		r1,0x0_0001_9578
	bnei		r1,0x000000340000000e,FAILURE
	ori		r1,r1,0x0000_0000_0000_0001
	stored		0x0_0001_9578,r1


# Store into virtual addresses. This will have the effect of loading two TLB registers
	movi		r1,0x1234567812345678
	stored		0xa_aaab_8000,r1
	movi		r1,0x8787656543432121
	stored		0xa_aaab_c008,r1

# Now modify the relevant PTEs to mark these pages as invalid.
	loadd		r1,0x0_0001_9570
	bnei		r1,0x000000300000000d,FAILURE
	andi		r1,r1,0xffff_ffff_ffff_fffe
	stored		0x0_0001_9570,r1

	loadd		r1,0x0_0001_9578
	bnei		r1,0x000000340000000f,FAILURE
	andi		r1,r1,0xffff_ffff_ffff_fffe
	stored		0x0_0001_9578,r1


# Verify that we can load from these addresses.
	loadd		r1,0xa_aaab_8000
	bnei		r1,0x1234567812345678,FAILURE
	loadd		r1,0xa_aaab_c008
	bnei		r1,0x8787656543432121,FAILURE
	



# Clear the TLBs for ASID 2222
	tlbclear



# Set the ASID to 1111.

	movi		r1,0x1111_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

# Load from the virtual addresses and verify that they are still there.
# ----- This will cause a Page_Invalid_Exception if there are fewer than 4 TLB registers. -----

	loadd		r1,0xa_aaab_8000
	bnei		r1,0x1234567812345678,FAILURE
	loadd		r1,0xa_aaab_c008
	bnei		r1,0x8787656543432121,FAILURE

# Set the ASID to 2222.

	movi		r1,0x2222_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1


# Load from the virtual address and verify that this causes a Page_Invalid_Exception -- KERNEL MODE

# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T110_3_OK
	stored		Jump_PageInvalid,r1
#	call		goIntoUserMode

# Perform the instruction
	movi		r2,0xa_aaab_c008		# With this address, a LOADD will become 2 instructions.
T110_3_Loc:
	loadd		r1,0(r2)
	jump		FAILURE

# Make sure all is good after the exception
T110_3_OK:
	movi		r1, T110_3_Loc			# r1 = expected csr_prevpc (Addr of offending instruction)
#	movi		t,0x0000_0008_0000_0000		#   which is in
#	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_PAGE_INVALID	# r2 = expected csr_cause  (Debug Exception code)
	movi		r3, 0				# r3 = expected csr_bad
	movi		r4,0xa_aaab_c008		# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs



# Load from the virtual address and verify that this causes a Page_Invalid_Exception -- USER MODE

# Setup
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T110_4_OK
	stored		Jump_PageInvalid,r1
	call		goIntoUserMode

# Perform the instruction
	movi		r2,0xa_aaab_c008		# With this address, a LOADD will become 2 instructions.
T110_4_Loc:
	loadd		r1,0(r2)
	jump		FAILURE

# Make sure all is good after the exception
T110_4_OK:
	movi		r1, T110_4_Loc			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		t,0x0000_0008_0000_0000		#   which is in
	add		r1,r1,t				#   virtual space
	movi		r2, TRAP_CAUSE_PAGE_INVALID	# r2 = expected csr_cause  (Debug Exception code)
	movi		r3, 0				# r3 = expected csr_bad
	movi		r4,0xa_aaab_c008		# r4 = expected csr_addr   (The bad address)
	call		CheckCSRs_2


	call		InitJumpTable


###########################################################
#
# Test TLBFLUSH
#
# This test requires that at least 4 TLB registers exist (plus several more for the code and the stack). It will
# be using these entries in the page table, which are initialized as follows:
#
#
#    Addr of PTE           PTE          Virt Page   VirtPageAddr     Phys Page      PhysPageAddr     C   D   W   X   V
#    ===========   ==================   =========  ==============  =============  ================  === === === === ===
#    0x000019570:  0x000000300000000d     699054     0xaaaab8000             12    0x000000030000        D   W       V
#    0x000019578:  0x000000340000000f     699055     0xaaaabc000             13    0x000000034000        D   W   X   V
#    0x000019580:  0x0000003800000011     699056     0xaaaac0000             14    0x000000038000    C               V
#    0x000019588:  0x0000003c00000013     699057     0xaaaac4000             15    0x00000003c000    C           X   V
#
Test_111:
	movi		s0,111



	movi		r1,Test111_WelcomeMess
	call		PrintString
	jump		Test111_WelcomeMess_X
Test111_WelcomeMess:
	.string		"Beginning Test 111 (TLBFLUSH)...\n\0"
	.align		4
Test111_WelcomeMess_X:


	call		InitPageTable

	tlbclear

# Store known values into pages 0x0_0003_0000, 0x0_0003_4000, 0x0_0003_8000, 0x0_0003_c000

	movi		r1, 0x3c00_1111_1111_9988
	stored		0x0_0003_0000, r1

	movi		r1, 0x4000_2222_2222_9988 
	stored		0x0_0003_4000, r1

	movi		r1, 0x4400_3333_3333_9988 
	stored		0x0_0003_8000, r1

	movi		r1, 0x4800_4444_4444_9988 
	stored		0x0_0003_c000, r1

# Set the ASID to 1111.

	movi		r1,0x1111_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

# Verify that the first two pages are accessible in the virtual space. This will load the TLBs.

	loadd		r1, 0xa_aaab_8000
	bnei		r1, 0x3c00_1111_1111_9988, FAILURE

	loadd		r1, 0xa_aaab_c000
	bnei		r1, 0x4000_2222_2222_9988, FAILURE

# Now change the ASID to 2222.

	movi		r1,0x2222_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

# Verify that the first two pages are accessible in the virtual space. This will load the TLBs.

	loadd		r1, 0xa_aaab_8000
	bnei		r1, 0x3c00_1111_1111_9988, FAILURE

	loadd		r1, 0xa_aaab_c000
	bnei		r1, 0x4000_2222_2222_9988, FAILURE

# Now alter the page table entries, now mapping the first two pages into the second two.

	movi		r1, 0x0000003800000011
	stored		0x000019570, r1

	movi		r1, 0x0000003c00000013
	stored		0x000019578, r1

# Verify that the TLB is being used for accesses

	loadd		r1, 0xa_aaab_8000
	bnei		r1, 0x3c00_1111_1111_9988, FAILURE

	loadd		r1, 0xa_aaab_c000
	bnei		r1, 0x4000_2222_2222_9988, FAILURE

# Now flush the first TLB entry for 2222

	movi		r1, 0xa_aaab_8000
	tlbflush	r1

# Go to 3333 and flush both addresses. This should have no effect on the existing TLB entries.

	movi		r1,0x3333_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

	movi		r1, 0xa_aaab_8000
	tlbflush	r1

	movi		r1, 0xa_aaab_c000
	tlbflush	r1

# Go to 2222

	movi		r1,0x2222_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

# Verify

	loadd		r1, 0xa_aaab_8000
	bnei		r1, 0x4400_3333_3333_9988, FAILURE		# Uses page table and gets new value

	loadd		r1, 0xa_aaab_c000
	bnei		r1, 0x4000_2222_2222_9988, FAILURE		# Still uses TLB

# Verify that the entries for 1111 are unchanged.

	movi		r1,0x1111_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

	loadd		r1, 0xa_aaab_8000
	bnei		r1, 0x3c00_1111_1111_9988, FAILURE		# Gets old value

	loadd		r1, 0xa_aaab_c000
	bnei		r1, 0x4000_2222_2222_9988, FAILURE		# Still uses TLB

# Go back to 2222.

	movi		r1,0x2222_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1

# Now restore the first entry and flush the second TLB entry.

	movi		r1, 0x000000300000000d
	stored		0x000019570, r1

	movi		r1, 0xa_aaab_c000 + 0x3fff
	tlbflush	r1

# Flush entries that are not in the TLB at all.

	movi		r1, 0xaaaad0000			# This address has a page table entry
	tlbflush	r1

	movi		r1, 0xb_bbbb_3333		# This address does not have a page table entry
	tlbflush	r1

# Verify

	loadd		r1, 0xa_aaab_8000
	bnei		r1, 0x4400_3333_3333_9988, FAILURE		# Uses the TLB

	loadd		r1, 0xa_aaab_c000
	bnei		r1, 0x4800_4444_4444_9988, FAILURE		# Uses page table and gets new value



###########################################################
#
# Test FENCE
#
# The FENCE instruction is extremely difficult to test and is not well tested here.
#
# In the MicroBlitz hardware, pretty much everything is done immediately; There
# is no store buffer and, since there is only one core, there is never any question
# about propagating changes to other cores at the time of a FENCE. All we do here
# is make sure the instruction can be executed in USER mode without exception and
# that the instruction immediately following it is executed.
#
Test_112:
	movi		s0,112

	movi		r1,Test112_WelcomeMess
	call		PrintString
	jump		Test112_WelcomeMess_X
Test112_WelcomeMess:
	.string		"Beginning Test 112 (FENCE)...\n\0"
	.align		4
Test112_WelcomeMess_X:

	call		InitCSRs
	call		InitJumpTable
	call		InitPageTable
	call		goIntoUserMode
	movi		r1,100

	fence					# Executed in User Mode
	addi		r1,r1,10

	controlu	r0,r0,ENABLE_KERNEL

	fence					# Executed in Kernel Mode
	add		r1,r1,r1

	nop
	nop
	bnei		r1,220,FAILURE




###########################################################
#
# Test CAS
#
Test_113:
	movi		s0,113



	movi		r1,Test113_WelcomeMess
	call		PrintString
	jump		Test113_WelcomeMess_X
Test113_WelcomeMess:
	.string		"Beginning Test 113 (CAS)...\n\0"
	.align		4
Test113_WelcomeMess_X:


# ---------------  First, execute CAS in Kernel Mode  ---------------

	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	call		InitPageTable

# ---------------  test success  ---------------

	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0007_ffff_ffff		# .  in kernel space
	and		r1,r1,r2				# .
	movi		r7,0x1234_7878_7878_9999		# Store some value in the variable
	stored		0(r1),r7				# .
	movi		r2,0x1234_7878_7878_9999		# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

	cas		r4,r1,r2,r3

	bnei		r4,1,FAILURE				# Expect success
	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0007_ffff_ffff		# .  in kernel space
	and		r1,r1,r2				# .
	loadd		r5,0(r1)				# Check variable
	bnei		r5,0x4321_3434_3434_8888,FAILURE	# .

# ---------------  test success (with unaligned address, which is rounded down) ---------------

	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0007_ffff_ffff		# .  in kernel space
	and		r1,r1,r2				# .
	movi		r7,0x1234_7878_7878_9999		# Store some value in the variable
	stored		0(r1),r7				# .
	movi		r2,0x1234_7878_7878_9999		# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

	addi		r4,r4,7					# r1 is unaligned
	cas		r4,r1,r2,r3

	bnei		r4,1,FAILURE				# Expect success
	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0007_ffff_ffff		# .  in kernel space
	and		r1,r1,r2				# .
	loadd		r5,0(r1)				# Check variable
	bnei		r5,0x4321_3434_3434_8888,FAILURE	# .

# ---------------  Test failure  ---------------

	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0007_ffff_ffff		# .  in kernel space
	and		r1,r1,r2				# .
	movi		r7,0x1234_7878_7878_9999		# Store some value in the variable
	stored		0(r1),r7				# .
	movi		r2,0x9234_7878_7878_9999		# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

	cas		r4,r1,r2,r3

	bnei		r4,0,FAILURE				# Expect failure
	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0007_ffff_ffff		# .  in kernel space
	and		r1,r1,r2				# .
	loadd		r5,0(r1)				# Check variable
	bnei		r5,0x1234_7878_7878_9999,FAILURE	# .


# ---------------  Test NULL ADDRESS EXCEPTION  ---------------

# Setup for exception
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T113_1_OK
	stored		Jump_NullAddress,r1
	movi		r1,0x0000_0000_0000_01ab
	csrwrite	csr_status,r1

# Setup for the instruction

	movi		r1,0					# r1 = address of variable
	movi		r2,0x1234_7878_7878_9999		# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

# Execute the instruction

T113_1_Loc:
	cas		r4,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T113_1_OK:

#	loadd		r5,0(r1)				# Check that nothing happened
#	bnei		r5,0x1234_7878_7878_9999,FAILURE	# .
	bnei		r4,0x2323_2323_2323_2323,FAILURE	# .

	movi		r1, T113_1_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T113_1_Loc				# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0					# r4 = expected csr_addr
	call		CheckCSRs



# ---------------  Next, execute CAS in user mode...  ---------------

	call		InitCSRs
	call		InitJumpTable
	call		InitPageTable
	call		goIntoUserMode



# ---------------  Test success  ---------------

	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r7,0x1234_7878_7878_9999		# Store some value in the variable
	stored		0(r1),r7				# .
	movi		r2,0x1234_7878_7878_9999		# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

	cas		r4,r1,r2,r3

	bnei		r4,1,FAILURE				# Expect success
	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	loadd		r5,0(r1)				# Check variable
	bnei		r5,0x4321_3434_3434_8888,FAILURE	# .

# ---------------  test success (with unaligned address, which is rounded down) ---------------

	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r7,0x1234_7878_7878_9999		# Store some value in the variable
	stored		0(r1),r7				# .
	movi		r2,0x1234_7878_7878_9999		# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

	addi		r4,r4,7					# r1 is unaligned
	cas		r4,r1,r2,r3

	bnei		r4,1,FAILURE				# Expect success
	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	loadd		r5,0(r1)				# Check variable
	bnei		r5,0x4321_3434_3434_8888,FAILURE	# .


# ---------------  Test failure  ---------------

	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r7,0x1234_7878_7878_9999		# Store some value in the variable
	stored		0(r1),r7				# .
	movi		r2,0x9234_7878_7878_9999		# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

	cas		r4,r1,r2,r3

	bnei		r4,0,FAILURE				# Expect failure
	movi		r1,casvar				# r1 = address of variable
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	loadd		r5,0(r1)				# Check variable
	bnei		r5,0x1234_7878_7878_9999,FAILURE	# .


# ---------------  Test NULL ADDRESS EXCEPTION  ---------------

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T113_2_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Setup for the instruction

	movi		r1,0					# r1 = address of variable
	movi		r2,0x1234_7878_7878_9999		# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

# Execute the instruction

T113_2_Loc:
	cas		r4,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T113_2_OK:

#	loadd		r5,0(r1)				# Check that nothing happened
#	bnei		r5,0x1234_7878_7878_9999,FAILURE	# .
	bnei		r4,0x2323_2323_2323_2323,FAILURE	# .

	movi		r1, T113_2_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T113_2_Loc				# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0					# r4 = expected csr_addr
	call		CheckCSRs_2


# ---------------  Test PAGE ILLEGAL EXCEPTION  TRAP_CAUSE_PAGE_ILLEGAL_ADDRESS 0x000004000---------------

# Setup for exception
	call		goIntoKernelMode			# Store previous value in r7
	loadd		r7, 0x0_0000_4000			#
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T113_3_OK
	stored		Jump_PageIllegalAddr,r1
	call		goIntoUserMode

# Setup for the instruction

	movi		r1, 0x0_0000_4000			# r1 = address of variable
	mov		r2, r7					# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

# Execute the instruction

T113_3_Loc:
	cas		r4,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T113_3_OK:

	bnei		r4,0x2323_2323_2323_2323,FAILURE	# Check that nothing happened
	loadd		r5, 0x0_0000_4000			# .
	bne		r5,r7,FAILURE				# .

	movi		r1, T113_3_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_PAGE_ILLEGAL_ADDRESS	# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x0_0000_4000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

# ---------------  Test PAGE WRITE EXCEPTION  TRAP_CAUSE_PAGE_WRITE 0xa_aaab_4000---------------

# Setup for exception
	call		goIntoKernelMode			# Store previous value in r7
	loadd		r7, 0x0_0003_8000			#
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T113_4_OK
	stored		Jump_PageWrite,r1
	call		goIntoUserMode

# Setup for the instruction

	movi		r1, 0xa_aaab_4000			# r1 = address of variable
	mov		r2, r7					# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

# Execute the instruction

T113_4_Loc:
	cas		r4,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T113_4_OK:

	bnei		r4,0x2323_2323_2323_2323,FAILURE	# Check that nothing happened
	loadd		r5, 0x0_0003_8000			# .
	bne		r5,r7,FAILURE				# .

	movi		r1, T113_4_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_PAGE_WRITE		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xa_aaab_4000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2


# ---------------  Test PAGE COPY-ON_WRITE EXCEPTION  TRAP_CAUSE_PAGE_COPY_ON_WRITE 0xa_aaac_c000 0_0003_4000---------------

# Setup for exception
	call		goIntoKernelMode			# Store previous value in r7
	loadd		r7, 0x0_0003_4000			#
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T113_5_OK
	stored		Jump_PageCopyOnWrite,r1
	call		goIntoUserMode

# Setup for the instruction

	movi		r1, 0xa_aaac_c000			# r1 = address of variable
	mov		r2, r7					# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

# Execute the instruction

T113_5_Loc:
	cas		r4,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T113_5_OK:

	bnei		r4,0x2323_2323_2323_2323,FAILURE	# Check that nothing happened
	loadd		r5, 0x0_0003_4000			# .
	bne		r5,r7,FAILURE				# .

	movi		r1, T113_5_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_PAGE_COPY_ON_WRITE	# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xa_aaac_c000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

# ---------------  Test PAGE ILLEGAL EXCEPTION  TRAP_CAUSE_PAGE_FIRST_DIRTY 0xa_aaaa_c000 0_0003_0000---------------

# Setup for exception
	call		goIntoKernelMode			# Store previous value in r7
	loadd		r7, 0x0_0003_0000			#
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T113_6_OK
	stored		Jump_PageFirstDirty,r1
	call		goIntoUserMode

# Setup for the instruction

	movi		r1, 0xa_aaaa_c000			# r1 = address of variable
	mov		r2, r7					# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

# Execute the instruction

T113_6_Loc:
	cas		r4,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T113_6_OK:

	bnei		r4,0x2323_2323_2323_2323,FAILURE	# Check that nothing happened
	loadd		r5, 0x0_0003_0000			# .
	bne		r5,r7,FAILURE				# .

	movi		r1, T113_6_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_PAGE_FIRST_DIRTY		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xa_aaaa_c000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

# ---------------  Test PAGE INVALID EXCEPTION TRAP_CAUSE_PAGE_INVALID 0xf_ffff_0000 (problem in root page) ---------------

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T113_7_OK
	stored		Jump_PageInvalid,r1
	call		goIntoUserMode

# Setup for the instruction

	movi		r1, 0xf_ffff_0000			# r1 = address of variable
	mov		r2, r7					# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

# Execute the instruction

T113_7_Loc:
	cas		r4,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T113_7_OK:

	bnei		r4,0x2323_2323_2323_2323,FAILURE	# Check that nothing happened

	movi		r1, T113_7_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xf_ffff_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

# ---------------  Test PAGE INVALID EXCEPTION TRAP_CAUSE_PAGE_INVALID 0xa_aaae_0000 (problem in index page) ---------------

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T113_8_OK
	stored		Jump_PageInvalid,r1
	call		goIntoUserMode

# Setup for the instruction

	movi		r1, 0xa_aaae_0000			# r1 = address of variable
	mov		r2, r7					# r2 = expected old value
	movi		r3,0x4321_3434_3434_8888		# r3 = new value
	movi		r4,0x2323_2323_2323_2323		# r4 = result to be stored in this reg

# Execute the instruction

T113_8_Loc:
	cas		r4,r1,r2,r3
	jump		FAILURE

# Make sure all is good after the exception
T113_8_OK:

	bnei		r4,0x2323_2323_2323_2323,FAILURE	# Check that nothing happened

	movi		r1, T113_8_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xa_aaae_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

	jump		casvar_x

		.align		8
casvar:		.doubleword	0
casvar_x:





###########################################################
#
# Test Page Table Exception
#
Test_114:
	movi		s0,114



	movi		r1,Test114_WelcomeMess
	call		PrintString
	jump		Test114_WelcomeMess_X
Test114_WelcomeMess:
	.string		"Beginning Test 114 (Page Table Exception)...\n\0"
	.align		4
Test114_WelcomeMess_X:

###############  Attempt to read a value using a virtual address. But before that, clear
###############  csr_pgtable (and also clear the TLBs), which will cause the exception.

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	call		InitPageTable
	movi		r1,T114_1_OK
	stored		Jump_PageTable,r1
	csrwrite	csr_pgtable,r0
	tlbclear

# Execute the instruction
	movi		r1, 0x8_0000_4000
T114_1_Loc:
	load.b		r4,0(r1)
	jump		FAILURE

# Make sure all is good after the exception
T114_1_OK:
	movi		r1, T114_1_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_TABLE		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0000_4000			# r4 = expected csr_addr (address causing the problem)
	movi		r5,0x1234_0000_0000_0000 | PageTable	# Restore csr_pgtable so CheckCSRs will be happy.
	csrwrite	csr_pgtable,r5
	call		CheckCSRs


###############  Attempt to jump to an address in the virtual space. But before that, clear
###############  csr_pgtable (and also clear the TLBs), which will cause the exception.
###############  Note that the exception will leave csr_prevpc pointing to the address of the branch target,
###############  not the branch instruction.

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	call		InitPageTable
	movi		r1,T114_2_OK
	stored		Jump_PageTable,r1
	csrwrite	csr_pgtable,r0
	tlbclear

# Execute the instruction
	movi		r1, 0x8_0000_8000
T114_2_Loc:
	jr		r1
	jump		FAILURE

# Make sure all is good after the exception
T114_2_OK:
	movi		r1, 0x8_0000_8000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_TABLE		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0000_8000			# r4 = expected csr_addr (address causing the problem)
	movi		r5,0x1234_0000_0000_0000 | PageTable	# Restore csr_pgtable so CheckCSRs will be happy.
	csrwrite	csr_pgtable,r5
	call		CheckCSRs




###########################################################
#
# Test FETCH Exceptions
#
# Instructions that can branch:
#   B.EQ
#   JAL
#   JALR
#   SYSRET
#
# User Mode:
#   Null Address Exception
#   Page Illegal Address Exception
#   Page Invalid Exception
#   Page Fetch Exception
#
# Kernel Mode:
#   Null Address Exception
#   Page Invalid Exception
#   Page Fetch Exception
#
Test_115:
	movi		s0,115



	movi		r1,Test115_WelcomeMess
	call		PrintString
	jump		Test115_WelcomeMess_X
Test115_WelcomeMess:
	.string		"Beginning Test 115 (Exceptions during FETCH)...\n\0"
	.align		4
Test115_WelcomeMess_X:

	call		InitPageTable

# Store entry for index page 2 into root page
	movi	r1,pt_2	
	stored	pt_addr_2,r1
# Store PTEs into index page 2
	movi	r1,index_2_0
	stored	index_addr_2_0,r1

	call		goIntoKernelMode

###############  In KERNEL MODE: Cause Page Fetch Exception -- using JALR -- address 0xa_aaaa_0000

# Setup for exception
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_1_OK
	stored		Jump_PageFetch,r1

# Execute the instruction
	movi		r1, 0xa_aaaa_0000

T115_1_Loc:
	jalr		r2,0(r1)
	jump		FAILURE

# Make sure all is good after the exception
T115_1_OK:
	movi		r1, 0xa_aaaa_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_FETCH		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xa_aaaa_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

###############  In KERNEL MODE: Cause Page Fetch Exception -- using SYSRET -- address 0xa_aaaa_0000

# Setup for exception
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_2_OK
	stored		Jump_PageFetch,r1

# Execute the instruction
	movi		r1, 0xa_aaaa_0000
	csrwrite	csr_prevpc,r1
	movi		r1, 0x0000_0000_0000_01ab	# Ints enabled, kernel mode
	csrwrite	csr_stat2,r1

T115_2_Loc:
	sysret
	jump		FAILURE

# Make sure all is good after the exception
T115_2_OK:
	movi		r1, 0xa_aaaa_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_FETCH		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xa_aaaa_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs


###############  In KERNEL MODE: Cause Page Invalid Exception -- using JALR -- address 0xa_aaae_0000

# Setup for exception
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_3_OK
	stored		Jump_PageInvalid,r1

# Execute the instruction
	movi		r1, 0xa_aaae_0000

T115_3_Loc:
	jalr		r2,0(r1)
	jump		FAILURE

# Make sure all is good after the exception
T115_3_OK:
	movi		r1, 0xa_aaae_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xa_aaae_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

###############  In KERNEL MODE: Cause Page Invalid Exception -- using SYSRET -- address 0xa_aaae_0000

# Setup for exception
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_4_OK
	stored		Jump_PageInvalid,r1

# Execute the instruction
	movi		r1, 0xa_aaae_0000
	csrwrite	csr_prevpc,r1
	movi		r1, 0x0000_0000_0000_01ab	# Ints enabled, kernel mode
	csrwrite	csr_stat2,r1

T115_4_Loc:
	sysret
	jump		FAILURE

# Make sure all is good after the exception
T115_4_OK:
	movi		r1, 0xa_aaae_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0xa_aaae_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee01
#	controlu	r1,r1,DIGITAL_WRITE

###############  In KERNEL MODE: Jump to a NULL address using JAL

# Setup for exception
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_5_OK
	stored		Jump_NullAddress,r1

# Execute the instruction
	auipc		r1,0			# Modify the following JAL instruction
	neg		r1,r1			# .  to jump to location 0
	addi		r1,r1,-52		# Handcrafted value to get the address of the JAL
	slli		r1,r1,4
	movi		r2,0x00ff_fff0
	and		r1,r1,r2
	movi		r2,0x1900_0002
	or		r1,r1,r2
	storew		T115_5_Loc,r1
	fence
T115_5_Loc:
	jal		r2,0
	jump		FAILURE

# Make sure all is good after the exception
T115_5_OK:
	movi		r1, T115_5_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T115_5_Loc				# r3 = expected csr_bad
	movi		r4, 0					# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee08
#	controlu	r1,r1,DIGITAL_WRITE


###############  In KERNEL MODE: Jump to a NULL address using JALR

# Setup for exception
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_6_OK
	stored		Jump_NullAddress,r1

# Execute the instruction
	movi		r1,0x0
T115_6_Loc:
	jalr		r2,0(r1)
	jump		FAILURE

# Make sure all is good after the exception
T115_6_OK:
	movi		r1, T115_6_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T115_6_Loc				# r3 = expected csr_bad
	movi		r4, 0					# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee09
#	controlu	r1,r1,DIGITAL_WRITE


###############  In KERNEL MODE: Jump to a NULL address using SYSRET

# Setup for exception
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_7_OK
	stored		Jump_NullAddress,r1

# Execute the instruction
	movi		r1, 0x0
	csrwrite	csr_prevpc,r1
	movi		r1, 0x0000_0000_0000_01ab	# Ints enabled, kernel mode
	csrwrite	csr_stat2,r1
T115_7_Loc:
	sysret
	jump		FAILURE

# Make sure all is good after the exception
T115_7_OK:
	movi		r1, T115_7_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T115_7_Loc				# r3 = expected csr_bad
	movi		r4, 0					# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee0a
#	controlu	r1,r1,DIGITAL_WRITE


###############  In USER MODE: Jump to a NULL address using JAL


# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_11_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# The last virtual page maps to the the currently executing page. Begin executing in this page,
# which will allow us to reach the target address with a short offset.
	movi		r1,T115_11_Jump
	movi		r2,0xf_ffff_c000
	or		r1,r1,r2
	jr		r1
T115_11_Jump:
	addi		r1,r2,1234

# Execute the instruction
	auipc		r1,0			# Modify the following instruction
						# .  to jump to location 0x8_0001_0000
	movi		r2,-0x0_0001_0000+0x48	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	andi		r3,r1,0x0000_000f
	slli		r1,r1,8
	movi		r2,0x00ff_f000
	and		r1,r1,r2
	movi		r2,0x1000_0110
	or		r1,r1,r2
	or		r1,r1,r3
	storew		T115_11_Loc,r1
	nop	
	fence
T115_11_Loc:
	b.eq		r1,r1,0
	jump		FAILURE

# Make sure all is good after the exception
T115_11_OK:

	movi		r1, T115_11_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_000f_ffff_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T115_11_Loc				# r3 = expected csr_bad
	movi		r4, 0					# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee14
#	controlu	r1,r1,DIGITAL_WRITE


###############  In USER MODE: Jump to a NULL address using JALR

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_8_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# Execute the instruction
	movi		r1,0x0
T115_8_Loc:
	jalr		r2,0(r1)
	jump		FAILURE

# Make sure all is good after the exception
T115_8_OK:

	movi		r1, T115_8_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_0008_0000_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T115_8_Loc				# r3 = expected csr_bad
	movi		r4, 0					# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee0b
#	controlu	r1,r1,DIGITAL_WRITE

###############  In USER MODE: Jump to a NULL address using SYSRET  --  Can't occur since SYSRET is privileged

###############  In USER MODE: Jump to a NULL address using B.EQ

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_13_OK
	stored		Jump_NullAddress,r1
	call		goIntoUserMode

# The last virtual page maps to the the currently executing page. Begin executing in this page,
# which will allow us to reach the target address with a short offset.
	movi		r1,T115_13_Jump
	movi		r2,0xf_ffff_c000
	or		r1,r1,r2
	jr		r1
T115_13_Jump:
	addi		r1,r2,1234

# Execute the instruction
	auipc		r1,0			# Modify the instruction to jump to 0x0_0000_0000
	addi		r1,r1,0x44		# Address of the instruction to modify
	movi		r2, 0x0_0000_0000
	sub		r1,r2,r1
	andi		r3,r1,0x0000_000f
	slli		r1,r1,8
	movi		r2,0x00ff_f000
	and		r1,r1,r2
	movi		r2,0x1000_0110
	or		r1,r1,r2
	or		r1,r1,r3
	storew		T115_13_Loc,r1
	nop	
	fence
T115_13_Loc:
	b.eq		r1,r1,0
	jump		FAILURE

# Make sure all is good after the exception
T115_13_OK:

	movi		r1, T115_13_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_000f_ffff_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T115_13_Loc				# r3 = expected csr_bad
	movi		r4, 0					# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee15
#	controlu	r1,r1,DIGITAL_WRITE

###############  In KERNEL MODE: Jump to a NULL address using B.EQ

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_14_OK
	stored		Jump_NullAddress,r1

# The last virtual page maps to the the currently executing page. Begin executing in this page,
# which will allow us to reach the target address with a short offset.
	movi		r1,T115_14_Jump
	movi		r2,0xf_ffff_c000
	or		r1,r1,r2
	jr		r1
T115_14_Jump:
	addi		r1,r2,1234

# Execute the instruction
	auipc		r1,0			# Modify the instruction to jump to 0x0_0000_0000
	addi		r1,r1,0x44		# Address of the instruction to modify
	movi		r2, 0x0_0000_0000
	sub		r1,r2,r1
	andi		r3,r1,0x0000_000f
	slli		r1,r1,8
	movi		r2,0x00ff_f000
	and		r1,r1,r2
	movi		r2,0x1000_0110
	or		r1,r1,r2
	or		r1,r1,r3
	storew		T115_14_Loc,r1
	nop	
	fence
T115_14_Loc:
	b.eq		r1,r1,0
	jump		FAILURE

# Make sure all is good after the exception
T115_14_OK:

	movi		r1, T115_14_Loc				# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2,0x0000_000f_ffff_0000		# .  in user space
	or		r1,r1,r2				# .
	movi		r2, TRAP_CAUSE_NULL_ADDRESS		# r2 = expected csr_cause
	loadw		r3, T115_14_Loc				# r3 = expected csr_bad
	movi		r4, 0					# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee16
#	controlu	r1,r1,DIGITAL_WRITE

###############  In USER MODE: Cause Page Illegal Address Exception -- using B.EQ -- target is 0x0_0000_0800

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_12_OK
	stored		Jump_PageIllegalAddr,r1
	call		goIntoUserMode

# The last virtual page maps to the the currently executing page. Begin executing in this page,
# which will allow us to reach the target address with a short offset.
	movi		r1,T115_12_Jump
	movi		r2,0xf_ffff_c000
	or		r1,r1,r2
	jr		r1
T115_12_Jump:
	addi		r1,r2,1234

# Execute the instruction
	auipc		r1,0			# Modify the instruction to jump to 0x0_0000_0800
	addi		r1,r1,0x44		# Address of the instruction to modify
	movi		r2, 0x0_0000_0800
	sub		r1,r2,r1
	andi		r3,r1,0x0000_000f
	slli		r1,r1,8
	movi		r2,0x00ff_f000
	and		r1,r1,r2
	movi		r2,0x1000_0110
	or		r1,r1,r2
	or		r1,r1,r3
	storew		T115_12_Loc,r1
	nop	
	fence
T115_12_Loc:
	b.eq		r1,r1,0
	jump		FAILURE

# Make sure all is good after the exception
T115_12_OK:
	movi		r1,0x0_0000_0800			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_ILLEGAL_ADDRESS	# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x0_0000_0800			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee17
#	controlu	r1,r1,DIGITAL_WRITE

###############  In USER MODE: Cause Page Illegal Address Exception -- using JAL -- address 0x7_ffff_fff0

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_9_OK
	stored		Jump_PageIllegalAddr,r1
	call		goIntoUserMode

# Execute the instruction

	auipc		r1,0			# Modify the following JAL instruction
						# .  to jump to location 0x7_ffff_fff0
	movi		r2,-0x7_FFFF_FFF0+0x40	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	slli		r1,r1,4
	movi		r2,0x00ff_fff0
	and		r1,r1,r2
	movi		r2,0x1900_0002
	or		r1,r1,r2
	storew		T115_9_Loc,r1
nop	
	fence

T115_9_Loc:
	jal		r2,0
	jump		FAILURE

# Make sure all is good after the exception
T115_9_OK:

	movi		r1, 0x0000_0007_ffff_fff0		# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_ILLEGAL_ADDRESS	# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x0000_0007_ffff_fff0		# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee0c
#	controlu	r1,r1,DIGITAL_WRITE

###############  In USER MODE: Cause Page Illegal Address Exception -- using JALR -- address 0x7_ffff_fff0

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_a_OK
	stored		Jump_PageIllegalAddr,r1
	call		goIntoUserMode

# Execute the instruction

	movi		r1,0x7_FFFF_FFF0
T115_a_Loc:
	jalr		r2,0(r1)
	jump		FAILURE

# Make sure all is good after the exception
T115_a_OK:

	movi		r1, 0x0000_0007_ffff_fff0		# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_ILLEGAL_ADDRESS	# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x0000_0007_ffff_fff0		# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee0d
#	controlu	r1,r1,DIGITAL_WRITE

###############  Add virtual page 4 to the page table, after the page we are executing in, and mark NOT-EXECUTABLE
#
#    Addr of PTE           PTE          Virt Page   VirtPageAddr     Phys Page      PhysPageAddr     C   D   W   X   V
#    ===========   ==================   =========  ==============  =============  ================  === === === === ===
#    0x000014018:  0x0000000c0000000f          3     0x80000c000              3    0x00000000c000        D   W   X   V
#    0x000014020:  0x0000000c0000000d          4     0x800010000              3    0x00000000c000        D   W   -   V

	movi	r1, 0x0000000c0000000d
	stored	0x000014020,r1
	tlbclear
	fence

###############  In USER MODE: Cause Page Fetch Exception -- using B.EQ -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_b_OK
	stored		Jump_PageFetch,r1
	call		goIntoUserMode

# Execute the instruction

	auipc		r1,0			# Modify the following instruction
						# .  to jump to location 0x8_0001_0000
	movi		r2,-0x8_0001_0000+0x4c	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	andi		r3,r1,0x0000_000f
	slli		r1,r1,8
	movi		r2,0x00ff_f000
	and		r1,r1,r2
	movi		r2,0x1000_0110
	or		r1,r1,r2
	or		r1,r1,r3
	storew		T115_b_Loc,r1
	nop	
	fence
T115_b_Loc:
	b.eq		r1,r1,0
	jump		FAILURE

# Make sure all is good after the exception
T115_b_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_FETCH		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee0e
#	controlu	r1,r1,DIGITAL_WRITE

###############  In KERNEL MODE: Cause Page Fetch Exception -- using B.EQ -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_15_OK
	stored		Jump_PageFetch,r1

# The last virtual page maps to the the currently executing page. Begin executing in this page,
# which will allow us to reach the target address with a short offset.
	movi		r1,T115_15_Jump
	movi		r2,0x8_0000_c000
	or		r1,r1,r2
	jr		r1
T115_15_Jump:
	addi		r1,r2,1234

# Execute the instruction
	auipc		r1,0			# Modify the instruction to jump to 0x8_0001_0000
	addi		r1,r1,0x4c		# Address of the instruction to modify
	movi		r2, 0x8_0001_0000
	sub		r1,r2,r1
	andi		r3,r1,0x0000_000f
	slli		r1,r1,8
	movi		r2,0x00ff_f000
	and		r1,r1,r2
	movi		r2,0x1000_0110
	or		r1,r1,r2
	or		r1,r1,r3
	storew		T115_15_Loc,r1
	nop	
	fence
T115_15_Loc:
	b.eq		r1,r1,0
	jump		FAILURE

# Make sure all is good after the exception
T115_15_OK:
	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_FETCH		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee15
#	controlu	r1,r1,DIGITAL_WRITE


###############  In USER MODE: Cause Page Fetch Exception -- using JAL -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_c_OK
	stored		Jump_PageFetch,r1
	call		goIntoUserMode

# Execute the instruction
	auipc		r1,0			# Modify the following instruction
						# .  to jump to location 0x8_0001_0000
	movi		r2,-0x8_0001_0000+0x44	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	slli		r1,r1,4
	movi		r2,0x00ff_fff0
	and		r1,r1,r2
	movi		r2,0x1900_0002
	or		r1,r1,r2
	storew		T115_c_Loc,r1
	nop	
	fence
T115_c_Loc:
	jal		r2,0
	jump		FAILURE

# Make sure all is good after the exception
T115_c_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_FETCH		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee0e
#	controlu	r1,r1,DIGITAL_WRITE


###############  In KERNEL MODE: Cause Page Fetch Exception -- using JAL -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_18_OK
	stored		Jump_PageFetch,r1

# The last virtual page maps to the the currently executing page. Begin executing in this page,
# which will allow us to reach the target address with a short offset.
	movi		r1,T115_18_Jump
	movi		r2,0x8_0000_c000
	or		r1,r1,r2
	jr		r1
T115_18_Jump:
	addi		r1,r2,1234

# Execute the instruction
	auipc		r1,0			# Modify the following instruction
						# .  to jump to location 0x8_0001_0000
	movi		r2,-0x8_0001_0000+0x44	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	slli		r1,r1,4
	movi		r2,0x00ff_fff0
	and		r1,r1,r2
	movi		r2,0x1900_0002
	or		r1,r1,r2
	storew		T115_18_Loc,r1
	nop	
	fence
T115_18_Loc:
	jal		r2,0
	jump		FAILURE

# Make sure all is good after the exception
T115_18_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_FETCH		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee0e
#	controlu	r1,r1,DIGITAL_WRITE

###############  In USER MODE: Cause Page Fetch Exception -- using JALR -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_d_OK
	stored		Jump_PageFetch,r1
	call		goIntoUserMode

# Execute the instruction

	movi		r1, 0x8_0001_0000
T115_d_Loc:
	jalr		r2,0(r1)
	jump		FAILURE

# Make sure all is good after the exception
T115_d_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_FETCH		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee10
#	controlu	r1,r1,DIGITAL_WRITE


###############  Modify virtual page 4 to mark it NOT VALID
#
#    Addr of PTE           PTE          Virt Page   VirtPageAddr     Phys Page      PhysPageAddr     C   D   W   X   V
#    ===========   ==================   =========  ==============  =============  ================  === === === === ===
#    0x000014018:  0x0000000c0000000f          3     0x80000c000              3    0x00000000c000        D   W   X   V
#    0x000014020:  0x0000000c0000000e          4     0x800010000              3    0x00000000c000        D   W   X   -

	movi	r1, 0x0000000c0000000e
	stored	0x000014020,r1
	tlbclear
	fence

###############  In USER MODE: Cause Page Invalid Exception -- using B.EQ -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_e_OK
	stored		Jump_PageInvalid,r1
	call		goIntoUserMode

# Execute the instruction

	auipc		r1,0			# Modify the following instruction
						# .  to jump to location 0x8_0001_0000
	movi		r2,-0x8_0001_0000+0x4c	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	andi		r3,r1,0x0000_000f
	slli		r1,r1,8
	movi		r2,0x00ff_f000
	and		r1,r1,r2
	movi		r2,0x1000_0110
	or		r1,r1,r2
	or		r1,r1,r3
	storew		T115_e_Loc,r1
	nop	
	fence
T115_e_Loc:
	b.eq		r1,r1,0
	jump		FAILURE

# Make sure all is good after the exception
T115_e_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee11
#	controlu	r1,r1,DIGITAL_WRITE

###############  In USER MODE: Cause Page Invalid Exception -- using JAL -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_f_OK
	stored		Jump_PageInvalid,r1
	call		goIntoUserMode

# Execute the instruction
	auipc		r1,0			# Modify the following instruction
						# .  to jump to location 0x8_0001_0000
	movi		r2,-0x8_0001_0000+0x44	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	slli		r1,r1,4
	movi		r2,0x00ff_fff0
	and		r1,r1,r2
	movi		r2,0x1900_0002
	or		r1,r1,r2
	storew		T115_f_Loc,r1
	nop	
	fence
T115_f_Loc:
	jal		r2,0
	jump		FAILURE

# Make sure all is good after the exception
T115_f_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee12
#	controlu	r1,r1,DIGITAL_WRITE

###############  In KERNEL MODE: Cause Page Invalid Address Exception -- using JAL -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_16_OK
	stored		Jump_PageInvalid,r1

# Begin executing in virtual space
	movi		r1,T115_16_Jump
	movi		r2,0x8_0000_0000
	or		r1,r1,r2
	jr		r1
T115_16_Jump:
	addi		r1,r2,1234

# Execute the instruction
	auipc		r1,0			# Modify the following instruction
						# .  to jump to location 0x8_0001_0000
	movi		r2,-0x8_0001_0000+0x44	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	slli		r1,r1,4
	movi		r2,0x00ff_fff0
	and		r1,r1,r2
	movi		r2,0x1900_0002
	or		r1,r1,r2
	storew		T115_16_Loc,r1
	nop	
	fence

T115_16_Loc:
	jal		r2,0
	jump		FAILURE

# Make sure all is good after the exception
T115_16_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee0c
#	controlu	r1,r1,DIGITAL_WRITE

###############  In KERNEL MODE: Cause Page Invalid Address Exception -- using B.EQ -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_17_OK
	stored		Jump_PageInvalid,r1

# Begin executing in virtual space
	movi		r1,T115_17_Jump
	movi		r2,0x8_0000_0000
	or		r1,r1,r2
	jr		r1
T115_17_Jump:
	addi		r1,r2,1234

# Execute the instruction
	auipc		r1,0			# Modify the following instruction
						# .  to jump to location 0x8_0001_0000
	movi		r2,-0x8_0001_0000+0x4c	# Handcrafted value to compute the PC-rel offset
	add		r1,r1,r2
	neg		r1,r1
	andi		r3,r1,0x0000_000f
	slli		r1,r1,8
	movi		r2,0x00ff_f000
	and		r1,r1,r2
	movi		r2,0x1000_0110
	or		r1,r1,r2
	or		r1,r1,r3
	storew		T115_17_Loc,r1
	nop	
	fence

T115_17_Loc:
	b.eq		r1,r1,0
	jump		FAILURE

# Make sure all is good after the exception
T115_17_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xee0c
#	controlu	r1,r1,DIGITAL_WRITE

###############  In USER MODE: Cause Page Invalid Exception -- using JALR -- address 0x8_0001_0000

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T115_10_OK
	stored		Jump_PageInvalid,r1
	call		goIntoUserMode

# Execute the instruction

	movi		r1, 0x8_0001_0000
T115_10_Loc:
	jalr		r2,0(r1)
	jump		FAILURE

# Make sure all is good after the exception
T115_10_OK:

	movi		r1, 0x8_0001_0000			# r1 = expected csr_prevpc (Addr of offending instruction)
	movi		r2, TRAP_CAUSE_PAGE_INVALID		# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0x8_0001_0000			# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs_2

#	movi		r1,0xee13
#	controlu	r1,r1,DIGITAL_WRITE



###########################################################
#
# Test Timer Interrupts
#
Test_116: movi		s0,116

	movi		r1,Test116_WelcomeMess
	call		PrintString
	jump		Test116_WelcomeMess_X
Test116_WelcomeMess:
	.string		"Beginning Test 116 (Timer Interrupts)...\n\0"
	.align		4
Test116_WelcomeMess_X:

# Determine how many cycles to execute 50 iterations of this loop
	csrread		r2,csr_cycle
	movi		r1,50
T116_loop1:
	addi		r1,r1,-1
	bnez		r1, T116_loop1
	csrread		r1,csr_cycle
	sub		r3,r1,r2

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T116_2_OK
	stored		Jump_TimerInterrupt,r1

# Set the timer interrupt to happen in this many cycles
	csrwrite	csr_timer,r3

# Loop for twice as long. The interrupt will happen during this time.
	movi		r1,100
T116_loop2:
	addi		r1,r1,-1
	bnez		r1, T116_loop2
	jump		FAILURE

# Make sure all is good after the exception
T116_2_OK:
	csrread		r1,csr_timer				# Check csr_timer. It will be e.g., -50 after going
	bgez		r1,FAILURE				# . thru GlobalTrapHandler
	blti		r1,-100,FAILURE				# .
	movi		r1,0x3333333333333333			# Reset csr_timer, so CheckCSRs will be happy.
	csrwrite	csr_timer,r1
	movi		r1, 0x123456789				# r1 = expected csr_prevpc (Addr of offending instruction)
	csrwrite	csr_prevpc, r1				# Could be anything, so ignore actual value.

	movi		r2, TRAP_CAUSE_TIMER			# r2 = expected csr_cause
	movi		r3, 0					# r3 = expected csr_bad
	movi		r4, 0					# r4 = expected csr_addr (address causing the problem)
	call		CheckCSRs

#	movi		r1,0xff01
#	controlu	r1,r1,DIGITAL_WRITE

###############  Now we will return to execution after the trap handler runs.

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T116_3_OK
	stored		Jump_TimerInterrupt,r1

# Set the timer interrupt to happen in this many cycles
	csrwrite	csr_timer,r3

# Loop. The interrupt will happen during this time.
	movi		r1,100
T116_3_loop:
	addi		r1,r1,-1
	bnez		r1, T116_3_loop
	jump		T116_3_done

# Trap handler:
T116_3_OK:

	movi		r2,0x7fff_ffff_ffff_ffff		# Reset the timer
	csrwrite	csr_timer,r2
	sysret

T116_3_done:

#	movi		r1,0xff02
#	controlu	r1,r1,DIGITAL_WRITE

###############  In this test, we will return to the interrupted code but will immediately get another interrupt.

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T116_4_Handler_1
	stored		Jump_TimerInterrupt,r1

# Set the timer interrupt to happen in this many cycles
	csrwrite	csr_timer,r3

# Loop. The interrupt will happen during this time.
	movi		r1,100
T116_4_loop:
	addi		r1,r1,-1
	bnez		r1, T116_4_loop
	jump		T116_4_done

T116_4_Handler_1:
	movi		r1,T116_4_Handler_2
	stored		Jump_TimerInterrupt,r1
	sysret

T116_4_Handler_2:
	movi		r2,0x7fff_ffff_ffff_ffff		# Reset the timer
	csrwrite	csr_timer,r2
	sysret

T116_4_done:

#	movi		r1,0xff03
#	controlu	r1,r1,DIGITAL_WRITE

	
	

###########################################################
#
# Test Unaligned Instructions - Basic Test
#
Test_117: movi		s0,117

	movi		r1,Test117_WelcomeMess
	call		PrintString
	jump		Test117_WelcomeMess_X
Test117_WelcomeMess:
	.string		"Beginning Test 117 (Unaligned Instructions)...\n\0"
	.align		4
Test117_WelcomeMess_X:


# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T117_1_OK
	stored		Jump_UnalignedLoadStore,r1
	stored		Jump_Illegal,r1
	nop

# At this time, this code causes these assembler messages:
#   Warning on line 15515: Instruction is not on halfword-aligned address
#   Warning on line 15505: The address specified in this PC-relative CALL/JUMP is not even
#   Warning on line 15515: The address specified in this PC-relative CALL/JUMP is not even

T117_1_bad:
	jump		T117_1_Here

	.byte		0x7f

T117_1_Here:
	.byte		0x01		# NOP instruction is 0x0100_0000
	.byte		0x00		# .
	.byte		0x00		# .
	.byte		0x00		# .
	
	jump		T117_1_allowed
	.align		4

# Make sure all is good after the exception
T117_1_OK:
# Don't bother trying to check the CSRs; the emulator and the FPGA fail in different ways.

	movi		r1, Test117_NOT_OK_Mess
	call		PrintString
	jump		T117_1_done

T117_1_allowed:
	movi		r1, Test117_OK_Mess
	call		PrintString
	jump		T117_1_done

Test117_OK_Mess:
	.string		"   Unaligned Instructions are allowed.\n\0"	
Test117_NOT_OK_Mess:
	.string		"   Unaligned Instructions are NOT allowed.\n\0"
	.align		4
T117_1_done:


###########################################################
#
# Test ENTERFUN and EXITFUN
#
Test_118: movi		s0,118

	movi		r1,Test118_WelcomeMess
	call		PrintString
	jump		Test118_WelcomeMess_X
Test118_WelcomeMess:
	.string		"Beginning Test 118 (ENTERFUN and EXITFUN)...\n\0"
	.align		4
Test118_WelcomeMess_X:

	movi		r1,0x3301
	controlu	r1,r1,DIGITAL_WRITE

	movi		sp,StackRegionX
	movi		lr,0x1234_5678_90ab_cdef
	stored		-8(sp),r0
	csrwrite	csr_cause,r0
	csrwrite	csr_prevpc,r0
	csrwrite	csr_bad,r0
	csrwrite	csr_addr,r0
nop
	enterfun	sp,sp,-0x40

	movi		r1,0x3321
	controlu	r1,r1,DIGITAL_WRITE

	bnei		sp,StackRegionX-0x40,FAILURE
	movi		r1,0x3331
	controlu	r1,r1,DIGITAL_WRITE
	loadd		r1, StackRegionX-8
	bnei		r1, 0x1234_5678_90ab_cdef, FAILURE

	movi		r1,0x3302
	controlu	r1,r1,DIGITAL_WRITE

	movi		sp,StackRegionX
	movi		lr,0x1234_5678_90ab_cdef
	stored		-8(sp),r0
	movi		r2,0x1000
	enterfun	r1,r2,+0x40
	bnei		r1,0x1000+0x40,FAILURE
	loadd		r1, StackRegionX-8
	bnei		r1, 0x1234_5678_90ab_cdef, FAILURE

	movi		r1,0x3303
	controlu	r1,r1,DIGITAL_WRITE

	movi		sp,StackRegionX-0x40
	movi		r1,T118_OK_1
	stored		StackRegionX-8,r1
	exitfun		sp,sp,0x40
	jump		FAILURE
T118_OK_1:
	bnei		sp, StackRegionX,FAILURE

	movi		r1,0x3304
	controlu	r1,r1,DIGITAL_WRITE

	movi		sp,StackRegionX-0x40
	movi		r1,T118_OK_2
	stored		StackRegionX-8,r1
	exitfun		r1,sp,0x40
	jump		FAILURE
T118_OK_2:
	bnei		sp, StackRegionX-0x40,FAILURE
	bnei		r1, StackRegionX,FAILURE

# Test ENTERFUN with arithmetic overflow

	movi		r1,0x3305
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitJumpTable
	movi		r1, T118_OK_3
	stored		Jump_ArithmeticException,r1
	movi		sp,StackRegionX
	movi		lr,0x1234_5678_90ab_cdef
	stored		-8(sp),r0
	movi		r2,0x7fff_ffff_ffff_fff0
	enterfun	r1,r2,+0x40
	jump		FAILURE
T118_OK_3:

# Test ENTERFUN with Null Address

	movi		r1,0x3306
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitJumpTable
	movi		r1, T118_OK_4
	stored		Jump_NullAddress,r1
	movi		sp,8
	movi		lr,0x1234_5678_90ab_cdef
	stored		-8(sp),r0
	movi		r2,0x1000
	enterfun	r1,r2,+0x40
	jump		FAILURE
T118_OK_4:

# Test ENTERFUN with Unaligned Address

	movi		r1,0x3307
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitJumpTable
	movi		r1, T118_OK_5
	stored		Jump_UnalignedLoadStore,r1
	movi		sp,0x101
	movi		lr,0x1234_5678_90ab_cdef
	stored		-8(sp),r0
	movi		r2,0x1000
	enterfun	r1,r2,+0x40
	jump		FAILURE
T118_OK_5:

# Test ENTERFUN with Page Write Exception

	movi		r1,0x3308
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T118_OK_6
	stored		Jump_PageWrite,r1
	movi		sp,0xa_aaaa_0100
	movi		lr,0x1234_5678_90ab_cdef
	stored		-8(sp),r0
	movi		r2,0x1000
	enterfun	r1,r2,+0x40
	jump		FAILURE
T118_OK_6:

# Test EXITFUN with arithmetic overflow

	movi		r1,0x3309
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitJumpTable
	movi		r1, T118_OK_7
	stored		Jump_ArithmeticException,r1
	movi		sp,StackRegionX
	movi		r1,FAILURE
	stored		StackRegionX-8,r1
	movi		r2,0x7fff_ffff_ffff_fff0
	exitfun		r1,r2,0x40
	jump		FAILURE
T118_OK_7:

# Test EXITFUN with Null Address

	movi		r1,0x330a
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitJumpTable
	movi		r1, T118_OK_8
	stored		Jump_NullAddress,r1
	movi		sp,0x1008
	exitfun		sp,sp,-0x1000
	jump		FAILURE
T118_OK_8:


# Test EXITFUN with Unaligned Exception

	movi		r1,0x330b
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitJumpTable
	movi		r1, T118_OK_9
	stored		Jump_UnalignedLoadStore,r1
	movi		sp,0x1107
	exitfun		sp,sp,-0x1000
	jump		FAILURE
T118_OK_9:

# Test EXITFUN with Page Invalid Exception

	movi		r1,0x330b
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T118_OK_10
	stored		Jump_PageInvalid,r1
	movi		sp,0x8_0001_1100
	exitfun		sp,sp,0x40
	jump		FAILURE
T118_OK_10:

	movi		sp, StackRegionX




###########################################################
#
# Test that ADD, ADDI, and ENTERFUN cause a Stack Overflow Exception.
#
# Verify that Arithmetic Exceptions take precedence over Stack Overflow Exceptions.
# Verify that sp is not updated.
#
Test_119: movi		s0,119

	movi		r1,Test119_WelcomeMess
	call		PrintString
	jump		Test119_WelcomeMess_X
Test119_WelcomeMess:
	.string		"Beginning Test 119 (Stack Overflow Exception)...\n\0"
	.align		4
Test119_WelcomeMess_X:

# Test ADDI - No stack overflow

	movi		r1,0x330c
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		sp,0x1040
	movi		r1,0x00000100000001ab
	csrwrite	csr_status,r1
	addi		sp,sp,-0x40
	bnei		sp,0x1000,FAILURE

# Test ADDI - stack overflow

	movi		r1,0x330d
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_2
	stored		Jump_StackOverflow,r1
	movi		sp,0x1040
	movi		r1,0x00000100000001ab
	csrwrite	csr_status,r1
	addi		sp,sp,-0x48
	jump		FAILURE
T119_OK_2:
	bnei		sp,0x1040,FAILURE

# Test ADD - No stack overflow

	movi		r1,0x330e
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		sp,0x1040
	movi		r1,0x00000100000001ab
	csrwrite	csr_status,r1
	movi		r1,-0x40
	add		sp,sp,r1
	bnei		sp,0x1000,FAILURE

# Test ADD - stack overflow

	movi		r1,0x330f
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_4
	stored		Jump_StackOverflow,r1
	movi		sp,0x1040
	movi		r1,0x00000100000001ab
	csrwrite	csr_status,r1
	movi		r1,-0x48
	add		sp,sp,r1
	jump		FAILURE
T119_OK_4:
	bnei		sp,0x1040,FAILURE

# Test ENTERFUN - No stack overflow

	movi		r1,0x3310
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1,StackRegionX-0x100
	slli		r1,r1,28
	ori		r1,r1,0x01ab
	csrwrite	csr_status,r1
	movi		sp,StackRegionX
	enterfun	sp,sp,-0x100
	bnei		sp, StackRegionX-0x100,FAILURE

# Test ENTERFUN - Stack overflow

	movi		r1,0x3311
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_5
	stored		Jump_StackOverflow,r1
	movi		r1,StackRegionX-0x100
	slli		r1,r1,28
	ori		r1,r1,0x01ab
	csrwrite	csr_status,r1
	movi		sp,StackRegionX
	enterfun	sp,sp,-0x108
	jump		FAILURE
T119_OK_5:
	bnei		sp, StackRegionX,FAILURE

# Test ADDI - stack overflow and arithmetic overflow; arithmetic takes precedence 
# 8000_0000_0000_0000 - 10 = 7fff_ffff_ffff_fff0 ... f_ffff_fff0 < f_ffff_fff8

	movi		r1,0x3312
	controlu	r1,r1,DIGITAL_WRITE

	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_6
	stored		Jump_ArithmeticException,r1
	movi		sp,0x8000_0000_0000_0000
	movi		r1,0xffffffff800001ab
	csrwrite	csr_status,r1
	addi		sp,sp,-0x10
	jump		FAILURE
T119_OK_6:
	bnei		sp, 0x8000_0000_0000_0000,FAILURE

# Test ADD - stack overflow and arithmetic overflow; arithmetic takes precedence 
# 8000_0000_0000_0000 - 10 = 7fff_ffff_ffff_fff0 ... f_ffff_fff0 < f_ffff_fff8

	movi		r1,0x3313
	controlu	r1,r1,DIGITAL_WRITE

	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_7
	stored		Jump_ArithmeticException,r1
	movi		sp,0x8000_0000_0000_0000
	movi		r1,0xffffffff800001ab
	csrwrite	csr_status,r1
	movi		r1,-0x10
	add		sp,sp,r1
	jump		FAILURE
T119_OK_7:
	bnei		sp, 0x8000_0000_0000_0000,FAILURE

# Test ENTERFUN - stack overflow and arithmetic overflow; arithmetic takes precedence 
# 8000_0000_0000_0000 - 10 = 7fff_ffff_ffff_fff0 ... f_ffff_fff0 < f_ffff_fff8

	movi		r1,0x3314
	controlu	r1,r1,DIGITAL_WRITE

	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_8
	stored		Jump_ArithmeticException,r1
	movi		sp,0x8000_0000_0000_0000
	movi		r1,0xffffffff800001ab
	csrwrite	csr_status,r1
	enterfun	sp,sp,-0x10
	jump		FAILURE
T119_OK_8:
	bnei		sp, 0x8000_0000_0000_0000,FAILURE

# Test ADDI - arithmetic overflow only, no stack overflow 

	movi		r1,0x3315
	controlu	r1,r1,DIGITAL_WRITE

	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_9
	stored		Jump_ArithmeticException,r1
	movi		sp,0x8000_0000_0000_0000
	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	addi		sp,sp,-0x08
	jump		FAILURE
T119_OK_9:
	bnei		sp, 0x8000_0000_0000_0000,FAILURE

# Test ADD - arithmetic overflow only, no stack overflow 

	movi		r1,0x3316
	controlu	r1,r1,DIGITAL_WRITE

	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_10
	stored		Jump_ArithmeticException,r1
	movi		sp,0x8000_0000_0000_0000
	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	movi		r1,-0x08
	add		sp,sp,r1
	jump		FAILURE
T119_OK_10:
	bnei		sp, 0x8000_0000_0000_0000,FAILURE

# Test ENTERFUN - arithmetic overflow only, no stack overflow 

	movi		r1,0x3316
	controlu	r1,r1,DIGITAL_WRITE

	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		r1, T119_OK_11
	stored		Jump_ArithmeticException,r1
	movi		sp,0x8000_0000_0000_0000
	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	enterfun	sp,sp,-0x08
	jump		FAILURE
T119_OK_11:
	bnei		sp, 0x8000_0000_0000_0000,FAILURE

# Set up a situation where the stack overflow condition is true. Then verify that it is
# NOT checked for ADD

	movi		r1,0x3317
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		sp,0x1040
	movi		r1,0xfffffffee00001ab
	csrwrite	csr_status,r1
	addi		r1,sp,0x08

# Set up a situation where the stack overflow condition is true. Then verify that it is
# NOT checked for ADDI

	movi		r1,0x3318
	controlu	r1,r1,DIGITAL_WRITE

	call		goIntoKernelMode
	call		InitPageTable
	call		InitJumpTable
	movi		sp,0x1040
	movi		r1,0xfffffffee00001ab
	csrwrite	csr_status,r1
	movi		r1,0x08
	add		r1,sp,r2

	movi		r1,0x00000000000001ab
	csrwrite	csr_status,r1
	movi		sp, StackRegionX


###########################################################
#
# Test RESTART instruction.
#
Test_120: movi		s0,120

	movi		r1,Test120_WelcomeMess
	call		PrintString
	jump		Test120_WelcomeMess_X
Test120_WelcomeMess:
	.string		"Beginning Test 120 (RESTART instruction)...\n\0"
	.align		4
Test120_WelcomeMess_X:


###############  In USER MODE: attempt RESTART -- ILLEGAL INSTRUCTION EXCEPTION

# Setup for exception
	call		goIntoKernelMode
	call		InitCSRs
	call		InitJumpTable
	movi		r1,T120_OK
	stored		Jump_Illegal,r1
	call		goIntoUserMode

# Execute the instruction

T120_inst:
	restart
	jump		FAILURE

# Make sure all is good after the exception
T120_OK:
	movi		r1, T120_inst				# r1 = expected csr_prevpc (Addr of the instruction)
	movi		t,0x0000_0008_0000_0000			#   which is in
	or		r1,r1,t					#   virtual space
	movi		r2,TRAP_CAUSE_ILLEGAL_INSTRUCTION	# r2 = expected csr_cause
	loadw		r3, T120_inst				# r3 = expected csr_bad    (The offending instruction)
	movi		r4,0					# r4 = expected csr_addr
	call		CheckCSRs_2

# Now in Kernel Mode, executing in Kernel space.


##########
##########  This test will jump back to the boot loader, so you may wish to disable it.
##########

	jump	skip_restart

do_restart:
	movi		r1,Test120_Restarting
	call		PrintString
	restart
	jump		FAILURE

skip_restart:
	movi		r1,Test120_Skipping
	call		PrintString
	jump		T120_done


Test120_Restarting:
	.string		"   About to RESTART...\n\0"
Test120_Skipping:
	.string		"   Test disabled: Skipping the RESTART...\n\0"
	.align		4

T120_done:

###########################################################
#
# Unused test numbers
#
Test_121: movi		s0,121
Test_122: movi		s0,122
Test_123: movi		s0,123



# For fun, trying looping back and repeating the entire program, forever.
# This is useful for seeing how many instructions per second are executed.
# On my MAC laptop: 55 million IPS (instructions/sec)
#
#	movi		r1,0x0000000000000001
#	csrwrite	csr_status,r1
#	jump		_entry



	jump		SUCCESS



############################################################################
############################################################################
##
##  GLOBAL DATA
##
############################################################################
############################################################################

# Force doubleword alignment
		.align		8

#
# The number of TLB registers
#
TLB_COUNT:	.doubleword	-1

#
# These variables are initialized after exception processing has been
# tested. They indicate whether this core implements these or whether
# these operations must be done in software.
#
Unaligned_Load_Is_Implemented:		.byte	0
Unaligned_Store_Is_Implemented:		.byte	0
Divide_Is_Implemented:			.byte	0

Floating_Is_Implemented:		.byte	0
FMUL_Is_Implemented:			.byte	0
FDIV_Is_Implemented:			.byte	0
FSQRT_Is_Implemented:			.byte	0

FCVTFI_Is_Implemented:			.byte	0
FCVTIF_Is_Implemented:			.byte	0

# Make sure we are still aligned
					.align	8
# Floating constants

zero:			.float		0.0
one:			.float		1.0
two:			.float		2.0
three:			.float		3.0
four:			.float		4.0
five:			.float		5.0
seven:			.float		7.0
twelve:			.float		12.0
nineteen:		.float		19.0
twenty_five:		.float		25.0

root_two:		.doubleword	0x3FF6A09E667F3BCD		# 1.414213562373095145474621859
root_two_2:		.float		1.414213562373095145474621859	# This produces identical bytes

neg_zero:		.float		-0.0
neg_one:		.float		-1.0
neg_two:		.float		-2.0
neg_three:		.float		-3.0
neg_four:		.float		-4.0
neg_five:		.float		-5.0
neg_seven:		.float		-7.0
neg_twelve:		.float		-12.0
neg_nineteen:		.float		-19.0
neg_twenty_five:	.float		-25.0


f_max_pos:	.doubleword	0x43E0000000000000	# Exactly +9.223_372_036_854_775_808 e +18
							# 0x7FFFFFFFFFFFFFFF = 9,223,372,036,854,775,807
f_min_neg:	.doubleword	0xC3E0000000000000	# Exactly -9.223_372_036_854_775_808 e +18
							# 0x8000000000000000 = -9,223,372,036,854,775,808

f_max_pos_1:	.doubleword	0x43E0000000000001	# About 9.223_372_036_854_777_86 e +18
f_min_neg_1:	.doubleword	0xC3E0000000000001	# About -9.223_372_036_854_777_86 e +18

f_max_pos_2:	.doubleword	0x43DFFFFFFFFFFFFF	# Equal to 9,223,372,036,854,774,784.0
f_min_neg_2:	.doubleword	0xC3DFFFFFFFFFFFFF	# Equal -9,223,372,036,854,774,784.0

f_max:		.doubleword	0x7fefffffffffffff	# +1.79769313486231571e+308
f_min:		.doubleword	0xffefffffffffffff	# -1.79769313486231571e+308

pos_inf:	.doubleword	0x7ff0000000000000
neg_inf:	.doubleword	0xfff0000000000000

NaN:		.doubleword	0xffffffffffffffff	# Quiet NaN
sNaN:		.doubleword	0x7ff0000000000001	# Signaling NaN, used on x86, ARM
qNaN:		.doubleword	0x7ff8000000000001	# Quiet NaN, used on x86, ARM
weird_qNaN:	.doubleword	0xfff8000000000000	# Quiet NaN that is peculiar to C on Mac
strange_sNaN:		.doubleword	0x7ff0000123400000	# My strange signaling NaN
subnorm_1:	.doubleword     0x0000000000000001      # Smallest,        about 4.94065645841246544 e-324
subnorm_2:	.doubleword     0x0008000000000000      # Largest,         about 1.11253692925360069 e-308
smallest_norm:	.doubleword	0x0010000000000000      # Smallest normal, about 2.22507385850720138 e-308






###########################################################
#
# GlobalTrapHandler
#
# This is the routine that is invoked when an exception occurs.
#
# Previously, we stored a jump to this routine into csr_trapvec.
#
# This routine will look at csr_cause and use
# it to determine which entry in the JumpTable above is relevant.
# Then this routine will get the address from the JumpTable and
# branch to to it.
#
# The benefit of doing it this way is that the individual tests
# can simply update the JumpTable entries to get control after the
# exception occurs.
#
# REGISTERS USED:   s1,s2,t
#

GlobalTrapHandler:
	csrread	s1,csr_cause			# Load the cause code
	movi	s2,0x2000			# IF not a SYSCALL...
	blt	s1,s2,gotSyscall		#

	movi	s2,JumpTableBeyond		#   IF this value is out-of-range...
	bge	s1,s2,FAILURE			#     Jump to FAILURE
	addi	s1,s1,-0x2000			#   Use the cause code to index into the table
	movi	t,JumpTable			#   .
	add	s1,s1,t				#   .
	loadd	s1,0(s1)			#   Get the address of the handler from table
	jr	s1				#   Jump to the handler

gotSyscall:					# ELSE it is a SYSCALL...
	mov	r1,s1				#   r1 = syscall code (*8)
	loadd	s1,Jump_SyscallHandler		#   Jump to the current syscall handler
	jr	s1				#   .


# Here is a table of addresses. Each slot contains the address of some code.
# The idea is that these addresses will be used by the global trap handler.
# When an exception occurs, the global trap handler will go to this table,
# find the corresponding address, and then JUMP to that address.
#
# For now, we are just storing the address for FAILURE for each entry, but we
# will change these entries when we begin testing exception processing later
# in this program's execution.

	.align		8
JumpTable:

#   8192   0x2000   Arithmetic Exception
Jump_ArithmeticException:
	.doubleword	FAILURE

#   8200   0x2008   Unaligned LOAD/STORE
Jump_UnalignedLoadStore:
	.doubleword	FAILURE

#   8208   0x2010   Null Address Exception
Jump_NullAddress:
	.doubleword	FAILURE

#   8216   0x2018   Illegal Instruction, privilege violation
Jump_Illegal:
	.doubleword	FAILURE

#   8224   0x2020   Page Privilege Exception - attempt to access kernel space
Jump_PageIllegalAddr:
	.doubleword	FAILURE

#   8232   0x2028   Page Table Exception - bad csr_pgtable
Jump_PageTable:
	.doubleword	FAILURE

#   8240   0x2030   Page Invalid Exception - either index page or PTE
Jump_PageInvalid:
	.doubleword	FAILURE

#   8248   0x2038   Page Write Exception
Jump_PageWrite:
	.doubleword	FAILURE

#   8256   0x2040   Page Fetch Exception
Jump_PageFetch:
	.doubleword	FAILURE

#   8264   0x2048   Page Copy-On-Write Exception
Jump_PageCopyOnWrite:
	.doubleword	FAILURE

#   8272   0x2050   Page First Dirty Exception
Jump_PageFirstDirty:
	.doubleword	FAILURE

#   8280   0x2058   Debug Exception
Jump_Debug:
	.doubleword	FAILURE

#   8288   0x2060   Breakpoint Exception
Jump_Breakpoint:
	.doubleword	FAILURE

#   8296   0x2068   Singlestep Exception
Jump_Singlestep:
	.doubleword	FAILURE

#   8304   0x2070   Emulated Instruction Exception
Jump_EmulatedInstruction:
	.doubleword	FAILURE

#   8312   0x2078   Hardware Fault Exception
Jump_HardwareFault:
	.doubleword	FAILURE

#   8320   0x2080   Bad Array Index Exception
Jump_BadArrayIndex:
	.doubleword	FAILURE

#   8328   0x2088   Stack Overflow
Jump_StackOverflow:
	.doubleword	FAILURE

#   8336   0x2090   Timer Interrupt
Jump_TimerInterrupt:
	.doubleword	FAILURE


Jump_SyscallHandler:
	.doubleword	FAILURE

JumpTableBeyond:


###########################################################
#
# InitJumpTable
#
# This function resets the JumpTable so all entries point to FAILURE.
#
# Reg Usage: r1,r2
# Stack:     Not Used; this is a leaf function
#
InitJumpTable:
	movi		r2,FAILURE
	movi		r1,JumpTable
InitJT_Loop:
	stored		0(r1),r2
	addi		r1,r1,8
	bnei		r1,JumpTableBeyond,InitJT_Loop

# Set csr_trapvec so the table will be used.
	movi		r1, GlobalTrapHandler
	csrwrite	csr_trapvec,r1

# Clear some CSRs
	csrwrite	csr_cause,r0
	csrwrite	csr_stat2,r0
	csrwrite	csr_prevpc,r0
	csrwrite	csr_bad,r0
	csrwrite	csr_addr,r0
	ret


###########################################################
#
# InitCSRs
#
# This function resets all CSRs to known values. This a useful thing
# to do before an exception, so we can verify that exactly the right
# CSRs are modified by the exception.
#
# Reg Usage: r1,r2
# Stack:     Not Used; this is a leaf function
#
InitCSRs:
	movi		r1,0x3333333333333333
	csrwrite	csr_timer,r1

	movi		r1,0x00000000000001AB	# FloatRound=01, FloatStat=10101,
	csrwrite	csr_status,r1		# SingleStep=0, InterruptsEnabled=1, KernelMode=1

	movi		r1,0x5555555555555555
	csrwrite	csr_stat2,r1
	movi		r1,0x6666666666666666
	csrwrite	csr_prevpc,r1
	movi		r1,0x7777777777777777
	csrwrite	csr_cause,r1
	movi		r1,0x8888888888888888
	csrwrite	csr_bad,r1
	movi		r1,0x9999999999999999
	csrwrite	csr_addr,r1
	movi		r1,0xaaaaaaaaaaaaaaaa
	csrwrite	csr_ptr,r1
	movi		r1,0xbbbbbbbbbbbbbbbb
	csrwrite	csr_temp,r1
#	movi		r1,0xcccccccccccccccc
#	csrwrite	csr_trapvec,r1
	movi		r1,0x1234_0000_0000_0000 | PageTable
	csrwrite	csr_pgtable,r1
	ret


###########################################################
#
# CheckCSRs
#
# This function looks at the CSRs after an exception has been
# triggered and makes sure they contain the correct values. It jumps
# to FAILURE if problems.
#
### This function assumes the exception occurred in KERNEL MODE.
#
# The following CSRs will have values that depend on the exception
# details. Therefore, the expected values are passed in as arguments.
#     r1 = csr_prevpc
#     r2 = csr_cause
#     r3 = csr_bad
#     r4 = csr_addr
#
# Regs modified: r5
# Stack:         Not Used; this is a leaf function
#
CheckCSRs:

	csrread		r5,csr_timer
#	andi		r5,r5,0xFFFFFFFFFFFF8000	# It changes, so ignore LS bits
#	bnei		r5,0x3333333333330000,FAILURE_timer
##### With printing, this will be exceeded, so change above to...
	movi		t,0xFFFFFFFFFF000000		# It changes, so ignore LS bits
	and		r5,r5,t
	bnei		r5,0x3333333333000000,FAILURE_timer

	csrread		r5,csr_status
	bnei		r5,0x00000000000001A9,FAILURE_status	# Unchanged, except IntEnabled=0

	csrread		r5,csr_stat2
	bnei		r5,0x00000000000001AB,FAILURE_stat2	# Previous value of csr_status

	csrread		r5,csr_prevpc
	bne		r5,r1,FAILURE_prevpc

	csrread		r5,csr_cause
	bne		r5,r2,FAILURE_cause

	csrread		r5,csr_bad
	bne		r5,r3,FAILURE_bad

	csrread		r5,csr_addr
	bne		r5,r4,FAILURE_addr

	csrread		r5,csr_ptr
	bnei		r5,0xaaaaaaaaaaaaaaaa,FAILURE_ptr

	csrread		r5,csr_temp
	bnei		r5,0xbbbbbbbbbbbbbbbb,FAILURE_temp

	csrread		r5,csr_trapvec
	movi		t,GlobalTrapHandler
	bne		r5,t,FAILURE_trapvec

	csrread		r5,csr_pgtable
	bnei		r5,0x1234_0000_0000_0000 | PageTable,FAILURE_pgtable

# csr_prod and csr_core are read-only so don't check them.
	ret


FAILURE_timer:
	movi		r1, FAILURE_timer_mess
	call		PrintString
	jump		FAILURE
FAILURE_status:
	movi		r1, FAILURE_status_mess
	call		PrintString
	jump		FAILURE
FAILURE_stat2:
	movi		r1, FAILURE_stat2_mess
	call		PrintString
	jump		FAILURE
FAILURE_prevpc:
	movi		r1, FAILURE_prevpc_mess
	call		PrintString
	jump		FAILURE
FAILURE_cause:
	movi		r1, FAILURE_cause_mess
	call		PrintString
	jump		FAILURE
FAILURE_bad:
	movi		r1, FAILURE_bad_mess
	call		PrintString
	jump		FAILURE
FAILURE_addr:
	movi		r1, FAILURE_addr_mess
	call		PrintString
	jump		FAILURE
FAILURE_ptr:
	movi		r1, FAILURE_ptr_mess
	call		PrintString
	jump		FAILURE
FAILURE_temp:
	movi		r1, FAILURE_temp_mess
	call		PrintString
	jump		FAILURE
FAILURE_trapvec:
	movi		r1, FAILURE_trapvec_mess
	call		PrintString
	jump		FAILURE
FAILURE_pgtable:
	movi		r1, FAILURE_pgtable_mess
	call		PrintString
	jump		FAILURE

FAILURE_timer_mess:	.string		"--> csr_timer mismatch\n\0"
FAILURE_status_mess:	.string		"--> csr_status mismatch\n\0"
FAILURE_stat2_mess:	.string		"--> csr_stat2 mismatch\n\0"
FAILURE_prevpc_mess:	.string		"--> csr_prevpc mismatch\n\0"
FAILURE_cause_mess:	.string		"--> csr_cause mismatch\n\0"
FAILURE_bad_mess:	.string		"--> csr_bad mismatch\n\0"
FAILURE_addr_mess:	.string		"--> csr_addr mismatch\n\0"
FAILURE_ptr_mess:	.string		"--> csr_ptr mismatch\n\0"
FAILURE_temp_mess:	.string		"--> csr_temp mismatch\n\0"
FAILURE_trapvec_mess:	.string		"--> csr_trapvec mismatch\n\0"
FAILURE_pgtable_mess:	.string		"--> csr_pgtable mismatch\n\0"
	.align		4


###########################################################
#
# CheckCSRs_2
#
# This function looks at the CSRs after an exception has been
# triggered and makes sure they contain the correct values. It jumps
# to FAILURE if problems.
#
### This function assumes the exception occurred in USER MODE.
#
# The following CSRs will have values that depend on the exception
# details. Therefore, the expected values are passed in as arguments.
#     r1 = csr_prevpc
#     r2 = csr_cause
#     r3 = csr_bad
#     r4 = csr_addr
#
# Regs modified: r5
# Stack:         Not Used; this is a leaf function
#
CheckCSRs_2:

	csrread		r5,csr_timer
#	andi		r5,r5,0xFFFFFFFFFFFF8000	# It changes, so ignore LS bits
#	bnei		r5,0x3333333333330000,FAILURE_timer
##### With printing, this will be exceeded, so change above to...
	movi		t,0xFFFFFFFFFF000000		# It changes, so ignore LS bits
	and		r5,r5,t
	bnei		r5,0x3333333333000000,FAILURE_timer

	csrread		r5,csr_status
	bnei		r5,0x0000000000000001,FAILURE_status	# Current value of csr_status: Ints=Disabled, Mode=Kernel

	csrread		r5,csr_stat2
	bnei		r5,0x0000000000000002,FAILURE_stat2	# Previous value of csr_status: Ints=Enabled, Mode=User

	csrread		r5,csr_prevpc
	bne		r5,r1,FAILURE_prevpc

	csrread		r5,csr_cause
	bne		r5,r2,FAILURE_cause

	csrread		r5,csr_bad
	bne		r5,r3,FAILURE_bad

	csrread		r5,csr_addr
	bne		r5,r4,FAILURE_addr

	csrread		r5,csr_ptr
	bnei		r5,0xaaaaaaaaaaaaaaaa,FAILURE_ptr

	csrread		r5,csr_temp
	bnei		r5,0xbbbbbbbbbbbbbbbb,FAILURE_temp

	csrread		r5,csr_trapvec
	movi		t,GlobalTrapHandler
	bne		r5,t,FAILURE_trapvec

	csrread		r5,csr_pgtable
	bnei		r5,0x1234_0000_0000_0000 | PageTable,FAILURE_pgtable

# csr_prod and csr_core are read-only so don't check them.
	ret


###########################################################
#
# Go Into USER MODE
#
# This function goes to USER_MODE, with INTERRUPTS_ENABLED.
#
# The page table was previously initialized to map the first 4 pages (64KiBytes)
# of the virtual address space into the first 4 pages of physical memory.
# Thus, it doesn't matter whether we are running in virtual or physical memory.
#
# Regs used: r1, r2
# Stack:     Not used, leaf function
#
goIntoUserMode:
	
# Jump to the version of this code running in the virtual address space.
	movi		r1, goIntoUserMode_1
	movi		r2,0x0000_0008_0000_0000
	or		r1,r1,r2
	jr		r1
	jump		FAILURE
goIntoUserMode_1:

# Turn off kernel mode and enable interrupts
# Sets csr_status = FL_ROUND=00, FL_STAT=00000, INTERRUPTS=Enabled, Mode=User
	movi		r1,0x0000_0000_0000_0002
	csrwrite	csr_status,r1

# The return address is in kernel space. Change it to virtual.
	movi		r2,0x0000_0008_0000_0000
	or		lr,lr,r2

	ret




###########################################################
#
# Go Into KERNEL MODE
#
# This function gets back in to KERNEL MODE, interrupts enabled.
#
# If we were executing in the virtual address space, we return to
# executing instructions in kernel space.
#
# No checking is done.
#
# Regs used: r1
# Stack:     Not used, leaf function
#
goIntoKernelMode:
	movi		r1,goIntoKernelMode_ret
	stored		Jump_ArithmeticException,r1
	movi		r1,0x7fff_ffff_ffff_ffff
	addi		r1,r1,1				# Cause an Arithmetic Exception.
	jump		FAILURE
goIntoKernelMode_ret:
	movi		r1,0x0000_0000_0000_0003
	csrwrite	csr_status,r1
#	csrset		csr_status,0x0002		# Set INTERRUPTS ENABLED
# Make sure the return address is in kernel space
	movi		r2,0x0000_0007_ffff_ffff
	and		lr,lr,r2

	ret


###########################################################
#
# Set a page in memory to all zeros. r1=addr of page to clear.
#
# Regs used: r1 = Ptr to page
#            t = beyond
# Stack:     Not used, leaf function
#
ZeroPage:
	addi		r2,r1,16*1024
ZeroPageLoop:
	stored		0(r1),r0
	addi		r1,r1,8
	blt		r1,r2, ZeroPageLoop
	ret


###########################################################
#
# Initialize the page table tree and csr_pgtable.
#
# The data pages are not modified.
#
# Regs used: r1, r2, r3
# Stack:     Not used, leaf function
#
InitPageTable:
# Set csr_pgtable
	movi		r1,PageTable
	csrwrite	csr_pgtable,r1

# Initialize the root node and the three index nodes.
	mov		r3,lr			# save lr while we call ZeroPage
	movi		r1, PageTable
	call		ZeroPage
	movi		r1, IndexPage_0
	call		ZeroPage
	movi		r1, IndexPage_1
	call		ZeroPage
	movi		r1, IndexPage_2
	call		ZeroPage
	mov		lr,r3

# Initialize the page table nodes.
	movi	r1,pt_0			# Store entry for index page 0 into root page
	stored	pt_addr_0,r1

	movi	r1,pt_1			# Store entry for index page 1 into root page
	stored	pt_addr_1,r1

#	movi	r1,pt_2			# Store entry for index page 2 into root page - do this in test 115
#	stored	pt_addr_2,r1

# Store PTEs into index page 0

	movi	r1,index_0_0		# Store PTE for page 0
	stored	index_addr_0_0,r1

	movi	r1,index_0_8		# Store PTE for page 1
	stored	index_addr_0_8,r1

	movi	r1,index_0_10		# Store PTE for page 2
	stored	index_addr_0_10,r1

	movi	r1,index_0_18		# Store PTE for page 3
	stored	index_addr_0_18,r1

# Store PTEs into index page 1

	movi	r1,index_1_0		# Store PTE for virtual page 699048
	stored	index_addr_1_0,r1

	movi	r1,index_1_1
	stored	index_addr_1_1,r1

	movi	r1,index_1_2
	stored	index_addr_1_2,r1

	movi	r1,index_1_3
	stored	index_addr_1_3,r1

	movi	r1,index_1_4
	stored	index_addr_1_4,r1

	movi	r1,index_1_5
	stored	index_addr_1_5,r1

	movi	r1,index_1_6
	stored	index_addr_1_6,r1

	movi	r1,index_1_7
	stored	index_addr_1_7,r1

	movi	r1,index_1_8
	stored	index_addr_1_8,r1

	movi	r1,index_1_9
	stored	index_addr_1_9,r1

	movi	r1,index_1_a
	stored	index_addr_1_a,r1

	movi	r1,index_1_b
	stored	index_addr_1_b,r1

	movi	r1,index_1_c
	stored	index_addr_1_c,r1

	movi	r1,index_1_d
	stored	index_addr_1_d,r1

	movi	r1,index_1_e
	stored	index_addr_1_e,r1

	movi	r1,index_1_f
	stored	index_addr_1_f,r1

# Store PTEs into index page 2 - do this in test 115

#	movi	r1,index_2_0
#	stored	index_addr_2_0,r1

	ret
#
# Here is how this program uses physical memory...
#
# Page      Address
# ====   =============
#   0    0x0_0000_0000     ISA Code  -- Mapped to virtual page 0x8_0000_0000
#   1    0x0_0004_0000     ISA Code  -- Mapped to virtual page 0x8_0000_4000
#   2    0x0_0008_0000     ISA Code  -- Mapped to virtual page 0x8_0000_8000
#   3    0x0_000c_0000     ISA Code  -- Mapped to virtual page 0x8_0000_c000
#   4    0x0_0010_0000     Root Node of page table
#   5    0x0_0014_0000     Index page for virtual pages 0...1023
#   6    0x0_0018_0000     Index page for virtual pages 698368...699391
#   7    0x0_001c_0000     Index page for virtual pages 2095104...2097151
#   8    0x0_0020_0000     Virtual page 699048 at 0xa_aaaa0000
#   9    0x0_0024_0000        -- not used --
#  10    0x0_0028_0000     Virtual page 699049 at 0xa_aaaa_4000
#  11    0x0_002c_0000     Virtual page 699050 at 0xa_aaaa_8000
#  12    0x0_0030_0000     Virtual page 699051 at 0xa_aaaa_c000
#  13    0x0_0034_0000     Virtual page 699052 at 0xa_aaaa_c000
#  14    0x0_0038_0000     Virtual page 699053 at 0xa_aaab_0000
#  15    0x0_003c_0000     Virtual page 699054 at 0xa_aaab_4000
#      (same phys page     Virtual page 699055 at 0xa_aaab_8000
#          is reused)           ...
#  15    0x0_003c_0000     Virtual page 699062 at 0xa_aaad_8000
#  15    0x0_003c_0000     Virtual page 699063 at 0xa_aaad_c000
#
#  <<< Beyond 256Kbyte physical memory: 0x0_0040_0000 >>>

#  16    0x0_0040_0000     Virtual page 699055 at 0xa_aaab_8000
#  17    0x0_0044_0000     Virtual page 699056 at 0xa_aaab_c000
#  18    0x0_0048_0000     Virtual page 699057 at 0xa_aaac_0000
#  19    0x0_004c_0000     Virtual page 699058 at 0xa_aaac_4000
#  20    0x0_0050_0000     Virtual page 699059 at 0xa_aaac_8000
#  21    0x0_0054_0000     Virtual page 699060 at 0xa_aaac_c000
#  22    0x0_0058_0000     Virtual page 699061 at 0xa_aaad_4000
#  23    0x0_005c_0000     Virtual page 699062 at 0xa_aaad_8000
#  24    0x0_0060_0000     Virtual page 699063 at 0xa_aaad_c000
#
# Here is the page table we will create...
#
# Root page (in page 4 at 0x000010000):
#
#    Addr of PTE           PTE          Virt Page   VirtPageAddr     Phys Page      PhysPageAddr     C   D   W   X   V
#    ===========   ==================   =========  ==============  =============  ================  === === === === ===
#    0x000010000   ----------
#    0x000010000:  0x0000001400000001    0...1023                             5    0x000000014000                    V
#    0x000010aa8:  0x0000001800000001    698368...699391                      6    0x000000018000                    V
#      ...
#    0x000011ff8:  0x0000001c00000001                                         7    0x00000001c000                    V
#
# Index page (in page 5 at 0x000014000):
#
#    Addr of PTE           PTE          Virt Page   VirtPageAddr     Phys Page      PhysPageAddr     C   D   W   X   V
#    ===========   ==================   =========  ==============  =============  ================  === === === === ===
#    0x000014000   ----------
#    0x000014000:  0x000000000000000f          0     0x800000000              0    0x000000000000        D   W   X   V *** PPN = 0 ***
#    0x000014008:  0x000000040000000f          1     0x800004000              1    0x000000004000        D   W   X   V
#    0x000014010:  0x000000080000000f          2     0x800008000              2    0x000000008000        D   W   X   V
#
# Index page (in page 7 at 0x00001c000):
#
#    Addr of PTE           PTE          Virt Page   VirtPageAddr     Phys Page      PhysPageAddr     C   D   W   X   V
#    ===========   ==================   =========  ==============  =============  ================  === === === === ===
#    0x00001c000   ----------
#      ...
#    0x00001fff8:  0x0000000c0000000f    2097151     0xfffffc000              3    0x00000000c000        D   W   X   V
#
# Physical pages 7 and 9 intentionally skipped.
#
# Index page (in page 6 at 0x000018000):
#
#    Addr of PTE           PTE          Virt Page   VirtPageAddr     Phys Page      PhysPageAddr     C   D   W   X   V
#    ===========   ==================   =========  ==============  =============  ================  === === === === ===
#    0x000018000   ----------
#    0x000019540:  0x0000002000000001     699048     0xaaaaa0000              8    0x000000020000                    V
#    0x000019548:  0x0000002800000003     699049     0xaaaaa4000             10    0x000000028000                X   V
#    0x000019550:  0x0000002c00000005     699050     0xaaaaa8000             11    0x00000002c000            W       V
#    0x000019558:  0x0000003000000007     699051     0xaaaaac000             12    0x000000030000            W   X   V
#    0x000019560:  0x0000003400000009     699052     0xaaaab0000             13    0x000000034000        D           V
#    0x000019568:  0x000000380000000b     699053     0xaaaab4000             14    0x000000038000        D       X   V
#    0x000019570:  0x0000003c0000000d     699054     0xaaaab8000             15    0x00000003c000        D   W       V

#    0x000019578:  0x0000003c0000000f     699055     0xaaaabc000             15    0x00000003c000        D   W   X   V
#    0x000019580:  0x0000003c00000011     699056     0xaaaac0000             15    0x00000003c000    C               V
#    0x000019588:  0x0000003c00000013     699057     0xaaaac4000             15    0x00000003c000    C           X   V
#    0x000019590:  0x0000003c00000015     699058     0xaaaac8000             15    0x00000003c000    C       W       V
#    0x000019598:  0x0000003c00000017     699059     0xaaaacc000             15    0x00000003c000    C       W   X   V
#    0x0000195a0:  0x0000003c00000019     699060     0xaaaad0000             15    0x00000003c000    C   D           V
#    0x0000195a8:  0x0000003c0000001b     699061     0xaaaad4000             15    0x00000003c000    C   D       X   V
#    0x0000195b0:  0x0000003c0000001d     699062     0xaaaad8000             15    0x00000003c000    C   D   W       V
#    0x0000195b8:  0x0000003c0000001f     699063     0xaaaadc000             15    0x00000003c000    C   D   W   X   V

#    0x000019570:  0x000000300000000d     699054     0xaaaab8000             12    0x000000030000        D   W       V
#    0x000019578:  0x000000340000000f     699055     0xaaaabc000             13    0x000000034000        D   W   X   V
#    0x000019580:  0x0000003800000011     699056     0xaaaac0000             14    0x000000038000    C               V
#    0x000019588:  0x0000003c00000013     699057     0xaaaac4000             15    0x00000003c000    C           X   V
#    0x000019590:  0x0000003000000015     699058     0xaaaac8000             12    0x000000030000    C       W       V
#    0x000019598:  0x0000003400000017     699059     0xaaaacc000             13    0x000000034000    C       W   X   V
#    0x0000195a0:  0x0000003800000019     699060     0xaaaad0000             14    0x000000038000    C   D           V
#    0x0000195a8:  0x0000003c0000001b     699061     0xaaaad4000             15    0x00000003c000    C   D       X   V
#    0x0000195b0:  0x000000300000001d     699062     0xaaaad8000             12    0x000000030000    C   D   W       V
#    0x0000195b8:  0x000000340000001f     699063     0xaaaadc000             13    0x000000034000    C   D   W   X   V

#
# Page table root
#
PageTable:		.equ		0x0_0001_0000

pt_addr_0:		.equ		0x0_0001_0000
pt_0:			.equ		0x0000001400000001		# points to physical page 0x0_0001_4000

pt_addr_1:		.equ		0x0_0001_0aa8
pt_1:			.equ		0x0000001800000001		# points to physical page 0x0_0001_8000

pt_addr_2:		.equ		0x0_0001_1ff8
pt_2:			.equ		0x0000001c00000001		# points to physical page 0x0_0001_c000

#
# Index page 0
#
IndexPage_0:		.equ		0x0_0001_4000

index_addr_0_0:		.equ		0x0_0001_4000
index_0_0:		.equ		0x000000000000000f

index_addr_0_8:		.equ		0x0_0001_4008
index_0_8:		.equ		0x000000040000000f

index_addr_0_10:	.equ		0x0_0001_4010
index_0_10:		.equ		0x000000080000000f

index_addr_0_18:	.equ		0x0_0001_4018
index_0_18:		.equ		0x0000000c0000000f

#
# Index page 1
#
IndexPage_1:		.equ		0x0_0001_8000

index_addr_1_0:		.equ		0x0_0001_9540
index_1_0:		.equ		0x0000002000000001

index_addr_1_1:		.equ		0x0_0001_9548
index_1_1:		.equ		0x0000002800000003

index_addr_1_2:		.equ		0x0_0001_9550
index_1_2:		.equ		0x0000002c00000005

index_addr_1_3:		.equ		0x0_0001_9558
index_1_3:		.equ		0x0000003000000007

index_addr_1_4:		.equ		0x0_0001_9560
index_1_4:		.equ		0x0000003400000009

index_addr_1_5:		.equ		0x0_0001_9568
index_1_5:		.equ		0x000000380000000b

index_addr_1_6:		.equ		0x0_0001_9570
index_1_6:		.equ		0x000000300000000d

index_addr_1_7:		.equ		0x0_0001_9578
index_1_7:		.equ		0x000000340000000f

index_addr_1_8:		.equ		0x0_0001_9580
index_1_8:		.equ		0x0000003800000011

index_addr_1_9:		.equ		0x0_0001_9588
index_1_9:		.equ		0x0000003c00000013

index_addr_1_a:		.equ		0x0_0001_9590
index_1_a:		.equ		0x0000003000000015

index_addr_1_b:		.equ		0x0_0001_9598
index_1_b:		.equ		0x0000003400000017

index_addr_1_c:		.equ		0x0_0001_95a0
index_1_c:		.equ		0x0000003800000019

index_addr_1_d:		.equ		0x0_0001_95a8
index_1_d:		.equ		0x0000003c0000001b

index_addr_1_e:		.equ		0x0_0001_95b0
index_1_e:		.equ		0x000000300000001d

index_addr_1_f:		.equ		0x0_0001_95b8
index_1_f:		.equ		0x000000340000001f

#
# Index page 2
#
IndexPage_2:		.equ		0x0_0001_8000

index_addr_2_0:		.equ		0x0_0001_fff8
index_2_0:		.equ		0x0000000c0000000f



############################################################################
############################################################################
###
###   IF WE REACH HERE, WE HAVE PASSED ALL TESTS!
###
############################################################################
############################################################################

SUCCESS:
	movi	s0,0x1234123412341234

# Print "Success"
	movi		sp,StackRegionX
	movi		r1,SuccessMessage
	call		PrintString
	controlu	r0,r0,HALT



	.comment	"\n\n====================\n====================  SUCCESS: ALL TESTS WERE PASSED\n====================\n"


######
######  Comment out the following DEBUG when using -nodebug:
######
#	debug
######


SUCCESS_LOOP:
	jump	SUCCESS_LOOP



############################################################################
############################################################################
#########
#########  FAILURE REPORTING
#########
###
### This is not a function; it will execute and then HALT execution with
### a CONTROLU/HALT.
###
### This code will save all registers, create a  stack for its own
### usage, and then print all registers. It will then print some CSRs.
###
### There are two entry points:
###    UnexpectedException:
###      Will print "***  UNEXPECTED EXCEPTION!  ***"
###    FAILURE_2:
###      Will print "***  THIS TEST HAS FAILED!  ***"
###
############################################################################
############################################################################

	.comment	"\n\n====================\n====================  STOPPED IN FAILURE REPORTING SECTION\n====================\n"




UnexpectedException:
#	movi		t,0xeeee		# Display EEEE on the LED
#	controlu	r0,t,DIGITAL_WRITE

	stored		oldSP,sp		# Set up the stack
	movi		sp,StackRegionX-120

# save regs on the stack
#	addi		sp,sp,-120    # May cause Stack Overflow.
	store.d		  0(sp),r1
	store.d		  8(sp),r2
	store.d		 16(sp),r3
	store.d		 24(sp),r4
	store.d		 32(sp),r5
	store.d		 40(sp),r6
	store.d		 48(sp),r7
	store.d		 56(sp),r8
	store.d		 64(sp),r9
	store.d		 72(sp),r10
	store.d		 80(sp),r11
	store.d		 88(sp),r12
	store.d		 96(sp),r13
	store.d		104(sp),r14
#	store.d		112(sp),r15

# Switch to Kernel Mode. Save old CSR_STATUS. Clear StackLimit so CALL works.
	controlu	r2,r0,ENABLE_KERNEL
	stored		prevStat,r2
	movi		r1,0x0003
	csrwrite	csr_status,r1

	movi		r1,UnexpectMess		# Print message
	call		PrintString

	jump		FAIL_continue

FAILURE_2:
#	controlu	r0,s0,DIGITAL_WRITE	# Display s0
#	controlu	r0,r0,HALT		# HALT

	stored		oldSP,sp		# Set up the stack
	movi		sp,StackRegionX-120

# save regs on the stack
#	addi		sp,sp,-120    # May cause Stack Overflow.
	store.d		  0(sp),r1
	store.d		  8(sp),r2
	store.d		 16(sp),r3
	store.d		 24(sp),r4
	store.d		 32(sp),r5
	store.d		 40(sp),r6
	store.d		 48(sp),r7
	store.d		 56(sp),r8
	store.d		 64(sp),r9
	store.d		 72(sp),r10
	store.d		 80(sp),r11
	store.d		 88(sp),r12
	store.d		 96(sp),r13
	store.d		104(sp),r14
#	store.d		112(sp),r15


# Switch to Kernel Mode. Save old CSR_STATUS. Clear StackLimit so CALL works.
	controlu	r2,r0,ENABLE_KERNEL
	stored		prevStat,r2
	movi		r1,0x0003
	csrwrite	csr_status,r1

	movi		r1,FailureMessage
	call		PrintString

FAIL_continue:

# Print r1
	movi		r1,m_r1
	call		PrintString
	load.d		r1,0(sp)
	call		PrintIntNL

# Print r2
	movi		r1,m_r2
	call		PrintString
	load.d		r1,8(sp)
	call		PrintIntNL

# Print r3
	movi		r1,m_r3
	call		PrintString
	load.d		r1,16(sp)
	call		PrintIntNL

# Print r4
	movi		r1,m_r4
	call		PrintString
	load.d		r1,24(sp)
	call		PrintIntNL

# Print r5
	movi		r1,m_r5
	call		PrintString
	load.d		r1,32(sp)
	call		PrintIntNL

# Print r6
	movi		r1,m_r6
	call		PrintString
	load.d		r1,40(sp)
	call		PrintIntNL

# Print r7
	movi		r1,m_r7
	call		PrintString
	load.d		r1,48(sp)
	call		PrintIntNL

# Print r8
	movi		r1,m_r8
	call		PrintString
	load.d		r1,56(sp)
	call		PrintIntNL

# Print r9
	movi		r1,m_r9
	call		PrintString
	load.d		r1,64(sp)
	call		PrintIntNL

# Print r10
	movi		r1,m_r10
	call		PrintString
	load.d		r1,72(sp)
	call		PrintIntNL

# Print r11
	movi		r1,m_r11
	call		PrintString
	load.d		r1,80(sp)
	call		PrintIntNL

# Print r12
	movi		r1,m_r12
	call		PrintString
	load.d		r1,88(sp)
	call		PrintIntNL

# Print r13
	movi		r1,m_r13
	call		PrintString
	load.d		r1,96(sp)
	call		PrintIntNL

# Print r14
	movi		r1,m_r14
	call		PrintString
	load.d		r1,104(sp)
	call		PrintIntNL

# Print r15
	movi		r1,m_r15
	call		PrintString
	loadd		r1,oldSP
	call		PrintIntNL

# Print the values in the CSR regs.

# Look at bit [0] of old csr_status and print it
	loadd		r2, prevStat
	andi		r1,r2,0x0001
	beqz		r1,WasUser
	movi		r1,stat_was_kernel
	call		PrintString
	jump		Stat_Print_X
WasUser:
	movi		r1,stat_was_user
	call		PrintString
Stat_Print_X:


	movi		r1,m_timer
	call		PrintString
	csrread		r1,csr_timer
	call		PrintIntNL

	movi		r1,m_status
	call		PrintString
	loadd		r1, prevStat
	call		PrintIntNL

	movi		r1,m_stat2
	call		PrintString
	csrread		r1,csr_stat2
	call		PrintIntNL

	movi		r1,m_prevpc
	call		PrintString
	csrread		r1,csr_prevpc
	call		PrintIntNL

	movi		r1,m_cause
	call		PrintString
	csrread		r1,csr_cause
	call		PrintIntNL

	movi		r1,m_bad
	call		PrintString
	csrread		r1,csr_bad
	call		PrintIntNL

	movi		r1,m_addr
	call		PrintString
	csrread		r1,csr_addr
	call		PrintIntNL

#	movi		t,0x98
#	controlu	r0,t,DIGITAL_WRITE



CANNOT_PROCEED:
	movi		r1,HaltMessage
	call		PrintString
	controlu	r0,r0,HALT

	jump		CANNOT_PROCEED


		.align		8	# Doubleword alignment is required for the stack 
StackRegion:	.skip		8*100
StackRegionX:

stackSaveArea:	.doubleword	0
prevStat:	.doubleword	0
oldSP:		.doubleword	0

SuccessMessage:	.string		"\n**********  SUCCESS!  **********\n\n\0"
FailureMessage:	.string		"\n**********  THIS TEST HAS FAILED!  **********\n\n\0"
HaltMessage:	.string		"\n**********  HALTING  **********\n\n\0"
UnexpectMess:	.string		"\n**********  UNEXPECTED EXCEPTION!  **********\n\n\0"
m_lr:		.string		"lr:         \0"
m_sp:		.string		"sp:         \0"
m_r1:		.string		"r1:         \0"
m_r2:		.string		"r2:         \0"
m_r3:		.string		"r3:         \0"
m_r4:		.string		"r4:         \0"
m_r5:		.string		"r5:         \0"
m_r6:		.string		"r6:         \0"
m_r7:		.string		"r7:         \0"
m_r8:		.string		"t: (?)      \0"
m_r9:		.string		"s0:         \0"
m_r10:		.string		"s1:         \0"
m_r11:		.string		"s2:         \0"
m_r12:		.string		"tp:         \0"
m_r13:		.string		"gp:         \0"
m_r14:		.string		"lr:         \0"
m_r15:		.string		"sp:         \0"
m_timer:	.string		"csr_timer:  \0"
m_status:	.string		"csr_status: \0"
m_stat2:	.string		"csr_stat2:  \0"
m_prevpc:	.string		"csr_prevpc: \0"
m_cause:	.string		"csr_cause:  \0"
m_bad:		.string		"csr_bad:    \0"
m_addr:		.string		"csr_addr:   \0"
stat_was_user:	   .string	"\nPrevious CSR_STATUS: USER-MODE - NO STACK!\n\n\0"
stat_was_kernel:   .string	"\nPrevious CSR_STATUS: KERNEL-MODE\n\n\0"

		.align	4



############################################################################
#
# PrintHere1 2,3,...
#
# Print a message; useful in debugging FPGA to discover where the lights went out.
# Uses:
#    r1; uses stack
#
############################################################################

PrintHere1:
	movi	r1,PrintHereMess_1
	jump	PrintString
PrintHere2:
	movi	r1,PrintHereMess_2
	jump	PrintString
PrintHere3:
	movi	r1,PrintHereMess_3
	jump	PrintString
PrintHere4:
	movi	r1,PrintHereMess_4
	jump	PrintString

PrintHereMess_1:
	.string	"Here-1\n\0"
PrintHereMess_2:
	.string	"Here-2\n\0"
PrintHereMess_3:
	.string	"Here-3\n\0"
PrintHereMess_4:
	.string	"Here-4\n\0"
	.align	4

############################################################################
#
# PrintString
#
# Passed:
#    r1 = pointer to an array of bytes, terminated with \0.
# Uses:
#    none; uses stack
#
############################################################################

PrintString:
        addi      sp,sp,-32             # Function prologue
        store.d   0(sp),lr              #
        store.d   8(sp),r1              #
        store.d   16(sp),r2             #
        store.d   24(sp),r3             #
Ploop:                                  # LOOP
	load.b	r2,0(r1)		#   r2 = the next byte from the string
        bnez	r2,printLoop		#   IF r2 == 0
        load.d  lr,0(sp)                #     Return Sequence           
        load.d  r1,8(sp)                #     .
        load.d  r2,16(sp)               #     .  
        load.d  r3,24(sp)               #     .
        addi    sp,sp,32                #     .
        ret                             #     .
printLoop:				#   LOOP
	controlu	r3,r0,SERIAL_STAT	#     Get serial status
	andi	r3,r3,0x02		#     Look at bit [1] only
	beqz	r3,printLoop		#   UNTIL OUTPUT READY = 1
	controlu	r0,r2,SERIAL_SEND	#   Send a byte from r2
	addi	r1,r1,1			#   Increment pointer
	jump	Ploop	        	# ENDLOOP

############################################################################
#
# PrintChar
#
# Passed:
#    r1 = character -128...+127
# Uses:
#    none; uses stack
#
############################################################################

PrintChar:
        addi      sp,sp,-16           # Function prologue
        store.d   0(sp),r1            #
        store.d   8(sp),r2            #

PrintCharLoop:
	controlu	r2,r0,SERIAL_STAT     #   Get serial status
	andi	r2,r2,0x02	      #   Look at bit [1] only
	beqz	r2, PrintCharLoop     # UNTIL OUTPUT READY = 1
	controlu	r0,r1,SERIAL_SEND     # Print r1

        load.d    r1,0(sp)            # Return Sequence           
        load.d    r2,8(sp)            # .           
        addi      sp,sp,16            # .
        ret                           # .

############################################################################
#
# PrintNL
#
# Uses:
#    none; uses stack
#
############################################################################

PrintNL:
        addi      sp,sp,-16           # Function prologue
        store.d   0(sp),lr            #
        store.d   8(sp),r1            #

	movi      r1,0x0a		# Print \n
	call      PrintChar		#

        load.d    lr,0(sp)            # Return Sequence           
        load.d    r1,8(sp)            # .           
        addi      sp,sp,16            # .
        ret                           # .

############################################################################
#
# PrintNibble
#
# Passed:
#    r1 = number in 0...15 (ignores all but LSB 4 bits)
# Uses:
#    none
#
############################################################################

PrintNibble:
        addi      sp,sp,-24           # Function prologue
        store.d   0(sp),lr            #
        store.d   8(sp),r1            #
        store.d   16(sp),r2           #

	andi      r1,r1,0x000F        # Look only at LSB 4 bits
        bgei      r1,10,PrintAlpha    # IF r1 <= 9
        addi      r1,r1,0x30          #   Change to "0"..."9"
        jump      PrintNibbleLoop
PrintAlpha:                           # ELSE
        addi      r1,r1,0x61-10       #   Change to "a"..."f"
PrintNibbleLoop:
	controlu	r2,r0,SERIAL_STAT     #   Get serial status
	andi	r2,r2,0x02	      #   Look at bit [1] only
	beqz	r2, PrintNibbleLoop   # UNTIL OUTPUT READY = 1
	controlu	r0,r1,SERIAL_SEND     # Print r1

        load.d    lr,0(sp)            # Return           
        load.d    r1,8(sp)            # .           
        load.d    r2,16(sp)           # .           
        addi      sp,sp,24            # .
        ret                           # .

############################################################################
#
# PrintIntNL
#
# Prints a value in hex, e.g., "abcd1234fedc8765" followed by "\n".
#
# Passed:
#    r1 = 64 bit value
#
# Uses:
#    none; uses stack
#
############################################################################

PrintIntNL:
        addi      sp,sp,-16           # Function prologue
        store.d   0(sp),lr            #
        store.d   8(sp),r1            #

	call	PrintInt		# Print integer
	call	PrintNL			# Print \n

        load.d    lr,0(sp)            # Return Sequence           
        load.d    r1,8(sp)            # .           
        addi      sp,sp,16            # .
        ret                           # .

############################################################################
#
# PrintInt
#
# Prints a value in hex, e.g., "abcd_1234_fedc_8765"
#
# Passed:
#    r1 = 64 bit value
# Uses:
#    none; uses stack
#
############################################################################

PrintInt:
        addi      sp,sp,-24		# Function prologue
        store.d   0(sp),lr		#
        store.d   8(sp),r1		#
        store.d   16(sp),r2		#

#	movi	r2,16			# LOOP 16 times
#PrNibLoop:
#	rotri	r1,r1,60		#   Look at next 4 bits (rotate left 4 bits)
#	call	PrintNibble		#   Print as a hex char
#	addi	r2,r2,-1		# ENDLOOP
#	bgtz	r2,PrNibLoop		# .

	loadd	r1,8(sp)
	srli	r1,r1,48
	call	PrintInt16
	movi	r1,'_'
	call	PrintChar

	loadd	r1,8(sp)
	srli	r1,r1,32
	call	PrintInt16
	movi	r1,'_'
	call	PrintChar

	loadd	r1,8(sp)
	srli	r1,r1,16
	call	PrintInt16
	movi	r1,'_'
	call	PrintChar

	loadd	r1,8(sp)
	call	PrintInt16

        load.d    lr,0(sp)		# Return           
        load.d    r1,8(sp)		# .           
        load.d    r2,16(sp)		# .           
        addi      sp,sp,24		# .
        ret				# .

############################################################################
#
# PrintS0
#
# Prints the value in reg "s0" in hex, e.g.,
#     "Test 000000000000001C"
#
# Uses:
#    none; uses stack
#
############################################################################

PrintS0:
        addi      sp,sp,-24           # Function prologue
        store.d   0(sp),lr            #
        store.d   8(sp),r1            #
        store.d   16(sp),r2           #

        movi      r1,printS0_a        # Print
        call      PrintString         #
        mov       r1,s0               # Print int
        call      PrintInt            #
        movi      r1,printS0_b        # Print
        call      PrintString         #

        load.d    lr,0(sp)            # Return           
        load.d    r1,8(sp)            # .           
        load.d    r2,16(sp)           # .           
        addi      sp,sp,24            # .
        ret                           # .
printS0_a:	.string		"Test \0"
printS0_b:	.string		"\n\0"
		.align		4



############################################################################
#
# PrintTLBs
#
# Prints the TLB registers.
#
# Uses: All regs and the stack.
#
############################################################################

PrintTLBs:

        addi	sp,sp,-8		# Function prologue
        store.d	0(sp),lr		#

	movi	r1,pr_tlb_header
	call	PrintString

	movi	r1,0
	call	PrintTLB_reg

	movi	r1,1
	call	PrintTLB_reg

	movi	r1,2
	call	PrintTLB_reg

	movi	r1,3
	call	PrintTLB_reg

	movi	r1,4
	call	PrintTLB_reg

	movi	r1,5
	call	PrintTLB_reg

	movi	r1,6
	call	PrintTLB_reg

	movi	r1,7
	call	PrintTLB_reg


        load.d	lr,0(sp)		# Return Sequence           
        addi	sp,sp,8			# .
	ret

		#   ASID     VirtAddr      PhysAddr    C D W X V
		#   ====   ===========   ===========   =========
		#   0000   0_0000_0000   0_0000_0000   0 0 0 0 0
pr_tlb_header:	.string     	"\n   --------------- TLB REGISTERS --------------\n   ASID     VirtAddr      PhysAddr    C D W X V\n   ====   ===========   ===========   =========\n\0"

spaces:		.string     	"   \0"
dash:		.string		"_\0"
PB_2_spaces:	.string		"  \0"
		.align		4 

############################################################################
#
# PrintTLB_reg
#
# Passed:
#    r1 = the number of the TLB reg to print.
# Uses:
#    none
#
############################################################################

PrintTLB_reg:
        addi	sp,sp,-24		# Function prologue
        store.d	0(sp),lr		#
        store.d	8(sp),r1		#
        store.d	16(sp),r2		#

# Print spaces
	movi	r1,spaces
	call	PrintString

# Get the reg and print the ASID
        load.d	r1,8(sp)           
	controlu	r1,r1,TLB_DEBUG
	srli	r1,r1,48
	call	PrintInt16

# Print spaces
	movi	r1,spaces
	call	PrintString

# Get the reg and print the Virtual Address
        load.d	r1,8(sp)           
	controlu	r1,r1,TLB_DEBUG
	srli	r1,r1,27
	slli	r1,r1,14
	movi	r2,0x8_0000_0000
	or	r1,r1,r2
	call	PrintInt36

# Print spaces
	movi	r1,spaces
	call	PrintString

# Get the reg and print the Physical Address
        load.d	r1,8(sp)           
	controlu	r1,r1,TLB_DEBUG
	srli	r1,r1,5
	slli	r1,r1,14
	call	PrintInt36

# Print spaces
	movi	r1,spaces
	call	PrintString

# Get the reg and print the Bits

        load.d	r1,8(sp)           
	controlu	r1,r1,TLB_DEBUG
	srli	r1,r1,4
	movi	r2,'C'
	call	PrintBit

        load.d	r1,8(sp)           
	controlu	r1,r1,TLB_DEBUG
	srli	r1,r1,3
	movi	r2,'D'
	call	PrintBit

        load.d	r1,8(sp)           
	controlu	r1,r1,TLB_DEBUG
	srli	r1,r1,2
	movi	r2,'W'
	call	PrintBit

        load.d	r1,8(sp)           
	controlu	r1,r1,TLB_DEBUG
	srli	r1,r1,1
	movi	r2,'X'
	call	PrintBit

        load.d	r1,8(sp)           
	controlu	r1,r1,TLB_DEBUG
	movi	r2,'V'
	call	PrintBit

# Print NL
	call	PrintNL

        load.d	lr,0(sp)		# Return           
        load.d	r1,8(sp)		# .           
        load.d	r2,16(sp)		# .           
        addi	sp,sp,24		# .
        ret				# .

############################################################################
#
# PrintBit
#
# Passed:
#    r1 = Print the lowest bit, followed by a space. Ignore all other bits.
#         If the bit is 1, print r2; else print SPACE
#    r2 = Char to print if bit is 1
# Uses:
#    r1
#
############################################################################

PrintBit:
        addi	sp,sp,-8		# Function prologue
        store.d	0(sp),lr		#

	andi	r1,r1,0x01
	bnez	r1,PB_else
	movi	r1,PB_2_spaces	
	call	PrintString
	jump	PB_done
PB_else:
	mov	r1,r2	
	call	PrintChar
	movi	r1,' '	
	call	PrintChar
PB_done:
        load.d	lr,0(sp)		# Return           
        addi	sp,sp,8			# .
        ret				# .

############################################################################
#
# PrintInt16
#
# Passed:
#    r1 = 16 bit value (ignores all but LSB 16 bits)
# Uses:
#    r1,r2
#
############################################################################

PrintInt16:
        addi	sp,sp,-8		# Function prologue
        store.d	0(sp),lr		#

	mov	r2,r1

	srli	r1,r2,12
	call	PrintNibble

	srli	r1,r2,8
	call	PrintNibble

	srli	r1,r2,4
	call	PrintNibble

	mov	r1,r2
	call	PrintNibble

        load.d	lr,0(sp)		# Return           
        addi	sp,sp,8			# .
        ret				# .

############################################################################
#
# PrintInt36 in form 0_0000_0000
#
# Passed:
#    r1 = 36 bit value (ignores all but LSB 36 bits)
# Uses:
#    r1,r2
#
############################################################################

PrintInt36:
        addi	sp,sp,-8		# Function prologue
        store.d	0(sp),lr		#

	mov	r2,r1

	srli	r1,r2,32
	call	PrintNibble

	movi	r1,dash
	call	PrintString

	srli	r1,r2,28
	call	PrintNibble

	srli	r1,r2,24
	call	PrintNibble

	srli	r1,r2,20
	call	PrintNibble

	srli	r1,r2,16
	call	PrintNibble

	movi	r1,dash
	call	PrintString

	srli	r1,r2,12
	call	PrintNibble

	srli	r1,r2,8
	call	PrintNibble

	srli	r1,r2,4
	call	PrintNibble

	call	PrintNibble

        load.d	lr,0(sp)		# Return           
        addi	sp,sp,8			# .
        ret				# .


EndOfCode:


######
######  Comment out the following .ENDFUNCTION when assembling with "-hex".
######
	.endfunction
######
