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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [AS64/] [source/] [Int128.cpp] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
#include "stdafx.h"
2
 
3
bool Int128::Add(Int128 *sum, Int128 *a, Int128 *b) {
4
        Int128 s1;
5
        bool c;
6
        s1.low = a->low + b->low;
7
        s1.high = a->high + b->high;
8
        if (AddCarry(s1.low, a->low, b->low)) {
9
                s1.high++;
10
        }
11
        c = AddCarry(sum->high,a->high,b->high);
12
        Assign(sum,&s1);
13
        return (c);
14
}
15
 
16
// Subtract two 128 bit numbers.
17
bool Int128::Sub(Int128 *sum, Int128 *a, Int128 *b) {
18
        Int128 s1;
19
        bool c;
20
        s1.low = a->low - b->low;
21
        s1.high = a->high - b->high;
22
        if (SubBorrow(s1.low, a->low, b->low)) {
23
                s1.high--;
24
        }
25
        c = SubBorrow(s1.high,a->high,b->high);
26
        Assign(sum,&s1);
27
        return (c);
28
}
29
 
30
// Shift left one bit.
31
bool Int128::Shl(Int128 *o, Int128 *a) {
32
        bool c = (a->low & 0x8000000000000000LL) != 0LL;
33
        Int128 r;
34
        r.low = a->low << 1LL;
35
        r.high = a->high << 1LL;
36
        if (c)
37
                r.high |= 1LL;
38
        c = (a->high & 0x8000000000000000LL) != 0LL;
39
        o->low = r.low;
40
        o->high = r.high;
41
        return (c);
42
}
43
 
44
// Shift right one bit.
45
bool Int128::Shr(Int128 *o, Int128 *a) {
46
        bool c = (a->high & 1LL) != 0LL;
47
        Int128 r;
48
        r.low = a->low >> 1LL;
49
        r.high = a->high >> 1LL;
50
        if (c)
51
                r.low |= 0x8000000000000000LL;
52
        c = (a->low & 1LL) != 0LL;
53
        o->low = r.low;
54
        o->high = r.high;
55
        return (c);
56
}
57
 
58
void Int128::Mul(Int128 *p, Int128 *a, Int128 *b)
59
{
60
        Int128 p0,p1;
61
        Int128 oa,ob;
62
        int nn;
63
        bool sign;
64
 
65
        p0.low = 0LL;
66
        p0.high = 0LL;
67
        p1.low = 0LL;
68
        p1.high = 0LL;
69
        Assign(&oa,a);
70
        Assign(&ob,b);
71
        // Compute output sign
72
        sign = ((oa.high ^ ob.high) >> 63LL);
73
        // Make a positive
74
        if (oa.high < 0)
75
                Sub(&oa,Zero(),&oa);
76
        // Make b positive
77
        if (ob.high < 0)
78
                Sub(&ob,Zero(),&ob);
79
        for (nn = 0; nn < 128; nn++) {
80
                if (Shl(&p0,&p0)) {
81
                        Shl(&p1,&p1);
82
                        p1.low |= 1LL;
83
                }
84
                else
85
                        Shl(&p1,&p1);
86
                if (oa.high & 0x8000000000000000LL) {
87
                        if (Add(&p0,&p0,&ob))
88
                                p1.low|=1LL;
89
                }
90
                Shl(&oa,&oa);
91
        }
92
        Assign (p,&p0);
93
        if (sign) {
94
                Sub(p,Zero(),p);
95
        }
96
}
97
 
98
void Int128::Div(Int128 *q, Int128 *r, Int128 *a, Int128 *b)
99
{
100
        Int128 qu,rm,oa,ob;
101
        int nn;
102
        bool sign = ((a->high ^ b->high) >> 63) != 0LL;
103
 
104
        // Make operands positive
105
        if ((b->high >> 63LL) & 1LL)
106
                Sub(&ob,Zero(),b);
107
        else
108
                Assign(&ob,b);
109
        if ((a->high >> 63LL) & 1LL)
110
                Sub(&oa,Zero(),a);
111
        else
112
                Assign(&oa,a);
113
 
114
        qu.high = ob.high;
115
        qu.low = ob.low;
116
        rm.high = 0LL;
117
        rm.low = 0LL;
118
        for (nn = 0; nn < 128; nn++) {
119
                Shl(&rm,&rm);
120
                if (Shl(&qu,&qu))
121
                        rm.low |= 1LL;
122
                if (IsLessThan(&oa,&rm)) {
123
                        Sub(&rm,&rm,&oa);
124
                        qu.low |= 1LL;
125
                }
126
        }
127
        if (sign)
128
                Sub(r,Zero(),&rm);
129
        else
130
                Assign(r,&rm);
131
        if (sign)
132
                Sub(q,Zero(),&qu);
133
        else
134
                Assign(q,&qu);
135
}
136
 
137
bool Int128::IsEqual(Int128 *a, Int128 *b)
138
{
139
        if (a->low != b->low)
140
                return (false);
141
        if (a->high != b->high)
142
                return (false);
143
        return (true);
144
}
145
 
146
bool Int128::IsLessThan(Int128 *a, Int128 *b)
147
{
148
        Int128 d;
149
 
150
        Sub(&d, a, b);
151
        if ((d.high >> 63LL) & 1LL)
152
                return (true);
153
        return (false);
154
}

powered by: WebSVN 2.1.0

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