Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
x86
math-emu
fpu_etc.c
Go to the documentation of this file.
1
/*---------------------------------------------------------------------------+
2
| fpu_etc.c |
3
| |
4
| Implement a few FPU instructions. |
5
| |
6
| Copyright (C) 1992,1993,1994,1997 |
7
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
8
| Australia. E-mail
[email protected]
|
9
| |
10
| |
11
+---------------------------------------------------------------------------*/
12
13
#include "
fpu_system.h
"
14
#include "
exception.h
"
15
#include "
fpu_emu.h
"
16
#include "
status_w.h
"
17
#include "
reg_constant.h
"
18
19
static
void
fchs(
FPU_REG
*st0_ptr,
u_char
st0tag)
20
{
21
if
(st0tag ^
TAG_Empty
) {
22
signbyte
(st0_ptr) ^=
SIGN_NEG
;
23
clear_C1
();
24
}
else
25
FPU_stack_underflow
();
26
}
27
28
static
void
fabs
(
FPU_REG
*st0_ptr,
u_char
st0tag)
29
{
30
if
(st0tag ^
TAG_Empty
) {
31
setpositive
(st0_ptr);
32
clear_C1
();
33
}
else
34
FPU_stack_underflow
();
35
}
36
37
static
void
ftst_(
FPU_REG
*st0_ptr,
u_char
st0tag)
38
{
39
switch
(st0tag) {
40
case
TAG_Zero
:
41
setcc(
SW_C3
);
42
break
;
43
case
TAG_Valid
:
44
if
(
getsign
(st0_ptr) ==
SIGN_POS
)
45
setcc(0);
46
else
47
setcc(
SW_C0
);
48
break
;
49
case
TAG_Special
:
50
switch
(
FPU_Special
(st0_ptr)) {
51
case
TW_Denormal
:
52
if
(
getsign
(st0_ptr) ==
SIGN_POS
)
53
setcc(0);
54
else
55
setcc(
SW_C0
);
56
if
(
denormal_operand
() < 0) {
57
#ifdef PECULIAR_486
58
/* This is weird! */
59
if
(
getsign
(st0_ptr) ==
SIGN_POS
)
60
setcc(
SW_C3
);
61
#endif
/* PECULIAR_486 */
62
return
;
63
}
64
break
;
65
case
TW_NaN
:
66
setcc(
SW_C0
|
SW_C2
|
SW_C3
);
/* Operand is not comparable */
67
EXCEPTION
(
EX_Invalid
);
68
break
;
69
case
TW_Infinity
:
70
if
(
getsign
(st0_ptr) ==
SIGN_POS
)
71
setcc(0);
72
else
73
setcc(
SW_C0
);
74
break
;
75
default
:
76
setcc(
SW_C0
|
SW_C2
|
SW_C3
);
/* Operand is not comparable */
77
EXCEPTION
(
EX_INTERNAL
| 0x14);
78
break
;
79
}
80
break
;
81
case
TAG_Empty
:
82
setcc(
SW_C0
|
SW_C2
|
SW_C3
);
83
EXCEPTION
(
EX_StackUnder
);
84
break
;
85
}
86
}
87
88
static
void
fxam(
FPU_REG
*st0_ptr,
u_char
st0tag)
89
{
90
int
c
= 0;
91
switch
(st0tag) {
92
case
TAG_Empty
:
93
c =
SW_C3
|
SW_C0
;
94
break
;
95
case
TAG_Zero
:
96
c =
SW_C3
;
97
break
;
98
case
TAG_Valid
:
99
c =
SW_C2
;
100
break
;
101
case
TAG_Special
:
102
switch
(
FPU_Special
(st0_ptr)) {
103
case
TW_Denormal
:
104
c =
SW_C2
|
SW_C3
;
/* Denormal */
105
break
;
106
case
TW_NaN
:
107
/* We also use NaN for unsupported types. */
108
if
((st0_ptr->
sigh
& 0x80000000)
109
&& (
exponent
(st0_ptr) ==
EXP_OVER
))
110
c =
SW_C0
;
111
break
;
112
case
TW_Infinity
:
113
c =
SW_C2
|
SW_C0
;
114
break
;
115
}
116
}
117
if
(
getsign
(st0_ptr) ==
SIGN_NEG
)
118
c |=
SW_C1
;
119
setcc(c);
120
}
121
122
static
FUNC_ST0
const
fp_etc_table[] = {
123
fchs,
fabs
, (
FUNC_ST0
)
FPU_illegal
, (
FUNC_ST0
)
FPU_illegal
,
124
ftst_, fxam, (
FUNC_ST0
) FPU_illegal, (
FUNC_ST0
) FPU_illegal
125
};
126
127
void
FPU_etc
(
void
)
128
{
129
(fp_etc_table[
FPU_rm
]) (&
st
(0),
FPU_gettag0
());
130
}
Generated on Thu Jan 10 2013 13:21:25 for Linux Kernel by
1.8.2