OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [or1200/] [sim/] [or1200-ov.S] - Diff between revs 502 and 803

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 502 Rev 803
/*
/*
        OR1200 overflow bit checking
        OR1200 overflow bit checking
        Very basic, testing
        Very basic, testing
TODO:    Check range exception handling in delay slots
TODO:    Check range exception handling in delay slots
        Julius Baxter, ORSoC AB, julius.baxter@orsoc.se
        Julius Baxter, ORSoC AB, julius.baxter@orsoc.se
*/
*/
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
//// Copyright (C) 2011 Authors and OPENCORES.ORG                 ////
//// Copyright (C) 2011 Authors and OPENCORES.ORG                 ////
////                                                              ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
//// later version.                                               ////
////                                                              ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
//// details.                                                     ////
////                                                              ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
#include "spr-defs.h"
#include "spr-defs.h"
#include "board.h"
#include "board.h"
#include "or1200-defines.h"
#include "or1200-defines.h"
/* =================================================== [ exceptions ] === */
/* =================================================== [ exceptions ] === */
        .section .vectors, "ax"
        .section .vectors, "ax"
/* ---[ 0x100: RESET exception ]----------------------------------------- */
/* ---[ 0x100: RESET exception ]----------------------------------------- */
        .org 0x100
        .org 0x100
        l.movhi r0, 0
        l.movhi r0, 0
        /* Clear status register */
        /* Clear status register */
        l.ori r1, r0, SPR_SR_SM
        l.ori r1, r0, SPR_SR_SM
        l.mtspr r0, r1, SPR_SR
        l.mtspr r0, r1, SPR_SR
        /* Clear timer  */
        /* Clear timer  */
        l.mtspr r0, r0, SPR_TTMR
        l.mtspr r0, r0, SPR_TTMR
        /* Jump to program initialisation code */
        /* Jump to program initialisation code */
        .global _start
        .global _start
        l.movhi r4, hi(_start)
        l.movhi r4, hi(_start)
        l.ori r4, r4, lo(_start)
        l.ori r4, r4, lo(_start)
        l.jr    r4
        l.jr    r4
        l.nop
        l.nop
        .org 0x600
        .org 0x600
        l.nop 0x1
        l.nop 0x1
/* ---[ 0x700: Illegal instruction exception ]-------------------------- */
/* ---[ 0x700: Illegal instruction exception ]-------------------------- */
        .org 0x700
        .org 0x700
#ifndef OR1200_IMPL_ADDC
#ifndef OR1200_IMPL_ADDC
        // No problem - instruction not supported
        // No problem - instruction not supported
        l.movhi r3, hi(0x8000000d)
        l.movhi r3, hi(0x8000000d)
        l.ori   r3, r3, lo(0x8000000d)
        l.ori   r3, r3, lo(0x8000000d)
        l.nop   0x2
        l.nop   0x2
        l.ori   r3, r0, 0
        l.ori   r3, r0, 0
#else
#else
        l.ori   r3, r0, 1
        l.ori   r3, r0, 1
#endif
#endif
        l.nop   0x1
        l.nop   0x1
#define INCREMENT_EXCEPTION_COUNTER     l.addi r11, r11, 0x1
#define INCREMENT_EXCEPTION_COUNTER     l.addi r11, r11, 0x1
#define CHECK_EXCEPTION_COUNTER         \
#define CHECK_EXCEPTION_COUNTER         \
        l.sfne  r11, r12        ;       \
        l.sfne  r11, r12        ;       \
        l.bf    _fail           ;       \
        l.bf    _fail           ;       \
        l.nop                   ;
        l.nop                   ;
#define EXPECT_RANGE_EXCEPT             \
#define EXPECT_RANGE_EXCEPT             \
        l.addi  r12, r12, 1     ;       \
        l.addi  r12, r12, 1     ;       \
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
/* ---[ 0xb00: Range exception ]---------------------------------------- */
/* ---[ 0xb00: Range exception ]---------------------------------------- */
        .org 0xb00
        .org 0xb00
        l.sw    0(r0), r3       ;// Save r3 - don't disrupt it during exceptions
        l.sw    0(r0), r3       ;// Save r3 - don't disrupt it during exceptions
        l.ori   r3, r0, 0xaaee
        l.ori   r3, r0, 0xaaee
        l.nop   0x2
        l.nop   0x2
        // TODO - get instruction and decode to ensure it was an instruction
        // TODO - get instruction and decode to ensure it was an instruction
        // which is capable of causing a range exception. Remember delay slot!
        // which is capable of causing a range exception. Remember delay slot!
        INCREMENT_EXCEPTION_COUNTER
        INCREMENT_EXCEPTION_COUNTER
        // Clear OV in ESR
        // Clear OV in ESR
        l.mfspr r3,r0,SPR_ESR_BASE      ;// Get ESR
        l.mfspr r3,r0,SPR_ESR_BASE      ;// Get ESR
        l.nop   2
        l.nop   2
        l.xori  r3, r3,SPR_SR_OV        ;// Clear OV bit
        l.xori  r3, r3,SPR_SR_OV        ;// Clear OV bit
        l.mtspr r0,r3,SPR_ESR_BASE      ;// Get EPC
        l.mtspr r0,r3,SPR_ESR_BASE      ;// Get EPC
        l.mfspr r3,r0,SPR_EPCR_BASE     ;// Get EPC
        l.mfspr r3,r0,SPR_EPCR_BASE     ;// Get EPC
        l.nop   2
        l.nop   2
        l.addi  r3, r3, 0x4             ;// Increment
        l.addi  r3, r3, 0x4             ;// Increment
        l.mtspr r0,r3,SPR_EPCR_BASE     ;// Get EPC
        l.mtspr r0,r3,SPR_EPCR_BASE     ;// Get EPC
        // For now, increment EPCR so we step over instruction and continue
        // For now, increment EPCR so we step over instruction and continue
        l.lwz   r3, 0(r0)
        l.lwz   r3, 0(r0)
        l.rfe
        l.rfe
/* =================================================== [ text ] === */
/* =================================================== [ text ] === */
        .section .text
        .section .text
/* =================================================== [ start ] === */
/* =================================================== [ start ] === */
        .global _start
        .global _start
_start:
_start:
        // Clear all regs
        // Clear all regs
        l.movhi r1, 0
        l.movhi r1, 0
        l.movhi r2, 0
        l.movhi r2, 0
        l.movhi r3, 0
        l.movhi r3, 0
        l.movhi r4, 0
        l.movhi r4, 0
        l.movhi r5, 0
        l.movhi r5, 0
        l.movhi r6, 0
        l.movhi r6, 0
        l.movhi r7, 0
        l.movhi r7, 0
        l.movhi r8, 0
        l.movhi r8, 0
        l.movhi r9, 0
        l.movhi r9, 0
        l.movhi r10, 0
        l.movhi r10, 0
        l.movhi r11, 0
        l.movhi r11, 0
        l.movhi r12, 0
        l.movhi r12, 0
        l.movhi r13, 0
        l.movhi r13, 0
        l.movhi r14, 0
        l.movhi r14, 0
        l.movhi r15, 0
        l.movhi r15, 0
        l.movhi r16, 0
        l.movhi r16, 0
        l.movhi r17, 0
        l.movhi r17, 0
        l.movhi r18, 0
        l.movhi r18, 0
        l.movhi r19, 0
        l.movhi r19, 0
        l.movhi r20, 0
        l.movhi r20, 0
        l.movhi r21, 0
        l.movhi r21, 0
        l.movhi r22, 0
        l.movhi r22, 0
        l.movhi r23, 0
        l.movhi r23, 0
        l.movhi r24, 0
        l.movhi r24, 0
        l.movhi r25, 0
        l.movhi r25, 0
        l.movhi r26, 0
        l.movhi r26, 0
        l.movhi r27, 0
        l.movhi r27, 0
        l.movhi r28, 0
        l.movhi r28, 0
        l.movhi r29, 0
        l.movhi r29, 0
        l.movhi r30, 0
        l.movhi r30, 0
        l.movhi r31, 0
        l.movhi r31, 0
#ifdef OR1200_IMPL_OV
#ifdef OR1200_IMPL_OV
        // Kick off test
        // Kick off test
        l.jal   _main
        l.jal   _main
#else
#else
        // Not supported, exit test
        // Not supported, exit test
        l.j     _finish
        l.j     _finish
#endif
#endif
        l.nop
        l.nop
/* =================================================== [ main ] === */
/* =================================================== [ main ] === */
#define CHECK_OV_CLEAR                  \
#define CHECK_OV_CLEAR                  \
        l.mfspr r20, r0, SPR_SR ;       \
        l.mfspr r20, r0, SPR_SR ;       \
        l.andi  r21, r20, SPR_SR_OV ;   \
        l.andi  r21, r20, SPR_SR_OV ;   \
        l.sfne  r21, r0           ;     \
        l.sfne  r21, r0           ;     \
        l.bf    _fail             ;     \
        l.bf    _fail             ;     \
        l.nop
        l.nop
#define CHECK_OV_SET                    \
#define CHECK_OV_SET                    \
        l.mfspr r20, r0, SPR_SR ;       \
        l.mfspr r20, r0, SPR_SR ;       \
        l.andi  r21, r20, SPR_SR_OV ;   \
        l.andi  r21, r20, SPR_SR_OV ;   \
        l.sfnei r21, SPR_SR_OV    ;     \
        l.sfnei r21, SPR_SR_OV    ;     \
        l.bf    _fail             ;     \
        l.bf    _fail             ;     \
        l.addi  r12, r12, 0x1     ;     // Increment expected counter
        l.addi  r12, r12, 0x1     ;     // Increment expected counter
        .global _main
        .global _main
_main:
_main:
        // Set up some values, check the OV bit is cleared
        // Set up some values, check the OV bit is cleared
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        l.movhi r4, 0x7fff
        l.movhi r4, 0x7fff
        l.ori   r4, r4, 0xefff
        l.ori   r4, r4, 0xefff
        l.ori   r5, r0, 0xffff
        l.ori   r5, r0, 0xffff
        l.add   r3, r5, r4      ;// Should set overflow
        l.add   r3, r5, r4      ;// Should set overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        l.addi  r3, r4, 0x7fff  ;// Should set overflow
        l.addi  r3, r4, 0x7fff  ;// Should set overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // Now test negative numbers
        // Now test negative numbers
        l.movhi r4, 0x8000
        l.movhi r4, 0x8000
        l.ori   r4, r4, 0x0000
        l.ori   r4, r4, 0x0000
        l.movhi r5, 0xffff
        l.movhi r5, 0xffff
        l.ori   r5, r5, 0xffff
        l.ori   r5, r5, 0xffff
        l.add   r3, r4, r5      // Biggest and smallest negative number
        l.add   r3, r4, r5      // Biggest and smallest negative number
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        l.addi  r3, r4, 0xffff  // Biggest and smallest negative number
        l.addi  r3, r4, 0xffff  // Biggest and smallest negative number
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        l.add   r3, r4, r0      // Biggest negative number, and zero
        l.add   r3, r4, r0      // Biggest negative number, and zero
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        l.movhi r5, 0xffff
        l.movhi r5, 0xffff
        l.ori   r5, r5, 0xfffe
        l.ori   r5, r5, 0xfffe
        l.add   r3, r4, r5      // Biggest and second smallest negative number
        l.add   r3, r4, r5      // Biggest and second smallest negative number
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
#ifdef OR1200_IMPL_SUB
#ifdef OR1200_IMPL_SUB
        // report indicator that we're at l.sub section 0x55555555
        // report indicator that we're at l.sub section 0x55555555
        l.movhi r3, 0x5555
        l.movhi r3, 0x5555
        l.ori   r3, r3, 0x5555
        l.ori   r3, r3, 0x5555
        l.nop   0x2
        l.nop   0x2
        // Quick subtract check
        // Quick subtract check
        // Check largest negative number -1 tripping overflow
        // Check largest negative number -1 tripping overflow
        l.ori   r5, r0, 1               ; // +1
        l.ori   r5, r0, 1               ; // +1
        l.sub   r3, r4, r5              ; // -2147483647 - 1
        l.sub   r3, r4, r5              ; // -2147483647 - 1
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
 
 
 
        // Subtract the biggest negative number from the
 
        // biggest positive number.
 
        l.movhi r4,0x7fff
 
        l.ori   r4,r4,0xffff
 
        l.movhi r5,0x8000
 
        l.sub   r3,r4,r5
 
        l.nop   2
 
        CHECK_OV_SET
 
 
#endif
#endif
        l.movhi r4, 0x8000
        l.movhi r4, 0x8000
        l.ori   r4, r4, 0x0437
        l.ori   r4, r4, 0x0437
        l.movhi r5, 0xffff
        l.movhi r5, 0xffff
        l.ori   r5, r5, 0xfbc7
        l.ori   r5, r5, 0xfbc7
        l.add   r3, r4, r5      // Very big negative number, another one big
        l.add   r3, r4, r5      // Very big negative number, another one big
                                // enough to cause overflow hopefully
                                // enough to cause overflow hopefully
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        l.movhi r5, 0xffff
        l.movhi r5, 0xffff
        l.ori   r5, r5, 0xfff7
        l.ori   r5, r5, 0xfff7
        l.add   r3, r4, r5      // Two negative numbers but shouldn't overflow
        l.add   r3, r4, r5      // Two negative numbers but shouldn't overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
#ifdef OR1200_DIV_IMPLEMENTED
#ifdef OR1200_DIV_IMPLEMENTED
        // report indicator that we're at l.div section 0xdddddddd
        // report indicator that we're at l.div section 0xdddddddd
        l.movhi r3, 0xdddd
        l.movhi r3, 0xdddd
        l.ori   r3, r3, 0xdddd
        l.ori   r3, r3, 0xdddd
        l.nop   0x2
        l.nop   0x2
        // Test divide by zero
        // Test divide by zero
        l.div   r3, r5, r0
        l.div   r3, r5, r0
        l.nop   0x2
        l.nop   0x2
        l.sfne  r3, r0          ;// Check result was 0
        l.sfne  r3, r0          ;// Check result was 0
        l.bf    _fail
        l.bf    _fail
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r5, r0      ;// Should clear overflow
        l.add   r3, r5, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // Test divide by zero
        // Test divide by zero
        l.divu  r3, r0, r0
        l.divu  r3, r0, r0
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.sfne  r3, r0          ;// Check result was 0
        l.sfne  r3, r0          ;// Check result was 0
        l.bf    _fail
        l.bf    _fail
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
#endif
#endif
#ifdef OR1200_MULT_IMPLEMENTED
#ifdef OR1200_MULT_IMPLEMENTED
        // report indicator that we're at l.multiply section 0x11111111
        // report indicator that we're at l.multiply section 0x11111111
        l.movhi r3, 0x1111
        l.movhi r3, 0x1111
        l.ori   r3, r3, 0x1111
        l.ori   r3, r3, 0x1111
        l.nop   0x2
        l.nop   0x2
        // Check multiplying two large numbers, which will cause overflow,
        // Check multiplying two large numbers, which will cause overflow,
        // trigger the flag appropriately
        // trigger the flag appropriately
        // First signed multiply.
        // First signed multiply.
        l.movhi r4, 0xd555      ;//-(((2^32)-1)/3 + 2)
        l.movhi r4, 0xd555      ;//-(((2^32)-1)/3 + 2)
        l.ori   r4, r4, 0x5552
        l.ori   r4, r4, 0x5552
        l.ori   r5, r0, 2
        l.ori   r5, r0, 2
        l.ori   r6, r0, 3
        l.ori   r6, r0, 3
        // First multiply big negative number by 2 - shouldn't overflow
        // First multiply big negative number by 2 - shouldn't overflow
        l.mul   r3, r4, r5
        l.mul   r3, r4, r5
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // Now multiply by 3 - should just overflow negative
        // Now multiply by 3 - should just overflow negative
        l.mul   r3, r4, r6
        l.mul   r3, r4, r6
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // Now some big positive values
        // Now some big positive values
        l.movhi r4, 0x2aaa      ;//((2^32)-1)/3 + 2
        l.movhi r4, 0x2aaa      ;//((2^32)-1)/3 + 2
        l.ori   r4, r4, 0xaaae
        l.ori   r4, r4, 0xaaae
        l.ori   r5, r0, 2
        l.ori   r5, r0, 2
        l.ori   r6, r0, 3
        l.ori   r6, r0, 3
        // First multiply big number by 2 - shouldn't overflow
        // First multiply big number by 2 - shouldn't overflow
        l.mul   r3, r4, r5
        l.mul   r3, r4, r5
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // Now multiply by 3 - should only just overflow
        // Now multiply by 3 - should only just overflow
        l.mul   r3, r4, r6
        l.mul   r3, r4, r6
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // First multiply big number by 2 - shouldn't overflow
        // First multiply big number by 2 - shouldn't overflow
        l.muli  r3, r4, 0x2
        l.muli  r3, r4, 0x2
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // Now multiply by 3 - should just overflow negative
        // Now multiply by 3 - should just overflow negative
        l.muli  r3, r4, 0x3
        l.muli  r3, r4, 0x3
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // Now check overflow on  unsigned multiply
        // Now check overflow on  unsigned multiply
        // Some stimulus to make a 32-bit multiply overflow
        // Some stimulus to make a 32-bit multiply overflow
        l.movhi r4, 0x5555      ;//((2^32))/3 + 2
        l.movhi r4, 0x5555      ;//((2^32))/3 + 2
        l.ori   r4, r4, 0x5557
        l.ori   r4, r4, 0x5557
        l.ori   r5, r0, 2
        l.ori   r5, r0, 2
        l.ori   r6, r0, 3
        l.ori   r6, r0, 3
        // First multiply big negative number by 2 - shouldn't overflow
        // First multiply big negative number by 2 - shouldn't overflow
        l.mulu  r3, r4, r5
        l.mulu  r3, r4, r5
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
        // Now multiply by 3 - should just overflow negative
        // Now multiply by 3 - should just overflow negative
        l.mulu  r3, r4, r6
        l.mulu  r3, r4, r6
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_SET
        CHECK_OV_SET
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_OV_CLEAR
        CHECK_OV_CLEAR
#endif
#endif
        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
        //                                                         //
        //                                                         //
        // Range Exception Tests                                   //
        // Range Exception Tests                                   //
        //                                                         //
        //                                                         //
        /////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////
#ifdef OR1200_IMPL_OVE
#ifdef OR1200_IMPL_OVE
        // report indicator that we're at exception section 0xeeeeeeee
        // report indicator that we're at exception section 0xeeeeeeee
        l.movhi r3, 0xeeee
        l.movhi r3, 0xeeee
        l.ori   r3, r3, 0xeeee
        l.ori   r3, r3, 0xeeee
        l.nop   0x2
        l.nop   0x2
        // First enable OV exception in SR
        // First enable OV exception in SR
        l.mfspr r20, r0, SPR_SR
        l.mfspr r20, r0, SPR_SR
        l.ori   r21, r20, SPR_SR_OVE
        l.ori   r21, r20, SPR_SR_OVE
        l.mtspr r0, r21, SPR_SR
        l.mtspr r0, r21, SPR_SR
        // Check it's set
        // Check it's set
        l.mfspr r20, r0, SPR_SR
        l.mfspr r20, r0, SPR_SR
        l.andi  r21, r20, SPR_SR_OVE
        l.andi  r21, r20, SPR_SR_OVE
        l.sfnei r21, SPR_SR_OVE
        l.sfnei r21, SPR_SR_OVE
        l.bf    _fail
        l.bf    _fail
        l.nop
        l.nop
        // now set r11 to r12 to know how many tests we've done so far
        // now set r11 to r12 to know how many tests we've done so far
        l.or    r11, r12, r12
        l.or    r11, r12, r12
        l.movhi r4, 0x7fff
        l.movhi r4, 0x7fff
        l.ori   r4, r4, 0xefff
        l.ori   r4, r4, 0xefff
        l.ori   r5, r0, 0xffff
        l.ori   r5, r0, 0xffff
        l.add   r3, r5, r4      ;// Should set overflow
        l.add   r3, r5, r4      ;// Should set overflow
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        l.addi  r3, r4, 0x7fff  ;// Should set overflow
        l.addi  r3, r4, 0x7fff  ;// Should set overflow
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // Now test negative numbers
        // Now test negative numbers
        l.movhi r4, 0x8000
        l.movhi r4, 0x8000
        l.ori   r4, r4, 0x0000
        l.ori   r4, r4, 0x0000
        l.movhi r5, 0xffff
        l.movhi r5, 0xffff
        l.ori   r5, r5, 0xffff
        l.ori   r5, r5, 0xffff
        l.add   r3, r4, r5      // Biggest and smallest negative number
        l.add   r3, r4, r5      // Biggest and smallest negative number
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        l.addi  r3, r4, 0xffff  // Biggest and smallest negative number
        l.addi  r3, r4, 0xffff  // Biggest and smallest negative number
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        l.add   r3, r4, r0      // Biggest negative number, and zero
        l.add   r3, r4, r0      // Biggest negative number, and zero
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        l.movhi r5, 0xffff
        l.movhi r5, 0xffff
        l.ori   r5, r5, 0xfffe
        l.ori   r5, r5, 0xfffe
        l.add   r3, r4, r5      // Biggest and second smallest negative number
        l.add   r3, r4, r5      // Biggest and second smallest negative number
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
#ifdef OR1200_IMPL_SUB
#ifdef OR1200_IMPL_SUB
        // report indicator that we're at l.sub section 0x55555555
        // report indicator that we're at l.sub section 0x55555555
        l.movhi r3, 0x5555
        l.movhi r3, 0x5555
        l.ori   r3, r3, 0x5555
        l.ori   r3, r3, 0x5555
        l.nop   0x2
        l.nop   0x2
        // Quick subtract check
        // Quick subtract check
        // Check largest negative number -1 tripping overflow
        // Check largest negative number -1 tripping overflow
        l.ori   r5, r0, 1               ; // +1
        l.ori   r5, r0, 1               ; // +1
        l.sub   r3, r4, r5              ; // -2147483647 - 1
        l.sub   r3, r4, r5              ; // -2147483647 - 1
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.sub   r3, r0, r0      ;// Should clear overflow
        l.sub   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
#endif
#endif
        l.movhi r4, 0x8000
        l.movhi r4, 0x8000
        l.ori   r4, r4, 0x0437
        l.ori   r4, r4, 0x0437
        l.movhi r5, 0xffff
        l.movhi r5, 0xffff
        l.ori   r5, r5, 0xfbc7
        l.ori   r5, r5, 0xfbc7
        l.add   r3, r4, r5      // Very big negative number, another one big
        l.add   r3, r4, r5      // Very big negative number, another one big
                                // enough to cause overflow hopefully
                                // enough to cause overflow hopefully
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        l.movhi r5, 0xffff
        l.movhi r5, 0xffff
        l.ori   r5, r5, 0xfff7
        l.ori   r5, r5, 0xfff7
        l.add   r3, r4, r5      // Two negative numbers but shouldn't overflow
        l.add   r3, r4, r5      // Two negative numbers but shouldn't overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
#ifdef OR1200_DIV_IMPLEMENTED
#ifdef OR1200_DIV_IMPLEMENTED
        // report indicator that we're at l.div section 0xdddddddd
        // report indicator that we're at l.div section 0xdddddddd
        l.movhi r3, 0xdddd
        l.movhi r3, 0xdddd
        l.ori   r3, r3, 0xdddd
        l.ori   r3, r3, 0xdddd
        l.nop   0x2
        l.nop   0x2
        // Test divide by zero
        // Test divide by zero
        l.div   r3, r5, r0
        l.div   r3, r5, r0
        l.nop   0x2
        l.nop   0x2
        l.sfne  r3, r0          ;// Check result was 0
        l.sfne  r3, r0          ;// Check result was 0
        l.bf    _fail
        l.bf    _fail
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r5, r0      ;// Should clear overflow
        l.add   r3, r5, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // Test divide by zero
        // Test divide by zero
        l.divu  r3, r0, r0
        l.divu  r3, r0, r0
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.sfne  r3, r0          ;// Check result was 0
        l.sfne  r3, r0          ;// Check result was 0
        l.bf    _fail
        l.bf    _fail
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
#endif
#endif
#ifdef OR1200_MULT_IMPLEMENTED
#ifdef OR1200_MULT_IMPLEMENTED
        // report indicator that we're at l.multiply section 0x11111111
        // report indicator that we're at l.multiply section 0x11111111
        l.movhi r3, 0x1111
        l.movhi r3, 0x1111
        l.ori   r3, r3, 0x1111
        l.ori   r3, r3, 0x1111
        l.nop   0x2
        l.nop   0x2
        // Check multiplying two large numbers, which will cause overflow,
        // Check multiplying two large numbers, which will cause overflow,
        // trigger the flag appropriately
        // trigger the flag appropriately
        // First signed multiply.
        // First signed multiply.
        l.movhi r4, 0xd555      ;//-(((2^32)-1)/3 + 2)
        l.movhi r4, 0xd555      ;//-(((2^32)-1)/3 + 2)
        l.ori   r4, r4, 0x5552
        l.ori   r4, r4, 0x5552
        l.ori   r5, r0, 2
        l.ori   r5, r0, 2
        l.ori   r6, r0, 3
        l.ori   r6, r0, 3
        // First multiply big negative number by 2 - shouldn't overflow
        // First multiply big negative number by 2 - shouldn't overflow
        l.mul   r3, r4, r5
        l.mul   r3, r4, r5
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // Now multiply by 3 - should just overflow negative
        // Now multiply by 3 - should just overflow negative
        l.mul   r3, r4, r6
        l.mul   r3, r4, r6
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // Now some big positive values
        // Now some big positive values
        l.movhi r4, 0x2aaa      ;//((2^32)-1)/3 + 2
        l.movhi r4, 0x2aaa      ;//((2^32)-1)/3 + 2
        l.ori   r4, r4, 0xaaae
        l.ori   r4, r4, 0xaaae
        l.ori   r5, r0, 2
        l.ori   r5, r0, 2
        l.ori   r6, r0, 3
        l.ori   r6, r0, 3
        // First multiply big number by 2 - shouldn't overflow
        // First multiply big number by 2 - shouldn't overflow
        l.mul   r3, r4, r5
        l.mul   r3, r4, r5
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // Now multiply by 3 - should only just overflow
        // Now multiply by 3 - should only just overflow
        l.mul   r3, r4, r6
        l.mul   r3, r4, r6
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // First multiply big number by 2 - shouldn't overflow
        // First multiply big number by 2 - shouldn't overflow
        l.muli  r3, r4, 0x2
        l.muli  r3, r4, 0x2
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // Now multiply by 3 - should just overflow negative
        // Now multiply by 3 - should just overflow negative
        l.muli  r3, r4, 0x3
        l.muli  r3, r4, 0x3
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // Now check overflow on  unsigned multiply
        // Now check overflow on  unsigned multiply
        // Some stimulus to make a 32-bit multiply overflow
        // Some stimulus to make a 32-bit multiply overflow
        l.movhi r4, 0x5555      ;//((2^32))/3 + 2
        l.movhi r4, 0x5555      ;//((2^32))/3 + 2
        l.ori   r4, r4, 0x5557
        l.ori   r4, r4, 0x5557
        l.ori   r5, r0, 2
        l.ori   r5, r0, 2
        l.ori   r6, r0, 3
        l.ori   r6, r0, 3
        // First multiply big negative number by 2 - shouldn't overflow
        // First multiply big negative number by 2 - shouldn't overflow
        l.mulu  r3, r4, r5
        l.mulu  r3, r4, r5
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
        // Now multiply by 3 - should just overflow negative
        // Now multiply by 3 - should just overflow negative
        l.mulu  r3, r4, r6
        l.mulu  r3, r4, r6
        l.nop   0x2
        l.nop   0x2
        EXPECT_RANGE_EXCEPT
        EXPECT_RANGE_EXCEPT
        l.add   r3, r0, r0      ;// Should clear overflow
        l.add   r3, r0, r0      ;// Should clear overflow
        l.nop   0x2
        l.nop   0x2
        CHECK_EXCEPTION_COUNTER
        CHECK_EXCEPTION_COUNTER
#endif
#endif
#endif
#endif
_finish:
_finish:
        l.movhi r3, hi(0x8000000d)
        l.movhi r3, hi(0x8000000d)
        l.ori   r3, r3, lo(0x8000000d)
        l.ori   r3, r3, lo(0x8000000d)
        l.nop   0x2
        l.nop   0x2
        l.ori   r3, r0, 0
        l.ori   r3, r0, 0
        l.nop   0x1
        l.nop   0x1
_fail:
_fail:
        l.or    r3, r12, r0     ;// Fail and report test number we were up to
        l.or    r3, r12, r0     ;// Fail and report test number we were up to
        l.nop   0x1
        l.nop   0x1
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.