URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [or1200/] [sim/] [or1200-ov.S] - Rev 803
Compare with Previous | Blame | View Log
/*OR1200 overflow bit checkingVery basic, testingTODO: Check range exception handling in delay slotsJulius Baxter, ORSoC AB, julius.baxter@orsoc.se*/////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2011 Authors and OPENCORES.ORG //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer. //////// //////// This source file is free software; you can redistribute it //////// and/or modify it under the terms of the GNU Lesser General //////// Public License as published by the Free Software Foundation; //////// either version 2.1 of the License, or (at your option) any //////// later version. //////// //////// This source is distributed in the hope that it will be //////// useful, but WITHOUT ANY WARRANTY; without even the implied //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //////// PURPOSE. See the GNU Lesser General Public License for more //////// details. //////// //////// You should have received a copy of the GNU Lesser General //////// Public License along with this source; if not, download it //////// from http://www.opencores.org/lgpl.shtml //////// //////////////////////////////////////////////////////////////////////////#include "spr-defs.h"#include "board.h"#include "or1200-defines.h"/* =================================================== [ exceptions ] === */.section .vectors, "ax"/* ---[ 0x100: RESET exception ]----------------------------------------- */.org 0x100l.movhi r0, 0/* Clear status register */l.ori r1, r0, SPR_SR_SMl.mtspr r0, r1, SPR_SR/* Clear timer */l.mtspr r0, r0, SPR_TTMR/* Jump to program initialisation code */.global _startl.movhi r4, hi(_start)l.ori r4, r4, lo(_start)l.jr r4l.nop.org 0x600l.nop 0x1/* ---[ 0x700: Illegal instruction exception ]-------------------------- */.org 0x700#ifndef OR1200_IMPL_ADDC// No problem - instruction not supportedl.movhi r3, hi(0x8000000d)l.ori r3, r3, lo(0x8000000d)l.nop 0x2l.ori r3, r0, 0#elsel.ori r3, r0, 1#endifl.nop 0x1#define INCREMENT_EXCEPTION_COUNTER l.addi r11, r11, 0x1#define CHECK_EXCEPTION_COUNTER \l.sfne r11, r12 ; \l.bf _fail ; \l.nop ;#define EXPECT_RANGE_EXCEPT \l.addi r12, r12, 1 ; \CHECK_EXCEPTION_COUNTER/* ---[ 0xb00: Range exception ]---------------------------------------- */.org 0xb00l.sw 0(r0), r3 ;// Save r3 - don't disrupt it during exceptionsl.ori r3, r0, 0xaaeel.nop 0x2// TODO - get instruction and decode to ensure it was an instruction// which is capable of causing a range exception. Remember delay slot!INCREMENT_EXCEPTION_COUNTER// Clear OV in ESRl.mfspr r3,r0,SPR_ESR_BASE ;// Get ESRl.nop 2l.xori r3, r3,SPR_SR_OV ;// Clear OV bitl.mtspr r0,r3,SPR_ESR_BASE ;// Get EPCl.mfspr r3,r0,SPR_EPCR_BASE ;// Get EPCl.nop 2l.addi r3, r3, 0x4 ;// Incrementl.mtspr r0,r3,SPR_EPCR_BASE ;// Get EPC// For now, increment EPCR so we step over instruction and continuel.lwz r3, 0(r0)l.rfe/* =================================================== [ text ] === */.section .text/* =================================================== [ start ] === */.global _start_start:// Clear all regsl.movhi r1, 0l.movhi r2, 0l.movhi r3, 0l.movhi r4, 0l.movhi r5, 0l.movhi r6, 0l.movhi r7, 0l.movhi r8, 0l.movhi r9, 0l.movhi r10, 0l.movhi r11, 0l.movhi r12, 0l.movhi r13, 0l.movhi r14, 0l.movhi r15, 0l.movhi r16, 0l.movhi r17, 0l.movhi r18, 0l.movhi r19, 0l.movhi r20, 0l.movhi r21, 0l.movhi r22, 0l.movhi r23, 0l.movhi r24, 0l.movhi r25, 0l.movhi r26, 0l.movhi r27, 0l.movhi r28, 0l.movhi r29, 0l.movhi r30, 0l.movhi r31, 0#ifdef OR1200_IMPL_OV// Kick off testl.jal _main#else// Not supported, exit testl.j _finish#endifl.nop/* =================================================== [ main ] === */#define CHECK_OV_CLEAR \l.mfspr r20, r0, SPR_SR ; \l.andi r21, r20, SPR_SR_OV ; \l.sfne r21, r0 ; \l.bf _fail ; \l.nop#define CHECK_OV_SET \l.mfspr r20, r0, SPR_SR ; \l.andi r21, r20, SPR_SR_OV ; \l.sfnei r21, SPR_SR_OV ; \l.bf _fail ; \l.addi r12, r12, 0x1 ; // Increment expected counter.global _main_main:// Set up some values, check the OV bit is clearedCHECK_OV_CLEARl.movhi r4, 0x7fffl.ori r4, r4, 0xefffl.ori r5, r0, 0xffffl.add r3, r5, r4 ;// Should set overflowl.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEARl.addi r3, r4, 0x7fff ;// Should set overflowl.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR// Now test negative numbersl.movhi r4, 0x8000l.ori r4, r4, 0x0000l.movhi r5, 0xffffl.ori r5, r5, 0xffffl.add r3, r4, r5 // Biggest and smallest negative numberl.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEARl.addi r3, r4, 0xffff // Biggest and smallest negative numberl.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEARl.add r3, r4, r0 // Biggest negative number, and zerol.nop 0x2CHECK_OV_CLEARl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEARl.movhi r5, 0xffffl.ori r5, r5, 0xfffel.add r3, r4, r5 // Biggest and second smallest negative numberl.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR#ifdef OR1200_IMPL_SUB// report indicator that we're at l.sub section 0x55555555l.movhi r3, 0x5555l.ori r3, r3, 0x5555l.nop 0x2// Quick subtract check// Check largest negative number -1 tripping overflowl.ori r5, r0, 1 ; // +1l.sub r3, r4, r5 ; // -2147483647 - 1l.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR// Subtract the biggest negative number from the// biggest positive number.l.movhi r4,0x7fffl.ori r4,r4,0xffffl.movhi r5,0x8000l.sub r3,r4,r5l.nop 2CHECK_OV_SET#endifl.movhi r4, 0x8000l.ori r4, r4, 0x0437l.movhi r5, 0xffffl.ori r5, r5, 0xfbc7l.add r3, r4, r5 // Very big negative number, another one big// enough to cause overflow hopefullyl.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEARl.movhi r5, 0xffffl.ori r5, r5, 0xfff7l.add r3, r4, r5 // Two negative numbers but shouldn't overflowl.nop 0x2CHECK_OV_CLEAR#ifdef OR1200_DIV_IMPLEMENTED// report indicator that we're at l.div section 0xddddddddl.movhi r3, 0xddddl.ori r3, r3, 0xddddl.nop 0x2// Test divide by zerol.div r3, r5, r0l.nop 0x2l.sfne r3, r0 ;// Check result was 0l.bf _failCHECK_OV_SETl.add r3, r5, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR// Test divide by zerol.divu r3, r0, r0l.nop 0x2CHECK_OV_SETl.sfne r3, r0 ;// Check result was 0l.bf _faill.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR#endif#ifdef OR1200_MULT_IMPLEMENTED// report indicator that we're at l.multiply section 0x11111111l.movhi r3, 0x1111l.ori r3, r3, 0x1111l.nop 0x2// Check multiplying two large numbers, which will cause overflow,// trigger the flag appropriately// First signed multiply.l.movhi r4, 0xd555 ;//-(((2^32)-1)/3 + 2)l.ori r4, r4, 0x5552l.ori r5, r0, 2l.ori r6, r0, 3// First multiply big negative number by 2 - shouldn't overflowl.mul r3, r4, r5l.nop 0x2CHECK_OV_CLEAR// Now multiply by 3 - should just overflow negativel.mul r3, r4, r6l.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR// Now some big positive valuesl.movhi r4, 0x2aaa ;//((2^32)-1)/3 + 2l.ori r4, r4, 0xaaael.ori r5, r0, 2l.ori r6, r0, 3// First multiply big number by 2 - shouldn't overflowl.mul r3, r4, r5l.nop 0x2CHECK_OV_CLEAR// Now multiply by 3 - should only just overflowl.mul r3, r4, r6l.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR// First multiply big number by 2 - shouldn't overflowl.muli r3, r4, 0x2l.nop 0x2CHECK_OV_CLEAR// Now multiply by 3 - should just overflow negativel.muli r3, r4, 0x3l.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR// Now check overflow on unsigned multiply// Some stimulus to make a 32-bit multiply overflowl.movhi r4, 0x5555 ;//((2^32))/3 + 2l.ori r4, r4, 0x5557l.ori r5, r0, 2l.ori r6, r0, 3// First multiply big negative number by 2 - shouldn't overflowl.mulu r3, r4, r5l.nop 0x2CHECK_OV_CLEAR// Now multiply by 3 - should just overflow negativel.mulu r3, r4, r6l.nop 0x2CHECK_OV_SETl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_OV_CLEAR#endif/////////////////////////////////////////////////////////////// //// Range Exception Tests //// ///////////////////////////////////////////////////////////////#ifdef OR1200_IMPL_OVE// report indicator that we're at exception section 0xeeeeeeeel.movhi r3, 0xeeeel.ori r3, r3, 0xeeeel.nop 0x2// First enable OV exception in SRl.mfspr r20, r0, SPR_SRl.ori r21, r20, SPR_SR_OVEl.mtspr r0, r21, SPR_SR// Check it's setl.mfspr r20, r0, SPR_SRl.andi r21, r20, SPR_SR_OVEl.sfnei r21, SPR_SR_OVEl.bf _faill.nop// now set r11 to r12 to know how many tests we've done so farl.or r11, r12, r12l.movhi r4, 0x7fffl.ori r4, r4, 0xefffl.ori r5, r0, 0xffffl.add r3, r5, r4 ;// Should set overflowl.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTERl.addi r3, r4, 0x7fff ;// Should set overflowl.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER// Now test negative numbersl.movhi r4, 0x8000l.ori r4, r4, 0x0000l.movhi r5, 0xffffl.ori r5, r5, 0xffffl.add r3, r4, r5 // Biggest and smallest negative numberl.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTERl.addi r3, r4, 0xffff // Biggest and smallest negative numberl.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTERl.add r3, r4, r0 // Biggest negative number, and zerol.nop 0x2CHECK_EXCEPTION_COUNTERl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTERl.movhi r5, 0xffffl.ori r5, r5, 0xfffel.add r3, r4, r5 // Biggest and second smallest negative numberl.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER#ifdef OR1200_IMPL_SUB// report indicator that we're at l.sub section 0x55555555l.movhi r3, 0x5555l.ori r3, r3, 0x5555l.nop 0x2// Quick subtract check// Check largest negative number -1 tripping overflowl.ori r5, r0, 1 ; // +1l.sub r3, r4, r5 ; // -2147483647 - 1l.nop 0x2EXPECT_RANGE_EXCEPTl.sub r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER#endifl.movhi r4, 0x8000l.ori r4, r4, 0x0437l.movhi r5, 0xffffl.ori r5, r5, 0xfbc7l.add r3, r4, r5 // Very big negative number, another one big// enough to cause overflow hopefullyl.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTERl.movhi r5, 0xffffl.ori r5, r5, 0xfff7l.add r3, r4, r5 // Two negative numbers but shouldn't overflowl.nop 0x2CHECK_EXCEPTION_COUNTER#ifdef OR1200_DIV_IMPLEMENTED// report indicator that we're at l.div section 0xddddddddl.movhi r3, 0xddddl.ori r3, r3, 0xddddl.nop 0x2// Test divide by zerol.div r3, r5, r0l.nop 0x2l.sfne r3, r0 ;// Check result was 0l.bf _failEXPECT_RANGE_EXCEPTl.add r3, r5, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER// Test divide by zerol.divu r3, r0, r0l.nop 0x2EXPECT_RANGE_EXCEPTl.sfne r3, r0 ;// Check result was 0l.bf _faill.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER#endif#ifdef OR1200_MULT_IMPLEMENTED// report indicator that we're at l.multiply section 0x11111111l.movhi r3, 0x1111l.ori r3, r3, 0x1111l.nop 0x2// Check multiplying two large numbers, which will cause overflow,// trigger the flag appropriately// First signed multiply.l.movhi r4, 0xd555 ;//-(((2^32)-1)/3 + 2)l.ori r4, r4, 0x5552l.ori r5, r0, 2l.ori r6, r0, 3// First multiply big negative number by 2 - shouldn't overflowl.mul r3, r4, r5l.nop 0x2CHECK_EXCEPTION_COUNTER// Now multiply by 3 - should just overflow negativel.mul r3, r4, r6l.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER// Now some big positive valuesl.movhi r4, 0x2aaa ;//((2^32)-1)/3 + 2l.ori r4, r4, 0xaaael.ori r5, r0, 2l.ori r6, r0, 3// First multiply big number by 2 - shouldn't overflowl.mul r3, r4, r5l.nop 0x2CHECK_EXCEPTION_COUNTER// Now multiply by 3 - should only just overflowl.mul r3, r4, r6l.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER// First multiply big number by 2 - shouldn't overflowl.muli r3, r4, 0x2l.nop 0x2CHECK_EXCEPTION_COUNTER// Now multiply by 3 - should just overflow negativel.muli r3, r4, 0x3l.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER// Now check overflow on unsigned multiply// Some stimulus to make a 32-bit multiply overflowl.movhi r4, 0x5555 ;//((2^32))/3 + 2l.ori r4, r4, 0x5557l.ori r5, r0, 2l.ori r6, r0, 3// First multiply big negative number by 2 - shouldn't overflowl.mulu r3, r4, r5l.nop 0x2CHECK_EXCEPTION_COUNTER// Now multiply by 3 - should just overflow negativel.mulu r3, r4, r6l.nop 0x2EXPECT_RANGE_EXCEPTl.add r3, r0, r0 ;// Should clear overflowl.nop 0x2CHECK_EXCEPTION_COUNTER#endif#endif_finish:l.movhi r3, hi(0x8000000d)l.ori r3, r3, lo(0x8000000d)l.nop 0x2l.ori r3, r0, 0l.nop 0x1_fail:l.or r3, r12, r0 ;// Fail and report test number we were up tol.nop 0x1
