diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2005-08-03 14:49:17 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-08-03 14:49:17 -0400 |
commit | f148af2593ef76ac705d1cc6abe48f455c9912cc (patch) | |
tree | cd1e0b0959624234ca3489df8888434ffea5050e /arch/arm/nwfpe/single_cpdo.c | |
parent | 1fcf844861eb08ee05e05dba13b5436f2f2e29ed (diff) |
[PATCH] ARM: 2837/2: Re: ARM: Make NWFPE preempt safe
Patch from Richard Purdie
NWFPE used global variables which meant it wasn't safe for use with
preemptive kernels. This patch removes them and communicates the
information between functions in a preempt safe manner. Generation
of some exceptions was broken and this has also been corrected.
Tests with glibc's maths test suite show no change in the results
before/after this patch.
Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/nwfpe/single_cpdo.c')
-rw-r--r-- | arch/arm/nwfpe/single_cpdo.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/arch/arm/nwfpe/single_cpdo.c b/arch/arm/nwfpe/single_cpdo.c index 705808e88d9d..c66981d682cf 100644 --- a/arch/arm/nwfpe/single_cpdo.c +++ b/arch/arm/nwfpe/single_cpdo.c | |||
@@ -36,17 +36,17 @@ float32 float32_arccos(float32 rFm); | |||
36 | float32 float32_pow(float32 rFn, float32 rFm); | 36 | float32 float32_pow(float32 rFn, float32 rFm); |
37 | float32 float32_pol(float32 rFn, float32 rFm); | 37 | float32 float32_pol(float32 rFn, float32 rFm); |
38 | 38 | ||
39 | static float32 float32_rsf(float32 rFn, float32 rFm) | 39 | static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm) |
40 | { | 40 | { |
41 | return float32_sub(rFm, rFn); | 41 | return float32_sub(roundData, rFm, rFn); |
42 | } | 42 | } |
43 | 43 | ||
44 | static float32 float32_rdv(float32 rFn, float32 rFm) | 44 | static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm) |
45 | { | 45 | { |
46 | return float32_div(rFm, rFn); | 46 | return float32_div(roundData, rFm, rFn); |
47 | } | 47 | } |
48 | 48 | ||
49 | static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = { | 49 | static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = { |
50 | [ADF_CODE >> 20] = float32_add, | 50 | [ADF_CODE >> 20] = float32_add, |
51 | [MUF_CODE >> 20] = float32_mul, | 51 | [MUF_CODE >> 20] = float32_mul, |
52 | [SUF_CODE >> 20] = float32_sub, | 52 | [SUF_CODE >> 20] = float32_sub, |
@@ -60,22 +60,22 @@ static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = { | |||
60 | [FRD_CODE >> 20] = float32_rdv, | 60 | [FRD_CODE >> 20] = float32_rdv, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static float32 float32_mvf(float32 rFm) | 63 | static float32 float32_mvf(struct roundingData *roundData, float32 rFm) |
64 | { | 64 | { |
65 | return rFm; | 65 | return rFm; |
66 | } | 66 | } |
67 | 67 | ||
68 | static float32 float32_mnf(float32 rFm) | 68 | static float32 float32_mnf(struct roundingData *roundData, float32 rFm) |
69 | { | 69 | { |
70 | return rFm ^ 0x80000000; | 70 | return rFm ^ 0x80000000; |
71 | } | 71 | } |
72 | 72 | ||
73 | static float32 float32_abs(float32 rFm) | 73 | static float32 float32_abs(struct roundingData *roundData, float32 rFm) |
74 | { | 74 | { |
75 | return rFm & 0x7fffffff; | 75 | return rFm & 0x7fffffff; |
76 | } | 76 | } |
77 | 77 | ||
78 | static float32 (*const monadic_single[16])(float32 rFm) = { | 78 | static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = { |
79 | [MVF_CODE >> 20] = float32_mvf, | 79 | [MVF_CODE >> 20] = float32_mvf, |
80 | [MNF_CODE >> 20] = float32_mnf, | 80 | [MNF_CODE >> 20] = float32_mnf, |
81 | [ABS_CODE >> 20] = float32_abs, | 81 | [ABS_CODE >> 20] = float32_abs, |
@@ -85,7 +85,7 @@ static float32 (*const monadic_single[16])(float32 rFm) = { | |||
85 | [NRM_CODE >> 20] = float32_mvf, | 85 | [NRM_CODE >> 20] = float32_mvf, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) | 88 | unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) |
89 | { | 89 | { |
90 | FPA11 *fpa11 = GET_FPA11(); | 90 | FPA11 *fpa11 = GET_FPA11(); |
91 | float32 rFm; | 91 | float32 rFm; |
@@ -108,13 +108,13 @@ unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) | |||
108 | if (fpa11->fType[Fn] == typeSingle && | 108 | if (fpa11->fType[Fn] == typeSingle && |
109 | dyadic_single[opc_mask_shift]) { | 109 | dyadic_single[opc_mask_shift]) { |
110 | rFn = fpa11->fpreg[Fn].fSingle; | 110 | rFn = fpa11->fpreg[Fn].fSingle; |
111 | rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm); | 111 | rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm); |
112 | } else { | 112 | } else { |
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | } else { | 115 | } else { |
116 | if (monadic_single[opc_mask_shift]) { | 116 | if (monadic_single[opc_mask_shift]) { |
117 | rFd->fSingle = monadic_single[opc_mask_shift](rFm); | 117 | rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm); |
118 | } else { | 118 | } else { |
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |