unsigned int PerformLDF(const unsigned int opcode) { unsigned int *pBase, *pAddress, *pFinal, nRc = 1, write_back = WRITE_BACK(opcode); //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode)); 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 : loadSingle(getFd(opcode),pAddress); break; case TRANSFER_DOUBLE : loadDouble(getFd(opcode),pAddress); break; case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break; default: nRc = 0; } if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal); return nRc; }
void AssemblyHelpers::purifyNaN(FPRReg fpr) { MacroAssembler::Jump notNaN = branchDouble(DoubleEqual, fpr, fpr); static const double NaN = PNaN; loadDouble(TrustedImmPtr(&NaN), fpr); notNaN.link(this); }
static bool genInlineSqrt(CompilationUnit *cUnit, MIR *mir) { int offset = offsetof(InterpState, retval); int vSrc = mir->dalvikInsn.vA; loadDouble(cUnit, vSrc, dr1); newLIR2(cUnit, THUMB2_VSQRTD, dr0, dr1); assert(offset & 0x3 == 0); /* Must be word aligned */ assert(offset < 1024); newLIR3(cUnit, THUMB2_VSTRD, dr0, rGLUE, offset >> 2); return true; }
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; }
unsigned int PerformLDF(const unsigned int opcode) { unsigned int __user *pBase, *pAddress, *pFinal; unsigned int nRc = 1, write_back = WRITE_BACK(opcode); 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: loadSingle(getFd(opcode), pAddress); break; case TRANSFER_DOUBLE: loadDouble(getFd(opcode), pAddress); break; #ifdef CONFIG_FPE_NWFPE_XP case TRANSFER_EXTENDED: loadExtended(getFd(opcode), pAddress); break; #endif default: nRc = 0; } 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 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; }
void Interpreter::executeFun(uint16_t id) { _bc = ((BytecodeFunction*)_code->functionById(id))->bytecode(); _insPtr = 0; Instruction inst; while (true) { inst = nextInsn(); //cout << "Current instruction " << inst << endl; //cout << "__STACK:" << endl; //printStack(); switch (inst) { case BC_INVALID: _out << inst << " Invalid instruction" << endl; assert(false); break; case BC_DLOAD: loadDouble(); break; case BC_ILOAD: loadInt(); break; case BC_SLOAD: loadString(); break; case BC_DLOAD0: _out << inst << " Not implemented" << endl; assert(false); break; case BC_ILOAD0: pushInt(0); break; case BC_SLOAD0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_DLOAD1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_ILOAD1: pushInt(1); break; case BC_DLOADM1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_ILOADM1: pushInt(-1); break; case BC_DADD: addDoubles(); break; case BC_IADD: addInts(); break; case BC_DSUB: subDoubles(); break; case BC_ISUB: subInts(); break; case BC_DMUL: dMul(); break; case BC_IMUL: iMul(); break; case BC_DDIV: divDoubles(); break; case BC_IDIV: divInts(); break; case BC_IMOD: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_DNEG: dNeg(); break; case BC_INEG: iNeg(); break; case BC_IPRINT: printInt(); break; case BC_DPRINT: printDouble(); break; case BC_SPRINT: printString(); break; case BC_I2D: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_D2I: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_S2I: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_SWAP: swap(); break; case BC_POP: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADCTXDVAR: loadCtxDouble(); break; case BC_LOADCTXIVAR: loadCtxInt(); break; case BC_LOADCTXSVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORECTXDVAR: storeCtxDouble(); break; case BC_STORECTXIVAR: storeCtxInt(); break; case BC_STORECTXSVAR: _out << inst << " STORE STRING ? Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_DCMP: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_ICMP: compareInts(); break; case BC_JA: jumpAlways(); break; case BC_IFICMPNE: intsNotEqualJMP(); break; case BC_IFICMPE: intsEqualJMP(); break; case BC_IFICMPG: GJump(); break; case BC_IFICMPGE: GEJump(); break; case BC_IFICMPL: //cout << "IFLESS" << endl; assert(false); break; case BC_IFICMPLE: LEJump(); break; case BC_DUMP: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOP: this->popContext(); return; case BC_CALL: //cout << "CALLING. STACK SIZE: " << _stack.size() << endl; call(); break; case BC_CALLNATIVE: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_RETURN: doReturn(); break; case BC_BREAK: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; default: _out << "Bad instruction" << endl; break; } } this->popContext(); }