Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
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
Hide 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
...
@@ -104,6 +104,7 @@ logo_*.c
logo_*_clut224.c
logo_*_clut224.c
logo_*_mono.c
logo_*_mono.c
lxdialog
lxdialog
mach-types
mach-types.h
mach-types.h
make_times_h
make_times_h
map
map
...
...
arch/arm/mach-ixp4xx/coyote-setup.c
View file @
194d0710
...
@@ -61,7 +61,7 @@ static struct plat_serial8250_port coyote_uart_data[] = {
...
@@ -61,7 +61,7 @@ static struct plat_serial8250_port coyote_uart_data[] = {
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART2
,
.
irq
=
IRQ_IXP4XX_UART2
,
.
flags
=
UPF_BOOT_AUTOCONF
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
.
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[] = {
...
@@ -83,7 +83,7 @@ static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART2
,
.
irq
=
IRQ_IXP4XX_UART2
,
.
flags
=
UPF_BOOT_AUTOCONF
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
.
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[] = {
...
@@ -82,7 +82,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
.
mapbase
=
IXP4XX_UART1_BASE_PHYS
,
.
mapbase
=
IXP4XX_UART1_BASE_PHYS
,
.
membase
=
(
char
*
)
IXP4XX_UART1_BASE_VIRT
+
REG_OFFSET
,
.
membase
=
(
char
*
)
IXP4XX_UART1_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART1
,
.
irq
=
IRQ_IXP4XX_UART1
,
.
flags
=
UPF_BOOT_AUTOCONF
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
.
uartclk
=
IXP4XX_UART_XTAL
,
...
@@ -91,7 +91,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
...
@@ -91,7 +91,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = {
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
mapbase
=
IXP4XX_UART2_BASE_PHYS
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
membase
=
(
char
*
)
IXP4XX_UART2_BASE_VIRT
+
REG_OFFSET
,
.
irq
=
IRQ_IXP4XX_UART1
,
.
irq
=
IRQ_IXP4XX_UART1
,
.
flags
=
UPF_BOOT_AUTOCONF
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
.
iotype
=
UPIO_MEM
,
.
iotype
=
UPIO_MEM
,
.
regshift
=
2
,
.
regshift
=
2
,
.
uartclk
=
IXP4XX_UART_XTAL
,
.
uartclk
=
IXP4XX_UART_XTAL
,
...
...
arch/arm/mach-s3c2410/mach-bast.c
View file @
194d0710
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
* 28-Jun-2005 BJD Moved pm functionality out to common code
* 28-Jun-2005 BJD Moved pm functionality out to common code
* 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s
* 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s
* 25-Jul-2005 BJD Removed ASIX static mappings
* 25-Jul-2005 BJD Removed ASIX static mappings
* 27-Jul-2005 BJD Ensure maximum frequency of i2c bus
*/
*/
#include <linux/kernel.h>
#include <linux/kernel.h>
...
@@ -60,6 +61,7 @@
...
@@ -60,6 +61,7 @@
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/nand.h>
#include <asm/arch/nand.h>
#include <asm/arch/iic.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand.h>
...
@@ -304,7 +306,7 @@ static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
...
@@ -304,7 +306,7 @@ static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
}
}
static
struct
s3c2410_platform_nand
bast_nand_info
=
{
static
struct
s3c2410_platform_nand
bast_nand_info
=
{
.
tacls
=
8
0
,
.
tacls
=
4
0
,
.
twrph0
=
80
,
.
twrph0
=
80
,
.
twrph1
=
80
,
.
twrph1
=
80
,
.
nr_sets
=
ARRAY_SIZE
(
bast_nand_sets
),
.
nr_sets
=
ARRAY_SIZE
(
bast_nand_sets
),
...
@@ -385,6 +387,17 @@ static struct platform_device bast_sio = {
...
@@ -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 */
/* Standard BAST devices */
static
struct
platform_device
*
bast_devices
[]
__initdata
=
{
static
struct
platform_device
*
bast_devices
[]
__initdata
=
{
...
@@ -431,6 +444,7 @@ void __init bast_map_io(void)
...
@@ -431,6 +444,7 @@ void __init bast_map_io(void)
s3c24xx_uclk
.
parent
=
&
s3c24xx_clkout1
;
s3c24xx_uclk
.
parent
=
&
s3c24xx_clkout1
;
s3c_device_nand
.
dev
.
platform_data
=
&
bast_nand_info
;
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_io
(
bast_iodesc
,
ARRAY_SIZE
(
bast_iodesc
));
s3c24xx_init_clocks
(
0
);
s3c24xx_init_clocks
(
0
);
...
...
arch/arm/mm/proc-xscale.S
View file @
194d0710
...
@@ -370,142 +370,6 @@ ENTRY(cpu_xscale_dcache_clean_area)
...
@@ -370,142 +370,6 @@ ENTRY(cpu_xscale_dcache_clean_area)
bhi
1
b
bhi
1
b
mov
pc
,
lr
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
==============================
*/
/*
==============================
=
PageTable
==============================
*/
#define PTE_CACHE_WRITE_ALLOCATE 0
#define PTE_CACHE_WRITE_ALLOCATE 0
...
...
arch/arm/nwfpe/double_cpdo.c
View file @
194d0710
...
@@ -40,17 +40,17 @@ float64 float64_arccos(float64 rFm);
...
@@ -40,17 +40,17 @@ float64 float64_arccos(float64 rFm);
float64
float64_pow
(
float64
rFn
,
float64
rFm
);
float64
float64_pow
(
float64
rFn
,
float64
rFm
);
float64
float64_pol
(
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
,
[
ADF_CODE
>>
20
]
=
float64_add
,
[
MUF_CODE
>>
20
]
=
float64_mul
,
[
MUF_CODE
>>
20
]
=
float64_mul
,
[
SUF_CODE
>>
20
]
=
float64_sub
,
[
SUF_CODE
>>
20
]
=
float64_sub
,
...
@@ -65,12 +65,12 @@ static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
...
@@ -65,12 +65,12 @@ static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
[
FRD_CODE
>>
20
]
=
float64_rdv
,
[
FRD_CODE
>>
20
]
=
float64_rdv
,
};
};
static
float64
float64_mvf
(
float64
rFm
)
static
float64
float64_mvf
(
struct
roundingData
*
roundData
,
float64
rFm
)
{
{
return
rFm
;
return
rFm
;
}
}
static
float64
float64_mnf
(
float64
rFm
)
static
float64
float64_mnf
(
struct
roundingData
*
roundData
,
float64
rFm
)
{
{
union
float64_components
u
;
union
float64_components
u
;
...
@@ -84,7 +84,7 @@ static float64 float64_mnf(float64 rFm)
...
@@ -84,7 +84,7 @@ static float64 float64_mnf(float64 rFm)
return
u
.
f64
;
return
u
.
f64
;
}
}
static
float64
float64_abs
(
float64
rFm
)
static
float64
float64_abs
(
struct
roundingData
*
roundData
,
float64
rFm
)
{
{
union
float64_components
u
;
union
float64_components
u
;
...
@@ -98,7 +98,7 @@ static float64 float64_abs(float64 rFm)
...
@@ -98,7 +98,7 @@ static float64 float64_abs(float64 rFm)
return
u
.
f64
;
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
,
[
MVF_CODE
>>
20
]
=
float64_mvf
,
[
MNF_CODE
>>
20
]
=
float64_mnf
,
[
MNF_CODE
>>
20
]
=
float64_mnf
,
[
ABS_CODE
>>
20
]
=
float64_abs
,
[
ABS_CODE
>>
20
]
=
float64_abs
,
...
@@ -108,7 +108,7 @@ static float64 (*const monadic_double[16])(float64 rFm) = {
...
@@ -108,7 +108,7 @@ static float64 (*const monadic_double[16])(float64 rFm) = {
[
NRM_CODE
>>
20
]
=
float64_mvf
,
[
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
();
FPA11
*
fpa11
=
GET_FPA11
();
float64
rFm
;
float64
rFm
;
...
@@ -151,13 +151,13 @@ unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
...
@@ -151,13 +151,13 @@ unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
}
}
if
(
dyadic_double
[
opc_mask_shift
])
{
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
{
}
else
{
return
0
;
return
0
;
}
}
}
else
{
}
else
{
if
(
monadic_double
[
opc_mask_shift
])
{
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
{
}
else
{
return
0
;
return
0
;
}
}
...
...
arch/arm/nwfpe/extended_cpdo.c
View file @
194d0710
...
@@ -35,17 +35,17 @@ floatx80 floatx80_arccos(floatx80 rFm);
...
@@ -35,17 +35,17 @@ floatx80 floatx80_arccos(floatx80 rFm);
floatx80
floatx80_pow
(
floatx80
rFn
,
floatx80
rFm
);
floatx80
floatx80_pow
(
floatx80
rFn
,
floatx80
rFm
);
floatx80
floatx80_pol
(
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
,
[
ADF_CODE
>>
20
]
=
floatx80_add
,
[
MUF_CODE
>>
20
]
=
floatx80_mul
,
[
MUF_CODE
>>
20
]
=
floatx80_mul
,
[
SUF_CODE
>>
20
]
=
floatx80_sub
,
[
SUF_CODE
>>
20
]
=
floatx80_sub
,
...
@@ -60,24 +60,24 @@ static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
...
@@ -60,24 +60,24 @@ static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
[
FRD_CODE
>>
20
]
=
floatx80_rdv
,
[
FRD_CODE
>>
20
]
=
floatx80_rdv
,
};
};
static
floatx80
floatx80_mvf
(
floatx80
rFm
)
static
floatx80
floatx80_mvf
(
struct
roundingData
*
roundData
,
floatx80
rFm
)
{
{
return
rFm
;
return
rFm
;
}
}
static
floatx80
floatx80_mnf
(
floatx80
rFm
)
static
floatx80
floatx80_mnf
(
struct
roundingData
*
roundData
,
floatx80
rFm
)
{
{
rFm
.
high
^=
0x8000
;
rFm
.
high
^=
0x8000
;
return
rFm
;
return
rFm
;
}
}
static
floatx80
floatx80_abs
(
floatx80
rFm
)
static
floatx80
floatx80_abs
(
struct
roundingData
*
roundData
,
floatx80
rFm
)
{
{
rFm
.
high
&=
0x7fff
;
rFm
.
high
&=
0x7fff
;
return
rFm
;
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
,
[
MVF_CODE
>>
20
]
=
floatx80_mvf
,
[
MNF_CODE
>>
20
]
=
floatx80_mnf
,
[
MNF_CODE
>>
20
]
=
floatx80_mnf
,
[
ABS_CODE
>>
20
]
=
floatx80_abs
,
[
ABS_CODE
>>
20
]
=
floatx80_abs
,
...
@@ -87,7 +87,7 @@ static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
...
@@ -87,7 +87,7 @@ static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
[
NRM_CODE
>>
20
]
=
floatx80_mvf
,
[
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
();
FPA11
*
fpa11
=
GET_FPA11
();
floatx80
rFm
;
floatx80
rFm
;
...
@@ -138,13 +138,13 @@ unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
...
@@ -138,13 +138,13 @@ unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
}
}
if
(
dyadic_extended
[
opc_mask_shift
])
{
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
{
}
else
{
return
0
;
return
0
;
}
}
}
else
{
}
else
{
if
(
monadic_extended
[
opc_mask_shift
])
{
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
{
}
else
{
return
0
;
return
0
;
}
}
...
...
arch/arm/nwfpe/fpa11.c
View file @
194d0710
...
@@ -51,48 +51,42 @@ static void resetFPA11(void)
...
@@ -51,48 +51,42 @@ static void resetFPA11(void)
fpa11
->
fpsr
=
FP_EMULATOR
|
BIT_AC
;
fpa11
->
fpsr
=
FP_EMULATOR
|
BIT_AC
;
}
}
void
SetRoundingMode
(
const
unsigned
int
opcode
)
int8
SetRoundingMode
(
const
unsigned
int
opcode
)
{
{
switch
(
opcode
&
MASK_ROUNDING_MODE
)
{
switch
(
opcode
&
MASK_ROUNDING_MODE
)
{
default:
default:
case
ROUND_TO_NEAREST
:
case
ROUND_TO_NEAREST
:
float_rounding_mode
=
float_round_nearest_even
;
return
float_round_nearest_even
;
break
;
case
ROUND_TO_PLUS_INFINITY
:
case
ROUND_TO_PLUS_INFINITY
:
float_rounding_mode
=
float_round_up
;
return
float_round_up
;
break
;
case
ROUND_TO_MINUS_INFINITY
:
case
ROUND_TO_MINUS_INFINITY
:
float_rounding_mode
=
float_round_down
;
return
float_round_down
;
break
;
case
ROUND_TO_ZERO
:
case
ROUND_TO_ZERO
:
float_rounding_mode
=
float_round_to_zero
;
return
float_round_to_zero
;
break
;
}
}
}
}
void
SetRoundingPrecision
(
const
unsigned
int
opcode
)
int8
SetRoundingPrecision
(
const
unsigned
int
opcode
)
{
{
#ifdef CONFIG_FPE_NWFPE_XP
#ifdef CONFIG_FPE_NWFPE_XP
switch
(
opcode
&
MASK_ROUNDING_PRECISION
)
{
switch
(
opcode
&
MASK_ROUNDING_PRECISION
)
{
case
ROUND_SINGLE
:
case
ROUND_SINGLE
:
floatx80_rounding_precision
=
32
;
return
32
;
break
;
case
ROUND_DOUBLE
:
case
ROUND_DOUBLE
:
floatx80_rounding_precision
=
64
;
return
64
;
break
;
case
ROUND_EXTENDED
:
case
ROUND_EXTENDED
:
floatx80_rounding_precision
=
80
;
return
80
;
break
;
default:
default:
floatx80_rounding_precision
=
80
;
return
80
;
}
}
#endif
#endif
return
80
;
}
}
void
nwfpe_init_fpa
(
union
fp_state
*
fp
)
void
nwfpe_init_fpa
(
union
fp_state
*
fp
)
...
@@ -103,8 +97,6 @@ void nwfpe_init_fpa(union fp_state *fp)
...
@@ -103,8 +97,6 @@ void nwfpe_init_fpa(union fp_state *fp)
#endif
#endif
memset
(
fpa11
,
0
,
sizeof
(
FPA11
));
memset
(
fpa11
,
0
,
sizeof
(
FPA11
));
resetFPA11
();
resetFPA11
();
SetRoundingMode
(
ROUND_TO_NEAREST
);
SetRoundingPrecision
(
ROUND_EXTENDED
);
fpa11
->
initflag
=
1
;
fpa11
->
initflag
=
1
;
}
}
...
...
arch/arm/nwfpe/fpa11.h
View file @
194d0710
...
@@ -37,6 +37,13 @@
...
@@ -37,6 +37,13 @@
/* includes */
/* includes */
#include "fpsr.h"
/* FP control and status register definitions */
#include "fpsr.h"
/* FP control and status register definitions */
#include "milieu.h"
#include "milieu.h"
struct
roundingData
{
int8
mode
;
int8
precision
;
signed
char
exception
;
};
#include "softfloat.h"
#include "softfloat.h"
#define typeNone 0x00
#define typeNone 0x00
...
@@ -84,8 +91,8 @@ typedef struct tagFPA11 {
...
@@ -84,8 +91,8 @@ typedef struct tagFPA11 {
initialised. */
initialised. */
}
FPA11
;
}
FPA11
;
extern
void
SetRoundingMode
(
const
unsigned
int
);
extern
int8
SetRoundingMode
(
const
unsigned
int
);
extern
void
SetRoundingPrecision
(
const
unsigned
int
);
extern
int8
SetRoundingPrecision
(
const
unsigned
int
);
extern
void
nwfpe_init_fpa
(
union
fp_state
*
fp
);
extern
void
nwfpe_init_fpa
(
union
fp_state
*
fp
);
#endif
#endif
arch/arm/nwfpe/fpa11_cpdo.c
View file @
194d0710
...
@@ -24,15 +24,16 @@
...
@@ -24,15 +24,16 @@
#include "fpa11.h"
#include "fpa11.h"
#include "fpopcode.h"
#include "fpopcode.h"
unsigned
int
SingleCPDO
(
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
SingleCPDO
(
struct
roundingData
*
roundData
,
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
DoubleCPDO
(
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
DoubleCPDO
(
struct
roundingData
*
roundData
,
const
unsigned
int
opcode
,
FPREG
*
rFd
);
unsigned
int
ExtendedCPDO
(
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
)
unsigned
int
EmulateCPDO
(
const
unsigned
int
opcode
)
{
{
FPA11
*
fpa11
=
GET_FPA11
();
FPA11
*
fpa11
=
GET_FPA11
();
FPREG
*
rFd
;
FPREG
*
rFd
;
unsigned
int
nType
,
nDest
,
nRc
;
unsigned
int
nType
,
nDest
,
nRc
;
struct
roundingData
roundData
;
/* Get the destination size. If not valid let Linux perform
/* Get the destination size. If not valid let Linux perform
an invalid instruction trap. */
an invalid instruction trap. */
...
@@ -40,7 +41,9 @@ unsigned int EmulateCPDO(const unsigned int opcode)
...
@@ -40,7 +41,9 @@ unsigned int EmulateCPDO(const unsigned int opcode)
if
(
typeNone
==
nDest
)
if
(
typeNone
==
nDest
)
return
0
;
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.
/* Compare the size of the operands in Fn and Fm.
Choose the largest size and perform operations in that size,
Choose the largest size and perform operations in that size,
...
@@ -63,14 +66,14 @@ unsigned int EmulateCPDO(const unsigned int opcode)
...
@@ -63,14 +66,14 @@ unsigned int EmulateCPDO(const unsigned int opcode)
switch
(
nType
)
{
switch
(
nType
)
{
case
typeSingle
:
case
typeSingle
:
nRc
=
SingleCPDO
(
opcode
,
rFd
);
nRc
=
SingleCPDO
(
&
roundData
,
opcode
,
rFd
);
break
;
break
;
case
typeDouble
:
case
typeDouble
:
nRc
=
DoubleCPDO
(
opcode
,
rFd
);
nRc
=
DoubleCPDO
(
&
roundData
,
opcode
,
rFd
);
break
;
break
;
#ifdef CONFIG_FPE_NWFPE_XP
#ifdef CONFIG_FPE_NWFPE_XP
case
typeExtended
:
case
typeExtended
:
nRc
=
ExtendedCPDO
(
opcode
,
rFd
);
nRc
=
ExtendedCPDO
(
&
roundData
,
opcode
,
rFd
);
break
;
break
;
#endif
#endif
default:
default:
...
@@ -93,9 +96,9 @@ unsigned int EmulateCPDO(const unsigned int opcode)
...
@@ -93,9 +96,9 @@ unsigned int EmulateCPDO(const unsigned int opcode)
case
typeSingle
:
case
typeSingle
:
{
{
if
(
typeDouble
==
nType
)
if
(
typeDouble
==
nType
)
rFd
->
fSingle
=
float64_to_float32
(
rFd
->
fDouble
);
rFd
->
fSingle
=
float64_to_float32
(
&
roundData
,
rFd
->
fDouble
);
else
else
rFd
->
fSingle
=
floatx80_to_float32
(
rFd
->
fExtended
);
rFd
->
fSingle
=
floatx80_to_float32
(
&
roundData
,
rFd
->
fExtended
);
}
}
break
;
break
;
...
@@ -104,7 +107,7 @@ unsigned int EmulateCPDO(const unsigned int opcode)
...
@@ -104,7 +107,7 @@ unsigned int EmulateCPDO(const unsigned int opcode)
if
(
typeSingle
==
nType
)
if
(
typeSingle
==
nType
)
rFd
->
fDouble
=
float32_to_float64
(
rFd
->
fSingle
);
rFd
->
fDouble
=
float32_to_float64
(
rFd
->
fSingle
);
else
else
rFd
->
fDouble
=
floatx80_to_float64
(
rFd
->
fExtended
);
rFd
->
fDouble
=
floatx80_to_float64
(
&
roundData
,
rFd
->
fExtended
);
}
}
break
;
break
;
...
@@ -121,12 +124,15 @@ unsigned int EmulateCPDO(const unsigned int opcode)
...
@@ -121,12 +124,15 @@ unsigned int EmulateCPDO(const unsigned int opcode)
#else
#else
if
(
nDest
!=
nType
)
{
if
(
nDest
!=
nType
)
{
if
(
nDest
==
typeSingle
)
if
(
nDest
==
typeSingle
)
rFd
->
fSingle
=
float64_to_float32
(
rFd
->
fDouble
);
rFd
->
fSingle
=
float64_to_float32
(
&
roundData
,
rFd
->
fDouble
);
else
else
rFd
->
fDouble
=
float32_to_float64
(
rFd
->
fSingle
);
rFd
->
fDouble
=
float32_to_float64
(
rFd
->
fSingle
);
}
}
#endif
#endif
}
}
if
(
roundData
.
exception
)
float_raise
(
roundData
.
exception
);
return
nRc
;
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
...
@@ -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
();
FPA11
*
fpa11
=
GET_FPA11
();
union
{
union
{
...
@@ -106,12 +106,12 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
...
@@ -106,12 +106,12 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
switch
(
fpa11
->
fType
[
Fn
])
{
switch
(
fpa11
->
fType
[
Fn
])
{
case
typeDouble
:
case
typeDouble
:
val
.
f
=
float64_to_float32
(
fpa11
->
fpreg
[
Fn
].
fDouble
);
val
.
f
=
float64_to_float32
(
roundData
,
fpa11
->
fpreg
[
Fn
].
fDouble
);
break
;
break
;
#ifdef CONFIG_FPE_NWFPE_XP
#ifdef CONFIG_FPE_NWFPE_XP
case
typeExtended
:
case
typeExtended
:
val
.
f
=
floatx80_to_float32
(
fpa11
->
fpreg
[
Fn
].
fExtended
);
val
.
f
=
floatx80_to_float32
(
roundData
,
fpa11
->
fpreg
[
Fn
].
fExtended
);
break
;
break
;
#endif
#endif
...
@@ -122,7 +122,7 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
...
@@ -122,7 +122,7 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
put_user
(
val
.
i
[
0
],
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
();
FPA11
*
fpa11
=
GET_FPA11
();
union
{
union
{
...
@@ -137,7 +137,7 @@ static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
...
@@ -137,7 +137,7 @@ static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
#ifdef CONFIG_FPE_NWFPE_XP
#ifdef CONFIG_FPE_NWFPE_XP
case
typeExtended
:
case
typeExtended
:
val
.
f
=
floatx80_to_float64
(
fpa11
->
fpreg
[
Fn
].
fExtended
);
val
.
f
=
floatx80_to_float64
(
roundData
,
fpa11
->
fpreg
[
Fn
].
fExtended
);
break
;
break
;
#endif
#endif
...
@@ -259,8 +259,11 @@ unsigned int PerformSTF(const unsigned int opcode)
...
@@ -259,8 +259,11 @@ unsigned int PerformSTF(const unsigned int opcode)
{
{
unsigned
int
__user
*
pBase
,
*
pAddress
,
*
pFinal
;
unsigned
int
__user
*
pBase
,
*
pAddress
,
*
pFinal
;
unsigned
int
nRc
=
1
,
write_back
=
WRITE_BACK
(
opcode
);
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
));
pBase
=
(
unsigned
int
__user
*
)
readRegister
(
getRn
(
opcode
));
if
(
REG_PC
==
getRn
(
opcode
))
{
if
(
REG_PC
==
getRn
(
opcode
))
{
...
@@ -281,10 +284,10 @@ unsigned int PerformSTF(const unsigned int opcode)
...
@@ -281,10 +284,10 @@ unsigned int PerformSTF(const unsigned int opcode)
switch
(
opcode
&
MASK_TRANSFER_LENGTH
)
{
switch
(
opcode
&
MASK_TRANSFER_LENGTH
)
{
case
TRANSFER_SINGLE
:
case
TRANSFER_SINGLE
:
storeSingle
(
getFd
(
opcode
),
pAddress
);
storeSingle
(
&
roundData
,
getFd
(
opcode
),
pAddress
);
break
;
break
;
case
TRANSFER_DOUBLE
:
case
TRANSFER_DOUBLE
:
storeDouble
(
getFd
(
opcode
),
pAddress
);
storeDouble
(
&
roundData
,
getFd
(
opcode
),
pAddress
);
break
;
break
;
#ifdef CONFIG_FPE_NWFPE_XP
#ifdef CONFIG_FPE_NWFPE_XP
case
TRANSFER_EXTENDED
:
case
TRANSFER_EXTENDED
:
...
@@ -295,6 +298,9 @@ unsigned int PerformSTF(const unsigned int opcode)
...
@@ -295,6 +298,9 @@ unsigned int PerformSTF(const unsigned int opcode)
nRc
=
0
;
nRc
=
0
;
}
}
if
(
roundData
.
exception
)
float_raise
(
roundData
.
exception
);
if
(
write_back
)
if
(
write_back
)
writeRegister
(
getRn
(
opcode
),
(
unsigned
long
)
pFinal
);
writeRegister
(
getRn
(
opcode
),
(
unsigned
long
)
pFinal
);
return
nRc
;
return
nRc
;
...
...
arch/arm/nwfpe/fpa11_cprt.c
View file @
194d0710
...
@@ -33,8 +33,6 @@ extern flag floatx80_is_nan(floatx80);
...
@@ -33,8 +33,6 @@ extern flag floatx80_is_nan(floatx80);
extern
flag
float64_is_nan
(
float64
);
extern
flag
float64_is_nan
(
float64
);
extern
flag
float32_is_nan
(
float32
);
extern
flag
float32_is_nan
(
float32
);
void
SetRoundingMode
(
const
unsigned
int
opcode
);
unsigned
int
PerformFLT
(
const
unsigned
int
opcode
);
unsigned
int
PerformFLT
(
const
unsigned
int
opcode
);
unsigned
int
PerformFIX
(
const
unsigned
int
opcode
);
unsigned
int
PerformFIX
(
const
unsigned
int
opcode
);
...
@@ -77,14 +75,17 @@ unsigned int EmulateCPRT(const unsigned int opcode)
...
@@ -77,14 +75,17 @@ unsigned int EmulateCPRT(const unsigned int opcode)
unsigned
int
PerformFLT
(
const
unsigned
int
opcode
)
unsigned
int
PerformFLT
(
const
unsigned
int
opcode
)
{
{
FPA11
*
fpa11
=
GET_FPA11
();
FPA11
*
fpa11
=
GET_FPA11
();
SetRoundingMode
(
opcode
);
struct
roundingData
roundData
;
SetRoundingPrecision
(
opcode
);
roundData
.
mode
=
SetRoundingMode
(
opcode
);
roundData
.
precision
=
SetRoundingPrecision
(
opcode
);
roundData
.
exception
=
0
;
switch
(
opcode
&
MASK_ROUNDING_PRECISION
)
{
switch
(
opcode
&
MASK_ROUNDING_PRECISION
)
{
case
ROUND_SINGLE
:
case
ROUND_SINGLE
:
{
{
fpa11
->
fType
[
getFn
(
opcode
)]
=
typeSingle
;
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
;
break
;
...
@@ -108,6 +109,9 @@ unsigned int PerformFLT(const unsigned int opcode)
...
@@ -108,6 +109,9 @@ unsigned int PerformFLT(const unsigned int opcode)
return
0
;
return
0
;
}
}
if
(
roundData
.
exception
)
float_raise
(
roundData
.
exception
);
return
1
;
return
1
;
}
}
...
@@ -115,26 +119,29 @@ unsigned int PerformFIX(const unsigned int opcode)
...
@@ -115,26 +119,29 @@ unsigned int PerformFIX(const unsigned int opcode)
{
{
FPA11
*
fpa11
=
GET_FPA11
();
FPA11
*
fpa11
=
GET_FPA11
();
unsigned
int
Fn
=
getFm
(
opcode
);
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
])
{
switch
(
fpa11
->
fType
[
Fn
])
{
case
typeSingle
:
case
typeSingle
:
{
{
writeRegister
(
getRd
(
opcode
),
float32_to_int32
(
fpa11
->
fpreg
[
Fn
].
fSingle
));
writeRegister
(
getRd
(
opcode
),
float32_to_int32
(
&
roundData
,
fpa11
->
fpreg
[
Fn
].
fSingle
));
}
}
break
;
break
;
case
typeDouble
:
case
typeDouble
:
{
{
writeRegister
(
getRd
(
opcode
),
float64_to_int32
(
fpa11
->
fpreg
[
Fn
].
fDouble
));
writeRegister
(
getRd
(
opcode
),
float64_to_int32
(
&
roundData
,
fpa11
->
fpreg
[
Fn
].
fDouble
));
}
}
break
;
break
;
#ifdef CONFIG_FPE_NWFPE_XP
#ifdef CONFIG_FPE_NWFPE_XP
case
typeExtended
:
case
typeExtended
:
{
{
writeRegister
(
getRd
(
opcode
),
floatx80_to_int32
(
fpa11
->
fpreg
[
Fn
].
fExtended
));
writeRegister
(
getRd
(
opcode
),
floatx80_to_int32
(
&
roundData
,
fpa11
->
fpreg
[
Fn
].
fExtended
));
}
}
break
;
break
;
#endif
#endif
...
@@ -143,6 +150,9 @@ unsigned int PerformFIX(const unsigned int opcode)
...
@@ -143,6 +150,9 @@ unsigned int PerformFIX(const unsigned int opcode)
return
0
;
return
0
;
}
}
if
(
roundData
.
exception
)
float_raise
(
roundData
.
exception
);
return
1
;
return
1
;
}
}
...
...
arch/arm/nwfpe/fpmodule.c
View file @
194d0710
...
@@ -116,8 +116,6 @@ fpmodule.c to integrate with the NetBSD kernel (I hope!).
...
@@ -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
code to access data in user space in some other source files at the
moment (grep for get_user / put_user calls). --philb]
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
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
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
a SIGFPE exception if necessary. If not the relevant bits in the
...
@@ -129,15 +127,14 @@ void float_raise(signed char flags)
...
@@ -129,15 +127,14 @@ void float_raise(signed char flags)
register
unsigned
int
fpsr
,
cumulativeTraps
;
register
unsigned
int
fpsr
,
cumulativeTraps
;
#ifdef CONFIG_DEBUG_USER
#ifdef CONFIG_DEBUG_USER
printk
(
KERN_DEBUG
/* Ignore inexact errors as there are far too many of them to log */
"NWFPE: %s[%d] takes exception %08x at %p from %08lx
\n
"
,
if
(
flags
&
~
BIT_IXC
)
current
->
comm
,
current
->
pid
,
flags
,
printk
(
KERN_DEBUG
__builtin_return_address
(
0
),
GET_USERREG
()
->
ARM_pc
);
"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
#endif
/* Keep SoftFloat exception flags up to date. */
float_exception_flags
|=
flags
;
/* Read fpsr and initialize the cumulativeTraps. */
/* Read fpsr and initialize the cumulativeTraps. */
fpsr
=
readFPSR
();
fpsr
=
readFPSR
();
cumulativeTraps
=
0
;
cumulativeTraps
=
0
;
...
...
arch/arm/nwfpe/single_cpdo.c
View file @
194d0710
...
@@ -36,17 +36,17 @@ float32 float32_arccos(float32 rFm);
...
@@ -36,17 +36,17 @@ float32 float32_arccos(float32 rFm);
float32
float32_pow
(
float32
rFn
,
float32
rFm
);
float32
float32_pow
(
float32
rFn
,
float32
rFm
);
float32
float32_pol
(
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
,
[
ADF_CODE
>>
20
]
=
float32_add
,
[
MUF_CODE
>>
20
]
=
float32_mul
,
[
MUF_CODE
>>
20
]
=
float32_mul
,
[
SUF_CODE
>>
20
]
=
float32_sub
,
[
SUF_CODE
>>
20
]
=
float32_sub
,
...
@@ -60,22 +60,22 @@ static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
...
@@ -60,22 +60,22 @@ static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
[
FRD_CODE
>>
20
]
=
float32_rdv
,
[
FRD_CODE
>>
20
]
=
float32_rdv
,
};
};
static
float32
float32_mvf
(
float32
rFm
)
static
float32
float32_mvf
(
struct
roundingData
*
roundData
,
float32
rFm
)
{
{
return
rFm
;
return
rFm
;
}
}
static
float32
float32_mnf
(
float32
rFm
)
static
float32
float32_mnf
(
struct
roundingData
*
roundData
,
float32
rFm
)
{
{
return
rFm
^
0x80000000
;
return
rFm
^
0x80000000
;
}
}
static
float32
float32_abs
(
float32
rFm
)
static
float32
float32_abs
(
struct
roundingData
*
roundData
,
float32
rFm
)
{
{
return
rFm
&
0x7fffffff
;
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
,
[
MVF_CODE
>>
20
]
=
float32_mvf
,
[
MNF_CODE
>>
20
]
=
float32_mnf
,
[
MNF_CODE
>>
20
]
=
float32_mnf
,
[
ABS_CODE
>>
20
]
=
float32_abs
,
[
ABS_CODE
>>
20
]
=
float32_abs
,
...
@@ -85,7 +85,7 @@ static float32 (*const monadic_single[16])(float32 rFm) = {
...
@@ -85,7 +85,7 @@ static float32 (*const monadic_single[16])(float32 rFm) = {
[
NRM_CODE
>>
20
]
=
float32_mvf
,
[
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
();
FPA11
*
fpa11
=
GET_FPA11
();
float32
rFm
;
float32
rFm
;
...
@@ -108,13 +108,13 @@ unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
...
@@ -108,13 +108,13 @@ unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
if
(
fpa11
->
fType
[
Fn
]
==
typeSingle
&&
if
(
fpa11
->
fType
[
Fn
]
==
typeSingle
&&
dyadic_single
[
opc_mask_shift
])
{
dyadic_single
[
opc_mask_shift
])
{
rFn
=
fpa11
->
fpreg
[
Fn
].
fSingle
;
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
{
}
else
{
return
0
;
return
0
;
}
}
}
else
{
}
else
{
if
(
monadic_single
[
opc_mask_shift
])
{
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
{
}
else
{
return
0
;
return
0
;
}
}
...
...
arch/arm/nwfpe/softfloat.c
View file @
194d0710
...
@@ -34,16 +34,6 @@ this code that are retained.
...
@@ -34,16 +34,6 @@ this code that are retained.
//#include "milieu.h"
//#include "milieu.h"
//#include "softfloat.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
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
...
@@ -77,14 +67,14 @@ input is too large, however, the invalid exception is raised and the largest
positive or negative integer is returned.
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
;
int8
roundingMode
;
flag
roundNearestEven
;
flag
roundNearestEven
;
int8
roundIncrement
,
roundBits
;
int8
roundIncrement
,
roundBits
;
int32
z
;
int32
z
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundIncrement
=
0x40
;
roundIncrement
=
0x40
;
if
(
!
roundNearestEven
)
{
if
(
!
roundNearestEven
)
{
...
@@ -107,10 +97,10 @@ static int32 roundAndPackInt32( flag zSign, bits64 absZ )
...
@@ -107,10 +97,10 @@ static int32 roundAndPackInt32( flag zSign, bits64 absZ )
z
=
absZ
;
z
=
absZ
;
if
(
zSign
)
z
=
-
z
;
if
(
zSign
)
z
=
-
z
;
if
(
(
absZ
>>
32
)
||
(
z
&&
(
(
z
<
0
)
^
zSign
)
)
)
{
if
(
(
absZ
>>
32
)
||
(
z
&&
(
(
z
<
0
)
^
zSign
)
)
)
{
float_exception_flags
|=
float_flag_invalid
;
roundData
->
exception
|=
float_flag_invalid
;
return
zSign
?
0x80000000
:
0x7FFFFFFF
;
return
zSign
?
0x80000000
:
0x7FFFFFFF
;
}
}
if
(
roundBits
)
float_exception_flags
|=
float_flag_inexact
;
if
(
roundBits
)
roundData
->
exception
|=
float_flag_inexact
;
return
z
;
return
z
;
}
}
...
@@ -224,14 +214,14 @@ The handling of underflow and overflow follows the IEC/IEEE Standard for
...
@@ -224,14 +214,14 @@ The handling of underflow and overflow follows the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
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
;
int8
roundingMode
;
flag
roundNearestEven
;
flag
roundNearestEven
;
int8
roundIncrement
,
roundBits
;
int8
roundIncrement
,
roundBits
;
flag
isTiny
;
flag
isTiny
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundIncrement
=
0x40
;
roundIncrement
=
0x40
;
if
(
!
roundNearestEven
)
{
if
(
!
roundNearestEven
)
{
...
@@ -254,7 +244,7 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
...
@@ -254,7 +244,7 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
||
(
(
zExp
==
0xFD
)
||
(
(
zExp
==
0xFD
)
&&
(
(
sbits32
)
(
zSig
+
roundIncrement
)
<
0
)
)
&&
(
(
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
);
return
packFloat32
(
zSign
,
0xFF
,
0
)
-
(
roundIncrement
==
0
);
}
}
if
(
zExp
<
0
)
{
if
(
zExp
<
0
)
{
...
@@ -265,10 +255,10 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
...
@@ -265,10 +255,10 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
shift32RightJamming
(
zSig
,
-
zExp
,
&
zSig
);
shift32RightJamming
(
zSig
,
-
zExp
,
&
zSig
);
zExp
=
0
;
zExp
=
0
;
roundBits
=
zSig
&
0x7F
;
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
=
(
zSig
+
roundIncrement
)
>>
7
;
zSig
&=
~
(
(
(
roundBits
^
0x40
)
==
0
)
&
roundNearestEven
);
zSig
&=
~
(
(
(
roundBits
^
0x40
)
==
0
)
&
roundNearestEven
);
if
(
zSig
==
0
)
zExp
=
0
;
if
(
zSig
==
0
)
zExp
=
0
;
...
@@ -287,12 +277,12 @@ point exponent.
...
@@ -287,12 +277,12 @@ point exponent.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
static
float32
static
float32
normalizeRoundAndPackFloat32
(
flag
zSign
,
int16
zExp
,
bits32
zSig
)
normalizeRoundAndPackFloat32
(
struct
roundingData
*
roundData
,
flag
zSign
,
int16
zExp
,
bits32
zSig
)
{
{
int8
shiftCount
;
int8
shiftCount
;
shiftCount
=
countLeadingZeros32
(
zSig
)
-
1
;
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
...
@@ -395,14 +385,14 @@ The handling of underflow and overflow follows the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
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
;
int8
roundingMode
;
flag
roundNearestEven
;
flag
roundNearestEven
;
int16
roundIncrement
,
roundBits
;
int16
roundIncrement
,
roundBits
;
flag
isTiny
;
flag
isTiny
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundIncrement
=
0x200
;
roundIncrement
=
0x200
;
if
(
!
roundNearestEven
)
{
if
(
!
roundNearestEven
)
{
...
@@ -427,7 +417,7 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
...
@@ -427,7 +417,7 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
)
{
)
{
//register int lr = __builtin_return_address(0);
//register int lr = __builtin_return_address(0);
//printk("roundAndPackFloat64 called from 0x%08x\n",lr);
//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
);
return
packFloat64
(
zSign
,
0x7FF
,
0
)
-
(
roundIncrement
==
0
);
}
}
if
(
zExp
<
0
)
{
if
(
zExp
<
0
)
{
...
@@ -438,10 +428,10 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
...
@@ -438,10 +428,10 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
shift64RightJamming
(
zSig
,
-
zExp
,
&
zSig
);
shift64RightJamming
(
zSig
,
-
zExp
,
&
zSig
);
zExp
=
0
;
zExp
=
0
;
roundBits
=
zSig
&
0x3FF
;
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
=
(
zSig
+
roundIncrement
)
>>
10
;
zSig
&=
~
(
(
(
roundBits
^
0x200
)
==
0
)
&
roundNearestEven
);
zSig
&=
~
(
(
(
roundBits
^
0x200
)
==
0
)
&
roundNearestEven
);
if
(
zSig
==
0
)
zExp
=
0
;
if
(
zSig
==
0
)
zExp
=
0
;
...
@@ -460,12 +450,12 @@ point exponent.
...
@@ -460,12 +450,12 @@ point exponent.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
static
float64
static
float64
normalizeRoundAndPackFloat64
(
flag
zSign
,
int16
zExp
,
bits64
zSig
)
normalizeRoundAndPackFloat64
(
struct
roundingData
*
roundData
,
flag
zSign
,
int16
zExp
,
bits64
zSig
)
{
{
int8
shiftCount
;
int8
shiftCount
;
shiftCount
=
countLeadingZeros64
(
zSig
)
-
1
;
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.
...
@@ -572,14 +562,15 @@ Floating-point Arithmetic.
*/
*/
static
floatx80
static
floatx80
roundAndPackFloatx80
(
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
;
flag
roundNearestEven
,
increment
,
isTiny
;
int64
roundIncrement
,
roundMask
,
roundBits
;
int64
roundIncrement
,
roundMask
,
roundBits
;
roundingMode
=
float_rounding_mode
;
roundingMode
=
roundData
->
mode
;
roundingPrecision
=
roundData
->
precision
;
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
roundNearestEven
=
(
roundingMode
==
float_round_nearest_even
);
if
(
roundingPrecision
==
80
)
goto
precision80
;
if
(
roundingPrecision
==
80
)
goto
precision80
;
if
(
roundingPrecision
==
64
)
{
if
(
roundingPrecision
==
64
)
{
...
@@ -623,8 +614,8 @@ static floatx80
...
@@ -623,8 +614,8 @@ static floatx80
shift64RightJamming
(
zSig0
,
1
-
zExp
,
&
zSig0
);
shift64RightJamming
(
zSig0
,
1
-
zExp
,
&
zSig0
);
zExp
=
0
;
zExp
=
0
;
roundBits
=
zSig0
&
roundMask
;
roundBits
=
zSig0
&
roundMask
;
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
;
zSig0
+=
roundIncrement
;
zSig0
+=
roundIncrement
;
if
(
(
sbits64
)
zSig0
<
0
)
zExp
=
1
;
if
(
(
sbits64
)
zSig0
<
0
)
zExp
=
1
;
roundIncrement
=
roundMask
+
1
;
roundIncrement
=
roundMask
+
1
;
...
@@ -635,7 +626,7 @@ static floatx80
...
@@ -635,7 +626,7 @@ static floatx80
return
packFloatx80
(
zSign
,
zExp
,
zSig0
);
return
packFloatx80
(
zSign
,
zExp
,
zSig0
);
}
}
}
}
if
(
roundBits
)
float_exception_flags
|=
float_flag_inexact
;
if
(
roundBits
)
roundData
->
exception
|=
float_flag_inexact
;
zSig0
+=
roundIncrement
;
zSig0
+=
roundIncrement
;
if
(
zSig0
<
roundIncrement
)
{
if
(
zSig0
<
roundIncrement
)
{
++
zExp
;
++
zExp
;
...
@@ -672,7 +663,7 @@ static floatx80
...
@@ -672,7 +663,7 @@ static floatx80
)
{
)
{
roundMask
=
0
;
roundMask
=
0
;
overflow:
overflow:
float_raise
(
float_flag_overflow
|
float_flag_inexact
)
;
roundData
->
exception
|=
float_flag_overflow
|
float_flag_inexact
;
if
(
(
roundingMode
==
float_round_to_zero
)
if
(
(
roundingMode
==
float_round_to_zero
)
||
(
zSign
&&
(
roundingMode
==
float_round_up
)
)
||
(
zSign
&&
(
roundingMode
==
float_round_up
)
)
||
(
!
zSign
&&
(
roundingMode
==
float_round_down
)
)
||
(
!
zSign
&&
(
roundingMode
==
float_round_down
)
)
...
@@ -689,8 +680,8 @@ static floatx80
...
@@ -689,8 +680,8 @@ static floatx80
||
(
zSig0
<
LIT64
(
0xFFFFFFFFFFFFFFFF
)
);
||
(
zSig0
<
LIT64
(
0xFFFFFFFFFFFFFFFF
)
);
shift64ExtraRightJamming
(
zSig0
,
zSig1
,
1
-
zExp
,
&
zSig0
,
&
zSig1
);
shift64ExtraRightJamming
(
zSig0
,
zSig1
,
1
-
zExp
,
&
zSig0
,
&
zSig1
);
zExp
=
0
;
zExp
=
0
;
if
(
isTiny
&&
zSig1
)
float_raise
(
float_flag_underflow
)
;
if
(
isTiny
&&
zSig1
)
roundData
->
exception
|=
float_flag_underflow
;
if
(
zSig1
)
float_exception_flags
|=
float_flag_inexact
;
if
(
zSig1
)
roundData
->
exception
|=
float_flag_inexact
;
if
(
roundNearestEven
)
{
if
(
roundNearestEven
)
{
increment
=
(
(
sbits64
)
zSig1
<
0
);
increment
=
(
(
sbits64
)
zSig1
<
0
);
}
}
...
@@ -710,7 +701,7 @@ static floatx80
...
@@ -710,7 +701,7 @@ static floatx80
return
packFloatx80
(
zSign
,
zExp
,
zSig0
);
return
packFloatx80
(
zSign
,
zExp
,
zSig0
);
}
}
}
}
if
(
zSig1
)
float_exception_flags
|=
float_flag_inexact
;
if
(
zSig1
)
roundData
->
exception
|=
float_flag_inexact
;
if
(
increment
)
{
if
(
increment
)
{
++
zSig0
;
++
zSig0
;
if
(
zSig0
==
0
)
{
if
(
zSig0
==
0
)
{
...
@@ -740,7 +731,7 @@ normalized.
...
@@ -740,7 +731,7 @@ normalized.
*/
*/
static
floatx80
static
floatx80
normalizeRoundAndPackFloatx80
(
normalizeRoundAndPackFloatx80
(
int8
roundingPrecision
,
flag
zSign
,
int32
zExp
,
bits64
zSig0
,
bits64
zSig1
struct
roundingData
*
roundData
,
flag
zSign
,
int32
zExp
,
bits64
zSig0
,
bits64
zSig1
)
)
{
{
int8
shiftCount
;
int8
shiftCount
;
...
@@ -754,7 +745,7 @@ static floatx80
...
@@ -754,7 +745,7 @@ static floatx80
shortShift128Left
(
zSig0
,
zSig1
,
shiftCount
,
&
zSig0
,
&
zSig1
);
shortShift128Left
(
zSig0
,
zSig1
,
shiftCount
,
&
zSig0
,
&
zSig1
);
zExp
-=
shiftCount
;
zExp
-=
shiftCount
;
return
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
...
@@ -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.
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
;
flag
zSign
;
if
(
a
==
0
)
return
0
;
if
(
a
==
0
)
return
0
;
if
(
a
==
0x80000000
)
return
packFloat32
(
1
,
0x9E
,
0
);
if
(
a
==
0x80000000
)
return
packFloat32
(
1
,
0x9E
,
0
);
zSign
=
(
a
<
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
...
@@ -840,7 +831,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the
largest integer with the same sign as `a' is returned.
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
;
flag
aSign
;
int16
aExp
,
shiftCount
;
int16
aExp
,
shiftCount
;
...
@@ -856,7 +847,7 @@ int32 float32_to_int32( float32 a )
...
@@ -856,7 +847,7 @@ int32 float32_to_int32( float32 a )
zSig
=
aSig
;
zSig
=
aSig
;
zSig
<<=
32
;
zSig
<<=
32
;
if
(
0
<
shiftCount
)
shift64RightJamming
(
zSig
,
shiftCount
,
&
zSig
);
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 )
...
@@ -889,13 +880,13 @@ int32 float32_to_int32_round_to_zero( float32 a )
return
0x80000000
;
return
0x80000000
;
}
}
else
if
(
aExp
<=
0x7E
)
{
else
if
(
aExp
<=
0x7E
)
{
if
(
aExp
|
aSig
)
float_
exception_flags
|=
float_flag_inexact
;
if
(
aExp
|
aSig
)
float_
raise
(
float_flag_inexact
)
;
return
0
;
return
0
;
}
}
aSig
=
(
aSig
|
0x00800000
)
<<
8
;
aSig
=
(
aSig
|
0x00800000
)
<<
8
;
z
=
aSig
>>
(
-
shiftCount
);
z
=
aSig
>>
(
-
shiftCount
);
if
(
(
bits32
)
(
aSig
<<
(
shiftCount
&
31
)
)
)
{
if
(
(
bits32
)
(
aSig
<<
(
shiftCount
&
31
)
)
)
{
float_
exception_flags
|=
float_flag_inexact
;
float_
raise
(
float_flag_inexact
)
;
}
}
return
aSign
?
-
z
:
z
;
return
aSign
?
-
z
:
z
;
...
@@ -973,7 +964,7 @@ operation is performed according to the IEC/IEEE Standard for Binary
...
@@ -973,7 +964,7 @@ operation is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float32
float32_round_to_int
(
float32
a
)
float32
float32_round_to_int
(
struct
roundingData
*
roundData
,
float32
a
)
{
{
flag
aSign
;
flag
aSign
;
int16
aExp
;
int16
aExp
;
...
@@ -988,11 +979,12 @@ float32 float32_round_to_int( float32 a )
...
@@ -988,11 +979,12 @@ float32 float32_round_to_int( float32 a )
}
}
return
a
;
return
a
;
}
}
roundingMode
=
roundData
->
mode
;
if
(
aExp
<=
0x7E
)
{
if
(
aExp
<=
0x7E
)
{
if
(
(
bits32
)
(
a
<<
1
)
==
0
)
return
a
;
if
(
(
bits32
)
(
a
<<
1
)
==
0
)
return
a
;
float_exception_flags
|=
float_flag_inexact
;
roundData
->
exception
|=
float_flag_inexact
;
aSign
=
extractFloat32Sign
(
a
);
aSign
=
extractFloat32Sign
(
a
);
switch
(
float_rounding_m
ode
)
{
switch
(
roundingM
ode
)
{
case
float_round_nearest_even
:
case
float_round_nearest_even
:
if
(
(
aExp
==
0x7E
)
&&
extractFloat32Frac
(
a
)
)
{
if
(
(
aExp
==
0x7E
)
&&
extractFloat32Frac
(
a
)
)
{
return
packFloat32
(
aSign
,
0x7F
,
0
);
return
packFloat32
(
aSign
,
0x7F
,
0
);
...
@@ -1009,7 +1001,6 @@ float32 float32_round_to_int( float32 a )
...
@@ -1009,7 +1001,6 @@ float32 float32_round_to_int( float32 a )
lastBitMask
<<=
0x96
-
aExp
;
lastBitMask
<<=
0x96
-
aExp
;
roundBitsMask
=
lastBitMask
-
1
;
roundBitsMask
=
lastBitMask
-
1
;
z
=
a
;
z
=
a
;
roundingMode
=
float_rounding_mode
;
if
(
roundingMode
==
float_round_nearest_even
)
{
if
(
roundingMode
==
float_round_nearest_even
)
{
z
+=
lastBitMask
>>
1
;
z
+=
lastBitMask
>>
1
;
if
(
(
z
&
roundBitsMask
)
==
0
)
z
&=
~
lastBitMask
;
if
(
(
z
&
roundBitsMask
)
==
0
)
z
&=
~
lastBitMask
;
...
@@ -1020,7 +1011,7 @@ float32 float32_round_to_int( float32 a )
...
@@ -1020,7 +1011,7 @@ float32 float32_round_to_int( float32 a )
}
}
}
}
z
&=
~
roundBitsMask
;
z
&=
~
roundBitsMask
;
if
(
z
!=
a
)
float_exception_flags
|=
float_flag_inexact
;
if
(
z
!=
a
)
roundData
->
exception
|=
float_flag_inexact
;
return
z
;
return
z
;
}
}
...
@@ -1034,7 +1025,7 @@ addition is performed according to the IEC/IEEE Standard for Binary
...
@@ -1034,7 +1025,7 @@ addition is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
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
;
int16
aExp
,
bExp
,
zExp
;
bits32
aSig
,
bSig
,
zSig
;
bits32
aSig
,
bSig
,
zSig
;
...
@@ -1093,7 +1084,7 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
...
@@ -1093,7 +1084,7 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
++
zExp
;
++
zExp
;
}
}
roundAndPack:
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
...
@@ -1106,7 +1097,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE
Standard for Binary Floating-point Arithmetic.
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
;
int16
aExp
,
bExp
,
zExp
;
bits32
aSig
,
bSig
,
zSig
;
bits32
aSig
,
bSig
,
zSig
;
...
@@ -1123,7 +1114,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
...
@@ -1123,7 +1114,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
if
(
expDiff
<
0
)
goto
bExpBigger
;
if
(
expDiff
<
0
)
goto
bExpBigger
;
if
(
aExp
==
0xFF
)
{
if
(
aExp
==
0xFF
)
{
if
(
aSig
|
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
aSig
|
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
if
(
aExp
==
0
)
{
if
(
aExp
==
0
)
{
...
@@ -1132,7 +1123,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
...
@@ -1132,7 +1123,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
}
}
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
aSig
<
bSig
)
goto
bBigger
;
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:
bExpBigger:
if
(
bExp
==
0xFF
)
{
if
(
bExp
==
0xFF
)
{
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
...
@@ -1169,7 +1160,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
...
@@ -1169,7 +1160,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
zExp
=
aExp
;
zExp
=
aExp
;
normalizeRoundAndPack:
normalizeRoundAndPack:
--
zExp
;
--
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
...
@@ -1180,17 +1171,17 @@ and `b'. The operation is performed according to the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float32
float32_add
(
float32
a
,
float32
b
)
float32
float32_add
(
struct
roundingData
*
roundData
,
float32
a
,
float32
b
)
{
{
flag
aSign
,
bSign
;
flag
aSign
,
bSign
;
aSign
=
extractFloat32Sign
(
a
);
aSign
=
extractFloat32Sign
(
a
);
bSign
=
extractFloat32Sign
(
b
);
bSign
=
extractFloat32Sign
(
b
);
if
(
aSign
==
bSign
)
{
if
(
aSign
==
bSign
)
{
return
addFloat32Sigs
(
a
,
b
,
aSign
);
return
addFloat32Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
else
{
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
...
@@ -1202,17 +1193,17 @@ Returns the result of subtracting the single-precision floating-point values
for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
;
aSign
=
extractFloat32Sign
(
a
);
aSign
=
extractFloat32Sign
(
a
);
bSign
=
extractFloat32Sign
(
b
);
bSign
=
extractFloat32Sign
(
b
);
if
(
aSign
==
bSign
)
{
if
(
aSign
==
bSign
)
{
return
subFloat32Sigs
(
a
,
b
,
aSign
);
return
subFloat32Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
else
{
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
...
@@ -1224,7 +1215,7 @@ Returns the result of multiplying the single-precision floating-point values
for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
zExp
;
int16
aExp
,
bExp
,
zExp
;
...
@@ -1244,7 +1235,7 @@ float32 float32_mul( float32 a, float32 b )
...
@@ -1244,7 +1235,7 @@ float32 float32_mul( float32 a, float32 b )
return
propagateFloat32NaN
(
a
,
b
);
return
propagateFloat32NaN
(
a
,
b
);
}
}
if
(
(
bExp
|
bSig
)
==
0
)
{
if
(
(
bExp
|
bSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
return
packFloat32
(
zSign
,
0xFF
,
0
);
return
packFloat32
(
zSign
,
0xFF
,
0
);
...
@@ -1252,7 +1243,7 @@ float32 float32_mul( float32 a, float32 b )
...
@@ -1252,7 +1243,7 @@ float32 float32_mul( float32 a, float32 b )
if
(
bExp
==
0xFF
)
{
if
(
bExp
==
0xFF
)
{
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
(
aExp
|
aSig
)
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
return
packFloat32
(
zSign
,
0xFF
,
0
);
return
packFloat32
(
zSign
,
0xFF
,
0
);
...
@@ -1274,7 +1265,7 @@ float32 float32_mul( float32 a, float32 b )
...
@@ -1274,7 +1265,7 @@ float32 float32_mul( float32 a, float32 b )
zSig
<<=
1
;
zSig
<<=
1
;
--
zExp
;
--
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
...
@@ -1285,7 +1276,7 @@ by the corresponding value `b'. The operation is performed according to the
IEC/IEEE Standard for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
zExp
;
int16
aExp
,
bExp
,
zExp
;
...
@@ -1302,7 +1293,7 @@ float32 float32_div( float32 a, float32 b )
...
@@ -1302,7 +1293,7 @@ float32 float32_div( float32 a, float32 b )
if
(
aSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
aSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
bExp
==
0xFF
)
{
if
(
bExp
==
0xFF
)
{
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
if
(
bSig
)
return
propagateFloat32NaN
(
a
,
b
);
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
return
packFloat32
(
zSign
,
0xFF
,
0
);
return
packFloat32
(
zSign
,
0xFF
,
0
);
...
@@ -1314,10 +1305,10 @@ float32 float32_div( float32 a, float32 b )
...
@@ -1314,10 +1305,10 @@ float32 float32_div( float32 a, float32 b )
if
(
bExp
==
0
)
{
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
if
(
bSig
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
float_raise
(
float_flag_divbyzero
)
;
roundData
->
exception
|=
float_flag_divbyzero
;
return
packFloat32
(
zSign
,
0xFF
,
0
);
return
packFloat32
(
zSign
,
0xFF
,
0
);
}
}
normalizeFloat32Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
normalizeFloat32Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
@@ -1341,7 +1332,7 @@ float32 float32_div( float32 a, float32 b )
...
@@ -1341,7 +1332,7 @@ float32 float32_div( float32 a, float32 b )
if
(
(
zSig
&
0x3F
)
==
0
)
{
if
(
(
zSig
&
0x3F
)
==
0
)
{
zSig
|=
(
(
(
bits64
)
bSig
)
*
zSig
!=
(
(
bits64
)
aSig
)
<<
32
);
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
...
@@ -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.
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
;
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
expDiff
;
int16
aExp
,
bExp
,
expDiff
;
...
@@ -1372,7 +1363,7 @@ float32 float32_rem( float32 a, float32 b )
...
@@ -1372,7 +1363,7 @@ float32 float32_rem( float32 a, float32 b )
if
(
aSig
||
(
(
bExp
==
0xFF
)
&&
bSig
)
)
{
if
(
aSig
||
(
(
bExp
==
0xFF
)
&&
bSig
)
)
{
return
propagateFloat32NaN
(
a
,
b
);
return
propagateFloat32NaN
(
a
,
b
);
}
}
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
if
(
bExp
==
0xFF
)
{
if
(
bExp
==
0xFF
)
{
...
@@ -1381,7 +1372,7 @@ float32 float32_rem( float32 a, float32 b )
...
@@ -1381,7 +1372,7 @@ float32 float32_rem( float32 a, float32 b )
}
}
if
(
bExp
==
0
)
{
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
if
(
bSig
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
normalizeFloat32Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
normalizeFloat32Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
@@ -1444,7 +1435,7 @@ float32 float32_rem( float32 a, float32 b )
...
@@ -1444,7 +1435,7 @@ float32 float32_rem( float32 a, float32 b )
}
}
zSign
=
(
(
sbits32
)
aSig
<
0
);
zSign
=
(
(
sbits32
)
aSig
<
0
);
if
(
zSign
)
aSig
=
-
aSig
;
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
...
@@ -1455,7 +1446,7 @@ The operation is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float32
float32_sqrt
(
float32
a
)
float32
float32_sqrt
(
struct
roundingData
*
roundData
,
float32
a
)
{
{
flag
aSign
;
flag
aSign
;
int16
aExp
,
zExp
;
int16
aExp
,
zExp
;
...
@@ -1468,12 +1459,12 @@ float32 float32_sqrt( float32 a )
...
@@ -1468,12 +1459,12 @@ float32 float32_sqrt( float32 a )
if
(
aExp
==
0xFF
)
{
if
(
aExp
==
0xFF
)
{
if
(
aSig
)
return
propagateFloat32NaN
(
a
,
0
);
if
(
aSig
)
return
propagateFloat32NaN
(
a
,
0
);
if
(
!
aSign
)
return
a
;
if
(
!
aSign
)
return
a
;
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
if
(
aSign
)
{
if
(
aSign
)
{
if
(
(
aExp
|
aSig
)
==
0
)
return
a
;
if
(
(
aExp
|
aSig
)
==
0
)
return
a
;
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float32_default_nan
;
return
float32_default_nan
;
}
}
if
(
aExp
==
0
)
{
if
(
aExp
==
0
)
{
...
@@ -1499,7 +1490,7 @@ float32 float32_sqrt( float32 a )
...
@@ -1499,7 +1490,7 @@ float32 float32_sqrt( float32 a )
}
}
}
}
shift32RightJamming
(
zSig
,
1
,
&
zSig
);
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
...
@@ -1661,7 +1652,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the
largest integer with the same sign as `a' is returned.
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
;
flag
aSign
;
int16
aExp
,
shiftCount
;
int16
aExp
,
shiftCount
;
...
@@ -1674,7 +1665,7 @@ int32 float64_to_int32( float64 a )
...
@@ -1674,7 +1665,7 @@ int32 float64_to_int32( float64 a )
if
(
aExp
)
aSig
|=
LIT64
(
0x0010000000000000
);
if
(
aExp
)
aSig
|=
LIT64
(
0x0010000000000000
);
shiftCount
=
0x42C
-
aExp
;
shiftCount
=
0x42C
-
aExp
;
if
(
0
<
shiftCount
)
shift64RightJamming
(
aSig
,
shiftCount
,
&
aSig
);
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 )
...
@@ -1705,7 +1696,7 @@ int32 float64_to_int32_round_to_zero( float64 a )
goto
invalid
;
goto
invalid
;
}
}
else
if
(
52
<
shiftCount
)
{
else
if
(
52
<
shiftCount
)
{
if
(
aExp
||
aSig
)
float_
exception_flags
|=
float_flag_inexact
;
if
(
aExp
||
aSig
)
float_
raise
(
float_flag_inexact
)
;
return
0
;
return
0
;
}
}
aSig
|=
LIT64
(
0x0010000000000000
);
aSig
|=
LIT64
(
0x0010000000000000
);
...
@@ -1715,11 +1706,11 @@ int32 float64_to_int32_round_to_zero( float64 a )
...
@@ -1715,11 +1706,11 @@ int32 float64_to_int32_round_to_zero( float64 a )
if
(
aSign
)
z
=
-
z
;
if
(
aSign
)
z
=
-
z
;
if
(
(
z
<
0
)
^
aSign
)
{
if
(
(
z
<
0
)
^
aSign
)
{
invalid:
invalid:
float_
exception_flags
|=
float_flag_invalid
;
float_
raise
(
float_flag_invalid
)
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
}
}
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
float_
exception_flags
|=
float_flag_inexact
;
float_
raise
(
float_flag_inexact
)
;
}
}
return
z
;
return
z
;
...
@@ -1736,7 +1727,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the
...
@@ -1736,7 +1727,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the
largest positive integer is returned.
largest positive integer is returned.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
int32
float64_to_uint32
(
float64
a
)
int32
float64_to_uint32
(
struct
roundingData
*
roundData
,
float64
a
)
{
{
flag
aSign
;
flag
aSign
;
int16
aExp
,
shiftCount
;
int16
aExp
,
shiftCount
;
...
@@ -1749,7 +1740,7 @@ int32 float64_to_uint32( float64 a )
...
@@ -1749,7 +1740,7 @@ int32 float64_to_uint32( float64 a )
if
(
aExp
)
aSig
|=
LIT64
(
0x0010000000000000
);
if
(
aExp
)
aSig
|=
LIT64
(
0x0010000000000000
);
shiftCount
=
0x42C
-
aExp
;
shiftCount
=
0x42C
-
aExp
;
if
(
0
<
shiftCount
)
shift64RightJamming
(
aSig
,
shiftCount
,
&
aSig
);
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 )
...
@@ -1778,7 +1769,7 @@ int32 float64_to_uint32_round_to_zero( float64 a )
goto
invalid
;
goto
invalid
;
}
}
else
if
(
52
<
shiftCount
)
{
else
if
(
52
<
shiftCount
)
{
if
(
aExp
||
aSig
)
float_
exception_flags
|=
float_flag_inexact
;
if
(
aExp
||
aSig
)
float_
raise
(
float_flag_inexact
)
;
return
0
;
return
0
;
}
}
aSig
|=
LIT64
(
0x0010000000000000
);
aSig
|=
LIT64
(
0x0010000000000000
);
...
@@ -1788,11 +1779,11 @@ int32 float64_to_uint32_round_to_zero( float64 a )
...
@@ -1788,11 +1779,11 @@ int32 float64_to_uint32_round_to_zero( float64 a )
if
(
aSign
)
z
=
-
z
;
if
(
aSign
)
z
=
-
z
;
if
(
(
z
<
0
)
^
aSign
)
{
if
(
(
z
<
0
)
^
aSign
)
{
invalid:
invalid:
float_
exception_flags
|=
float_flag_invalid
;
float_
raise
(
float_flag_invalid
)
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
}
}
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
float_
exception_flags
|=
float_flag_inexact
;
float_
raise
(
float_flag_inexact
)
;
}
}
return
z
;
return
z
;
}
}
...
@@ -1805,7 +1796,7 @@ performed according to the IEC/IEEE Standard for Binary Floating-point
...
@@ -1805,7 +1796,7 @@ performed according to the IEC/IEEE Standard for Binary Floating-point
Arithmetic.
Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float32
float64_to_float32
(
float64
a
)
float32
float64_to_float32
(
struct
roundingData
*
roundData
,
float64
a
)
{
{
flag
aSign
;
flag
aSign
;
int16
aExp
;
int16
aExp
;
...
@@ -1825,7 +1816,7 @@ float32 float64_to_float32( float64 a )
...
@@ -1825,7 +1816,7 @@ float32 float64_to_float32( float64 a )
zSig
|=
0x40000000
;
zSig
|=
0x40000000
;
aExp
-=
0x381
;
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
...
@@ -1872,7 +1863,7 @@ operation is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float64
float64_round_to_int
(
float64
a
)
float64
float64_round_to_int
(
struct
roundingData
*
roundData
,
float64
a
)
{
{
flag
aSign
;
flag
aSign
;
int16
aExp
;
int16
aExp
;
...
@@ -1889,9 +1880,9 @@ float64 float64_round_to_int( float64 a )
...
@@ -1889,9 +1880,9 @@ float64 float64_round_to_int( float64 a )
}
}
if
(
aExp
<=
0x3FE
)
{
if
(
aExp
<=
0x3FE
)
{
if
(
(
bits64
)
(
a
<<
1
)
==
0
)
return
a
;
if
(
(
bits64
)
(
a
<<
1
)
==
0
)
return
a
;
float_exception_flags
|=
float_flag_inexact
;
roundData
->
exception
|=
float_flag_inexact
;
aSign
=
extractFloat64Sign
(
a
);
aSign
=
extractFloat64Sign
(
a
);
switch
(
float_rounding_
mode
)
{
switch
(
roundData
->
mode
)
{
case
float_round_nearest_even
:
case
float_round_nearest_even
:
if
(
(
aExp
==
0x3FE
)
&&
extractFloat64Frac
(
a
)
)
{
if
(
(
aExp
==
0x3FE
)
&&
extractFloat64Frac
(
a
)
)
{
return
packFloat64
(
aSign
,
0x3FF
,
0
);
return
packFloat64
(
aSign
,
0x3FF
,
0
);
...
@@ -1909,7 +1900,7 @@ float64 float64_round_to_int( float64 a )
...
@@ -1909,7 +1900,7 @@ float64 float64_round_to_int( float64 a )
lastBitMask
<<=
0x433
-
aExp
;
lastBitMask
<<=
0x433
-
aExp
;
roundBitsMask
=
lastBitMask
-
1
;
roundBitsMask
=
lastBitMask
-
1
;
z
=
a
;
z
=
a
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
if
(
roundingMode
==
float_round_nearest_even
)
{
if
(
roundingMode
==
float_round_nearest_even
)
{
z
+=
lastBitMask
>>
1
;
z
+=
lastBitMask
>>
1
;
if
(
(
z
&
roundBitsMask
)
==
0
)
z
&=
~
lastBitMask
;
if
(
(
z
&
roundBitsMask
)
==
0
)
z
&=
~
lastBitMask
;
...
@@ -1920,7 +1911,7 @@ float64 float64_round_to_int( float64 a )
...
@@ -1920,7 +1911,7 @@ float64 float64_round_to_int( float64 a )
}
}
}
}
z
&=
~
roundBitsMask
;
z
&=
~
roundBitsMask
;
if
(
z
!=
a
)
float_exception_flags
|=
float_flag_inexact
;
if
(
z
!=
a
)
roundData
->
exception
|=
float_flag_inexact
;
return
z
;
return
z
;
}
}
...
@@ -1934,7 +1925,7 @@ addition is performed according to the IEC/IEEE Standard for Binary
...
@@ -1934,7 +1925,7 @@ addition is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
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
;
int16
aExp
,
bExp
,
zExp
;
bits64
aSig
,
bSig
,
zSig
;
bits64
aSig
,
bSig
,
zSig
;
...
@@ -1993,7 +1984,7 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
...
@@ -1993,7 +1984,7 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
++
zExp
;
++
zExp
;
}
}
roundAndPack:
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
...
@@ -2006,7 +1997,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE
Standard for Binary Floating-point Arithmetic.
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
;
int16
aExp
,
bExp
,
zExp
;
bits64
aSig
,
bSig
,
zSig
;
bits64
aSig
,
bSig
,
zSig
;
...
@@ -2023,7 +2014,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
...
@@ -2023,7 +2014,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
if
(
expDiff
<
0
)
goto
bExpBigger
;
if
(
expDiff
<
0
)
goto
bExpBigger
;
if
(
aExp
==
0x7FF
)
{
if
(
aExp
==
0x7FF
)
{
if
(
aSig
|
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
aSig
|
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
if
(
aExp
==
0
)
{
if
(
aExp
==
0
)
{
...
@@ -2032,7 +2023,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
...
@@ -2032,7 +2023,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
}
}
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
aSig
<
bSig
)
goto
bBigger
;
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:
bExpBigger:
if
(
bExp
==
0x7FF
)
{
if
(
bExp
==
0x7FF
)
{
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
...
@@ -2069,7 +2060,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
...
@@ -2069,7 +2060,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
zExp
=
aExp
;
zExp
=
aExp
;
normalizeRoundAndPack:
normalizeRoundAndPack:
--
zExp
;
--
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
...
@@ -2080,17 +2071,17 @@ and `b'. The operation is performed according to the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float64
float64_add
(
float64
a
,
float64
b
)
float64
float64_add
(
struct
roundingData
*
roundData
,
float64
a
,
float64
b
)
{
{
flag
aSign
,
bSign
;
flag
aSign
,
bSign
;
aSign
=
extractFloat64Sign
(
a
);
aSign
=
extractFloat64Sign
(
a
);
bSign
=
extractFloat64Sign
(
b
);
bSign
=
extractFloat64Sign
(
b
);
if
(
aSign
==
bSign
)
{
if
(
aSign
==
bSign
)
{
return
addFloat64Sigs
(
a
,
b
,
aSign
);
return
addFloat64Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
else
{
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
...
@@ -2102,17 +2093,17 @@ Returns the result of subtracting the double-precision floating-point values
for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
;
aSign
=
extractFloat64Sign
(
a
);
aSign
=
extractFloat64Sign
(
a
);
bSign
=
extractFloat64Sign
(
b
);
bSign
=
extractFloat64Sign
(
b
);
if
(
aSign
==
bSign
)
{
if
(
aSign
==
bSign
)
{
return
subFloat64Sigs
(
a
,
b
,
aSign
);
return
subFloat64Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
else
{
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
...
@@ -2124,7 +2115,7 @@ Returns the result of multiplying the double-precision floating-point values
for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
zExp
;
int16
aExp
,
bExp
,
zExp
;
...
@@ -2142,7 +2133,7 @@ float64 float64_mul( float64 a, float64 b )
...
@@ -2142,7 +2133,7 @@ float64 float64_mul( float64 a, float64 b )
return
propagateFloat64NaN
(
a
,
b
);
return
propagateFloat64NaN
(
a
,
b
);
}
}
if
(
(
bExp
|
bSig
)
==
0
)
{
if
(
(
bExp
|
bSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
return
packFloat64
(
zSign
,
0x7FF
,
0
);
return
packFloat64
(
zSign
,
0x7FF
,
0
);
...
@@ -2150,7 +2141,7 @@ float64 float64_mul( float64 a, float64 b )
...
@@ -2150,7 +2141,7 @@ float64 float64_mul( float64 a, float64 b )
if
(
bExp
==
0x7FF
)
{
if
(
bExp
==
0x7FF
)
{
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
(
aExp
|
aSig
)
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
return
packFloat64
(
zSign
,
0x7FF
,
0
);
return
packFloat64
(
zSign
,
0x7FF
,
0
);
...
@@ -2172,7 +2163,7 @@ float64 float64_mul( float64 a, float64 b )
...
@@ -2172,7 +2163,7 @@ float64 float64_mul( float64 a, float64 b )
zSig0
<<=
1
;
zSig0
<<=
1
;
--
zExp
;
--
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
...
@@ -2183,7 +2174,7 @@ by the corresponding value `b'. The operation is performed according to
the IEC/IEEE Standard for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
zExp
;
int16
aExp
,
bExp
,
zExp
;
...
@@ -2202,7 +2193,7 @@ float64 float64_div( float64 a, float64 b )
...
@@ -2202,7 +2193,7 @@ float64 float64_div( float64 a, float64 b )
if
(
aSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
aSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
bExp
==
0x7FF
)
{
if
(
bExp
==
0x7FF
)
{
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
if
(
bSig
)
return
propagateFloat64NaN
(
a
,
b
);
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
return
packFloat64
(
zSign
,
0x7FF
,
0
);
return
packFloat64
(
zSign
,
0x7FF
,
0
);
...
@@ -2214,10 +2205,10 @@ float64 float64_div( float64 a, float64 b )
...
@@ -2214,10 +2205,10 @@ float64 float64_div( float64 a, float64 b )
if
(
bExp
==
0
)
{
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
if
(
bSig
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
float_raise
(
float_flag_divbyzero
)
;
roundData
->
exception
|=
float_flag_divbyzero
;
return
packFloat64
(
zSign
,
0x7FF
,
0
);
return
packFloat64
(
zSign
,
0x7FF
,
0
);
}
}
normalizeFloat64Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
normalizeFloat64Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
@@ -2243,7 +2234,7 @@ float64 float64_div( float64 a, float64 b )
...
@@ -2243,7 +2234,7 @@ float64 float64_div( float64 a, float64 b )
}
}
zSig
|=
(
rem1
!=
0
);
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
...
@@ -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.
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
;
flag
aSign
,
bSign
,
zSign
;
int16
aExp
,
bExp
,
expDiff
;
int16
aExp
,
bExp
,
expDiff
;
...
@@ -2272,7 +2263,7 @@ float64 float64_rem( float64 a, float64 b )
...
@@ -2272,7 +2263,7 @@ float64 float64_rem( float64 a, float64 b )
if
(
aSig
||
(
(
bExp
==
0x7FF
)
&&
bSig
)
)
{
if
(
aSig
||
(
(
bExp
==
0x7FF
)
&&
bSig
)
)
{
return
propagateFloat64NaN
(
a
,
b
);
return
propagateFloat64NaN
(
a
,
b
);
}
}
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
if
(
bExp
==
0x7FF
)
{
if
(
bExp
==
0x7FF
)
{
...
@@ -2281,7 +2272,7 @@ float64 float64_rem( float64 a, float64 b )
...
@@ -2281,7 +2272,7 @@ float64 float64_rem( float64 a, float64 b )
}
}
if
(
bExp
==
0
)
{
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
if
(
bSig
==
0
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
normalizeFloat64Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
normalizeFloat64Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
@@ -2329,7 +2320,7 @@ float64 float64_rem( float64 a, float64 b )
...
@@ -2329,7 +2320,7 @@ float64 float64_rem( float64 a, float64 b )
}
}
zSign
=
(
(
sbits64
)
aSig
<
0
);
zSign
=
(
(
sbits64
)
aSig
<
0
);
if
(
zSign
)
aSig
=
-
aSig
;
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
...
@@ -2340,7 +2331,7 @@ The operation is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float64
float64_sqrt
(
float64
a
)
float64
float64_sqrt
(
struct
roundingData
*
roundData
,
float64
a
)
{
{
flag
aSign
;
flag
aSign
;
int16
aExp
,
zExp
;
int16
aExp
,
zExp
;
...
@@ -2354,12 +2345,12 @@ float64 float64_sqrt( float64 a )
...
@@ -2354,12 +2345,12 @@ float64 float64_sqrt( float64 a )
if
(
aExp
==
0x7FF
)
{
if
(
aExp
==
0x7FF
)
{
if
(
aSig
)
return
propagateFloat64NaN
(
a
,
a
);
if
(
aSig
)
return
propagateFloat64NaN
(
a
,
a
);
if
(
!
aSign
)
return
a
;
if
(
!
aSign
)
return
a
;
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
if
(
aSign
)
{
if
(
aSign
)
{
if
(
(
aExp
|
aSig
)
==
0
)
return
a
;
if
(
(
aExp
|
aSig
)
==
0
)
return
a
;
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
float64_default_nan
;
return
float64_default_nan
;
}
}
if
(
aExp
==
0
)
{
if
(
aExp
==
0
)
{
...
@@ -2390,7 +2381,7 @@ float64 float64_sqrt( float64 a )
...
@@ -2390,7 +2381,7 @@ float64 float64_sqrt( float64 a )
}
}
}
}
shift64RightJamming
(
zSig
,
1
,
&
zSig
);
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
...
@@ -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.
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
;
flag
aSign
;
int32
aExp
,
shiftCount
;
int32
aExp
,
shiftCount
;
...
@@ -2567,7 +2558,7 @@ int32 floatx80_to_int32( floatx80 a )
...
@@ -2567,7 +2558,7 @@ int32 floatx80_to_int32( floatx80 a )
shiftCount
=
0x4037
-
aExp
;
shiftCount
=
0x4037
-
aExp
;
if
(
shiftCount
<=
0
)
shiftCount
=
1
;
if
(
shiftCount
<=
0
)
shiftCount
=
1
;
shift64RightJamming
(
aSig
,
shiftCount
,
&
aSig
);
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 )
...
@@ -2598,7 +2589,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a )
goto
invalid
;
goto
invalid
;
}
}
else
if
(
63
<
shiftCount
)
{
else
if
(
63
<
shiftCount
)
{
if
(
aExp
||
aSig
)
float_
exception_flags
|=
float_flag_inexact
;
if
(
aExp
||
aSig
)
float_
raise
(
float_flag_inexact
)
;
return
0
;
return
0
;
}
}
savedASig
=
aSig
;
savedASig
=
aSig
;
...
@@ -2607,11 +2598,11 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a )
...
@@ -2607,11 +2598,11 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a )
if
(
aSign
)
z
=
-
z
;
if
(
aSign
)
z
=
-
z
;
if
(
(
z
<
0
)
^
aSign
)
{
if
(
(
z
<
0
)
^
aSign
)
{
invalid:
invalid:
float_
exception_flags
|=
float_flag_invalid
;
float_
raise
(
float_flag_invalid
)
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
return
aSign
?
0x80000000
:
0x7FFFFFFF
;
}
}
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
if
(
(
aSig
<<
shiftCount
)
!=
savedASig
)
{
float_
exception_flags
|=
float_flag_inexact
;
float_
raise
(
float_flag_inexact
)
;
}
}
return
z
;
return
z
;
...
@@ -2625,7 +2616,7 @@ conversion is performed according to the IEC/IEEE Standard for Binary
...
@@ -2625,7 +2616,7 @@ conversion is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float32
floatx80_to_float32
(
floatx80
a
)
float32
floatx80_to_float32
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
{
flag
aSign
;
flag
aSign
;
int32
aExp
;
int32
aExp
;
...
@@ -2642,7 +2633,7 @@ float32 floatx80_to_float32( floatx80 a )
...
@@ -2642,7 +2633,7 @@ float32 floatx80_to_float32( floatx80 a )
}
}
shift64RightJamming
(
aSig
,
33
,
&
aSig
);
shift64RightJamming
(
aSig
,
33
,
&
aSig
);
if
(
aExp
||
aSig
)
aExp
-=
0x3F81
;
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
...
@@ -2654,7 +2645,7 @@ conversion is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float64
floatx80_to_float64
(
floatx80
a
)
float64
floatx80_to_float64
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
{
flag
aSign
;
flag
aSign
;
int32
aExp
;
int32
aExp
;
...
@@ -2671,7 +2662,7 @@ float64 floatx80_to_float64( floatx80 a )
...
@@ -2671,7 +2662,7 @@ float64 floatx80_to_float64( floatx80 a )
}
}
shift64RightJamming
(
aSig
,
1
,
&
zSig
);
shift64RightJamming
(
aSig
,
1
,
&
zSig
);
if
(
aExp
||
aSig
)
aExp
-=
0x3C01
;
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
...
@@ -2683,7 +2674,7 @@ value. The operation is performed according to the IEC/IEEE Standard for
Binary Floating-point Arithmetic.
Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
floatx80
floatx80_round_to_int
(
floatx80
a
)
floatx80
floatx80_round_to_int
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
{
flag
aSign
;
flag
aSign
;
int32
aExp
;
int32
aExp
;
...
@@ -2703,9 +2694,9 @@ floatx80 floatx80_round_to_int( floatx80 a )
...
@@ -2703,9 +2694,9 @@ floatx80 floatx80_round_to_int( floatx80 a )
&&
(
(
bits64
)
(
extractFloatx80Frac
(
a
)
<<
1
)
==
0
)
)
{
&&
(
(
bits64
)
(
extractFloatx80Frac
(
a
)
<<
1
)
==
0
)
)
{
return
a
;
return
a
;
}
}
float_exception_flags
|=
float_flag_inexact
;
roundData
->
exception
|=
float_flag_inexact
;
aSign
=
extractFloatx80Sign
(
a
);
aSign
=
extractFloatx80Sign
(
a
);
switch
(
float_rounding_
mode
)
{
switch
(
roundData
->
mode
)
{
case
float_round_nearest_even
:
case
float_round_nearest_even
:
if
(
(
aExp
==
0x3FFE
)
&&
(
bits64
)
(
extractFloatx80Frac
(
a
)
<<
1
)
if
(
(
aExp
==
0x3FFE
)
&&
(
bits64
)
(
extractFloatx80Frac
(
a
)
<<
1
)
)
{
)
{
...
@@ -2729,7 +2720,7 @@ floatx80 floatx80_round_to_int( floatx80 a )
...
@@ -2729,7 +2720,7 @@ floatx80 floatx80_round_to_int( floatx80 a )
lastBitMask
<<=
0x403E
-
aExp
;
lastBitMask
<<=
0x403E
-
aExp
;
roundBitsMask
=
lastBitMask
-
1
;
roundBitsMask
=
lastBitMask
-
1
;
z
=
a
;
z
=
a
;
roundingMode
=
float_rounding_
mode
;
roundingMode
=
roundData
->
mode
;
if
(
roundingMode
==
float_round_nearest_even
)
{
if
(
roundingMode
==
float_round_nearest_even
)
{
z
.
low
+=
lastBitMask
>>
1
;
z
.
low
+=
lastBitMask
>>
1
;
if
(
(
z
.
low
&
roundBitsMask
)
==
0
)
z
.
low
&=
~
lastBitMask
;
if
(
(
z
.
low
&
roundBitsMask
)
==
0
)
z
.
low
&=
~
lastBitMask
;
...
@@ -2744,7 +2735,7 @@ floatx80 floatx80_round_to_int( floatx80 a )
...
@@ -2744,7 +2735,7 @@ floatx80 floatx80_round_to_int( floatx80 a )
++
z
.
high
;
++
z
.
high
;
z
.
low
=
LIT64
(
0x8000000000000000
);
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
;
return
z
;
}
}
...
@@ -2758,7 +2749,7 @@ The addition is performed according to the IEC/IEEE Standard for Binary
...
@@ -2758,7 +2749,7 @@ The addition is performed according to the IEC/IEEE Standard for Binary
Floating-point Arithmetic.
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
;
int32
aExp
,
bExp
,
zExp
;
bits64
aSig
,
bSig
,
zSig0
,
zSig1
;
bits64
aSig
,
bSig
,
zSig0
,
zSig1
;
...
@@ -2814,7 +2805,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
...
@@ -2814,7 +2805,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
roundAndPack:
roundAndPack:
return
return
roundAndPackFloatx80
(
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
...
@@ -2827,7 +2818,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE
Standard for Binary Floating-point Arithmetic.
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
;
int32
aExp
,
bExp
,
zExp
;
bits64
aSig
,
bSig
,
zSig0
,
zSig1
;
bits64
aSig
,
bSig
,
zSig0
,
zSig1
;
...
@@ -2845,7 +2836,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
...
@@ -2845,7 +2836,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
if
(
(
bits64
)
(
(
aSig
|
bSig
)
<<
1
)
)
{
if
(
(
bits64
)
(
(
aSig
|
bSig
)
<<
1
)
)
{
return
propagateFloatx80NaN
(
a
,
b
);
return
propagateFloatx80NaN
(
a
,
b
);
}
}
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
return
z
;
...
@@ -2857,7 +2848,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
...
@@ -2857,7 +2848,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
zSig1
=
0
;
zSig1
=
0
;
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
bSig
<
aSig
)
goto
aBigger
;
if
(
aSig
<
bSig
)
goto
bBigger
;
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:
bExpBigger:
if
(
bExp
==
0x7FFF
)
{
if
(
bExp
==
0x7FFF
)
{
if
(
(
bits64
)
(
bSig
<<
1
)
)
return
propagateFloatx80NaN
(
a
,
b
);
if
(
(
bits64
)
(
bSig
<<
1
)
)
return
propagateFloatx80NaN
(
a
,
b
);
...
@@ -2883,7 +2874,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
...
@@ -2883,7 +2874,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
normalizeRoundAndPack:
normalizeRoundAndPack:
return
return
normalizeRoundAndPackFloatx80
(
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
...
@@ -2894,17 +2885,17 @@ values `a' and `b'. The operation is performed according to the IEC/IEEE
Standard for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
;
aSign
=
extractFloatx80Sign
(
a
);
aSign
=
extractFloatx80Sign
(
a
);
bSign
=
extractFloatx80Sign
(
b
);
bSign
=
extractFloatx80Sign
(
b
);
if
(
aSign
==
bSign
)
{
if
(
aSign
==
bSign
)
{
return
addFloatx80Sigs
(
a
,
b
,
aSign
);
return
addFloatx80Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
else
{
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
...
@@ -2916,17 +2907,17 @@ point values `a' and `b'. The operation is performed according to the
IEC/IEEE Standard for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
;
aSign
=
extractFloatx80Sign
(
a
);
aSign
=
extractFloatx80Sign
(
a
);
bSign
=
extractFloatx80Sign
(
b
);
bSign
=
extractFloatx80Sign
(
b
);
if
(
aSign
==
bSign
)
{
if
(
aSign
==
bSign
)
{
return
subFloatx80Sigs
(
a
,
b
,
aSign
);
return
subFloatx80Sigs
(
roundData
,
a
,
b
,
aSign
);
}
}
else
{
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
...
@@ -2938,7 +2929,7 @@ point values `a' and `b'. The operation is performed according to the
IEC/IEEE Standard for Binary Floating-point Arithmetic.
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
;
flag
aSign
,
bSign
,
zSign
;
int32
aExp
,
bExp
,
zExp
;
int32
aExp
,
bExp
,
zExp
;
...
@@ -2964,7 +2955,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b )
...
@@ -2964,7 +2955,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b )
if
(
(
bits64
)
(
bSig
<<
1
)
)
return
propagateFloatx80NaN
(
a
,
b
);
if
(
(
bits64
)
(
bSig
<<
1
)
)
return
propagateFloatx80NaN
(
a
,
b
);
if
(
(
aExp
|
aSig
)
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
invalid:
invalid:
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
return
z
;
...
@@ -2987,7 +2978,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b )
...
@@ -2987,7 +2978,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b )
}
}
return
return
roundAndPackFloatx80
(
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
...
@@ -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.
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
;
flag
aSign
,
bSign
,
zSign
;
int32
aExp
,
bExp
,
zExp
;
int32
aExp
,
bExp
,
zExp
;
...
@@ -3029,12 +3020,12 @@ floatx80 floatx80_div( floatx80 a, floatx80 b )
...
@@ -3029,12 +3020,12 @@ floatx80 floatx80_div( floatx80 a, floatx80 b )
if
(
bSig
==
0
)
{
if
(
bSig
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
if
(
(
aExp
|
aSig
)
==
0
)
{
invalid:
invalid:
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
return
z
;
}
}
float_raise
(
float_flag_divbyzero
)
;
roundData
->
exception
|=
float_flag_divbyzero
;
return
packFloatx80
(
zSign
,
0x7FFF
,
LIT64
(
0x8000000000000000
)
);
return
packFloatx80
(
zSign
,
0x7FFF
,
LIT64
(
0x8000000000000000
)
);
}
}
normalizeFloatx80Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
normalizeFloatx80Subnormal
(
bSig
,
&
bExp
,
&
bSig
);
...
@@ -3068,7 +3059,7 @@ floatx80 floatx80_div( floatx80 a, floatx80 b )
...
@@ -3068,7 +3059,7 @@ floatx80 floatx80_div( floatx80 a, floatx80 b )
}
}
return
return
roundAndPackFloatx80
(
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
...
@@ -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.
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
;
flag
aSign
,
bSign
,
zSign
;
int32
aExp
,
bExp
,
expDiff
;
int32
aExp
,
bExp
,
expDiff
;
...
@@ -3107,7 +3098,7 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b )
...
@@ -3107,7 +3098,7 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b )
if
(
bExp
==
0
)
{
if
(
bExp
==
0
)
{
if
(
bSig
==
0
)
{
if
(
bSig
==
0
)
{
invalid:
invalid:
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
return
z
;
...
@@ -3164,9 +3155,10 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b )
...
@@ -3164,9 +3155,10 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b )
aSig1
=
alternateASig1
;
aSig1
=
alternateASig1
;
zSign
=
!
zSign
;
zSign
=
!
zSign
;
}
}
return
return
normalizeRoundAndPackFloatx80
(
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
...
@@ -3177,7 +3169,7 @@ value `a'. The operation is performed according to the IEC/IEEE Standard
for Binary Floating-point Arithmetic.
for Binary Floating-point Arithmetic.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
floatx80
floatx80_sqrt
(
floatx80
a
)
floatx80
floatx80_sqrt
(
struct
roundingData
*
roundData
,
floatx80
a
)
{
{
flag
aSign
;
flag
aSign
;
int32
aExp
,
zExp
;
int32
aExp
,
zExp
;
...
@@ -3197,7 +3189,7 @@ floatx80 floatx80_sqrt( floatx80 a )
...
@@ -3197,7 +3189,7 @@ floatx80 floatx80_sqrt( floatx80 a )
if
(
aSign
)
{
if
(
aSign
)
{
if
(
(
aExp
|
aSig0
)
==
0
)
return
a
;
if
(
(
aExp
|
aSig0
)
==
0
)
return
a
;
invalid:
invalid:
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
z
.
low
=
floatx80_default_nan_low
;
z
.
low
=
floatx80_default_nan_low
;
z
.
high
=
floatx80_default_nan_high
;
z
.
high
=
floatx80_default_nan_high
;
return
z
;
return
z
;
...
@@ -3242,7 +3234,7 @@ floatx80 floatx80_sqrt( floatx80 a )
...
@@ -3242,7 +3234,7 @@ floatx80 floatx80_sqrt( floatx80 a )
}
}
return
return
roundAndPackFloatx80
(
roundAndPackFloatx80
(
floatx80_rounding_precision
,
0
,
zExp
,
zSig0
,
zSig1
);
roundData
,
0
,
zExp
,
zSig0
,
zSig1
);
}
}
...
@@ -3264,7 +3256,7 @@ flag floatx80_eq( floatx80 a, floatx80 b )
...
@@ -3264,7 +3256,7 @@ flag floatx80_eq( floatx80 a, floatx80 b )
)
{
)
{
if
(
floatx80_is_signaling_nan
(
a
)
if
(
floatx80_is_signaling_nan
(
a
)
||
floatx80_is_signaling_nan
(
b
)
)
{
||
floatx80_is_signaling_nan
(
b
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
}
}
return
0
;
return
0
;
}
}
...
@@ -3294,7 +3286,7 @@ flag floatx80_le( floatx80 a, floatx80 b )
...
@@ -3294,7 +3286,7 @@ flag floatx80_le( floatx80 a, floatx80 b )
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
)
{
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
0
;
return
0
;
}
}
aSign
=
extractFloatx80Sign
(
a
);
aSign
=
extractFloatx80Sign
(
a
);
...
@@ -3328,7 +3320,7 @@ flag floatx80_lt( floatx80 a, floatx80 b )
...
@@ -3328,7 +3320,7 @@ flag floatx80_lt( floatx80 a, floatx80 b )
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
)
{
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
0
;
return
0
;
}
}
aSign
=
extractFloatx80Sign
(
a
);
aSign
=
extractFloatx80Sign
(
a
);
...
@@ -3361,7 +3353,7 @@ flag floatx80_eq_signaling( floatx80 a, floatx80 b )
...
@@ -3361,7 +3353,7 @@ flag floatx80_eq_signaling( floatx80 a, floatx80 b )
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
||
(
(
extractFloatx80Exp
(
b
)
==
0x7FFF
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
&&
(
bits64
)
(
extractFloatx80Frac
(
b
)
<<
1
)
)
)
{
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
return
0
;
return
0
;
}
}
return
return
...
@@ -3392,7 +3384,7 @@ flag floatx80_le_quiet( floatx80 a, floatx80 b )
...
@@ -3392,7 +3384,7 @@ flag floatx80_le_quiet( floatx80 a, floatx80 b )
)
{
)
{
if
(
floatx80_is_signaling_nan
(
a
)
if
(
floatx80_is_signaling_nan
(
a
)
||
floatx80_is_signaling_nan
(
b
)
)
{
||
floatx80_is_signaling_nan
(
b
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
}
}
return
0
;
return
0
;
}
}
...
@@ -3429,7 +3421,7 @@ flag floatx80_lt_quiet( floatx80 a, floatx80 b )
...
@@ -3429,7 +3421,7 @@ flag floatx80_lt_quiet( floatx80 a, floatx80 b )
)
{
)
{
if
(
floatx80_is_signaling_nan
(
a
)
if
(
floatx80_is_signaling_nan
(
a
)
||
floatx80_is_signaling_nan
(
b
)
)
{
||
floatx80_is_signaling_nan
(
b
)
)
{
float_raise
(
float_flag_invalid
)
;
roundData
->
exception
|=
float_flag_invalid
;
}
}
return
0
;
return
0
;
}
}
...
...
arch/arm/nwfpe/softfloat.h
View file @
194d0710
...
@@ -74,7 +74,7 @@ enum {
...
@@ -74,7 +74,7 @@ enum {
Software IEC/IEEE floating-point rounding mode.
Software IEC/IEEE floating-point rounding mode.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
extern
signed
char
float_rounding_mode
;
//extern int8
float_rounding_mode;
enum
{
enum
{
float_round_nearest_even
=
0
,
float_round_nearest_even
=
0
,
float_round_to_zero
=
1
,
float_round_to_zero
=
1
,
...
@@ -86,7 +86,6 @@ enum {
...
@@ -86,7 +86,6 @@ enum {
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Software IEC/IEEE floating-point exception flags.
Software IEC/IEEE floating-point exception flags.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
extern signed char float_exception_flags;
enum {
enum {
float_flag_inexact = 1,
float_flag_inexact = 1,
float_flag_underflow = 2,
float_flag_underflow = 2,
...
@@ -99,7 +98,6 @@ ScottB: November 4, 1998
...
@@ -99,7 +98,6 @@ ScottB: November 4, 1998
Changed the enumeration to match the bit order in the FPA11.
Changed the enumeration to match the bit order in the FPA11.
*/
*/
extern
signed
char
float_exception_flags
;
enum
{
enum
{
float_flag_invalid
=
1
,
float_flag_invalid
=
1
,
float_flag_divbyzero
=
2
,
float_flag_divbyzero
=
2
,
...
@@ -121,7 +119,7 @@ void float_raise( signed char );
...
@@ -121,7 +119,7 @@ void float_raise( signed char );
Software IEC/IEEE integer-to-floating-point conversion routines.
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
);
float64
int32_to_float64
(
signed
int
);
#ifdef FLOATX80
#ifdef FLOATX80
floatx80
int32_to_floatx80
(
signed
int
);
floatx80
int32_to_floatx80
(
signed
int
);
...
@@ -132,7 +130,7 @@ floatx80 int32_to_floatx80( signed int );
...
@@ -132,7 +130,7 @@ floatx80 int32_to_floatx80( signed int );
Software IEC/IEEE single-precision conversion routines.
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
);
signed
int
float32_to_int32_round_to_zero
(
float32
);
float64
float32_to_float64
(
float32
);
float64
float32_to_float64
(
float32
);
#ifdef FLOATX80
#ifdef FLOATX80
...
@@ -144,13 +142,13 @@ floatx80 float32_to_floatx80( float32 );
...
@@ -144,13 +142,13 @@ floatx80 float32_to_floatx80( float32 );
Software IEC/IEEE single-precision operations.
Software IEC/IEEE single-precision operations.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float32
float32_round_to_int
(
float32
);
float32
float32_round_to_int
(
struct
roundingData
*
,
float32
);
float32
float32_add
(
float32
,
float32
);
float32
float32_add
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_sub
(
float32
,
float32
);
float32
float32_sub
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_mul
(
float32
,
float32
);
float32
float32_mul
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_div
(
float32
,
float32
);
float32
float32_div
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_rem
(
float32
,
float32
);
float32
float32_rem
(
struct
roundingData
*
,
float32
,
float32
);
float32
float32_sqrt
(
float32
);
float32
float32_sqrt
(
struct
roundingData
*
,
float32
);
char
float32_eq
(
float32
,
float32
);
char
float32_eq
(
float32
,
float32
);
char
float32_le
(
float32
,
float32
);
char
float32_le
(
float32
,
float32
);
char
float32_lt
(
float32
,
float32
);
char
float32_lt
(
float32
,
float32
);
...
@@ -164,9 +162,9 @@ char float32_is_signaling_nan( float32 );
...
@@ -164,9 +162,9 @@ char float32_is_signaling_nan( float32 );
Software IEC/IEEE double-precision conversion routines.
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
);
signed
int
float64_to_int32_round_to_zero
(
float64
);
float32
float64_to_float32
(
float64
);
float32
float64_to_float32
(
struct
roundingData
*
,
float64
);
#ifdef FLOATX80
#ifdef FLOATX80
floatx80
float64_to_floatx80
(
float64
);
floatx80
float64_to_floatx80
(
float64
);
#endif
#endif
...
@@ -176,13 +174,13 @@ floatx80 float64_to_floatx80( float64 );
...
@@ -176,13 +174,13 @@ floatx80 float64_to_floatx80( float64 );
Software IEC/IEEE double-precision operations.
Software IEC/IEEE double-precision operations.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
float64
float64_round_to_int
(
float64
);
float64
float64_round_to_int
(
struct
roundingData
*
,
float64
);
float64
float64_add
(
float64
,
float64
);
float64
float64_add
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_sub
(
float64
,
float64
);
float64
float64_sub
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_mul
(
float64
,
float64
);
float64
float64_mul
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_div
(
float64
,
float64
);
float64
float64_div
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_rem
(
float64
,
float64
);
float64
float64_rem
(
struct
roundingData
*
,
float64
,
float64
);
float64
float64_sqrt
(
float64
);
float64
float64_sqrt
(
struct
roundingData
*
,
float64
);
char
float64_eq
(
float64
,
float64
);
char
float64_eq
(
float64
,
float64
);
char
float64_le
(
float64
,
float64
);
char
float64_le
(
float64
,
float64
);
char
float64_lt
(
float64
,
float64
);
char
float64_lt
(
float64
,
float64
);
...
@@ -198,31 +196,23 @@ char float64_is_signaling_nan( float64 );
...
@@ -198,31 +196,23 @@ char float64_is_signaling_nan( float64 );
Software IEC/IEEE extended double-precision conversion routines.
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
);
signed
int
floatx80_to_int32_round_to_zero
(
floatx80
);
float32
floatx80_to_float32
(
floatx80
);
float32
floatx80_to_float32
(
struct
roundingData
*
,
floatx80
);
float64
floatx80_to_float64
(
floatx80
);
float64
floatx80_to_float64
(
struct
roundingData
*
,
floatx80
);
/*
-------------------------------------------------------------------------------
Software IEC/IEEE extended double-precision rounding precision. Valid
values are 32, 64, and 80.
-------------------------------------------------------------------------------
*/
extern
signed
char
floatx80_rounding_precision
;
/*
/*
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Software IEC/IEEE extended double-precision operations.
Software IEC/IEEE extended double-precision operations.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
*/
*/
floatx80
floatx80_round_to_int
(
floatx80
);
floatx80
floatx80_round_to_int
(
struct
roundingData
*
,
floatx80
);
floatx80
floatx80_add
(
floatx80
,
floatx80
);
floatx80
floatx80_add
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_sub
(
floatx80
,
floatx80
);
floatx80
floatx80_sub
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_mul
(
floatx80
,
floatx80
);
floatx80
floatx80_mul
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_div
(
floatx80
,
floatx80
);
floatx80
floatx80_div
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_rem
(
floatx80
,
floatx80
);
floatx80
floatx80_rem
(
struct
roundingData
*
,
floatx80
,
floatx80
);
floatx80
floatx80_sqrt
(
floatx80
);
floatx80
floatx80_sqrt
(
struct
roundingData
*
,
floatx80
);
char
floatx80_eq
(
floatx80
,
floatx80
);
char
floatx80_eq
(
floatx80
,
floatx80
);
char
floatx80_le
(
floatx80
,
floatx80
);
char
floatx80_le
(
floatx80
,
floatx80
);
char
floatx80_lt
(
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,
...
@@ -770,6 +770,9 @@ vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,
if
((
s64
)
m_sig
<
0
)
{
if
((
s64
)
m_sig
<
0
)
{
vdd
->
sign
=
vfp_sign_negate
(
vdd
->
sign
);
vdd
->
sign
=
vfp_sign_negate
(
vdd
->
sign
);
m_sig
=
-
m_sig
;
m_sig
=
-
m_sig
;
}
else
if
(
m_sig
==
0
)
{
vdd
->
sign
=
(
fpscr
&
FPSCR_RMODE_MASK
)
==
FPSCR_ROUND_MINUSINF
?
0x8000
:
0
;
}
}
}
else
{
}
else
{
m_sig
+=
vdn
->
significand
;
m_sig
+=
vdn
->
significand
;
...
...
drivers/char/watchdog/sa1100_wdt.c
View file @
194d0710
...
@@ -36,13 +36,10 @@
...
@@ -36,13 +36,10 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#define OSCR_FREQ CLOCK_TICK_RATE
#define OSCR_FREQ CLOCK_TICK_RATE
#define SA1100_CLOSE_MAGIC (0x5afc4453)
static
unsigned
long
sa1100wdt_users
;
static
unsigned
long
sa1100wdt_users
;
static
int
expect_close
;
static
int
pre_margin
;
static
int
pre_margin
;
static
int
boot_status
;
static
int
boot_status
;
static
int
nowayout
=
WATCHDOG_NOWAYOUT
;
/*
/*
* Allow only one person to hold it open
* Allow only one person to hold it open
...
@@ -62,55 +59,33 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
...
@@ -62,55 +59,33 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
}
}
/*
/*
* Shut off the timer.
* The watchdog cannot be disabled.
* Lock it in if it's a module and we defined ...NOWAYOUT
*
* Oddly, the watchdog can only be enabled, but we can turn off
* Previous comments suggested that turning off the interrupt by
* the interrupt, which appears to prevent the watchdog timing out.
* 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
)
static
int
sa1100dog_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
{
OSMR3
=
OSCR
+
pre_margin
;
printk
(
KERN_CRIT
"WATCHDOG: Device closed - timer will not stop
\n
"
);
if
(
expect_close
==
SA1100_CLOSE_MAGIC
)
{
OIER
&=
~
OIER_E3
;
}
else
{
printk
(
KERN_CRIT
"WATCHDOG: WDT device closed unexpectedly. WDT will not stop!
\n
"
);
}
clear_bit
(
1
,
&
sa1100wdt_users
);
clear_bit
(
1
,
&
sa1100wdt_users
);
expect_close
=
0
;
return
0
;
return
0
;
}
}
static
ssize_t
sa1100dog_write
(
struct
file
*
file
,
const
char
*
data
,
size_t
len
,
loff_t
*
ppos
)
static
ssize_t
sa1100dog_write
(
struct
file
*
file
,
const
char
*
data
,
size_t
len
,
loff_t
*
ppos
)
{
{
if
(
len
)
{
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
;
}
}
/* Refresh OSMR3 timer. */
/* Refresh OSMR3 timer. */
OSMR3
=
OSCR
+
pre_margin
;
OSMR3
=
OSCR
+
pre_margin
;
}
return
len
;
return
len
;
}
}
static
struct
watchdog_info
ident
=
{
static
struct
watchdog_info
ident
=
{
.
options
=
WDIOF_CARDRESET
|
WDIOF_MAGICCLOSE
|
.
options
=
WDIOF_CARDRESET
|
WDIOF_SETTIMEOUT
|
WDIOF_KEEPALIVEPING
,
WDIOF_SETTIMEOUT
|
WDIOF_KEEPALIVEPING
,
.
identity
=
"SA1100/PXA255 Watchdog"
,
.
identity
=
"SA1100 Watchdog"
,
};
};
static
int
sa1100dog_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
static
int
sa1100dog_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
...
@@ -172,7 +147,7 @@ static struct file_operations sa1100dog_fops =
...
@@ -172,7 +147,7 @@ static struct file_operations sa1100dog_fops =
static
struct
miscdevice
sa1100dog_miscdev
=
static
struct
miscdevice
sa1100dog_miscdev
=
{
{
.
minor
=
WATCHDOG_MINOR
,
.
minor
=
WATCHDOG_MINOR
,
.
name
=
"
SA1100/PXA2xx
watchdog"
,
.
name
=
"watchdog"
,
.
fops
=
&
sa1100dog_fops
,
.
fops
=
&
sa1100dog_fops
,
};
};
...
@@ -194,7 +169,6 @@ static int __init sa1100dog_init(void)
...
@@ -194,7 +169,6 @@ static int __init sa1100dog_init(void)
if
(
ret
==
0
)
if
(
ret
==
0
)
printk
(
"SA1100/PXA2xx Watchdog Timer: timer margin %d sec
\n
"
,
printk
(
"SA1100/PXA2xx Watchdog Timer: timer margin %d sec
\n
"
,
margin
);
margin
);
return
ret
;
return
ret
;
}
}
...
@@ -212,8 +186,5 @@ MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog");
...
@@ -212,8 +186,5 @@ MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog");
module_param
(
margin
,
int
,
0
);
module_param
(
margin
,
int
,
0
);
MODULE_PARM_DESC
(
margin
,
"Watchdog margin in seconds (default 60s)"
);
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_LICENSE
(
"GPL"
);
MODULE_ALIAS_MISCDEV
(
WATCHDOG_MINOR
);
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