arith01.cpp revision 12855:588919e0e4aa
1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20/***************************************************************************** 21 22 arith01.cpp -- 23 24 Original Author: Martin Janssen, Synopsys, Inc., 2002-02-15 25 26 *****************************************************************************/ 27 28/***************************************************************************** 29 30 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 changes you are making here. 32 33 Name, Affiliation, Date: 34 Description of Modification: 35 36 *****************************************************************************/ 37 38#include <stdio.h> 39#include <stdlib.h> 40#include "systemc.h" 41 42/* 43 44 int9 x; 45 46 x.q = -256; 47 48 x.q is equal to 256 in Sun's CC, and -256 in gcc. The standard leaves 49 this issue as implementation dependent unless the definition is 50 qualified explicitly by signed or unsigned. 51 52 In order to force consistent behavior, I've qualified every int 53 definition accordingly in all the arith files. 54 55*/ 56 57typedef struct int9 { 58 signed int q : 9; 59} int9; 60 61typedef struct int31 { 62 signed int q : 31; 63} int31; 64 65void 66crunch(sc_signed& z, int31 v31, int u, int v) 67{ 68 for (int i = 0; i < 100000; ++i) { 69 z *= u; 70 z += v; 71 v31.q *= u; 72 v31.q += v; 73 sc_assert(z == v31.q); 74 } 75} 76 77// Function to fix result in int9 struct to correctly under-/overflow 78// within its 9 bits range and still ensure the correct sign encoding 79// over the full size of the integer variable. Otherwise, compiler 80// optimization may lead to spurious assertion errors. 81void 82fix_int9(int9& v) { 83 v.q %= 0x200; 84} 85 86int 87sc_main( int argc, char* argv[] ) 88{ 89 sc_signed x(31); 90 sc_signed y(9); 91 sc_signed z(31); 92 int9 v; 93 94 y = -256; 95 v.q = -256; 96 sc_assert(y == v.q); 97 cout << y << '\t' << v.q << endl; 98 for (int i = 0; i < 1000; ++i) { 99 y++; 100 v.q++; 101 fix_int9(v); 102 cout << y << '\t' << v.q << endl; 103 sc_assert(y == v.q); 104 } 105 for (int i = 0; i < 1000; ++i) { 106 y--; 107 v.q--; 108 fix_int9(v); 109 cout << y << '\t' << v.q << endl; 110 sc_assert(y == v.q); 111 } 112 for (int i = 0; i < 1000; ++i) { 113 ++y; 114 ++v.q; 115 fix_int9(v); 116 cout << y << '\t' << v.q << endl; 117 sc_assert(y == v.q); 118 } 119 for (int i = 0; i < 1000; ++i) { 120 --y; 121 --v.q; 122 fix_int9(v); 123 cout << y << '\t' << v.q << endl; 124 sc_assert(y == v.q); 125 } 126 127 z = 129023; 128 int31 v31; 129 v31.q = 129023; 130 crunch(z, v31, 491, 12089); 131 132 x = -129023; 133 v31.q = -129023; 134 crunch(x, v31, 109, -426); 135 136 x = -1; 137 v31.q = -1; 138 crunch(x, v31, 30941, -1188); 139 140 return 0; 141} 142