diff options
Diffstat (limited to 'ANDROID_3.4.5/arch/alpha/math-emu')
-rw-r--r-- | ANDROID_3.4.5/arch/alpha/math-emu/Makefile | 9 | ||||
-rw-r--r-- | ANDROID_3.4.5/arch/alpha/math-emu/math.c | 400 | ||||
-rw-r--r-- | ANDROID_3.4.5/arch/alpha/math-emu/qrnnd.S | 163 | ||||
-rw-r--r-- | ANDROID_3.4.5/arch/alpha/math-emu/sfp-util.h | 35 |
4 files changed, 0 insertions, 607 deletions
diff --git a/ANDROID_3.4.5/arch/alpha/math-emu/Makefile b/ANDROID_3.4.5/arch/alpha/math-emu/Makefile deleted file mode 100644 index 7f467199..00000000 --- a/ANDROID_3.4.5/arch/alpha/math-emu/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for the FPU instruction emulation. -# - -ccflags-y := -w - -obj-$(CONFIG_MATHEMU) += math-emu.o - -math-emu-objs := math.o qrnnd.o diff --git a/ANDROID_3.4.5/arch/alpha/math-emu/math.c b/ANDROID_3.4.5/arch/alpha/math-emu/math.c deleted file mode 100644 index 58c2669a..00000000 --- a/ANDROID_3.4.5/arch/alpha/math-emu/math.c +++ /dev/null @@ -1,400 +0,0 @@ -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> - -#include <asm/uaccess.h> - -#include "sfp-util.h" -#include <math-emu/soft-fp.h> -#include <math-emu/single.h> -#include <math-emu/double.h> - -#define OPC_PAL 0x00 -#define OPC_INTA 0x10 -#define OPC_INTL 0x11 -#define OPC_INTS 0x12 -#define OPC_INTM 0x13 -#define OPC_FLTC 0x14 -#define OPC_FLTV 0x15 -#define OPC_FLTI 0x16 -#define OPC_FLTL 0x17 -#define OPC_MISC 0x18 -#define OPC_JSR 0x1a - -#define FOP_SRC_S 0 -#define FOP_SRC_T 2 -#define FOP_SRC_Q 3 - -#define FOP_FNC_ADDx 0 -#define FOP_FNC_CVTQL 0 -#define FOP_FNC_SUBx 1 -#define FOP_FNC_MULx 2 -#define FOP_FNC_DIVx 3 -#define FOP_FNC_CMPxUN 4 -#define FOP_FNC_CMPxEQ 5 -#define FOP_FNC_CMPxLT 6 -#define FOP_FNC_CMPxLE 7 -#define FOP_FNC_SQRTx 11 -#define FOP_FNC_CVTxS 12 -#define FOP_FNC_CVTxT 14 -#define FOP_FNC_CVTxQ 15 - -#define MISC_TRAPB 0x0000 -#define MISC_EXCB 0x0400 - -extern unsigned long alpha_read_fp_reg (unsigned long reg); -extern void alpha_write_fp_reg (unsigned long reg, unsigned long val); -extern unsigned long alpha_read_fp_reg_s (unsigned long reg); -extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val); - - -#ifdef MODULE - -MODULE_DESCRIPTION("FP Software completion module"); - -extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long); -extern long (*alpha_fp_emul) (unsigned long pc); - -static long (*save_emul_imprecise)(struct pt_regs *, unsigned long); -static long (*save_emul) (unsigned long pc); - -long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long); -long do_alpha_fp_emul(unsigned long); - -int init_module(void) -{ - save_emul_imprecise = alpha_fp_emul_imprecise; - save_emul = alpha_fp_emul; - alpha_fp_emul_imprecise = do_alpha_fp_emul_imprecise; - alpha_fp_emul = do_alpha_fp_emul; - return 0; -} - -void cleanup_module(void) -{ - alpha_fp_emul_imprecise = save_emul_imprecise; - alpha_fp_emul = save_emul; -} - -#undef alpha_fp_emul_imprecise -#define alpha_fp_emul_imprecise do_alpha_fp_emul_imprecise -#undef alpha_fp_emul -#define alpha_fp_emul do_alpha_fp_emul - -#endif /* MODULE */ - - -/* - * Emulate the floating point instruction at address PC. Returns -1 if the - * instruction to be emulated is illegal (such as with the opDEC trap), else - * the SI_CODE for a SIGFPE signal, else 0 if everything's ok. - * - * Notice that the kernel does not and cannot use FP regs. This is good - * because it means that instead of saving/restoring all fp regs, we simply - * stick the result of the operation into the appropriate register. - */ -long -alpha_fp_emul (unsigned long pc) -{ - FP_DECL_EX; - FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR); - FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR); - - unsigned long fa, fb, fc, func, mode, src; - unsigned long res, va, vb, vc, swcr, fpcr; - __u32 insn; - long si_code; - - get_user(insn, (__u32 __user *)pc); - fc = (insn >> 0) & 0x1f; /* destination register */ - fb = (insn >> 16) & 0x1f; - fa = (insn >> 21) & 0x1f; - func = (insn >> 5) & 0xf; - src = (insn >> 9) & 0x3; - mode = (insn >> 11) & 0x3; - - fpcr = rdfpcr(); - swcr = swcr_update_status(current_thread_info()->ieee_state, fpcr); - - if (mode == 3) { - /* Dynamic -- get rounding mode from fpcr. */ - mode = (fpcr >> FPCR_DYN_SHIFT) & 3; - } - - switch (src) { - case FOP_SRC_S: - va = alpha_read_fp_reg_s(fa); - vb = alpha_read_fp_reg_s(fb); - - FP_UNPACK_SP(SA, &va); - FP_UNPACK_SP(SB, &vb); - - switch (func) { - case FOP_FNC_SUBx: - FP_SUB_S(SR, SA, SB); - goto pack_s; - - case FOP_FNC_ADDx: - FP_ADD_S(SR, SA, SB); - goto pack_s; - - case FOP_FNC_MULx: - FP_MUL_S(SR, SA, SB); - goto pack_s; - - case FOP_FNC_DIVx: - FP_DIV_S(SR, SA, SB); - goto pack_s; - - case FOP_FNC_SQRTx: - FP_SQRT_S(SR, SB); - goto pack_s; - } - goto bad_insn; - - case FOP_SRC_T: - va = alpha_read_fp_reg(fa); - vb = alpha_read_fp_reg(fb); - - if ((func & ~3) == FOP_FNC_CMPxUN) { - FP_UNPACK_RAW_DP(DA, &va); - FP_UNPACK_RAW_DP(DB, &vb); - if (!DA_e && !_FP_FRAC_ZEROP_1(DA)) { - FP_SET_EXCEPTION(FP_EX_DENORM); - if (FP_DENORM_ZERO) - _FP_FRAC_SET_1(DA, _FP_ZEROFRAC_1); - } - if (!DB_e && !_FP_FRAC_ZEROP_1(DB)) { - FP_SET_EXCEPTION(FP_EX_DENORM); - if (FP_DENORM_ZERO) - _FP_FRAC_SET_1(DB, _FP_ZEROFRAC_1); - } - FP_CMP_D(res, DA, DB, 3); - vc = 0x4000000000000000UL; - /* CMPTEQ, CMPTUN don't trap on QNaN, - while CMPTLT and CMPTLE do */ - if (res == 3 - && ((func & 3) >= 2 - || FP_ISSIGNAN_D(DA) - || FP_ISSIGNAN_D(DB))) { - FP_SET_EXCEPTION(FP_EX_INVALID); - } - switch (func) { - case FOP_FNC_CMPxUN: if (res != 3) vc = 0; break; - case FOP_FNC_CMPxEQ: if (res) vc = 0; break; - case FOP_FNC_CMPxLT: if (res != -1) vc = 0; break; - case FOP_FNC_CMPxLE: if ((long)res > 0) vc = 0; break; - } - goto done_d; - } - - FP_UNPACK_DP(DA, &va); - FP_UNPACK_DP(DB, &vb); - - switch (func) { - case FOP_FNC_SUBx: - FP_SUB_D(DR, DA, DB); - goto pack_d; - - case FOP_FNC_ADDx: - FP_ADD_D(DR, DA, DB); - goto pack_d; - - case FOP_FNC_MULx: - FP_MUL_D(DR, DA, DB); - goto pack_d; - - case FOP_FNC_DIVx: - FP_DIV_D(DR, DA, DB); - goto pack_d; - - case FOP_FNC_SQRTx: - FP_SQRT_D(DR, DB); - goto pack_d; - - case FOP_FNC_CVTxS: - /* It is irritating that DEC encoded CVTST with - SRC == T_floating. It is also interesting that - the bit used to tell the two apart is /U... */ - if (insn & 0x2000) { - FP_CONV(S,D,1,1,SR,DB); - goto pack_s; - } else { - vb = alpha_read_fp_reg_s(fb); - FP_UNPACK_SP(SB, &vb); - DR_c = DB_c; - DR_s = DB_s; - DR_e = DB_e + (1024 - 128); - DR_f = SB_f << (52 - 23); - goto pack_d; - } - - case FOP_FNC_CVTxQ: - if (DB_c == FP_CLS_NAN - && (_FP_FRAC_HIGH_RAW_D(DB) & _FP_QNANBIT_D)) { - /* AAHB Table B-2 says QNaN should not trigger INV */ - vc = 0; - } else - FP_TO_INT_ROUND_D(vc, DB, 64, 2); - goto done_d; - } - goto bad_insn; - - case FOP_SRC_Q: - vb = alpha_read_fp_reg(fb); - - switch (func) { - case FOP_FNC_CVTQL: - /* Notice: We can get here only due to an integer - overflow. Such overflows are reported as invalid - ops. We return the result the hw would have - computed. */ - vc = ((vb & 0xc0000000) << 32 | /* sign and msb */ - (vb & 0x3fffffff) << 29); /* rest of the int */ - FP_SET_EXCEPTION (FP_EX_INVALID); - goto done_d; - - case FOP_FNC_CVTxS: - FP_FROM_INT_S(SR, ((long)vb), 64, long); - goto pack_s; - - case FOP_FNC_CVTxT: - FP_FROM_INT_D(DR, ((long)vb), 64, long); - goto pack_d; - } - goto bad_insn; - } - goto bad_insn; - -pack_s: - FP_PACK_SP(&vc, SR); - if ((_fex & FP_EX_UNDERFLOW) && (swcr & IEEE_MAP_UMZ)) - vc = 0; - alpha_write_fp_reg_s(fc, vc); - goto done; - -pack_d: - FP_PACK_DP(&vc, DR); - if ((_fex & FP_EX_UNDERFLOW) && (swcr & IEEE_MAP_UMZ)) - vc = 0; -done_d: - alpha_write_fp_reg(fc, vc); - goto done; - - /* - * Take the appropriate action for each possible - * floating-point result: - * - * - Set the appropriate bits in the FPCR - * - If the specified exception is enabled in the FPCR, - * return. The caller (entArith) will dispatch - * the appropriate signal to the translated program. - * - * In addition, properly track the exception state in software - * as described in the Alpha Architecture Handbook section 4.7.7.3. - */ -done: - if (_fex) { - /* Record exceptions in software control word. */ - swcr |= (_fex << IEEE_STATUS_TO_EXCSUM_SHIFT); - current_thread_info()->ieee_state - |= (_fex << IEEE_STATUS_TO_EXCSUM_SHIFT); - - /* Update hardware control register. */ - fpcr &= (~FPCR_MASK | FPCR_DYN_MASK); - fpcr |= ieee_swcr_to_fpcr(swcr); - wrfpcr(fpcr); - - /* Do we generate a signal? */ - _fex = _fex & swcr & IEEE_TRAP_ENABLE_MASK; - si_code = 0; - if (_fex) { - if (_fex & IEEE_TRAP_ENABLE_DNO) si_code = FPE_FLTUND; - if (_fex & IEEE_TRAP_ENABLE_INE) si_code = FPE_FLTRES; - if (_fex & IEEE_TRAP_ENABLE_UNF) si_code = FPE_FLTUND; - if (_fex & IEEE_TRAP_ENABLE_OVF) si_code = FPE_FLTOVF; - if (_fex & IEEE_TRAP_ENABLE_DZE) si_code = FPE_FLTDIV; - if (_fex & IEEE_TRAP_ENABLE_INV) si_code = FPE_FLTINV; - } - - return si_code; - } - - /* We used to write the destination register here, but DEC FORTRAN - requires that the result *always* be written... so we do the write - immediately after the operations above. */ - - return 0; - -bad_insn: - printk(KERN_ERR "alpha_fp_emul: Invalid FP insn %#x at %#lx\n", - insn, pc); - return -1; -} - -long -alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask) -{ - unsigned long trigger_pc = regs->pc - 4; - unsigned long insn, opcode, rc, si_code = 0; - - /* - * Turn off the bits corresponding to registers that are the - * target of instructions that set bits in the exception - * summary register. We have some slack doing this because a - * register that is the target of a trapping instruction can - * be written at most once in the trap shadow. - * - * Branches, jumps, TRAPBs, EXCBs and calls to PALcode all - * bound the trap shadow, so we need not look any further than - * up to the first occurrence of such an instruction. - */ - while (write_mask) { - get_user(insn, (__u32 __user *)(trigger_pc)); - opcode = insn >> 26; - rc = insn & 0x1f; - - switch (opcode) { - case OPC_PAL: - case OPC_JSR: - case 0x30 ... 0x3f: /* branches */ - goto egress; - - case OPC_MISC: - switch (insn & 0xffff) { - case MISC_TRAPB: - case MISC_EXCB: - goto egress; - - default: - break; - } - break; - - case OPC_INTA: - case OPC_INTL: - case OPC_INTS: - case OPC_INTM: - write_mask &= ~(1UL << rc); - break; - - case OPC_FLTC: - case OPC_FLTV: - case OPC_FLTI: - case OPC_FLTL: - write_mask &= ~(1UL << (rc + 32)); - break; - } - if (!write_mask) { - /* Re-execute insns in the trap-shadow. */ - regs->pc = trigger_pc + 4; - si_code = alpha_fp_emul(trigger_pc); - goto egress; - } - trigger_pc -= 4; - } - -egress: - return si_code; -} diff --git a/ANDROID_3.4.5/arch/alpha/math-emu/qrnnd.S b/ANDROID_3.4.5/arch/alpha/math-emu/qrnnd.S deleted file mode 100644 index d6373ec1..00000000 --- a/ANDROID_3.4.5/arch/alpha/math-emu/qrnnd.S +++ /dev/null @@ -1,163 +0,0 @@ - # Alpha 21064 __udiv_qrnnd - # Copyright (C) 1992, 1994, 1995, 2000 Free Software Foundation, Inc. - - # This file is part of GCC. - - # The GNU MP Library is free software; you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by - # the Free Software Foundation; either version 2 of the License, or (at your - # option) any later version. - - # In addition to the permissions in the GNU General Public License, the - # Free Software Foundation gives you unlimited permission to link the - # compiled version of this file with other programs, and to distribute - # those programs without any restriction coming from the use of this - # file. (The General Public License restrictions do apply in other - # respects; for example, they cover modification of the file, and - # distribution when not linked into another program.) - - # This file is distributed in the hope that it will be useful, but - # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - # License for more details. - - # You should have received a copy of the GNU General Public License - # along with GCC; see the file COPYING. If not, write to the - # Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - # MA 02111-1307, USA. - - .set noreorder - .set noat - - .text - - .globl __udiv_qrnnd - .ent __udiv_qrnnd -__udiv_qrnnd: - .frame $30,0,$26,0 - .prologue 0 - -#define cnt $2 -#define tmp $3 -#define rem_ptr $16 -#define n1 $17 -#define n0 $18 -#define d $19 -#define qb $20 -#define AT $at - - ldiq cnt,16 - blt d,$largedivisor - -$loop1: cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule d,n1,qb - subq n1,d,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule d,n1,qb - subq n1,d,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule d,n1,qb - subq n1,d,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule d,n1,qb - subq n1,d,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - subq cnt,1,cnt - bgt cnt,$loop1 - stq n1,0(rem_ptr) - bis $31,n0,$0 - ret $31,($26),1 - -$largedivisor: - and n0,1,$4 - - srl n0,1,n0 - sll n1,63,tmp - or tmp,n0,n0 - srl n1,1,n1 - - and d,1,$6 - srl d,1,$5 - addq $5,$6,$5 - -$loop2: cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule $5,n1,qb - subq n1,$5,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule $5,n1,qb - subq n1,$5,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule $5,n1,qb - subq n1,$5,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - cmplt n0,0,tmp - addq n1,n1,n1 - bis n1,tmp,n1 - addq n0,n0,n0 - cmpule $5,n1,qb - subq n1,$5,tmp - cmovne qb,tmp,n1 - bis n0,qb,n0 - subq cnt,1,cnt - bgt cnt,$loop2 - - addq n1,n1,n1 - addq $4,n1,n1 - bne $6,$Odd - stq n1,0(rem_ptr) - bis $31,n0,$0 - ret $31,($26),1 - -$Odd: - /* q' in n0. r' in n1 */ - addq n1,n0,n1 - - cmpult n1,n0,tmp # tmp := carry from addq - subq n1,d,AT - addq n0,tmp,n0 - cmovne tmp,AT,n1 - - cmpult n1,d,tmp - addq n0,1,AT - cmoveq tmp,AT,n0 - subq n1,d,AT - cmoveq tmp,AT,n1 - - stq n1,0(rem_ptr) - bis $31,n0,$0 - ret $31,($26),1 - - .end __udiv_qrnnd diff --git a/ANDROID_3.4.5/arch/alpha/math-emu/sfp-util.h b/ANDROID_3.4.5/arch/alpha/math-emu/sfp-util.h deleted file mode 100644 index f53707f7..00000000 --- a/ANDROID_3.4.5/arch/alpha/math-emu/sfp-util.h +++ /dev/null @@ -1,35 +0,0 @@ -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <asm/byteorder.h> -#include <asm/fpu.h> - -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - ((sl) = (al) + (bl), (sh) = (ah) + (bh) + ((sl) < (al))) - -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - ((sl) = (al) - (bl), (sh) = (ah) - (bh) - ((al) < (bl))) - -#define umul_ppmm(wh, wl, u, v) \ - __asm__ ("mulq %2,%3,%1; umulh %2,%3,%0" \ - : "=r" ((UDItype)(wh)), \ - "=&r" ((UDItype)(wl)) \ - : "r" ((UDItype)(u)), \ - "r" ((UDItype)(v))) - -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { unsigned long __r; \ - (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ - (r) = __r; \ - } while (0) -extern unsigned long __udiv_qrnnd (unsigned long *, unsigned long, - unsigned long , unsigned long); - -#define UDIV_NEEDS_NORMALIZATION 1 - -#define abort() goto bad_insn - -#ifndef __LITTLE_ENDIAN -#define __LITTLE_ENDIAN -1 -#endif -#define __BYTE_ORDER __LITTLE_ENDIAN |