Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci-2.6.23
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci-2.6.23
Commits
194d0710
Commit
194d0710
authored
Aug 03, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/home/rmk/linux-2.6-arm
parents
a68d2ebc
9bbd0375
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
337 additions
and
484 deletions
+337
-484
Documentation/dontdiff
Documentation/dontdiff
+1
-0
arch/arm/mach-ixp4xx/coyote-setup.c
arch/arm/mach-ixp4xx/coyote-setup.c
+1
-1
arch/arm/mach-ixp4xx/gtwx5715-setup.c
arch/arm/mach-ixp4xx/gtwx5715-setup.c
+1
-1
arch/arm/mach-ixp4xx/ixdp425-setup.c
arch/arm/mach-ixp4xx/ixdp425-setup.c
+2
-2
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-bast.c
+15
-1
arch/arm/mm/proc-xscale.S
arch/arm/mm/proc-xscale.S
+0
-136
arch/arm/nwfpe/double_cpdo.c
arch/arm/nwfpe/double_cpdo.c
+12
-12
arch/arm/nwfpe/extended_cpdo.c
arch/arm/nwfpe/extended_cpdo.c
+12
-12
arch/arm/nwfpe/fpa11.c
arch/arm/nwfpe/fpa11.c
+11
-19
arch/arm/nwfpe/fpa11.h
arch/arm/nwfpe/fpa11.h
+9
-2
arch/arm/nwfpe/fpa11_cpdo.c
arch/arm/nwfpe/fpa11_cpdo.c
+17
-11
arch/arm/nwfpe/fpa11_cpdt.c
arch/arm/nwfpe/fpa11_cpdt.c
+14
-8
arch/arm/nwfpe/fpa11_cprt.c
arch/arm/nwfpe/fpa11_cprt.c
+19
-9
arch/arm/nwfpe/fpmodule.c
arch/arm/nwfpe/fpmodule.c
+6
-9
arch/arm/nwfpe/single_cpdo.c
arch/arm/nwfpe/single_cpdo.c
+12
-12
arch/arm/nwfpe/softfloat.c
arch/arm/nwfpe/softfloat.c
+163
-171
arch/arm/nwfpe/softfloat.h
arch/arm/nwfpe/softfloat.h
+29
-39
arch/arm/vfp/vfpdouble.c
arch/arm/vfp/vfpdouble.c
+3
-0
drivers/char/watchdog/sa1100_wdt.c
drivers/char/watchdog/sa1100_wdt.c
+10
-39
No files found.
Documentation/dontdiff
View file @
194d0710
...
...
@@ -104,6 +104,7 @@ logo_*.c
logo_*_clut224.c
logo_*_mono.c
lxdialog
mach-types
mach-types.h
make_times_h
map
...
...
arch/arm/mach-ixp4xx/coyote-setup.c
View file @
194d0710
...
...
@@ -61,7 +61,7 @@ static struct plat_serial8250_port coyote_uart_data[] = {
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART2
,
.
flags
=
UPF_BOOT_AUTOCONF
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
...
...
arch/arm/mach-ixp4xx/gtwx5715-setup.c
View file @
194d0710
...
...
@@ -83,7 +83,7 @@ static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART2
,
.
flags
=
UPF_BOOT_AUTOCONF
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
...
...
arch/arm/mach-ixp4xx/ixdp425-setup.c
View file @
194d0710
...
...
@@ -82,7 +82,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
.
mapbase
=
IXP4XX_UART1_BASE_PHYS
,
.
membase
=
(
char
*
)
IXP4XX_UART1_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART1
,
.
flags
=
UPF_BOOT_AUTOCONF
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
...
...
@@ -91,7 +91,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART1
,
.
flags
=
UPF_BOOT_AUTOCONF
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
...
...
arch/arm/mach-s3c2410/mach-bast.c
View file @
194d0710
...
...
@@ -30,6 +30,7 @@
* 28-Jun-2005 BJD Moved pm functionality out to common code
* 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s
* 25-Jul-2005 BJD Removed ASIX static mappings
* 27-Jul-2005 BJD Ensure maximum frequency of i2c bus
*/
#include <linux/kernel.h>
...
...
@@ -60,6 +61,7 @@
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/nand.h>
#include <asm/arch/iic.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
...
...
@@ -304,7 +306,7 @@ static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
}
static
struct
s3c2410_platform_nand
bast_nand_info
=
{
.
tacls
=
8
0
,
.
tacls
=
4
0
,
.
twrph0
=
80
,
.
twrph1
=
80
,
.
nr_sets
=
ARRAY_SIZE
(
bast_nand_sets
),
...
...
@@ -385,6 +387,17 @@ static struct platform_device bast_sio = {
},
};
/* we have devices on the bus which cannot work much over the
* standard 100KHz i2c bus frequency
*/
static
struct
s3c2410_platform_i2c
bast_i2c_info
=
{
.
flags
=
0
,
.
slave_addr
=
0x10
,
.
bus_freq
=
100
*
1000
,
.
max_freq
=
130
*
1000
,
};
/* Standard BAST devices */
static
struct
platform_device
*
bast_devices
[]
__initdata
=
{
...
...
@@ -431,6 +444,7 @@ void __init bast_map_io(void)
s3c24xx_uclk
.
parent
=
&
s3c24xx_clkout1
;
s3c_device_nand
.
dev
.
platform_data
=
&
bast_nand_info
;
s3c_device_i2c
.
dev
.
platform_data
=
&
bast_i2c_info
;
s3c24xx_init_io
(
bast_iodesc
,
ARRAY_SIZE
(
bast_iodesc
));
s3c24xx_init_clocks
(
0
);
...
...
arch/arm/mm/proc-xscale.S
View file @
194d0710
...
...
@@ -370,142 +370,6 @@ ENTRY(cpu_xscale_dcache_clean_area)
bhi
1
b
mov
pc
,
lr
/*
===============================
=
CACHE
LOCKING
============================
*
*
The
XScale
MicroArchitecture
implements
support
for
locking
entries
into
*
the
data
and
instruction
cache
.
The
following
functions
implement
the
core
*
low
level
instructions
needed
to
accomplish
the
locking
.
The
developer
's
*
manual
states
that
the
code
that
performs
the
locking
must
be
in
non
-
cached
*
memory
.
To
accomplish
this
,
the
code
in
xscale
-
cache
-
lock
.
c
copies
the
*
following
functions
from
the
cache
into
a
non
-
cached
memory
region
that
*
is
allocated
through
consistent_alloc
()
.
*
*/
.
align
5
/*
*
xscale_icache_lock
*
*
r0
:
starting
address
to
lock
*
r1
:
end
address
to
lock
*/
ENTRY
(
xscale_icache_lock
)
iLockLoop
:
bic
r0
,
r0
,
#
CACHELINESIZE
-
1
mcr
p15
,
0
,
r0
,
c9
,
c1
,
0
@
lock
into
cache
cmp
r0
,
r1
@
are
we
done
?
add
r0
,
r0
,
#
CACHELINESIZE
@
advance
to
next
cache
line
bls
iLockLoop
mov
pc
,
lr
/*
*
xscale_icache_unlock
*/
ENTRY
(
xscale_icache_unlock
)
mcr
p15
,
0
,
r0
,
c9
,
c1
,
1
@
Unlock
icache
mov
pc
,
lr
/*
*
xscale_dcache_lock
*
*
r0
:
starting
address
to
lock
*
r1
:
end
address
to
lock
*/
ENTRY
(
xscale_dcache_lock
)
mcr
p15
,
0
,
ip
,
c7
,
c10
,
4
@
Drain
Write
(&
Fill
)
Buffer
mov
r2
,
#
1
mcr
p15
,
0
,
r2
,
c9
,
c2
,
0
@
Put
dcache
in
lock
mode
cpwait
ip
@
Wait
for
completion
mrs
r2
,
cpsr
orr
r3
,
r2
,
#
PSR_F_BIT
|
PSR_I_BIT
dLockLoop
:
msr
cpsr_c
,
r3
mcr
p15
,
0
,
r0
,
c7
,
c10
,
1
@
Write
back
line
if
it
is
dirty
mcr
p15
,
0
,
r0
,
c7
,
c6
,
1
@
Flush
/
invalidate
line
msr
cpsr_c
,
r2
ldr
ip
,
[
r0
],
#
CACHELINESIZE
@
Preload
32
bytes
into
cache
from
@
location
[
r0
]
.
Post
-
increment
@
r3
to
next
cache
line
cmp
r0
,
r1
@
Are
we
done
?
bls
dLockLoop
mcr
p15
,
0
,
ip
,
c7
,
c10
,
4
@
Drain
Write
(&
Fill
)
Buffer
mov
r2
,
#
0
mcr
p15
,
0
,
r2
,
c9
,
c2
,
0
@
Get
out
of
lock
mode
cpwait_ret
lr
,
ip
/*
*
xscale_dcache_unlock
*/
ENTRY
(
xscale_dcache_unlock
)
mcr
p15
,
0
,
ip
,
c7
,
c10
,
4
@
Drain
Write
(&
Fill
)
Buffer
mcr
p15
,
0
,
ip
,
c9
,
c2
,
1
@
Unlock
cache
mov
pc
,
lr
/*
*
Needed
to
determine
the
length
of
the
code
that
needs
to
be
copied
.
*/
.
align
5
ENTRY
(
xscale_cache_dummy
)
mov
pc
,
lr
/*
===============================
=
TLB
LOCKING
==============================
*
*
The
XScale
MicroArchitecture
implements
support
for
locking
entries
into
*
the
Instruction
and
Data
TLBs
.
The
following
functions
provide
the
*
low
level
support
for
supporting
these
under
Linux
.
xscale
-
lock
.
c
*
implements
some
higher
level
management
code
.
Most
of
the
following
*
is
taken
straight
out
of
the
Developer
's Manual.
*/
/*
*
Lock
I
-
TLB
entry
*
*
r0
:
Virtual
address
to
translate
and
lock
*/
.
align
5
ENTRY
(
xscale_itlb_lock
)
mrs
r2
,
cpsr
orr
r3
,
r2
,
#
PSR_F_BIT
|
PSR_I_BIT
msr
cpsr_c
,
r3
@
Disable
interrupts
mcr
p15
,
0
,
r0
,
c8
,
c5
,
1
@
Invalidate
I
-
TLB
entry
mcr
p15
,
0
,
r0
,
c10
,
c4
,
0
@
Translate
and
lock
msr
cpsr_c
,
r2
@
Restore
interrupts
cpwait_ret
lr
,
ip
/*
*
Lock
D
-
TLB
entry
*
*
r0
:
Virtual
address
to
translate
and
lock
*/
.
align
5
ENTRY
(
xscale_dtlb_lock
)
mrs
r2
,
cpsr
orr
r3
,
r2
,
#
PSR_F_BIT
|
PSR_I_BIT
msr
cpsr_c
,
r3
@
Disable
interrupts
mcr
p15
,
0
,
r0
,
c8
,
c6
,
1
@
Invalidate
D
-
TLB
entry
mcr
p15
,
0
,
r0
,
c10
,
c8
,
0
@
Translate
and
lock
msr
cpsr_c
,
r2
@
Restore
interrupts
cpwait_ret
lr
,
ip
/*
*
Unlock
all
I
-
TLB
entries
*/
.
align
5
ENTRY
(
xscale_itlb_unlock
)
mcr
p15
,
0
,
ip
,
c10
,
c4
,
1
@
Unlock
I
-
TLB
mcr
p15
,
0
,
ip
,
c8
,
c5
,
0
@
Invalidate
I
-
TLB
cpwait_ret
lr
,
ip
/*
*
Unlock
all
D
-
TLB
entries
*/
ENTRY
(
xscale_dtlb_unlock
)
mcr
p15
,
0
,
ip
,
c10
,
c8
,
1
@
Unlock
D
-
TBL
mcr
p15
,
0
,
ip
,
c8
,
c6
,
0
@
Invalidate
D
-
TLB
cpwait_ret
lr
,
ip
/*
==============================
=
PageTable
==============================
*/
#define PTE_CACHE_WRITE_ALLOCATE 0
...
...
arch/arm/nwfpe/double_cpdo.c
View file @
194d0710
...
...
@@ -40,17 +40,17 @@ float64 float64_arccos(float64 rFm);
float64
float64_pow
(
float64
rFn
,
float64
rFm
);
float64
float64_pol
(
float64
rFn
,
float64
rFm
);
static
float64
float64_rsf
(
float64
rFn
,
float64
rFm
)
static
float64
float64_rsf
(
struct
roundingData
*
roundData
,
float64
rFn
,
float64
rFm
)
{
return
float64_sub
(
rFm
,
rFn
);
return
float64_sub
(
r
oundData
,
r
Fm
,
rFn
);
}
static
float64
float64_rdv
(
float64
rFn
,
float64
rFm
)
static
float64
float64_rdv
(
struct
roundingData
*
roundData
,
float64
rFn
,
float64
rFm
)
{
return
float64_div
(
rFm
,
rFn
);
return
float64_div
(
r
oundData
,
r
Fm
,
rFn
);
}
static
float64
(
*
const
dyadic_double
[
16
])(
float64
rFn
,
float64
rFm
)
=
{
static
float64
(
*
const
dyadic_double
[
16
])(
struct
roundingData
*
,
float64
rFn
,
float64
rFm
)
=
{
[
ADF_CODE
>>
20
]
=
float64_add
,
[
MUF_CODE
>>
20
]
=
float64_mul
,
[
SUF_CODE
>>
20
]
=
float64_sub
,
...
...
@@ -65,12 +65,12 @@ static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
[
FRD_CODE
>>
20
]
=
float64_rdv
,
};
static
float64
float64_mvf
(
float64
rFm
)
static
float64
float64_mvf
(
struct
roundingData
*
roundData
,
float64
rFm
)
{
return
rFm
;
}
static
float64
float64_mnf
(
float64
rFm
)
static
float64
float64_mnf
(
struct
roundingData
*
roundData
,
float64
rFm
)
{
union
float64_components
u
;
...
...
@@ -84,7 +84,7 @@ static float64 float64_mnf(float64 rFm)
return
u
.
f64
;
}
static
float64
float64_abs
(
float64
rFm
)
static
float64
float64_abs
(
struct
roundingData
*
roundData
,
float64
rFm
)
{
union
float64_components
u
;
...
...
@@ -98,7 +98,7 @@ static float64 float64_abs(float64 rFm)
return
u
.
f64
;
}
static
float64
(
*
const
monadic_double
[
16
])(
float64
rFm
)
=
{
static
float64
(
*
const
monadic_double
[
16
])(
struct
roundingData
*
,
float64
rFm
)
=
{
[
MVF_CODE
>>
20
]
=
float64_mvf
,
[
MNF_CODE
>>
20
]
=
float64_mnf
,
[
ABS_CODE
>>
20
]
=
float64_abs
,
...
...
@@ -108,7 +108,7 @@ static float64 (*const monadic_double[16])(float64 rFm) = {
[
NRM_CODE
>>
20
]
=
float64_mvf
,
};
unsigned
int
DoubleCPDO
(
const
unsigned
int
opcode
,
FPREG
*
rFd
)
unsigned
int
DoubleCPDO
(
struct
roundingData
*
roundData
,
const
unsigned
int
opcode
,
FPREG
*
rFd
)
{
FPA11
*
fpa11
=
GET_FPA11
();
float64
rFm
;
...
...
@@ -151,13 +151,13 @@ unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
}
if
(
dyadic_double
[
opc_mask_shift
])
{
rFd
->
fDouble
=
dyadic_double
[
opc_mask_shift
](
rFn
,
rFm
);
rFd
->
fDouble
=
dyadic_double
[
opc_mask_shift
](
r
oundData
,
r
Fn
,
rFm
);
}
else
{
return
0
;
}
}
else
{
if
(
monadic_double
[
opc_mask_shift
])
{
rFd
->
fDouble
=
monadic_double
[
opc_mask_shift
](
rFm
);
rFd
->
fDouble
=
monadic_double
[
opc_mask_shift
](
r
oundData
,
r
Fm
);
}
else
{
return
0
;
}
...
...
arch/arm/nwfpe/extended_cpdo.c
View file @
194d0710
...
...
@@ -35,17 +35,17 @@ floatx80 floatx80_arccos(floatx80 rFm);
floatx80
floatx80_pow
(
floatx80
rFn
,
floatx80
rFm
);
floatx80
floatx80_pol
(
floatx80
rFn
,
floatx80
rFm
);
static
floatx80
floatx80_rsf
(
floatx80
rFn
,
floatx80
rFm
)
static
floatx80
floatx80_rsf
(
struct
roundingData
*
roundData
,
floatx80
rFn
,
floatx80
rFm
)
{
return
floatx80_sub
(
rFm
,
rFn
);
return
floatx80_sub
(
r
oundData
,
r
Fm
,
rFn
);
}
static
floatx80
floatx80_rdv
(
floatx80
rFn
,
floatx80
rFm
)
static
floatx80
floatx80_rdv
(
struct
roundingData
*
roundData
,
floatx80
rFn
,
floatx80
rFm
)
{
return
floatx80_div
(
rFm
,
rFn
);
return
floatx80_div
(
r
oundData
,
r
Fm
,
rFn
);
}
static
floatx80
(
*
const
dyadic_extended
[
16
])(
floatx80
rFn
,
floatx80
rFm
)
=
{
static
floatx80
(
*
const
dyadic_extended
[
16
])(
struct
roundingData
*
,
floatx80
rFn
,
floatx80
rFm
)
=
{
[
ADF_CODE
>>
20
]
=
floatx80_add
,
[
MUF_CODE
>>
20
]
=
floatx80_mul
,
[
SUF_CODE
>>
20
]
=
floatx80_sub
,
...
...
@@ -60,24 +60,24 @@ static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
[
FRD_CODE
>>
20
]
=
floatx80_rdv
,
};
static
floatx80
floatx80_mvf
(
floatx80
rFm
)
static
floatx80
floatx80_mvf
(
struct
roundingData
*
roundData
,
floatx80
rFm
)
{
return
rFm
;
}
static
floatx80
floatx80_mnf
(
floatx80
rFm
)
static
floatx80
floatx80_mnf
(
struct
roundingData
*
roundData
,
floatx80
rFm
)
{
rFm
.
high
^=
0x8000
;
return
rFm
;
}
static
floatx80
floatx80_abs
(
floatx80
rFm
)
static
floatx80
floatx80_abs
(
struct
roundingData
*
roundData
,
floatx80
rFm
)
{
rFm
.
high
&=
0x7fff
;
return
rFm
;
}
static
floatx80
(
*
const
monadic_extended
[
16
])(
floatx80
rFm
)
=
{
static
floatx80
(
*
const
monadic_extended
[
16
])(
struct
roundingData
*
,
floatx80
rFm
)
=
{
[
MVF_CODE
>>
20
]
=
floatx80_mvf
,
[
MNF_CODE
>>
20
]
=
floatx80_mnf
,
[
ABS_CODE
>>
20
]
=
floatx80_abs
,
...
...
@@ -87,7 +87,7 @@ static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
[
NRM_CODE
>>
20
]
=
floatx80_mvf
,
};
unsigned
int
ExtendedCPDO
(
const
unsigned
int
opcode
,
FPREG
*
rFd
)
unsigned
int
ExtendedCPDO
(
struct
roundingData
*
roundData
,
const
unsigned
int
opcode
,
FPREG
*
rFd
)
{
FPA11
*
fpa11
=
GET_FPA11
();
floatx80
rFm
;
...
...
@@ -138,13 +138,13 @@ unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
}
if
(
dyadic_extended
[
opc_mask_shift
])
{
rFd
->
fExtended
=
dyadic_extended
[
opc_mask_shift
](
rFn
,
rFm
);
rFd
->
fExtended
=
dyadic_extended
[
opc_mask_shift
](
r
oundData
,
r
Fn
,
rFm
);
}
else
{
return
0
;
}
}
else
{
if
(
monadic_extended
[
opc_mask_shift
])
{
rFd
->
fExtended
=
monadic_extended
[
opc_mask_shift
](
rFm
);
rFd
->
fExtended
=
monadic_extended
[
opc_mask_shift
](
r
oundData
,
r
Fm
);
}
else
{
return
0
;
}
...
...
arch/arm/nwfpe/fpa11.c
View file @
194d0710
...
...
@@ -51,48 +51,42 @@ static void resetFPA11(void)
fpa11
->
fpsr
=
FP_EMULATOR
|
BIT_AC
;
}
void
SetRoundingMode
(
const
unsigned
int
opcode
)
int8
SetRoundingMode
(
const
unsigned
int
opcode
)
{
switch
(
opcode
&
MASK_ROUNDING_MODE
)
{
default:
case
ROUND_TO_NEAREST
:
float_rounding_mode
=
float_round_nearest_even
;
break
;
return
float_round_nearest_even
;
case
ROUND_TO_PLUS_INFINITY
:
float_rounding_mode
=
float_round_up
;
break
;
return
float_round_up
;
case
ROUND_TO_MINUS_INFINITY
:
float_rounding_mode
=
float_round_down
;
break
;
return
float_round_down
;
case
ROUND_TO_ZERO
:
float_rounding_mode
=
float_round_to_zero
;
break
;
return
float_round_to_zero
;
}
}
void
SetRoundingPrecision
(
const
unsigned
int
opcode
)
int8
SetRoundingPrecision
(
const
unsigned
int
opcode
)
{
#ifdef CONFIG_FPE_NWFPE_XP
switch
(
opcode
&
MASK_ROUNDING_PRECISION
)
{
case
ROUND_SINGLE
:
floatx80_rounding_precision
=
32
;
break
;
return
32
;
case
ROUND_DOUBLE
:
floatx80_rounding_precision
=
64
;
break
;
return
64
;
case
ROUND_EXTENDED
:
floatx80_rounding_precision
=
80
;
break
;
return
80
;
default:
floatx80_rounding_precision
=
80
;
return
80
;
}
#endif
return
80
;
}
void
nwfpe_init_fpa
(
union
fp_state
*
fp
)
...
...
@@ -103,8 +97,6 @@ void nwfpe_init_fpa(union fp_state *fp)
#endif
memset
(
fpa11
,
0
,
sizeof
(
FPA11
));
resetFPA11
();
SetRoundingMode
(
ROUND_TO_NEAREST
);
SetRoundingPrecision
(
ROUND_EXTENDED
);
fpa11
->
initflag
=
1
;
}
...
...
arch/arm/nwfpe/fpa11.h
View file @
194d0710
...
...
@@ -37,6 +37,13 @@
/* includes */
#include "fpsr.h"
/* FP control and status register definitions */
#include "milieu.h"
struct
roundingData
{
int8
mode
;
int8
precision
;
signed
char
exception
;
};
#include "softfloat.h"
#define typeNone 0x00
...
...
@@ -84,8 +91,8 @@ typedef struct tagFPA11 {
initialised. */
}
FPA11
;
extern
void
SetRoundingMode
(
const
unsigned
int
);
extern
void
SetRoundingPrecision
(
const
unsigned
int
);
extern
int8
SetRoundingMode
(
const
unsigned
int
);
extern
int8
SetRoundingPrecision
(
const
unsigned
int
);
extern
void
nwfpe_init_fpa
(
union
fp_state
*
fp
);
#endif
arch/arm/nwfpe/fpa11_cpdo.c
View file @
194d0710
...
...
@@ -24,15 +24,16 @@
#include "fpa11.h"
#include "fpopcode.h"
unsigned
int
SingleCPDO
(
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
DoubleCPDO
(
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
ExtendedCPDO
(
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
SingleCPDO
(
struct
roundingData
*
roundData
,
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
DoubleCPDO
(
struct
roundingData
*
roundData
,
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
ExtendedCPDO
(
struct
roundingData
*
roundData
,
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
EmulateCPDO
(
const
unsigned
int
opcode
)
{
FPA11
*
fpa11
=
GET_FPA11
();
FPREG
*
rFd
;
unsigned
int
nType
,
nDest
,
nRc
;
struct
roundingData
roundData
;
/* Get the destination size. If not valid let Linux perform
an invalid instruction trap. */
...
...
@@ -40,7 +41,9 @@ unsigned int EmulateCPDO(const unsigned int opcode)
if
(
typeNone
==
nDest
)
return
0
;
SetRoundingMode
(
opcode
);
roundData
.
mode
=
SetRoundingMode
(
opcode
);
roundData
.
precision
=
SetRoundingPrecision
(
opcode
);
roundData
.
exception
=
0
;
/* Compare the size of the operands in Fn and Fm.
Choose the largest size and perform operations in that size,
...
...
@@ -63,14 +66,14 @@ unsigned int EmulateCPDO(const unsigned int opcode)
switch
(
nType
)
{
case
typeSingle
:
nRc
=
SingleCPDO
(
opcode
,
rFd
);
nRc
=
SingleCPDO
(
&
roundData
,
opcode
,
rFd
);
break
;
case
typeDouble
:
nRc
=
DoubleCPDO
(
opcode
,
rFd
);
nRc
=
DoubleCPDO
(
&
roundData
,
opcode
,
rFd
);
break
;
#ifdef CONFIG_FPE_NWFPE_XP
case
typeExtended
:
nRc
=
ExtendedCPDO
(
opcode
,
rFd
);
nRc
=
ExtendedCPDO
(
&
roundData
,
opcode
,
rFd
);
break
;
#endif
default:
...
...
@@ -93,9 +96,9 @@ unsigned int EmulateCPDO(const unsigned int opcode)
case
typeSingle
:
{
if
(
typeDouble
==
nType
)
rFd
->
fSingle
=
float64_to_float32
(
rFd
->
fDouble
);
rFd
->
fSingle
=
float64_to_float32
(
&
roundData
,
rFd
->
fDouble
);
else
rFd
->
fSingle
=
floatx80_to_float32
(
rFd
->
fExtended
);
rFd
->
fSingle
=
floatx80_to_float32
(
&
roundData
,
rFd
->
fExtended
);
}
break
;
...
...
@@ -104,7 +107,7 @@ unsigned int EmulateCPDO(const unsigned int opcode)
if
(
typeSingle
==
nType
)
rFd
->
fDouble
=
float32_to_float64
(
rFd
->
fSingle
);
else
rFd
->
fDouble
=
floatx80_to_float64
(
rFd
->
fExtended
);
rFd
->
fDouble
=
floatx80_to_float64
(
&
roundData
,
rFd
->
fExtended
);
}
break
;
...
...
@@ -121,12 +124,15 @@ unsigned int EmulateCPDO(const unsigned int opcode)
#else
if
(
nDest
!=
nType
)
{
if
(
nDest
==
typeSingle
)
rFd
->
fSingle
=
float64_to_float32
(
rFd
->
fDouble
);
rFd
->
fSingle
=
float64_to_float32
(
&
roundData
,
rFd
->
fDouble
);
else
rFd
->
fDouble
=
float32_to_float64
(
rFd
->
fSingle
);
}
#endif
}
if
(
roundData
.
exception
)
float_raise
(
roundData
.
exception
);
return
nRc
;
}
arch/arm/nwfpe/fpa11_cpdt.c
View file @
194d0710
...
...
@@ -96,7 +96,7 @@ static inline void loadMultiple(const unsigned int Fn, const unsigned int __user
}
}
static
inline
void
storeSingle
(
const
unsigned
int
Fn
,
unsigned
int
__user
*
pMem
)
static
inline
void
storeSingle
(
struct
roundingData
*
roundData
,
const
unsigned
int
Fn
,
unsigned
int
__user
*
pMem
)
{
FPA11
*
fpa11
=
GET_FPA11
();
union
{
...
...
@@ -106,12 +106,12 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
switch
(
fpa11
->
fType
[
Fn
])
{
case
typeDouble
:
val
.
f
=
float64_to_float32
(
fpa11
->
fpreg
[
Fn
].
fDouble
);
val
.
f
=
float64_to_float32
(
roundData
,
fpa11
->
fpreg
[
Fn
].
fDouble
);
break
;
#ifdef CONFIG_FPE_NWFPE_XP
case
typeExtended
:
val
.
f
=
floatx80_to_float32
(
fpa11
->
fpreg
[
Fn
].
fExtended
);
val
.
f
=
floatx80_to_float32
(
roundData
,
fpa11
->
fpreg
[
Fn
].
fExtended
);
break
;
#endif
...
...
@@ -122,7 +122,7 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
put_user
(
val
.
i
[
0
],
pMem
);
}
static
inline
void
storeDouble
(
const
unsigned
int
Fn
,
unsigned
int
__user
*
pMem
)
static
inline
void
storeDouble
(
struct
roundingData
*
roundData
,
const
unsigned
int
Fn
,
unsigned
int
__user
*
pMem
)
{
FPA11
*
fpa11
=
GET_FPA11
();
union
{
...
...
@@ -137,7 +137,7 @@ static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
#ifdef CONFIG_FPE_NWFPE_XP
case
typeExtended
:
val
.
f
=
floatx80_to_float64
(
fpa11
->
fpreg
[
Fn
].
fExtended
);
val
.
f
=
floatx80_to_float64
(
roundData
,
fpa11
->
fpreg
[
Fn
].
fExtended
);
break
;
#endif
...
...
@@ -259,8 +259,11 @@ unsigned int PerformSTF(const unsigned int opcode)
{
unsigned
int
__user
*
pBase
,
*
pAddress
,
*
pFinal
;
unsigned
int
nRc
=
1
,
write_back
=
WRITE_BACK
(
opcode
);
struct
roundingData
roundData
;
SetRoundingMode
(
ROUND_TO_NEAREST
);
roundData
.
mode
=
SetRoundingMode
(
opcode
);
roundData
.
precision
=
SetRoundingPrecision
(
opcode
);
roundData
.
exception
=
0
;
pBase
=
(
unsigned
int
__user
*
)
readRegister
(
getRn
(
opcode
));
if
(
REG_PC
==
getRn
(
opcode
))
{
...
...
@@ -281,10 +284,10 @@ unsigned int PerformSTF(const unsigned int opcode)
switch
(
opcode
&
MASK_TRANSFER_LENGTH
)
{
case
TRANSFER_SINGLE
:
storeSingle
(
getFd
(
opcode
),
pAddress
);
storeSingle
(
&
roundData
,
getFd
(
opcode
),
pAddress
);
break
;
case
TRANSFER_DOUBLE
:
storeDouble
(
getFd
(
opcode
),
pAddress
);
storeDouble
(
&
roundData
,
getFd
(
opcode
),
pAddress
);
break
;
#ifdef CONFIG_FPE_NWFPE_XP
case
TRANSFER_EXTENDED
:
...
...
@@ -295,6 +298,9 @@ unsigned int PerformSTF(const unsigned int opcode)
nRc
=
0
;
}
if
(
roundData
.
exception
)
float_raise
(
roundData
.
exception
);
if
(
write_back
)
writeRegister
(
getRn
(
opcode
),
(
unsigned
long
)
pFinal
);
return
nRc
;
...
...
arch/arm/nwfpe/fpa11_cprt.c
View file @
194d0710
...
...
@@ -33,8 +33,6 @@ extern flag floatx80_is_nan(floatx80);
extern
flag
float64_is_nan
(
float64
);
extern
flag
float32_is_nan
(
float32
);
void
SetRoundingMode
(
const
unsigned
int
opcode
);
unsigned
int
PerformFLT
(
const
unsigned
int
opcode
);
unsigned
int
PerformFIX
(
const
unsigned
int
opcode
);
...
...
@@ -77,14 +75,17 @@ unsigned int EmulateCPRT(const unsigned int opcode)
unsigned
int
PerformFLT
(
const
unsigned
int
opcode
)
{
FPA11
*
fpa11
=
GET_FPA11
();
SetRoundingMode
(
opcode
);
SetRoundingPrecision
(
opcode
);
struct
roundingData
roundData
;
roundData
.
mode
=
SetRoundingMode
(
opcode
);
roundData
.
precision
=
SetRoundingPrecision
(
opcode
);
roundData
.
exception
=
0
;
switch
(
opcode
&
MASK_ROUNDING_PRECISION
)
{
case
ROUND_SINGLE
:
{
fpa11
->
fType
[
getFn
(
opcode
)]
=
typeSingle
;
fpa11
->
fpreg
[
getFn
(
opcode
)].
fSingle
=
int32_to_float32
(
readRegister
(
getRd
(
opcode
)));
fpa11
->
fpreg
[
getFn
(
opcode
)].
fSingle
=
int32_to_float32
(
&
roundData
,
readRegister
(
getRd
(
opcode
)));
}
break
;
...
...
@@ -108,6 +109,9 @@ unsigned int PerformFLT(const unsigned int opcode)
return
0
;
}
if
(
roundData
.
exception
)
float_raise
(
roundData
.
exception
);
return
1
;
}
...
...
@@ -115,26 +119,29 @@ unsigned int PerformFIX(const unsigned int opcode)
{
FPA11
*
fpa11
=
GET_FPA11
();
unsigned
int
Fn
=
getFm
(
opcode
);
struct
roundingData
roundData
;
SetRoundingMode
(
opcode
);
roundData
.
mode
=
SetRoundingMode
(
opcode
);
roundData
.
precision
=
SetRoundingPrecision
(
opcode
);
roundData
.
exception
=
0
;
switch
(
fpa11
->
fType
[
Fn
])
{
case
typeSingle
:
{
writeRegister
(
getRd
(
opcode
),
float32_to_int32
(
fpa11
->
fpreg
[
Fn
].
fSingle
));
writeRegister
(
getRd
(
opcode
),
float32_to_int32
(
&
roundData
,
fpa11
->
fpreg
[
Fn
].
fSingle
));
}
break
;
case
typeDouble
:
{
writeRegister
(
getRd
(
opcode
),
float64_to_int32
(
fpa11
->
fpreg
[
Fn
].
fDouble
));
writeRegister
(
getRd
(
opcode
),
float64_to_int32
(
&
roundData
,
fpa11
->
fpreg
[
Fn
].
fDouble
));
}
break
;
#ifdef CONFIG_FPE_NWFPE_XP
case
typeExtended
:
{
writeRegister
(
getRd
(
opcode
),
floatx80_to_int32
(
fpa11
->
fpreg
[
Fn
].
fExtended
));
writeRegister
(
getRd
(
opcode
),
floatx80_to_int32
(
&
roundData
,
fpa11
->
fpreg
[
Fn
].
fExtended
));
}
break
;
#endif
...
...
@@ -143,6 +150,9 @@ unsigned int PerformFIX(const unsigned int opcode)
return
0
;
}
if
(
roundData
.
exception
)
float_raise
(
roundData
.
exception
);
return
1
;
}
...
...
arch/arm/nwfpe/fpmodule.c
View file @
194d0710
...
...
@@ -116,8 +116,6 @@ fpmodule.c to integrate with the NetBSD kernel (I hope!).
code to access data in user space in some other source files at the
moment (grep for get_user / put_user calls). --philb]
float_exception_flags is a global variable in SoftFloat.
This function is called by the SoftFloat routines to raise a floating
point exception. We check the trap enable byte in the FPSR, and raise
a SIGFPE exception if necessary. If not the relevant bits in the
...
...
@@ -129,15 +127,14 @@ void float_raise(signed char flags)
register
unsigned
int
fpsr
,
cumulativeTraps
;
#ifdef CONFIG_DEBUG_USER
/* Ignore inexact errors as there are far too many of them to log */
if
(
flags
&
~
BIT_IXC
)
printk
(
KERN_DEBUG
"NWFPE: %s[%d] takes exception %08x at %p from %08lx
\n
"
,
current
->
comm
,
current
->
pid
,
flags
,
__builtin_return_address
(
0
),
GET_USERREG
()
->
ARM_pc
);
#endif
/* Keep SoftFloat exception flags up to date. */
float_exception_flags
|=
flags
;
/* Read fpsr and initialize the cumulativeTraps. */
fpsr
=
readFPSR
();
cumulativeTraps
=
0
;
...
...
arch/arm/nwfpe/single_cpdo.c
View file @
194d0710
...
...
@@ -36,17 +36,17 @@ float32 float32_arccos(float32 rFm);
float32
float32_pow
(
float32
rFn
,
float32
rFm
);
float32
float32_pol
(
float32
rFn
,
float32
rFm
);
static
float32
float32_rsf
(
float32
rFn
,
float32
rFm
)
static
float32
float32_rsf
(
struct
roundingData
*
roundData
,
float32
rFn
,
float32
rFm
)
{
return
float32_sub
(
rFm
,
rFn
);
return
float32_sub
(
r
oundData
,
r
Fm
,
rFn
);
}
static
float32
float32_rdv
(
float32
rFn
,
float32
rFm
)
static
float32
float32_rdv
(
struct
roundingData
*
roundData
,
float32
rFn
,
float32
rFm
)
{
return
float32_div
(
rFm
,
rFn
);
return
float32_div
(
r
oundData
,
r
Fm
,
rFn
);
}
static
float32
(
*
const
dyadic_single
[
16
])(
float32
rFn
,
float32
rFm
)
=
{
static
float32
(
*
const
dyadic_single
[
16
])(
struct
roundingData
*
,
float32
rFn
,
float32
rFm
)
=
{
[
ADF_CODE
>>
20
]
=
float32_add
,
[
MUF_CODE
>>
20
]
=
float32_mul
,
[
SUF_CODE
>>
20
]
=
float32_sub
,
...
...
@@ -60,22 +60,22 @@ static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
[
FRD_CODE
>>
20
]
=
float32_rdv
,
};
static
float32
float32_mvf
(
float32
rFm
)
static
float32
float32_mvf
(
struct
roundingData
*
roundData
,
float32
rFm
)
{
return
rFm
;
}
static
float32
float32_mnf
(
float32
rFm
)
static
float32
float32_mnf
(
struct
roundingData
*
roundData
,
float32
rFm
)
{
return
rFm
^
0x80000000
;
}
static
float32
float32_abs
(
float32
rFm
)
static
float32
float32_abs
(
struct
roundingData
*
roundData
,
float32
rFm
)
{
return
rFm
&
0x7fffffff
;
}
static
float32
(
*
const
monadic_single
[
16
])(
float32
rFm
)
=
{
static
float32
(
*
const
monadic_single
[
16
])(
struct
roundingData
*
,
float32
rFm
)
=
{
[
MVF_CODE
>>
20
]
=
float32_mvf
,
[
MNF_CODE
>>
20
]
=
float32_mnf
,
[
ABS_CODE
>>
20
]
=
float32_abs
,
...
...
@@ -85,7 +85,7 @@ static float32 (*const monadic_single[16])(float32 rFm) = {
[
NRM_CODE
>>
20
]
=
float32_mvf
,
};
unsigned
int
SingleCPDO
(
const
unsigned
int
opcode
,
FPREG
*
rFd
)
unsigned
int
SingleCPDO
(
struct
roundingData
*
roundData
,
const
unsigned
int
opcode
,
FPREG
*
rFd
)
{
FPA11
*
fpa11
=
GET_FPA11
();
float32
rFm
;
...
...
@@ -108,13 +108,13 @@ unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
if
(
fpa11
->
fType
[
Fn
]
==
typeSingle
&&
dyadic_single
[
opc_mask_shift
])
{
rFn
=
fpa11
->
fpreg
[
Fn
].
fSingle
;
rFd
->
fSingle
=
dyadic_single
[
opc_mask_shift
](
rFn
,
rFm
);
rFd
->
fSingle
=
dyadic_single
[
opc_mask_shift
](
r
oundData
,
r
Fn
,
rFm
);
}
else
{
return
0
;
}
}
else
{
if
(
monadic_single
[
opc_mask_shift
])
{
rFd
->
fSingle
=
monadic_single
[
opc_mask_shift
](
rFm
);
rFd
->
fSingle
=
monadic_single
[
opc_mask_shift
](
r
oundData
,
r
Fm
);
}
else
{
return
0
;
}
...
...
arch/arm/nwfpe/softfloat.c
View file @
194d0710
...
...
@@ -34,16 +34,6 @@ this code that are retained.
//#include "milieu.h"
//#include "softfloat.h"
/*
-------------------------------------------------------------------------------
Floating-point rounding mode, extended double-precision rounding precision,
and exception flags.
-------------------------------------------------------------------------------
*/
int8
float_rounding_mode
=
float_round_nearest_even
;
int8
floatx80_rounding_precision
=
80
;
int8
float_exception_flags
;
/*
-------------------------------------------------------------------------------
Primitive arithmetic functions, including multi-word arithmetic, and
...
...
@@ -77,14 +67,14 @@ input is too large, however, the invalid exception is raised and the largest
positive or negative integer is returned.
-------------------------------------------------------------------------------
*/
static
int32
roundAndPackInt32
(
flag
zSign
,
bits64
absZ
)
static
int32
roundAndPackInt32
(
struct
roundingData
*
roundData
,
flag
zSign
,
bits64
absZ
)
{
int8
roundingMode
;
flag
roundNearestEven
;
int8
roundIncrement
,
roundBits
;
int32
z
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundIncrement
=
0x40
;
if
(
!
roundNearestEven
)
{
...
...
@@ -107,10 +97,10 @@ static int32 roundAndPackInt32( flag zSign, bits64 absZ )
z
=
absZ
;
if
(
zSign
)
z
=
-
z
;
if
(
(
absZ
>>
32
)
||
(
z
&&
(
(
z
<
0
)
^
zSign
)
)
)
{
float_exception_flags
|=
float_flag_invalid
;
roundData
->
exception
|=
float_flag_invalid
;
return
zSign
?
0x80000000
:
0x7FFFFFFF
;
}
if
(
roundBits
)
float_exception_flags
|=
float_flag_inexact
;
if
(
roundBits
)
roundData
->
exception
|=
float_flag_inexact
;
return
z
;
}
...
...
@@ -224,14 +214,14 @@ The handling of underflow and overflow follows the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
static
float32
roundAndPackFloat32
(
flag
zSign
,
int16
zExp
,
bits32
zSig
)
static
float32
roundAndPackFloat32
(
struct
roundingData
*
roundData
,
flag
zSign
,
int16
zExp
,
bits32
zSig
)
{
int8
roundingMode
;
flag
roundNearestEven
;
int8
roundIncrement
,
roundBits
;
flag
isTiny
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundIncrement
=
0x40
;
if
(
!
roundNearestEven
)
{
...
...
@@ -254,7 +244,7 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
||
(
(
zExp
==
0xFD
)
&&
(
(
sbits32
)
(
zSig
+
roundIncrement
)
<
0
)
)
)
{
float_raise
(
float_flag_overflow
|
float_flag_inexact
)
;
roundData
->
exception
|=
float_flag_overflow
|
float_flag_inexact
;
return
packFloat32
(
zSign
,
0xFF
,
0
)
-
(
roundIncrement
==
0
);
}
if
(
zExp
<
0
)
{
...
...
@@ -265,10 +255,10 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
shift32RightJamming
(
zSig
,
-
zExp
,
&
zSig
);
zExp
=
0
;
roundBits
=
zSig
&
0x7F
;
if
(
isTiny
&&
roundBits
)
float_raise
(
float_flag_underflow
)
;
if
(
isTiny
&&
roundBits
)
roundData
->
exception
|=
float_flag_underflow
;
}
}
if
(
roundBits
)
float_exception_flags
|=
float_flag_inexact
;
if
(
roundBits
)
roundData
->
exception
|=
float_flag_inexact
;
zSig
=
(
zSig
+
roundIncrement
)
>>
7
;
zSig
&=
~
(
(
(
roundBits
^
0x40
)
==
0
)
&
roundNearestEven
);
if
(
zSig
==
0
)
zExp
=
0
;
...
...
@@ -287,12 +277,12 @@ point exponent.
-------------------------------------------------------------------------------
*/
static
float32
normalizeRoundAndPackFloat32
(
flag
zSign
,
int16
zExp
,
bits32
zSig
)
normalizeRoundAndPackFloat32
(
struct
roundingData
*
roundData
,
flag
zSign
,
int16
zExp
,
bits32
zSig
)
{
int8
shiftCount
;
shiftCount
=
countLeadingZeros32
(
zSig
)
-
1
;
return
roundAndPackFloat32
(
zSign
,
zExp
-
shiftCount
,
zSig
<<
shiftCount
);
return
roundAndPackFloat32
(
roundData
,
zSign
,
zExp
-
shiftCount
,
zSig
<<
shiftCount
);
}
...
...
@@ -395,14 +385,14 @@ The handling of underflow and overflow follows the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
static
float64
roundAndPackFloat64
(
flag
zSign
,
int16
zExp
,
bits64
zSig
)
static
float64
roundAndPackFloat64
(
struct
roundingData
*
roundData
,
flag
zSign
,
int16
zExp
,
bits64
zSig
)
{
int8
roundingMode
;
flag
roundNearestEven
;
int16
roundIncrement
,
roundBits
;
flag
isTiny
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundIncrement
=
0x200
;
if
(
!
roundNearestEven
)
{
...
...
@@ -427,7 +417,7 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
)
{
//register int lr = __builtin_return_address(0);
//printk("roundAndPackFloat64 called from 0x%08x\n",lr);
float_raise
(
float_flag_overflow
|
float_flag_inexact
)
;
roundData
->
exception
|=
float_flag_overflow
|
float_flag_inexact
;
return
packFloat64
(
zSign
,
0x7FF
,
0
)
-
(
roundIncrement
==
0
);
}
if
(
zExp
<
0
)
{
...
...
@@ -438,10 +428,10 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
shift64RightJamming
(
zSig
,
-
zExp
,
&
zSig
);
zExp
=
0
;
roundBits
=
zSig
&
0x3FF
;
if
(
isTiny
&&
roundBits
)
float_raise
(
float_flag_underflow
)
;
if
(
isTiny
&&
roundBits
)
roundData
->
exception
|=
float_flag_underflow
;
}
}
if
(
roundBits
)
float_exception_flags
|=
float_flag_inexact
;
if
(
roundBits
)
roundData
->
exception
|=
float_flag_inexact
;
zSig
=
(
zSig
+
roundIncrement
)
>>
10
;
zSig
&=
~
(
(
(
roundBits
^
0x200
)
==
0
)
&
roundNearestEven
);
if
(
zSig
==
0
)
zExp
=
0
;
...
...
@@ -460,12 +450,12 @@ point exponent.
-------------------------------------------------------------------------------
*/
static
float64
normalizeRoundAndPackFloat64
(
flag
zSign
,
int16
zExp
,
bits64
zSig
)
normalizeRoundAndPackFloat64
(
struct
roundingData
*
roundData
,
flag
zSign
,
int16
zExp
,
bits64
zSig
)
{
int8
shiftCount
;
shiftCount
=
countLeadingZeros64
(
zSig
)
-
1
;
return
roundAndPackFloat64
(
zSign
,
zExp
-
shiftCount
,
zSig
<<
shiftCount
);
return
roundAndPackFloat64
(
roundData
,
zSign
,
zExp
-
shiftCount
,
zSig
<<
shiftCount
);
}
...
...
@@ -572,14 +562,15 @@ Floating-point Arithmetic.
*/
static
floatx80
roundAndPackFloatx80
(
int8
roundingPrecision
,
flag
zSign
,
int32
zExp
,
bits64
zSig0
,
bits64
zSig1
struct
roundingData
*
roundData
,
flag
zSign
,
int32
zExp
,
bits64
zSig0
,
bits64
zSig1
)
{
int8
roundingMode
;
int8
roundingMode
,
roundingPrecision
;
flag
roundNearestEven
,
increment
,
isTiny
;
int64
roundIncrement
,
roundMask
,
roundBits
;
roundingMode
=
float_rounding_mode
;
roundingMode
=
roundData
->
mode
;
roundingPrecision
=
roundData
->
precision
;
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
if
(
roundingPrecision
==
80
)
goto
precision80
;
if
(
roundingPrecision
==
64
)
{
...
...
@@ -623,8 +614,8 @@ static floatx80
shift64RightJamming
(
zSig0
,
1
-
zExp
,
&
zSig0
);
zExp
=
0
;
roundBits
=
zSig0
&
roundMask
;
if
(
isTiny
&&
roundBits
)
float_raise
(
float_flag_underflow
)
;
if
(
roundBits
)
float_exception_flags
|=
float_flag_inexact
;
if
(
isTiny
&&
roundBits
)
roundData
->
exception
|=
float_flag_underflow
;
if
(
roundBits
)
roundData
->
exception
|=
float_flag_inexact
;
zSig0
+=
roundIncrement
;
if
(
(
sbits64
)
zSig0
<
0
)
zExp
=
1
;
roundIncrement
=
roundMask
+
1
;
...
...
@@ -635,7 +626,7 @@ static floatx80
return
packFloatx80
(
zSign
,
zExp
,
zSig0
);
}
}
if
(
roundBits
)
float_exception_flags
|=
float_flag_inexact
;
if
(
roundBits
)
roundData
->
exception
|=
float_flag_inexact
;
zSig0
+=
roundIncrement
;
if
(
zSig0
<
roundIncrement
)
{
++
zExp
;
...
...
@@ -672,7 +663,7 @@ static floatx80
)
{
roundMask
=
0
;
overflow:
float_raise
(
float_flag_overflow
|
float_flag_inexact
)
;
roundData
->
exception
|=
float_flag_overflow
|
float_flag_inexact
;
if
(
(
roundingMode
==
float_round_to_zero
)
||
(
zSign
&&
(
roundingMode
==
float_round_up
)
)
||
(
!
zSign
&&
(
roundingMode
==
float_round_down
)
)
...
...
@@ -689,8 +680,8 @@ static floatx80
||
(
zSig0
<
LIT64
(
0xFFFFFFFFFFFFFFFF
)
);
shift64ExtraRightJamming
(
zSig0
,
zSig1
,
1
-
zExp
,
&
zSig0
,
&
zSig1
);
zExp
=
0
;
if
(
isTiny
&&
zSig1
)
float_raise
(
float_flag_underflow
)
;
if
(
zSig1
)
float_exception_flags
|=
float_flag_inexact
;
if
(
isTiny
&&
zSig1
)
roundData
->
exception
|=
float_flag_underflow
;
if
(
zSig1
)
roundData
->
exception
|=
float_flag_inexact
;
if
(
roundNearestEven
)
{
increment
=
(
(
sbits64
)
zSig1
<
0
);
}
...
...
@@ -710,7 +701,7 @@ static floatx80
return
packFloatx80
(
zSign
,
zExp
,
zSig0
);
}
}
if
(
zSig1
)
float_exception_flags
|=
float_flag_inexact
;
if
(
zSig1
)
roundData
->
exception
|=
float_flag_inexact
;
if
(
increment
)
{
++
zSig0
;
if
(
zSig0
==
0
)
{
...
...
@@ -740,7 +731,7 @@ normalized.
*/
static
floatx80
normalizeRoundAndPackFloatx80
(
int8
roundingPrecision
,
flag
zSign
,
int32
zExp
,
bits64
zSig0
,
bits64
zSig1
struct
roundingData
*
roundData
,
flag
zSign
,
int32
zExp
,
bits64
zSig0
,
bits64
zSig1
)
{
int8
shiftCount
;
...
...
@@ -754,7 +745,7 @@ static floatx80
shortShift128Left
(
zSig0
,
zSig1
,
shiftCount
,
&
zSig0
,
&
zSig1
);
zExp
-=
shiftCount
;
return
roundAndPackFloatx80
(
round
ingPrecision
,
zSign
,
zExp
,
zSig0
,
zSig1
);
roundAndPackFloatx80
(
round
Data
,
zSign
,
zExp
,
zSig0
,
zSig1
);
}
...
...
@@ -767,14 +758,14 @@ the single-precision floating-point format. The conversion is performed
according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
int32_to_float32
(
int32
a
)
float32
int32_to_float32
(
struct
roundingData
*
roundData
,
int32
a
)
{
flag
zSign
;
if
(
a
==
0
)
return
0
;
if
(
a
==
0x80000000
)
return
packFloat32
(
1
,
0x9E
,
0
);
zSign
=
(
a
<
0
);
return
normalizeRoundAndPackFloat32
(
zSign
,
0x9C
,
zSign
?
-
a
:
a
);
return
normalizeRoundAndPackFloat32
(
roundData
,
zSign
,
0x9C
,
zSign
?
-
a
:
a
);
}
...
...
@@ -840,7 +831,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the
largest integer with the same sign as `a' is returned.
-------------------------------------------------------------------------------
*/
int32
float32_to_int32
(
float32
a
)
int32
float32_to_int32
(
struct
roundingData
*
roundData
,
float32
a
)
{
flag
aSign
;
int16
aExp
,
shiftCount
;
...
...
@@ -856,7 +847,7 @@ int32 float32_to_int32( float32 a )
zSig
=
aSig
;
zSig
<<=
32
;
if
(
0
<
shiftCount
)
shift64RightJamming
(
zSig
,
shiftCount
,
&
zSig
);
return
roundAndPackInt32
(
aSign
,
zSig
);
return
roundAndPackInt32
(
roundData
,
aSign
,
zSig
);
}
...
...
@@ -889,13 +880,13 @@ int32 float32_to_int32_round_to_zero( float32 a )
return
0x80000000
;
}
else
if
(
aExp
<=
0x7E
)
{
if
(
aExp
|
aSig
)
float_
exception_flags
|=
float_flag_inexact
;
if
(
aExp
|
aSig
)
float_
raise
(
float_flag_inexact
)
;
return
0
;
}
aSig
=
(
aSig
|
0x00800000
)
<<
8
;
z
=
aSig
>>
(
-
shiftCount
);
if
(
(
bits32
)
(
aSig
<<
(
shiftCount
&
31
)
)
)
{
float_
exception_flags
|=
float_flag_inexact
;
float_
raise
(
float_flag_inexact
)
;
}
return
aSign
?
-
z
:
z
;
...
...
@@ -973,7 +964,7 @@ operation is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
float32_round_to_int
(
float32
a
)
float32
float32_round_to_int
(
struct
roundingData
*
roundData
,
float32
a
)
{
flag
aSign
;
int16
aExp
;
...
...
@@ -988,11 +979,12 @@ float32 float32_round_to_int( float32 a )
}
return
a
;
}
roundingMode
=
roundData
->
mode
;
if
(
aExp
<=
0x7E
)
{
if
(
(
bits32
)
(
a
<<
1
)
==
0
)
return
a
;
float_exception_flags
|=
float_flag_inexact
;
roundData
->
exception
|=
float_flag_inexact
;
aSign
=
extractFloat32Sign
(
a
);
switch
(
float_rounding_m
ode
)
{
switch
(
roundingM
ode
)
{
case
float_round_nearest_even
:
if
(
(
aExp
==
0x7E
)
&&
extractFloat32Frac
(
a
)
)
{
return
packFloat32
(
aSign
,
0x7F
,
0
);
...
...
@@ -1009,7 +1001,6 @@ float32 float32_round_to_int( float32 a )
lastBitMask
<<=
0x96
-
aExp
;
roundBitsMask
=
lastBitMask
-
1
;
z
=
a
;
roundingMode
=
float_rounding_mode
;
if
(
roundingMode
==
float_round_nearest_even
)
{
z
+=
lastBitMask
>>
1
;
if
(
(
z
&
roundBitsMask
)
==
0
)
z
&=
~
lastBitMask
;
...
...
@@ -1020,7 +1011,7 @@ float32 float32_round_to_int( float32 a )
}
}
z
&=
~
roundBitsMask
;
if
(
z
!=
a
)
float_exception_flags
|=
float_flag_inexact
;
if
(
z
!=
a
)
roundData
->
exception
|=
float_flag_inexact
;
return
z
;
}
...
...
@@ -1034,7 +1025,7 @@ addition is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
static
float32
addFloat32Sigs
(
float32
a
,
float32
b
,
flag
zSign
)
static
float32
addFloat32Sigs
(
struct
roundingData
*
roundData
,
float32
a
,
float32
b
,
flag
zSign
)
{
int16
aExp
,
bExp
,
zExp
;
bits32
aSig
,
bSig
,
zSig
;
...
...
@@ -1093,7 +1084,7 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
++
zExp
;
}
roundAndPack:
return
roundAndPackFloat32
(
zSign
,
zExp
,
zSig
);
return
roundAndPackFloat32
(
roundData
,
zSign
,
zExp
,
zSig
);
}
...
...
@@ -1106,7 +1097,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE
Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
static
float32
subFloat32Sigs
(
float32
a
,
float32
b
,
flag
zSign
)
static
float32
subFloat32Sigs
(
struct
roundingData
*
roundData
,
float32
a
,
float32
b
,
flag
zSign
)
{
int16
aExp
,
bExp
,
zExp
;
bits32
aSig
,
bSig
,
zSig
;
...
...
@@ -1123,7 +1114,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
if
(
expDiff
<
0
)
goto
bExpBigger
;
if
(
aExp
==
0xFF
)
{
if
(
aSig
|
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
if
(
aExp
==
0
)
{
...
...
@@ -1132,7 +1123,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
}
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
aSig
<
bSig
)
goto
bBigger
;
return
packFloat32
(
float_rounding_
mode
==
float_round_down
,
0
,
0
);
return
packFloat32
(
roundData
->
mode
==
float_round_down
,
0
,
0
);
bExpBigger:
if
(
bExp
==
0xFF
)
{
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
...
...
@@ -1169,7 +1160,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
zExp
=
aExp
;
normalizeRoundAndPack:
--
zExp
;
return
normalizeRoundAndPackFloat32
(
zSign
,
zExp
,
zSig
);
return
normalizeRoundAndPackFloat32
(
roundData
,
zSign
,
zExp
,
zSig
);
}
...
...
@@ -1180,17 +1171,17 @@ and `b'. The operation is performed according to the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
float32_add
(
float32
a
,
float32
b
)
float32
float32_add
(
struct
roundingData
*
roundData
,
float32
a
,
float32
b
)
{
flag
aSign
,
bSign
;
aSign
=
extractFloat32Sign
(
a
);
bSign
=
extractFloat32Sign
(
b
);
if
(
aSign
==
bSign
)
{
return
addFloat32Sigs
(
a
,
b
,
aSign
);
return
addFloat32Sigs
(
roundData
,
a
,
b
,
aSign
);
}
else
{
return
subFloat32Sigs
(
a
,
b
,
aSign
);
return
subFloat32Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
...
...
@@ -1202,17 +1193,17 @@ Returns the result of subtracting the single-precision floating-point values
for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
float32_sub
(
float32
a
,
float32
b
)
float32
float32_sub
(
struct
roundingData
*
roundData
,
float32
a
,
float32
b
)
{
flag
aSign
,
bSign
;
aSign
=
extractFloat32Sign
(
a
);
bSign
=
extractFloat32Sign
(
b
);
if
(
aSign
==
bSign
)
{
return
subFloat32Sigs
(
a
,
b
,
aSign
);
return
subFloat32Sigs
(
roundData
,
a
,
b
,
aSign
);
}
else
{
return
addFloat32Sigs
(
a
,
b
,
aSign
);
return
addFloat32Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
...
...
@@ -1224,7 +1215,7 @@ Returns the result of multiplying the single-precision floating-point values
for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
float32_mul
(
float32
a
,
float32
b
)
float32
float32_mul
(
struct
roundingData
*
roundData
,
float32
a
,
float32
b
)
{
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
zExp
;
...
...
@@ -1244,7 +1235,7 @@ float32 float32_mul( float32 a, float32 b )
return
propagateFloat32NaN
(
a
,
b
);
}
if
(
(
bExp
|
bSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
return
packFloat32
(
zSign
,
0xFF
,
0
);
...
...
@@ -1252,7 +1243,7 @@ float32 float32_mul( float32 a, float32 b )
if
(
bExp
==
0xFF
)
{
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
(
aExp
|
aSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
return
packFloat32
(
zSign
,
0xFF
,
0
);
...
...
@@ -1274,7 +1265,7 @@ float32 float32_mul( float32 a, float32 b )
zSig
<<=
1
;
--
zExp
;
}
return
roundAndPackFloat32
(
zSign
,
zExp
,
zSig
);
return
roundAndPackFloat32
(
roundData
,
zSign
,
zExp
,
zSig
);
}
...
...
@@ -1285,7 +1276,7 @@ by the corresponding value `b'. The operation is performed according to the
IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
float32_div
(
float32
a
,
float32
b
)
float32
float32_div
(
struct
roundingData
*
roundData
,
float32
a
,
float32
b
)
{
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
zExp
;
...
...
@@ -1302,7 +1293,7 @@ float32 float32_div( float32 a, float32 b )
if
(
aSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
bExp
==
0xFF
)
{
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
return
packFloat32
(
zSign
,
0xFF
,
0
);
...
...
@@ -1314,10 +1305,10 @@ float32 float32_div( float32 a, float32 b )
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
float_raise
(
float_flag_divbyzero
)
;
roundData
->
exception
|=
float_flag_divbyzero
;
return
packFloat32
(
zSign
,
0xFF
,
0
);
}
normalizeFloat32Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
...
@@ -1341,7 +1332,7 @@ float32 float32_div( float32 a, float32 b )
if
(
(
zSig
&
0x3F
)
==
0
)
{
zSig
|=
(
(
(
bits64
)
bSig
)
*
zSig
!=
(
(
bits64
)
aSig
)
<<
32
);
}
return
roundAndPackFloat32
(
zSign
,
zExp
,
zSig
);
return
roundAndPackFloat32
(
roundData
,
zSign
,
zExp
,
zSig
);
}
...
...
@@ -1352,7 +1343,7 @@ with respect to the corresponding value `b'. The operation is performed
according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
float32_rem
(
float32
a
,
float32
b
)
float32
float32_rem
(
struct
roundingData
*
roundData
,
float32
a
,
float32
b
)
{
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
expDiff
;
...
...
@@ -1372,7 +1363,7 @@ float32 float32_rem( float32 a, float32 b )
if
(
aSig
||
(
(
bExp
==
0xFF
)
&&
bSig
)
)
{
return
propagateFloat32NaN
(
a
,
b
);
}
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
if
(
bExp
==
0xFF
)
{
...
...
@@ -1381,7 +1372,7 @@ float32 float32_rem( float32 a, float32 b )
}
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
normalizeFloat32Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
...
@@ -1444,7 +1435,7 @@ float32 float32_rem( float32 a, float32 b )
}
zSign
=
(
(
sbits32
)
aSig
<
0
);
if
(
zSign
)
aSig
=
-
aSig
;
return
normalizeRoundAndPackFloat32
(
aSign
^
zSign
,
bExp
,
aSig
);
return
normalizeRoundAndPackFloat32
(
roundData
,
aSign
^
zSign
,
bExp
,
aSig
);
}
...
...
@@ -1455,7 +1446,7 @@ The operation is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
float32_sqrt
(
float32
a
)
float32
float32_sqrt
(
struct
roundingData
*
roundData
,
float32
a
)
{
flag
aSign
;
int16
aExp
,
zExp
;
...
...
@@ -1468,12 +1459,12 @@ float32 float32_sqrt( float32 a )
if
(
aExp
==
0xFF
)
{
if
(
aSig
)
return
propagateFloat32NaN
(
a
,
0
);
if
(
!
aSign
)
return
a
;
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
if
(
aSign
)
{
if
(
(
aExp
|
aSig
)
==
0
)
return
a
;
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
}
if
(
aExp
==
0
)
{
...
...
@@ -1499,7 +1490,7 @@ float32 float32_sqrt( float32 a )
}
}
shift32RightJamming
(
zSig
,
1
,
&
zSig
);
return
roundAndPackFloat32
(
0
,
zExp
,
zSig
);
return
roundAndPackFloat32
(
roundData
,
0
,
zExp
,
zSig
);
}
...
...
@@ -1661,7 +1652,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the
largest integer with the same sign as `a' is returned.
-------------------------------------------------------------------------------
*/
int32
float64_to_int32
(
float64
a
)
int32
float64_to_int32
(
struct
roundingData
*
roundData
,
float64
a
)
{
flag
aSign
;
int16
aExp
,
shiftCount
;
...
...
@@ -1674,7 +1665,7 @@ int32 float64_to_int32( float64 a )
if
(
aExp
)
aSig
|=
LIT64
(
0x0010000000000000
);
shiftCount
=
0x42C
-
aExp
;
if
(
0
<
shiftCount
)
shift64RightJamming
(
aSig
,
shiftCount
,
&
aSig
);
return
roundAndPackInt32
(
aSign
,
aSig
);
return
roundAndPackInt32
(
roundData
,
aSign
,
aSig
);
}
...
...
@@ -1705,7 +1696,7 @@ int32 float64_to_int32_round_to_zero( float64 a )
goto
invalid
;
}
else
if
(
52
<
shiftCount
)
{
if
(
aExp
||
aSig
)
float_
exception_flags
|=
float_flag_inexact
;
if
(
aExp
||
aSig
)
float_
raise
(
float_flag_inexact
)
;
return
0
;
}
aSig
|=
LIT64
(
0x0010000000000000
);
...
...
@@ -1715,11 +1706,11 @@ int32 float64_to_int32_round_to_zero( float64 a )
if
(
aSign
)
z
=
-
z
;
if
(
(
z
<
0
)
^
aSign
)
{
invalid:
float_
exception_flags
|=
float_flag_invalid
;
float_
raise
(
float_flag_invalid
)
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
}
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
float_
exception_flags
|=
float_flag_inexact
;
float_
raise
(
float_flag_inexact
)
;
}
return
z
;
...
...
@@ -1736,7 +1727,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the
largest positive integer is returned.
-------------------------------------------------------------------------------
*/
int32
float64_to_uint32
(
float64
a
)
int32
float64_to_uint32
(
struct
roundingData
*
roundData
,
float64
a
)
{
flag
aSign
;
int16
aExp
,
shiftCount
;
...
...
@@ -1749,7 +1740,7 @@ int32 float64_to_uint32( float64 a )
if
(
aExp
)
aSig
|=
LIT64
(
0x0010000000000000
);
shiftCount
=
0x42C
-
aExp
;
if
(
0
<
shiftCount
)
shift64RightJamming
(
aSig
,
shiftCount
,
&
aSig
);
return
roundAndPackInt32
(
aSign
,
aSig
);
return
roundAndPackInt32
(
roundData
,
aSign
,
aSig
);
}
/*
...
...
@@ -1778,7 +1769,7 @@ int32 float64_to_uint32_round_to_zero( float64 a )
goto
invalid
;
}
else
if
(
52
<
shiftCount
)
{
if
(
aExp
||
aSig
)
float_
exception_flags
|=
float_flag_inexact
;
if
(
aExp
||
aSig
)
float_
raise
(
float_flag_inexact
)
;
return
0
;
}
aSig
|=
LIT64
(
0x0010000000000000
);
...
...
@@ -1788,11 +1779,11 @@ int32 float64_to_uint32_round_to_zero( float64 a )
if
(
aSign
)
z
=
-
z
;
if
(
(
z
<
0
)
^
aSign
)
{
invalid:
float_
exception_flags
|=
float_flag_invalid
;
float_
raise
(
float_flag_invalid
)
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
}
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
float_
exception_flags
|=
float_flag_inexact
;
float_
raise
(
float_flag_inexact
)
;
}
return
z
;
}
...
...
@@ -1805,7 +1796,7 @@ performed according to the IEC/IEEE Standard for Binary Floating-point
Arithmetic.
-------------------------------------------------------------------------------
*/
float32
float64_to_float32
(
float64
a
)
float32
float64_to_float32
(
struct
roundingData
*
roundData
,
float64
a
)
{
flag
aSign
;
int16
aExp
;
...
...
@@ -1825,7 +1816,7 @@ float32 float64_to_float32( float64 a )
zSig
|=
0x40000000
;
aExp
-=
0x381
;
}
return
roundAndPackFloat32
(
aSign
,
aExp
,
zSig
);
return
roundAndPackFloat32
(
roundData
,
aSign
,
aExp
,
zSig
);
}
...
...
@@ -1872,7 +1863,7 @@ operation is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float64
float64_round_to_int
(
float64
a
)
float64
float64_round_to_int
(
struct
roundingData
*
roundData
,
float64
a
)
{
flag
aSign
;
int16
aExp
;
...
...
@@ -1889,9 +1880,9 @@ float64 float64_round_to_int( float64 a )
}
if
(
aExp
<=
0x3FE
)
{
if
(
(
bits64
)
(
a
<<
1
)
==
0
)
return
a
;
float_exception_flags
|=
float_flag_inexact
;
roundData
->
exception
|=
float_flag_inexact
;
aSign
=
extractFloat64Sign
(
a
);
switch
(
float_rounding_
mode
)
{
switch
(
roundData
->
mode
)
{
case
float_round_nearest_even
:
if
(
(
aExp
==
0x3FE
)
&&
extractFloat64Frac
(
a
)
)
{
return
packFloat64
(
aSign
,
0x3FF
,
0
);
...
...
@@ -1909,7 +1900,7 @@ float64 float64_round_to_int( float64 a )
lastBitMask
<<=
0x433
-
aExp
;
roundBitsMask
=
lastBitMask
-
1
;
z
=
a
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
if
(
roundingMode
==
float_round_nearest_even
)
{
z
+=
lastBitMask
>>
1
;
if
(
(
z
&
roundBitsMask
)
==
0
)
z
&=
~
lastBitMask
;
...
...
@@ -1920,7 +1911,7 @@ float64 float64_round_to_int( float64 a )
}
}
z
&=
~
roundBitsMask
;
if
(
z
!=
a
)
float_exception_flags
|=
float_flag_inexact
;
if
(
z
!=
a
)
roundData
->
exception
|=
float_flag_inexact
;
return
z
;
}
...
...
@@ -1934,7 +1925,7 @@ addition is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
static
float64
addFloat64Sigs
(
float64
a
,
float64
b
,
flag
zSign
)
static
float64
addFloat64Sigs
(
struct
roundingData
*
roundData
,
float64
a
,
float64
b
,
flag
zSign
)
{
int16
aExp
,
bExp
,
zExp
;
bits64
aSig
,
bSig
,
zSig
;
...
...
@@ -1993,7 +1984,7 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
++
zExp
;
}
roundAndPack:
return
roundAndPackFloat64
(
zSign
,
zExp
,
zSig
);
return
roundAndPackFloat64
(
roundData
,
zSign
,
zExp
,
zSig
);
}
...
...
@@ -2006,7 +1997,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE
Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
static
float64
subFloat64Sigs
(
float64
a
,
float64
b
,
flag
zSign
)
static
float64
subFloat64Sigs
(
struct
roundingData
*
roundData
,
float64
a
,
float64
b
,
flag
zSign
)
{
int16
aExp
,
bExp
,
zExp
;
bits64
aSig
,
bSig
,
zSig
;
...
...
@@ -2023,7 +2014,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
if
(
expDiff
<
0
)
goto
bExpBigger
;
if
(
aExp
==
0x7FF
)
{
if
(
aSig
|
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
if
(
aExp
==
0
)
{
...
...
@@ -2032,7 +2023,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
}
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
aSig
<
bSig
)
goto
bBigger
;
return
packFloat64
(
float_rounding_
mode
==
float_round_down
,
0
,
0
);
return
packFloat64
(
roundData
->
mode
==
float_round_down
,
0
,
0
);
bExpBigger:
if
(
bExp
==
0x7FF
)
{
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
...
...
@@ -2069,7 +2060,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
zExp
=
aExp
;
normalizeRoundAndPack:
--
zExp
;
return
normalizeRoundAndPackFloat64
(
zSign
,
zExp
,
zSig
);
return
normalizeRoundAndPackFloat64
(
roundData
,
zSign
,
zExp
,
zSig
);
}
...
...
@@ -2080,17 +2071,17 @@ and `b'. The operation is performed according to the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float64
float64_add
(
float64
a
,
float64
b
)
float64
float64_add
(
struct
roundingData
*
roundData
,
float64
a
,
float64
b
)
{
flag
aSign
,
bSign
;
aSign
=
extractFloat64Sign
(
a
);
bSign
=
extractFloat64Sign
(
b
);
if
(
aSign
==
bSign
)
{
return
addFloat64Sigs
(
a
,
b
,
aSign
);
return
addFloat64Sigs
(
roundData
,
a
,
b
,
aSign
);
}
else
{
return
subFloat64Sigs
(
a
,
b
,
aSign
);
return
subFloat64Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
...
...
@@ -2102,17 +2093,17 @@ Returns the result of subtracting the double-precision floating-point values
for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float64
float64_sub
(
float64
a
,
float64
b
)
float64
float64_sub
(
struct
roundingData
*
roundData
,
float64
a
,
float64
b
)
{
flag
aSign
,
bSign
;
aSign
=
extractFloat64Sign
(
a
);
bSign
=
extractFloat64Sign
(
b
);
if
(
aSign
==
bSign
)
{
return
subFloat64Sigs
(
a
,
b
,
aSign
);
return
subFloat64Sigs
(
roundData
,
a
,
b
,
aSign
);
}
else
{
return
addFloat64Sigs
(
a
,
b
,
aSign
);
return
addFloat64Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
...
...
@@ -2124,7 +2115,7 @@ Returns the result of multiplying the double-precision floating-point values
for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float64
float64_mul
(
float64
a
,
float64
b
)
float64
float64_mul
(
struct
roundingData
*
roundData
,
float64
a
,
float64
b
)
{
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
zExp
;
...
...
@@ -2142,7 +2133,7 @@ float64 float64_mul( float64 a, float64 b )
return
propagateFloat64NaN
(
a
,
b
);
}
if
(
(
bExp
|
bSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
return
packFloat64
(
zSign
,
0x7FF
,
0
);
...
...
@@ -2150,7 +2141,7 @@ float64 float64_mul( float64 a, float64 b )
if
(
bExp
==
0x7FF
)
{
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
(
aExp
|
aSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
return
packFloat64
(
zSign
,
0x7FF
,
0
);
...
...
@@ -2172,7 +2163,7 @@ float64 float64_mul( float64 a, float64 b )
zSig0
<<=
1
;
--
zExp
;
}
return
roundAndPackFloat64
(
zSign
,
zExp
,
zSig0
);
return
roundAndPackFloat64
(
roundData
,
zSign
,
zExp
,
zSig0
);
}
...
...
@@ -2183,7 +2174,7 @@ by the corresponding value `b'. The operation is performed according to
the IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float64
float64_div
(
float64
a
,
float64
b
)
float64
float64_div
(
struct
roundingData
*
roundData
,
float64
a
,
float64
b
)
{
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
zExp
;
...
...
@@ -2202,7 +2193,7 @@ float64 float64_div( float64 a, float64 b )
if
(
aSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
bExp
==
0x7FF
)
{
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
return
packFloat64
(
zSign
,
0x7FF
,
0
);
...
...
@@ -2214,10 +2205,10 @@ float64 float64_div( float64 a, float64 b )
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
float_raise
(
float_flag_divbyzero
)
;
roundData
->
exception
|=
float_flag_divbyzero
;
return
packFloat64
(
zSign
,
0x7FF
,
0
);
}
normalizeFloat64Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
...
@@ -2243,7 +2234,7 @@ float64 float64_div( float64 a, float64 b )
}
zSig
|=
(
rem1
!=
0
);
}
return
roundAndPackFloat64
(
zSign
,
zExp
,
zSig
);
return
roundAndPackFloat64
(
roundData
,
zSign
,
zExp
,
zSig
);
}
...
...
@@ -2254,7 +2245,7 @@ with respect to the corresponding value `b'. The operation is performed
according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float64
float64_rem
(
float64
a
,
float64
b
)
float64
float64_rem
(
struct
roundingData
*
roundData
,
float64
a
,
float64
b
)
{
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
expDiff
;
...
...
@@ -2272,7 +2263,7 @@ float64 float64_rem( float64 a, float64 b )
if
(
aSig
||
(
(
bExp
==
0x7FF
)
&&
bSig
)
)
{
return
propagateFloat64NaN
(
a
,
b
);
}
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
if
(
bExp
==
0x7FF
)
{
...
...
@@ -2281,7 +2272,7 @@ float64 float64_rem( float64 a, float64 b )
}
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
normalizeFloat64Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
...
@@ -2329,7 +2320,7 @@ float64 float64_rem( float64 a, float64 b )
}
zSign
=
(
(
sbits64
)
aSig
<
0
);
if
(
zSign
)
aSig
=
-
aSig
;
return
normalizeRoundAndPackFloat64
(
aSign
^
zSign
,
bExp
,
aSig
);
return
normalizeRoundAndPackFloat64
(
roundData
,
aSign
^
zSign
,
bExp
,
aSig
);
}
...
...
@@ -2340,7 +2331,7 @@ The operation is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float64
float64_sqrt
(
float64
a
)
float64
float64_sqrt
(
struct
roundingData
*
roundData
,
float64
a
)
{
flag
aSign
;
int16
aExp
,
zExp
;
...
...
@@ -2354,12 +2345,12 @@ float64 float64_sqrt( float64 a )
if
(
aExp
==
0x7FF
)
{
if
(
aSig
)
return
propagateFloat64NaN
(
a
,
a
);
if
(
!
aSign
)
return
a
;
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
if
(
aSign
)
{
if
(
(
aExp
|
aSig
)
==
0
)
return
a
;
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
}
if
(
aExp
==
0
)
{
...
...
@@ -2390,7 +2381,7 @@ float64 float64_sqrt( float64 a )
}
}
shift64RightJamming
(
zSig
,
1
,
&
zSig
);
return
roundAndPackFloat64
(
0
,
zExp
,
zSig
);
return
roundAndPackFloat64
(
roundData
,
0
,
zExp
,
zSig
);
}
...
...
@@ -2554,7 +2545,7 @@ largest positive integer is returned. Otherwise, if the conversion
overflows, the largest integer with the same sign as `a' is returned.
-------------------------------------------------------------------------------
*/
int32
floatx80_to_int32
(
floatx80
a
)
int32
floatx80_to_int32
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
flag
aSign
;
int32
aExp
,
shiftCount
;
...
...
@@ -2567,7 +2558,7 @@ int32 floatx80_to_int32( floatx80 a )
shiftCount
=
0x4037
-
aExp
;
if
(
shiftCount
<=
0
)
shiftCount
=
1
;
shift64RightJamming
(
aSig
,
shiftCount
,
&
aSig
);
return
roundAndPackInt32
(
aSign
,
aSig
);
return
roundAndPackInt32
(
roundData
,
aSign
,
aSig
);
}
...
...
@@ -2598,7 +2589,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a )
goto
invalid
;
}
else
if
(
63
<
shiftCount
)
{
if
(
aExp
||
aSig
)
float_
exception_flags
|=
float_flag_inexact
;
if
(
aExp
||
aSig
)
float_
raise
(
float_flag_inexact
)
;
return
0
;
}
savedASig
=
aSig
;
...
...
@@ -2607,11 +2598,11 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a )
if
(
aSign
)
z
=
-
z
;
if
(
(
z
<
0
)
^
aSign
)
{
invalid:
float_
exception_flags
|=
float_flag_invalid
;
float_
raise
(
float_flag_invalid
)
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
}
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
float_
exception_flags
|=
float_flag_inexact
;
float_
raise
(
float_flag_inexact
)
;
}
return
z
;
...
...
@@ -2625,7 +2616,7 @@ conversion is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float32
floatx80_to_float32
(
floatx80
a
)
float32
floatx80_to_float32
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
flag
aSign
;
int32
aExp
;
...
...
@@ -2642,7 +2633,7 @@ float32 floatx80_to_float32( floatx80 a )
}
shift64RightJamming
(
aSig
,
33
,
&
aSig
);
if
(
aExp
||
aSig
)
aExp
-=
0x3F81
;
return
roundAndPackFloat32
(
aSign
,
aExp
,
aSig
);
return
roundAndPackFloat32
(
roundData
,
aSign
,
aExp
,
aSig
);
}
...
...
@@ -2654,7 +2645,7 @@ conversion is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
float64
floatx80_to_float64
(
floatx80
a
)
float64
floatx80_to_float64
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
flag
aSign
;
int32
aExp
;
...
...
@@ -2671,7 +2662,7 @@ float64 floatx80_to_float64( floatx80 a )
}
shift64RightJamming
(
aSig
,
1
,
&
zSig
);
if
(
aExp
||
aSig
)
aExp
-=
0x3C01
;
return
roundAndPackFloat64
(
aSign
,
aExp
,
zSig
);
return
roundAndPackFloat64
(
roundData
,
aSign
,
aExp
,
zSig
);
}
...
...
@@ -2683,7 +2674,7 @@ value. The operation is performed according to the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
floatx80
floatx80_round_to_int
(
floatx80
a
)
floatx80
floatx80_round_to_int
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
flag
aSign
;
int32
aExp
;
...
...
@@ -2703,9 +2694,9 @@ floatx80 floatx80_round_to_int( floatx80 a )
&&
(
(
bits64
)
(
extractFloatx80Frac
(
a
)
<<
1
)
==
0
)
)
{
return
a
;
}
float_exception_flags
|=
float_flag_inexact
;
roundData
->
exception
|=
float_flag_inexact
;
aSign
=
extractFloatx80Sign
(
a
);
switch
(
float_rounding_
mode
)
{
switch
(
roundData
->
mode
)
{
case
float_round_nearest_even
:
if
(
(
aExp
==
0x3FFE
)
&&
(
bits64
)
(
extractFloatx80Frac
(
a
)
<<
1
)
)
{
...
...
@@ -2729,7 +2720,7 @@ floatx80 floatx80_round_to_int( floatx80 a )
lastBitMask
<<=
0x403E
-
aExp
;
roundBitsMask
=
lastBitMask
-
1
;
z
=
a
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
if
(
roundingMode
==
float_round_nearest_even
)
{
z
.
low
+=
lastBitMask
>>
1
;
if
(
(
z
.
low
&
roundBitsMask
)
==
0
)
z
.
low
&=
~
lastBitMask
;
...
...
@@ -2744,7 +2735,7 @@ floatx80 floatx80_round_to_int( floatx80 a )
++
z
.
high
;
z
.
low
=
LIT64
(
0x8000000000000000
);
}
if
(
z
.
low
!=
a
.
low
)
float_exception_flags
|=
float_flag_inexact
;
if
(
z
.
low
!=
a
.
low
)
roundData
->
exception
|=
float_flag_inexact
;
return
z
;
}
...
...
@@ -2758,7 +2749,7 @@ The addition is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
static
floatx80
addFloatx80Sigs
(
floatx80
a
,
floatx80
b
,
flag
zSign
)
static
floatx80
addFloatx80Sigs
(
struct
roundingData
*
roundData
,
floatx80
a
,
floatx80
b
,
flag
zSign
)
{
int32
aExp
,
bExp
,
zExp
;
bits64
aSig
,
bSig
,
zSig0
,
zSig1
;
...
...
@@ -2814,7 +2805,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
roundAndPack:
return
roundAndPackFloatx80
(
floatx80_rounding_precision
,
zSign
,
zExp
,
zSig0
,
zSig1
);
roundData
,
zSign
,
zExp
,
zSig0
,
zSig1
);
}
...
...
@@ -2827,7 +2818,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE
Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
static
floatx80
subFloatx80Sigs
(
floatx80
a
,
floatx80
b
,
flag
zSign
)
static
floatx80
subFloatx80Sigs
(
struct
roundingData
*
roundData
,
floatx80
a
,
floatx80
b
,
flag
zSign
)
{
int32
aExp
,
bExp
,
zExp
;
bits64
aSig
,
bSig
,
zSig0
,
zSig1
;
...
...
@@ -2845,7 +2836,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
if
(
(
bits64
)
(
(
aSig
|
bSig
)
<<
1
)
)
{
return
propagateFloatx80NaN
(
a
,
b
);
}
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
...
...
@@ -2857,7 +2848,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
zSig1
=
0
;
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
aSig
<
bSig
)
goto
bBigger
;
return
packFloatx80
(
float_rounding_
mode
==
float_round_down
,
0
,
0
);
return
packFloatx80
(
roundData
->
mode
==
float_round_down
,
0
,
0
);
bExpBigger:
if
(
bExp
==
0x7FFF
)
{
if
(
(
bits64
)
(
bSig
<<
1
)
)
return
propagateFloatx80NaN
(
a
,
b
);
...
...
@@ -2883,7 +2874,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
normalizeRoundAndPack:
return
normalizeRoundAndPackFloatx80
(
floatx80_rounding_precision
,
zSign
,
zExp
,
zSig0
,
zSig1
);
roundData
,
zSign
,
zExp
,
zSig0
,
zSig1
);
}
...
...
@@ -2894,17 +2885,17 @@ values `a' and `b'. The operation is performed according to the IEC/IEEE
Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
floatx80
floatx80_add
(
floatx80
a
,
floatx80
b
)
floatx80
floatx80_add
(
struct
roundingData
*
roundData
,
floatx80
a
,
floatx80
b
)
{
flag
aSign
,
bSign
;
aSign
=
extractFloatx80Sign
(
a
);
bSign
=
extractFloatx80Sign
(
b
);
if
(
aSign
==
bSign
)
{
return
addFloatx80Sigs
(
a
,
b
,
aSign
);
return
addFloatx80Sigs
(
roundData
,
a
,
b
,
aSign
);
}
else
{
return
subFloatx80Sigs
(
a
,
b
,
aSign
);
return
subFloatx80Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
...
...
@@ -2916,17 +2907,17 @@ point values `a' and `b'. The operation is performed according to the
IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
floatx80
floatx80_sub
(
floatx80
a
,
floatx80
b
)
floatx80
floatx80_sub
(
struct
roundingData
*
roundData
,
floatx80
a
,
floatx80
b
)
{
flag
aSign
,
bSign
;
aSign
=
extractFloatx80Sign
(
a
);
bSign
=
extractFloatx80Sign
(
b
);
if
(
aSign
==
bSign
)
{
return
subFloatx80Sigs
(
a
,
b
,
aSign
);
return
subFloatx80Sigs
(
roundData
,
a
,
b
,
aSign
);
}
else
{
return
addFloatx80Sigs
(
a
,
b
,
aSign
);
return
addFloatx80Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
...
...
@@ -2938,7 +2929,7 @@ point values `a' and `b'. The operation is performed according to the
IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
floatx80
floatx80_mul
(
floatx80
a
,
floatx80
b
)
floatx80
floatx80_mul
(
struct
roundingData
*
roundData
,
floatx80
a
,
floatx80
b
)
{
flag
aSign
,
bSign
,
zSign
;
int32
aExp
,
bExp
,
zExp
;
...
...
@@ -2964,7 +2955,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b )
if
(
(
bits64
)
(
bSig
<<
1
)
)
return
propagateFloatx80NaN
(
a
,
b
);
if
(
(
aExp
|
aSig
)
==
0
)
{
invalid:
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
...
...
@@ -2987,7 +2978,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b )
}
return
roundAndPackFloatx80
(
floatx80_rounding_precision
,
zSign
,
zExp
,
zSig0
,
zSig1
);
roundData
,
zSign
,
zExp
,
zSig0
,
zSig1
);
}
...
...
@@ -2998,7 +2989,7 @@ value `a' by the corresponding value `b'. The operation is performed
according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
floatx80
floatx80_div
(
floatx80
a
,
floatx80
b
)
floatx80
floatx80_div
(
struct
roundingData
*
roundData
,
floatx80
a
,
floatx80
b
)
{
flag
aSign
,
bSign
,
zSign
;
int32
aExp
,
bExp
,
zExp
;
...
...
@@ -3029,12 +3020,12 @@ floatx80 floatx80_div( floatx80 a, floatx80 b )
if
(
bSig
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
invalid:
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
}
float_raise
(
float_flag_divbyzero
)
;
roundData
->
exception
|=
float_flag_divbyzero
;
return
packFloatx80
(
zSign
,
0x7FFF
,
LIT64
(
0x8000000000000000
)
);
}
normalizeFloatx80Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
...
@@ -3068,7 +3059,7 @@ floatx80 floatx80_div( floatx80 a, floatx80 b )
}
return
roundAndPackFloatx80
(
floatx80_rounding_precision
,
zSign
,
zExp
,
zSig0
,
zSig1
);
roundData
,
zSign
,
zExp
,
zSig0
,
zSig1
);
}
...
...
@@ -3079,7 +3070,7 @@ Returns the remainder of the extended double-precision floating-point value
according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
floatx80
floatx80_rem
(
floatx80
a
,
floatx80
b
)
floatx80
floatx80_rem
(
struct
roundingData
*
roundData
,
floatx80
a
,
floatx80
b
)
{
flag
aSign
,
bSign
,
zSign
;
int32
aExp
,
bExp
,
expDiff
;
...
...
@@ -3107,7 +3098,7 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b )
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
invalid:
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
...
...
@@ -3164,9 +3155,10 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b )
aSig1
=
alternateASig1
;
zSign
=
!
zSign
;
}
return
normalizeRoundAndPackFloatx80
(
80
,
zSign
,
bExp
+
expDiff
,
aSig0
,
aSig1
);
roundData
,
zSign
,
bExp
+
expDiff
,
aSig0
,
aSig1
);
}
...
...
@@ -3177,7 +3169,7 @@ value `a'. The operation is performed according to the IEC/IEEE Standard
for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
*/
floatx80
floatx80_sqrt
(
floatx80
a
)
floatx80
floatx80_sqrt
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
flag
aSign
;
int32
aExp
,
zExp
;
...
...
@@ -3197,7 +3189,7 @@ floatx80 floatx80_sqrt( floatx80 a )
if
(
aSign
)
{
if
(
(
aExp
|
aSig0
)
==
0
)
return
a
;
invalid:
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
...
...
@@ -3242,7 +3234,7 @@ floatx80 floatx80_sqrt( floatx80 a )
}
return
roundAndPackFloatx80
(
floatx80_rounding_precision
,
0
,
zExp
,
zSig0
,
zSig1
);
roundData
,
0
,
zExp
,
zSig0
,
zSig1
);
}
...
...
@@ -3264,7 +3256,7 @@ flag floatx80_eq( floatx80 a, floatx80 b )
)
{
if
(
floatx80_is_signaling_nan
(
a
)
||
floatx80_is_signaling_nan
(
b
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
}
return
0
;
}
...
...
@@ -3294,7 +3286,7 @@ flag floatx80_le( floatx80 a, floatx80 b )
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
0
;
}
aSign
=
extractFloatx80Sign
(
a
);
...
...
@@ -3328,7 +3320,7 @@ flag floatx80_lt( floatx80 a, floatx80 b )
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
0
;
}
aSign
=
extractFloatx80Sign
(
a
);
...
...
@@ -3361,7 +3353,7 @@ flag floatx80_eq_signaling( floatx80 a, floatx80 b )
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
0
;
}
return
...
...
@@ -3392,7 +3384,7 @@ flag floatx80_le_quiet( floatx80 a, floatx80 b )
)
{
if
(
floatx80_is_signaling_nan
(
a
)
||
floatx80_is_signaling_nan
(
b
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
}
return
0
;
}
...
...
@@ -3429,7 +3421,7 @@ flag floatx80_lt_quiet( floatx80 a, floatx80 b )
)
{
if
(
floatx80_is_signaling_nan
(
a
)
||
floatx80_is_signaling_nan
(
b
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
}
return
0
;
}
...
...
arch/arm/nwfpe/softfloat.h
View file @
194d0710
...
...
@@ -74,7 +74,7 @@ enum {
Software IEC/IEEE floating-point rounding mode.
-------------------------------------------------------------------------------
*/
extern
signed
char
float_rounding_mode
;
//extern int8
float_rounding_mode;
enum
{
float_round_nearest_even
=
0
,
float_round_to_zero
=
1
,
...
...
@@ -86,7 +86,6 @@ enum {
-------------------------------------------------------------------------------
Software IEC/IEEE floating-point exception flags.
-------------------------------------------------------------------------------
extern signed char float_exception_flags;
enum {
float_flag_inexact = 1,
float_flag_underflow = 2,
...
...
@@ -99,7 +98,6 @@ ScottB: November 4, 1998
Changed the enumeration to match the bit order in the FPA11.
*/
extern
signed
char
float_exception_flags
;
enum
{
float_flag_invalid
=
1
,
float_flag_divbyzero
=
2
,
...
...
@@ -121,7 +119,7 @@ void float_raise( signed char );
Software IEC/IEEE integer-to-floating-point conversion routines.
-------------------------------------------------------------------------------
*/
float32
int32_to_float32
(
signed
int
);
float32
int32_to_float32
(
s
truct
roundingData
*
,
s
igned
int
);
float64
int32_to_float64
(
signed
int
);
#ifdef FLOATX80
floatx80
int32_to_floatx80
(
signed
int
);
...
...
@@ -132,7 +130,7 @@ floatx80 int32_to_floatx80( signed int );
Software IEC/IEEE single-precision conversion routines.
-------------------------------------------------------------------------------
*/
signed
int
float32_to_int32
(
float32
);
signed
int
float32_to_int32
(
struct
roundingData
*
,
float32
);
signed
int
float32_to_int32_round_to_zero
(
float32
);
float64
float32_to_float64
(
float32
);
#ifdef FLOATX80
...
...
@@ -144,13 +142,13 @@ floatx80 float32_to_floatx80( float32 );
Software IEC/IEEE single-precision operations.
-------------------------------------------------------------------------------
*/
float32
float32_round_to_int
(
float32
);
float32
float32_add
(
float32
,
float32
);
float32
float32_sub
(
float32
,
float32
);
float32
float32_mul
(
float32
,
float32
);
float32
float32_div
(
float32
,
float32
);
float32
float32_rem
(
float32
,
float32
);
float32
float32_sqrt
(
float32
);
float32
float32_round_to_int
(
struct
roundingData
*
,
float32
);
float32
float32_add
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_sub
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_mul
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_div
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_rem
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_sqrt
(
struct
roundingData
*
,
float32
);
char
float32_eq
(
float32
,
float32
);
char
float32_le
(
float32
,
float32
);
char
float32_lt
(
float32
,
float32
);
...
...
@@ -164,9 +162,9 @@ char float32_is_signaling_nan( float32 );
Software IEC/IEEE double-precision conversion routines.
-------------------------------------------------------------------------------
*/
signed
int
float64_to_int32
(
float64
);
signed
int
float64_to_int32
(
struct
roundingData
*
,
float64
);
signed
int
float64_to_int32_round_to_zero
(
float64
);
float32
float64_to_float32
(
float64
);
float32
float64_to_float32
(
struct
roundingData
*
,
float64
);
#ifdef FLOATX80
floatx80
float64_to_floatx80
(
float64
);
#endif
...
...
@@ -176,13 +174,13 @@ floatx80 float64_to_floatx80( float64 );
Software IEC/IEEE double-precision operations.
-------------------------------------------------------------------------------
*/
float64
float64_round_to_int
(
float64
);
float64
float64_add
(
float64
,
float64
);
float64
float64_sub
(
float64
,
float64
);
float64
float64_mul
(
float64
,
float64
);
float64
float64_div
(
float64
,
float64
);
float64
float64_rem
(
float64
,
float64
);
float64
float64_sqrt
(
float64
);
float64
float64_round_to_int
(
struct
roundingData
*
,
float64
);
float64
float64_add
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_sub
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_mul
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_div
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_rem
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_sqrt
(
struct
roundingData
*
,
float64
);
char
float64_eq
(
float64
,
float64
);
char
float64_le
(
float64
,
float64
);
char
float64_lt
(
float64
,
float64
);
...
...
@@ -198,31 +196,23 @@ char float64_is_signaling_nan( float64 );
Software IEC/IEEE extended double-precision conversion routines.
-------------------------------------------------------------------------------
*/
signed
int
floatx80_to_int32
(
floatx80
);
signed
int
floatx80_to_int32
(
struct
roundingData
*
,
floatx80
);
signed
int
floatx80_to_int32_round_to_zero
(
floatx80
);
float32
floatx80_to_float32
(
floatx80
);
float64
floatx80_to_float64
(
floatx80
);
/*
-------------------------------------------------------------------------------
Software IEC/IEEE extended double-precision rounding precision. Valid
values are 32, 64, and 80.
-------------------------------------------------------------------------------
*/
extern
signed
char
floatx80_rounding_precision
;
float32
floatx80_to_float32
(
struct
roundingData
*
,
floatx80
);
float64
floatx80_to_float64
(
struct
roundingData
*
,
floatx80
);
/*
-------------------------------------------------------------------------------
Software IEC/IEEE extended double-precision operations.
-------------------------------------------------------------------------------
*/
floatx80
floatx80_round_to_int
(
floatx80
);
floatx80
floatx80_add
(
floatx80
,
floatx80
);
floatx80
floatx80_sub
(
floatx80
,
floatx80
);
floatx80
floatx80_mul
(
floatx80
,
floatx80
);
floatx80
floatx80_div
(
floatx80
,
floatx80
);
floatx80
floatx80_rem
(
floatx80
,
floatx80
);
floatx80
floatx80_sqrt
(
floatx80
);
floatx80
floatx80_round_to_int
(
struct
roundingData
*
,
floatx80
);
floatx80
floatx80_add
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_sub
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_mul
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_div
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_rem
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_sqrt
(
struct
roundingData
*
,
floatx80
);
char
floatx80_eq
(
floatx80
,
floatx80
);
char
floatx80_le
(
floatx80
,
floatx80
);
char
floatx80_lt
(
floatx80
,
floatx80
);
...
...
arch/arm/vfp/vfpdouble.c
View file @
194d0710
...
...
@@ -770,6 +770,9 @@ vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,
if
((
s64
)
m_sig
<
0
)
{
vdd
->
sign
=
vfp_sign_negate
(
vdd
->
sign
);
m_sig
=
-
m_sig
;
}
else
if
(
m_sig
==
0
)
{
vdd
->
sign
=
(
fpscr
&
FPSCR_RMODE_MASK
)
==
FPSCR_ROUND_MINUSINF
?
0x8000
:
0
;
}
}
else
{
m_sig
+=
vdn
->
significand
;
...
...
drivers/char/watchdog/sa1100_wdt.c
View file @
194d0710
...
...
@@ -36,13 +36,10 @@
#include <asm/uaccess.h>
#define OSCR_FREQ CLOCK_TICK_RATE
#define SA1100_CLOSE_MAGIC (0x5afc4453)
static
unsigned
long
sa1100wdt_users
;
static
int
expect_close
;
static
int
pre_margin
;
static
int
boot_status
;
static
int
nowayout
=
WATCHDOG_NOWAYOUT
;
/*
* Allow only one person to hold it open
...
...
@@ -62,55 +59,33 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
}
/*
* Shut off the timer.
* Lock it in if it's a module and we defined ...NOWAYOUT
* Oddly, the watchdog can only be enabled, but we can turn off
* the interrupt, which appears to prevent the watchdog timing out.
* The watchdog cannot be disabled.
*
* Previous comments suggested that turning off the interrupt by
* clearing OIER[E3] would prevent the watchdog timing out but this
* does not appear to be true (at least on the PXA255).
*/
static
int
sa1100dog_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
OSMR3
=
OSCR
+
pre_margin
;
if
(
expect_close
==
SA1100_CLOSE_MAGIC
)
{
OIER
&=
~
OIER_E3
;
}
else
{
printk
(
KERN_CRIT
"WATCHDOG: WDT device closed unexpectedly. WDT will not stop!
\n
"
);
}
printk
(
KERN_CRIT
"WATCHDOG: Device closed - timer will not stop
\n
"
);
clear_bit
(
1
,
&
sa1100wdt_users
);
expect_close
=
0
;
return
0
;
}
static
ssize_t
sa1100dog_write
(
struct
file
*
file
,
const
char
*
data
,
size_t
len
,
loff_t
*
ppos
)
{
if
(
len
)
{
if
(
!
nowayout
)
{
size_t
i
;
expect_close
=
0
;
for
(
i
=
0
;
i
!=
len
;
i
++
)
{
char
c
;
if
(
get_user
(
c
,
data
+
i
))
return
-
EFAULT
;
if
(
c
==
'V'
)
expect_close
=
SA1100_CLOSE_MAGIC
;
}
}
if
(
len
)
/* Refresh OSMR3 timer. */
OSMR3
=
OSCR
+
pre_margin
;
}
return
len
;
}
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_CARDRESET
|
WDIOF_MAGICCLOSE
|
WDIOF_SETTIMEOUT
|
WDIOF_KEEPALIVEPING
,
.
identity
=
"SA1100 Watchdog"
,
.
options
=
WDIOF_CARDRESET
|
WDIOF_SETTIMEOUT
|
WDIOF_KEEPALIVEPING
,
.
identity
=
"SA1100/PXA255 Watchdog"
,
};
static
int
sa1100dog_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
...
...
@@ -172,7 +147,7 @@ static struct file_operations sa1100dog_fops =
static
struct
miscdevice
sa1100dog_miscdev
=
{
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"
SA1100/PXA2xx
watchdog"
,
.
name
=
"watchdog"
,
.
fops
=
&
sa1100dog_fops
,
};
...
...
@@ -194,7 +169,6 @@ static int __init sa1100dog_init(void)
if
(
ret
==
0
)
printk
(
"SA1100/PXA2xx Watchdog Timer: timer margin %d sec
\n
"
,
margin
);
return
ret
;
}
...
...
@@ -212,8 +186,5 @@ MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog");
module_param
(
margin
,
int
,
0
);
MODULE_PARM_DESC
(
margin
,
"Watchdog margin in seconds (default 60s)"
);
module_param
(
nowayout
,
int
,
0
);
MODULE_PARM_DESC
(
nowayout
,
"Watchdog cannot be stopped once started"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS_MISCDEV
(
WATCHDOG_MINOR
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment