Exemple #1
0
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;
}
Exemple #2
0
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;
}