diff options
| -rw-r--r-- | arch/mips/math-emu/cp1emu.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 890f77927d62..454b53924490 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
| @@ -163,33 +163,34 @@ static int isBranchInstr(mips_instruction * i) | |||
| 163 | 163 | ||
| 164 | /* | 164 | /* |
| 165 | * In the Linux kernel, we support selection of FPR format on the | 165 | * In the Linux kernel, we support selection of FPR format on the |
| 166 | * basis of the Status.FR bit. This does imply that, if a full 32 | 166 | * basis of the Status.FR bit. If an FPU is not present, the FR bit |
| 167 | * FPRs are desired, there needs to be a flip-flop that can be written | 167 | * is hardwired to zero, which would imply a 32-bit FPU even for |
| 168 | * to one at that bit position. In any case, O32 MIPS ABI uses | 168 | * 64-bit CPUs. For 64-bit kernels with no FPU we use TIF_32BIT_REGS |
| 169 | * only the even FPRs (Status.FR = 0). | 169 | * as a proxy for the FR bit so that a 64-bit FPU is emulated. In any |
| 170 | * case, for a 32-bit kernel which uses the O32 MIPS ABI, only the | ||
| 171 | * even FPRs are used (Status.FR = 0). | ||
| 170 | */ | 172 | */ |
| 171 | 173 | static inline int cop1_64bit(struct pt_regs *xcp) | |
| 172 | #define CP0_STATUS_FR_SUPPORT | 174 | { |
| 173 | 175 | if (cpu_has_fpu) | |
| 174 | #ifdef CP0_STATUS_FR_SUPPORT | 176 | return xcp->cp0_status & ST0_FR; |
| 175 | #define FR_BIT ST0_FR | 177 | #ifdef CONFIG_64BIT |
| 178 | return !test_thread_flag(TIF_32BIT_REGS); | ||
| 176 | #else | 179 | #else |
| 177 | #define FR_BIT 0 | 180 | return 0; |
| 178 | #endif | 181 | #endif |
| 182 | } | ||
| 183 | |||
| 184 | #define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \ | ||
| 185 | (int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32)) | ||
| 179 | 186 | ||
| 180 | #define SIFROMREG(si, x) ((si) = \ | 187 | #define SITOREG(si, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \ |
| 181 | (xcp->cp0_status & FR_BIT) || !(x & 1) ? \ | 188 | cop1_64bit(xcp) || !(x & 1) ? \ |
| 182 | (int)ctx->fpr[x] : \ | ||
| 183 | (int)(ctx->fpr[x & ~1] >> 32 )) | ||
| 184 | #define SITOREG(si, x) (ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)] = \ | ||
| 185 | (xcp->cp0_status & FR_BIT) || !(x & 1) ? \ | ||
| 186 | ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \ | 189 | ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \ |
| 187 | ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32) | 190 | ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32) |
| 188 | 191 | ||
| 189 | #define DIFROMREG(di, x) ((di) = \ | 192 | #define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)]) |
| 190 | ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)]) | 193 | #define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di)) |
| 191 | #define DITOREG(di, x) (ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)] \ | ||
| 192 | = (di)) | ||
| 193 | 194 | ||
| 194 | #define SPFROMREG(sp, x) SIFROMREG((sp).bits, x) | 195 | #define SPFROMREG(sp, x) SIFROMREG((sp).bits, x) |
| 195 | #define SPTOREG(sp, x) SITOREG((sp).bits, x) | 196 | #define SPTOREG(sp, x) SITOREG((sp).bits, x) |
