unsigned int PerformSTF(const unsigned int opcode) { unsigned int *pBase, *pAddress, *pFinal, nRc = 1, write_back = WRITE_BACK(opcode); //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); SetRoundingMode(ROUND_TO_NEAREST); pBase = (unsigned int*)readRegister(getRn(opcode)); if (REG_PC == getRn(opcode)) { pBase += 2; write_back = 0; } pFinal = pBase; if (BIT_UP_SET(opcode)) pFinal += getOffset(opcode); else pFinal -= getOffset(opcode); if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; switch (opcode & MASK_TRANSFER_LENGTH) { case TRANSFER_SINGLE : storeSingle(getFd(opcode),pAddress); break; case TRANSFER_DOUBLE : storeDouble(getFd(opcode),pAddress); break; case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break; default: nRc = 0; } if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); return nRc; }
unsigned int PerformSTF(const unsigned int opcode) { unsigned int __user *pBase, *pAddress, *pFinal; unsigned int nRc = 1, write_back = WRITE_BACK(opcode); struct roundingData roundData; roundData.mode = SetRoundingMode(opcode); roundData.precision = SetRoundingPrecision(opcode); roundData.exception = 0; pBase = (unsigned int __user *) readRegister(getRn(opcode)); if (REG_PC == getRn(opcode)) { pBase += 2; write_back = 0; } pFinal = pBase; if (BIT_UP_SET(opcode)) pFinal += getOffset(opcode); else pFinal -= getOffset(opcode); if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase; switch (opcode & MASK_TRANSFER_LENGTH) { case TRANSFER_SINGLE: storeSingle(&roundData, getFd(opcode), pAddress); break; case TRANSFER_DOUBLE: storeDouble(&roundData, getFd(opcode), pAddress); break; #ifdef CONFIG_FPE_NWFPE_XP case TRANSFER_EXTENDED: storeExtended(getFd(opcode), pAddress); break; #endif default: nRc = 0; } if (roundData.exception) float_raise(roundData.exception); if (write_back) writeRegister(getRn(opcode), (unsigned long) pFinal); return nRc; }
void AssemblyHelpers::callExceptionFuzz() { if (!Options::enableExceptionFuzz()) return; EncodedJSValue* buffer = vm()->exceptionFuzzingBuffer(sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters)); for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) { #if USE(JSVALUE64) store64(GPRInfo::toRegister(i), buffer + i); #else store32(GPRInfo::toRegister(i), buffer + i); #endif } for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0); storeDouble(FPRInfo::toRegister(i), Address(GPRInfo::regT0)); } // Set up one argument. #if CPU(X86) poke(GPRInfo::callFrameRegister, 0); #else move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); #endif move(TrustedImmPtr(bitwise_cast<void*>(operationExceptionFuzz)), GPRInfo::nonPreservedNonReturnGPR); call(GPRInfo::nonPreservedNonReturnGPR); for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) { move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0); loadDouble(Address(GPRInfo::regT0), FPRInfo::toRegister(i)); } for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) { #if USE(JSVALUE64) load64(buffer + i, GPRInfo::toRegister(i)); #else load32(buffer + i, GPRInfo::toRegister(i)); #endif } }
static bool genArithOpDouble(CompilationUnit *cUnit, MIR *mir, int vDest, int vSrc1, int vSrc2) { int op = THUMB_BKPT; /* * Don't attempt to optimize register usage since these opcodes call out to * the handlers. */ switch (mir->dalvikInsn.opCode) { case OP_ADD_DOUBLE_2ADDR: case OP_ADD_DOUBLE: op = THUMB2_VADDD; break; case OP_SUB_DOUBLE_2ADDR: case OP_SUB_DOUBLE: op = THUMB2_VSUBD; break; case OP_DIV_DOUBLE_2ADDR: case OP_DIV_DOUBLE: op = THUMB2_VDIVD; break; case OP_MUL_DOUBLE_2ADDR: case OP_MUL_DOUBLE: op = THUMB2_VMULD; break; case OP_REM_DOUBLE_2ADDR: case OP_REM_DOUBLE: case OP_NEG_DOUBLE: { return genArithOpDoublePortable(cUnit, mir, vDest, vSrc1, vSrc2); } default: return true; } loadDouble(cUnit, vSrc1, dr1); loadDouble(cUnit, vSrc2, dr2); newLIR3(cUnit, op, dr0, dr1, dr2); storeDouble(cUnit, dr0, vDest, 0); return false; }
static bool genConversion(CompilationUnit *cUnit, MIR *mir) { OpCode opCode = mir->dalvikInsn.opCode; int vSrc1Dest = mir->dalvikInsn.vA; int vSrc2 = mir->dalvikInsn.vB; int op = THUMB_BKPT; bool longSrc = false; bool longDest = false; int srcReg; int tgtReg; switch (opCode) { case OP_INT_TO_FLOAT: longSrc = false; longDest = false; op = THUMB2_VCVTIF; break; case OP_FLOAT_TO_INT: longSrc = false; longDest = false; op = THUMB2_VCVTFI; break; case OP_DOUBLE_TO_FLOAT: longSrc = true; longDest = false; op = THUMB2_VCVTDF; break; case OP_FLOAT_TO_DOUBLE: longSrc = false; longDest = true; op = THUMB2_VCVTFD; break; case OP_INT_TO_DOUBLE: longSrc = false; longDest = true; op = THUMB2_VCVTID; break; case OP_DOUBLE_TO_INT: longSrc = true; longDest = false; op = THUMB2_VCVTDI; break; case OP_FLOAT_TO_LONG: case OP_LONG_TO_FLOAT: case OP_DOUBLE_TO_LONG: case OP_LONG_TO_DOUBLE: return genConversionPortable(cUnit, mir); default: return true; } if (longSrc) { srcReg = dr1; loadDouble(cUnit, vSrc2, srcReg); } else { srcReg = fr2; loadFloat(cUnit, vSrc2, srcReg); } if (longDest) { newLIR2(cUnit, op, dr0, srcReg); storeDouble(cUnit, dr0, vSrc1Dest, 0); } else { newLIR2(cUnit, op, fr0, srcReg); storeFloat(cUnit, fr0, vSrc1Dest, 0); } return false; }