-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathsoft.h
109 lines (89 loc) · 2.14 KB
/
soft.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#ifndef SOFT_H
#define SOFT_H
#include "array.h"
typedef Sint8 Flag;
typedef enum Round Round;
typedef enum Exception Exception;
typedef enum Tininess Tininess;
typedef enum Operation Operation;
typedef struct Context Context;
typedef struct Float32 Float32;
typedef struct Float64 Float64;
typedef struct Normal32 Normal32;
typedef struct Normal64 Normal64;
typedef struct CanonicalNaN CanonicalNaN;
struct Float32 {
Uint32 bits;
};
struct Float64 {
Uint64 bits;
};
struct Normal32 {
Uint32 sig;
Sint16 exp;
};
struct Normal64 {
Uint64 sig;
Sint16 exp;
};
// Canonical NaN format for conversion between NaNs in different precisions.
struct CanonicalNaN {
Flag sign;
Uint64 hi;
Uint64 lo;
};
enum Round {
ROUND_NEAREST_EVEN,
ROUND_TO_ZERO,
ROUND_DOWN,
ROUND_UP
};
enum Exception {
EXCEPTION_INEXACT = 1 << 0,
EXCEPTION_UNDERFLOW = 1 << 1,
EXCEPTION_OVERFLOW = 1 << 2,
EXCEPTION_INFINITE = 1 << 3,
EXCEPTION_INVALID = 1 << 4
};
enum Tininess {
TININESS_AFTER_ROUNDING,
TININESS_BEFORE_ROUNDING
};
enum Operation {
OPERATION_ADD,
OPERATION_SUB,
OPERATION_MUL,
OPERATION_DIV
};
struct Context {
Round round;
Size roundings;
ARRAY(Exception) exceptions; ///< Array of flags of triggered exceptions.
ARRAY(Operation) operations; ///< Array of all operations carried out
Tininess tininess;
};
void context_init(Context* context);
void context_free(Context* context);
void context_copy(Context* dst, const Context *src);
bool context_raise(Context *context, Exception exception);
// Special right shifts where the least significant bit of result is set when
// any non-zero bits are shifted off.
static inline Uint32 rshr32(Uint32 a, Sint16 count) {
if (count == 0) {
return a;
} else if (count < 32) {
return (a >> count) | ((a << ((-count) & 31)) != 0);
}
return a != 0 ? 1 : 0;
}
static inline Uint64 rshr64(Uint64 a, Sint16 count) {
if (count == 0) {
return a;
} else if (count < 64) {
return (a >> count) | ((a << ((-count) & 63)) != 0);
}
return a != 0 ? 1 : 0;
}
Float32 float64_to_float32(Context*, Float64);
Float64 float32_to_float64(Context*, Float32);
#endif // SOFT_H