/* * Emulate a VFP instruction. */ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) { u32 exceptions = VFP_EXCEPTION_ERROR; pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr); if (INST_CPRTDO(inst)) { if (!INST_CPRT(inst)) { /* * CPDO */ if (vfp_single(inst)) { exceptions = vfp_single_cpdo(inst, fpscr); } else { exceptions = vfp_double_cpdo(inst, fpscr); } } else { /* * A CPRT instruction can not appear in FPINST2, nor * can it cause an exception. Therefore, we do not * have to emulate it. */ } } else { /* * A CPDT instruction can not appear in FPINST2, nor can * it cause an exception. Therefore, we do not have to * emulate it. */ } return exceptions & ~VFP_NAN_FLAG; }
unsigned VFPCDP (ARMul_State * state, unsigned type, ARMword instr) { /* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */ int CoProc = BITS (8, 11); /* 10 or 11 */ int OPC_1 = BITS (20, 23); int CRd = BITS (12, 15); int CRn = BITS (16, 19); int CRm = BITS (0, 3); int OPC_2 = BITS (5, 7); /* TODO check access permission */ /* CRn/opc1 CRm/opc2 */ if (CoProc == 10 || CoProc == 11) { #define VFP_CDP_TRANS #include "core/arm/interpreter/vfp/vfpinstr.cpp" #undef VFP_CDP_TRANS int exceptions = 0; if (CoProc == 10) exceptions = vfp_single_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); else exceptions = vfp_double_cpdo(state, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); vfp_raise_exceptions(state, exceptions, instr, state->VFP[VFP_OFFSET(VFP_FPSCR)]); return ARMul_DONE; } DEBUG_LOG(ARM11, "Can't identify %x\n", instr); return ARMul_CANT; }
static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) { u32 exceptions = VFP_EXCEPTION_ERROR; pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr); if (INST_CPRTDO(inst)) { if (!INST_CPRT(inst)) { if (vfp_single(inst)) { exceptions = vfp_single_cpdo(inst, fpscr); } else { exceptions = vfp_double_cpdo(inst, fpscr); } } else { } } else { } return exceptions & ~VFP_NAN_FLAG; }