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