/** * Print a getelementptr instruction. * * @param v the aggregate data structure to index * @param i an iterator to the first type indexed by the instruction * @param e an iterator specifying the upper bound on the types indexed by the * instruction */ void JVMWriter::printGepInstruction(const Value *v, gep_type_iterator i, gep_type_iterator e) { // load address printCastInstruction(Instruction::IntToPtr, v, NULL, v->getType()); // calculate offset for(; i != e; i++) { unsigned int size = 0; const Value *indexValue = i.getOperand(); if(const StructType *structTy = dyn_cast<StructType>(*i)) { for(unsigned int f = 0, fieldIndex = cast<ConstantInt>(indexValue)->getZExtValue(); f < fieldIndex; f++) size = alignOffset( size + targetData->getTypeAllocSize( structTy->getContainedType(f)), targetData->getABITypeAlignment( structTy->getContainedType(f + 1))); printPtrLoad(size); printSimpleInstruction("iadd"); } else { if(const SequentialType *seqTy = dyn_cast<SequentialType>(*i)) size = targetData->getTypeAllocSize(seqTy->getElementType()); else size = targetData->getTypeAllocSize(*i); if(const ConstantInt *c = dyn_cast<ConstantInt>(indexValue)) { // constant optimisation if(c->isNullValue()) { // do nothing } else if(c->getValue().isNegative()) { printPtrLoad(c->getValue().abs().getZExtValue() * size); printSimpleInstruction("isub"); } else { printPtrLoad(c->getZExtValue() * size); printSimpleInstruction("iadd"); } } else { printPtrLoad(size); printCastInstruction(Instruction::IntToPtr, indexValue, NULL, indexValue->getType()); printSimpleInstruction("imul"); printSimpleInstruction("iadd"); } } } }
/** * Print an alloca instruction. * * @param inst the instruction */ void JVMWriter::printAllocaInstruction(const AllocaInst *inst) { uint64_t size = targetData->getTypeAllocSize(inst->getAllocatedType()); printLoadMemoryToStack( ); if(const ConstantInt *c = dyn_cast<ConstantInt>(inst->getOperand(0))) { // constant optimization printPtrLoad(c->getZExtValue() * size); } else { printPtrLoad(size); printValueLoad(inst->getOperand(0)); printSimpleInstruction("imul"); } printSimpleInstruction("invokevirtual", "lljvm/runtime/Memory/allocateStack(I)I"); }
/** * 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)); } }