/** * Print a memory intrinsic function. * * @param inst the instruction */ void JVMWriter::printMemIntrinsic(const MemIntrinsic *inst) { printValueLoad(inst->getDest()); if(const MemTransferInst *minst = dyn_cast<MemTransferInst>(inst)) printValueLoad(minst->getSource()); else if(const MemSetInst *minst = dyn_cast<MemSetInst>(inst)) printValueLoad(minst->getValue()); printValueLoad(inst->getLength()); printConstLoad(inst->getAlignmentCst()); std::string lenDescriptor = getTypeDescriptor( inst->getLength()->getType(), true); switch(inst->getIntrinsicID()) { case Intrinsic::memcpy: printSimpleInstruction("invokestatic", "lljvm/runtime/Memory/memcpy(II" + lenDescriptor + "I)V"); break; case Intrinsic::memmove: printSimpleInstruction("invokestatic", "lljvm/runtime/Memory/memmove(II" + lenDescriptor + "I)V"); break; case Intrinsic::memset: printSimpleInstruction("invokestatic", "lljvm/runtime/Memory/memset(IB" + lenDescriptor + "I)V"); break; } }
/** * Print the static class initialization method. */ void JVMWriter::printClInit() { //out << ".method public <clinit>()V\n"; out << ".method public initialiseEnvironment(Llljvm/runtime/Environment;)V\n"; printSimpleInstruction(".limit stack 5"); printSimpleInstruction(".limit locals 2"); out << "\n\t; load environment into class\n"; printSimpleInstruction("aload_0"); // this. printSimpleInstruction("aload_1"); // value printSimpleInstruction("putfield "+classname+"/__env Llljvm/runtime/Environment;"); out << "\n\t; allocate global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printLoadMemoryToStack(); printConstLoad( APInt(32, targetData->getTypeAllocSize(c->getType()), false)); printSimpleInstruction("invokevirtual", "lljvm/runtime/Memory/allocateData(I)I"); printSimpleInstruction("aload_0"); // "this" printSimpleInstruction("swap"); // move this 1 down the stack printSimpleInstruction("putfield", classname + "/" + getValueName(g) + " I"); } } out << "\n\t; initialise global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("aload_0"); // "this" printSimpleInstruction("getfield", classname + "/" + getValueName(g) + " I"); printStaticConstant(c); printSimpleInstruction("pop"); out << '\n'; } } printSimpleInstruction("return"); out << ".end method\n\n"; }
/** * Print a va_arg instruction. * * @param inst the instruction */ void JVMWriter::printVAArgInstruction(const VAArgInst *inst) { printIndirectLoad(inst->getOperand(0)); printSimpleInstruction("dup"); // op op printLoadMemoryToStack( ); // op op memory printSimpleInstruction("swap"); // op memory op printConstLoad( APInt(32, targetData->getTypeAllocSize(inst->getType()), false)); // op memory op const printSimpleInstruction("iadd"); // op memory added printValueLoad(inst->getOperand(0)); // op memory added loaded printSimpleInstruction("swap"); // op memory loaded added printIndirectStore(PointerType::getUnqual( IntegerType::get(inst->getContext(), 8))); // op printIndirectLoad(inst->getType()); }
/** * Load the given value. * * @param v the value to load */ void JVMWriter::printValueLoad(const Value *v) { if(const Function *f = dyn_cast<Function>(v)) { std::string sig = getValueName(f) + getCallSignature(f->getFunctionType()); if(externRefs.count(v)) printSimpleInstruction("CLASSFORMETHOD", sig); else printSimpleInstruction("ldc", '"' + classname + '"'); printSimpleInstruction("ldc", '"' + sig + '"'); printSimpleInstruction("invokestatic", "lljvm/runtime/Function/getFunctionPointer" "(Ljava/lang/String;Ljava/lang/String;)I"); } else if(isa<GlobalVariable>(v)) { const Type *ty = cast<PointerType>(v->getType())->getElementType(); if(externRefs.count(v)) printSimpleInstruction("getstatic", getValueName(v) + " I"); else printSimpleInstruction("getstatic", classname + "/" + getValueName(v) + " I"); } else if(isa<ConstantPointerNull>(v)) { printPtrLoad(0); } else if(const ConstantExpr *ce = dyn_cast<ConstantExpr>(v)) { printConstantExpr(ce); } else if(const Constant *c = dyn_cast<Constant>(v)) { printConstLoad(c); } else { if(getLocalVarNumber(v) <= 3) printSimpleInstruction( getTypePrefix(v->getType(), true) + "load_" + utostr(getLocalVarNumber(v)) + " ; " + getValueName(v)); else printSimpleInstruction( getTypePrefix(v->getType(), true) + "load", utostr(getLocalVarNumber(v)) + " ; " + getValueName(v)); } }
/** * Print the static class initialization method. */ void JVMWriter::printClInit() { out << ".method public <clinit>()V\n"; printSimpleInstruction(".limit stack 4"); out << "\n\t; allocate global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printConstLoad( APInt(32, targetData->getTypeAllocSize(c->getType()), false)); printSimpleInstruction("invokestatic", "lljvm/runtime/Memory/allocateData(I)I"); printSimpleInstruction("putstatic", classname + "/" + getValueName(g) + " I"); } } out << "\n\t; initialise global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("getstatic", classname + "/" + getValueName(g) + " I"); printStaticConstant(c); printSimpleInstruction("pop"); out << '\n'; } } printSimpleInstruction("return"); out << ".end method\n\n"; }
/** * Print the class constructor. */ void JVMWriter::printConstructor() { out << "; Constructor\n" ".method public <init>()V\n"; printSimpleInstruction("aload_0"); printSimpleInstruction("invokespecial","java/lang/Object/<init>()V"); printSimpleInstruction("return"); printSimpleInstruction(".limit stack 1"); printSimpleInstruction(".limit locals 1"); out << ".end method\n\n"; out << ".method public initialize(Llljvm/runtime/Context;)V\n"; printSimpleInstruction(".limit stack 12"); printSimpleInstruction(".limit locals 2"); out << "\n;;;START LINKER INITIALIZATIONS;;;\n"; printInitLinkerFields(); out << ";;;END LINKER INITIALIZATIONS;;;\n\n"; out << "\n\t; allocate global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("aload_0"); printStartInvocationTag(); printConstLoad( APInt(32, targetData->getTypeAllocSize(c->getType()), false)); printEndInvocationTag("lljvm/runtime/Memory/allocateData(I)I"); printSimpleInstruction("putfield", classname + "/" + getValueName(g) + " I"); } } out << "\n\t; initialize global variables\n"; for(Module::global_iterator i = module->global_begin(), e = module->global_end(); i != e; i++) { if(!i->isDeclaration()) { const GlobalVariable *g = i; const Constant *c = g->getInitializer(); printSimpleInstruction("aload_0"); printSimpleInstruction("getfield", classname + "/" + getValueName(g) + " I"); printStaticConstant(c); printSimpleInstruction("pop"); out << '\n'; } } out << "\n" "\treturn\n" ".end method\n\n"; out << ".method public destroy(Llljvm/runtime/Context;)V\n"; printSimpleInstruction("return"); printSimpleInstruction(".limit stack 0"); printSimpleInstruction(".limit locals 2"); out << ".end method\n\n"; }