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
arm
nwfpe
fpa11.c
Go to the documentation of this file.
1
/*
2
NetWinder Floating Point Emulator
3
(c) Rebel.COM, 1998,1999
4
(c) Philip Blundell, 2001
5
6
Direct questions, comments to Scott Bambrough <
[email protected]
>
7
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
12
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
17
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
*/
22
23
#include "
fpa11.h
"
24
#include "
fpopcode.h
"
25
26
#include "
fpmodule.h
"
27
#include "
fpmodule.inl
"
28
29
#include <linux/compiler.h>
30
#include <linux/string.h>
31
32
/* Reset the FPA11 chip. Called to initialize and reset the emulator. */
33
static
void
resetFPA11(
void
)
34
{
35
int
i
;
36
FPA11 *fpa11 =
GET_FPA11
();
37
38
/* initialize the register type array */
39
for
(i = 0; i <= 7; i++) {
40
fpa11->fType[
i
] =
typeNone
;
41
}
42
43
/* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
44
fpa11->fpsr =
FP_EMULATOR
|
BIT_AC
;
45
}
46
47
int8
SetRoundingMode
(
const
unsigned
int
opcode
)
48
{
49
switch
(opcode &
MASK_ROUNDING_MODE
) {
50
default
:
51
case
ROUND_TO_NEAREST
:
52
return
float_round_nearest_even
;
53
54
case
ROUND_TO_PLUS_INFINITY
:
55
return
float_round_up
;
56
57
case
ROUND_TO_MINUS_INFINITY
:
58
return
float_round_down
;
59
60
case
ROUND_TO_ZERO
:
61
return
float_round_to_zero
;
62
}
63
}
64
65
int8
SetRoundingPrecision
(
const
unsigned
int
opcode
)
66
{
67
#ifdef CONFIG_FPE_NWFPE_XP
68
switch
(opcode &
MASK_ROUNDING_PRECISION
) {
69
case
ROUND_SINGLE
:
70
return
32;
71
72
case
ROUND_DOUBLE
:
73
return
64;
74
75
case
ROUND_EXTENDED
:
76
return
80;
77
78
default
:
79
return
80;
80
}
81
#endif
82
return
80;
83
}
84
85
void
nwfpe_init_fpa
(
union
fp_state
*
fp
)
86
{
87
FPA11 *fpa11 = (FPA11 *)fp;
88
#ifdef NWFPE_DEBUG
89
printk
(
"NWFPE: setting up state.\n"
);
90
#endif
91
memset
(fpa11, 0,
sizeof
(FPA11));
92
resetFPA11();
93
fpa11->initflag = 1;
94
}
95
96
/* Emulate the instruction in the opcode. */
97
unsigned
int
EmulateAll
(
unsigned
int
opcode
)
98
{
99
unsigned
int
code
;
100
101
#ifdef NWFPE_DEBUG
102
printk
(
"NWFPE: emulating opcode %08x\n"
, opcode);
103
#endif
104
code = opcode & 0x00000f00;
105
if
(code == 0x00000100 || code == 0x00000200) {
106
/* For coprocessor 1 or 2 (FPA11) */
107
code = opcode & 0x0e000000;
108
if
(code == 0x0e000000) {
109
if
(opcode & 0x00000010) {
110
/* Emulate conversion opcodes. */
111
/* Emulate register transfer opcodes. */
112
/* Emulate comparison opcodes. */
113
return
EmulateCPRT
(opcode);
114
}
else
{
115
/* Emulate monadic arithmetic opcodes. */
116
/* Emulate dyadic arithmetic opcodes. */
117
return
EmulateCPDO
(opcode);
118
}
119
}
else
if
(code == 0x0c000000) {
120
/* Emulate load/store opcodes. */
121
/* Emulate load/store multiple opcodes. */
122
return
EmulateCPDT
(opcode);
123
}
124
}
125
126
/* Invalid instruction detected. Return FALSE. */
127
return
0;
128
}
Generated on Thu Jan 10 2013 13:03:01 for Linux Kernel by
1.8.2