Ejemplo n.º 1
0
/**
 * Print the virtual instruction with the given signature.
 * 
 * @param sig    the signature of the instruction
 * @param left   the first operand
 * @param right  the second operand
 */
void JVMWriter::printVirtualInstruction(const std::string &sig,
                                        const Value *left,
                                        const Value *right) {
    printValueLoad(left);
    printValueLoad(right);
    printVirtualInstruction(sig);
}
Ejemplo n.º 2
0
/**
 * Print the given binary instruction.
 * 
 * @param name   the name of the instruction
 * @param left   the first operand
 * @param right  the second operand
 */
void JVMWriter::printBinaryInstruction(const std::string &name,
                                       const Value *left,
                                       const Value *right) {
    printValueLoad(left);
    printValueLoad(right);
    out << '\t' << name << '\n';
}
Ejemplo n.º 3
0
/**
 * 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;
    }
}
Ejemplo n.º 4
0
/**
 * Print a mathematical intrinsic function.
 *
 * @param inst  the instruction
 */
void JVMWriter::printMathIntrinsic(const IntrinsicInst *inst) {
    bool f32 = (getBitWidth(inst->getOperand(1)->getType()) == 32);
    printValueLoad(inst->getOperand(1));
    if(f32) printSimpleInstruction("f2d");
    if(inst->getNumOperands() >= 3) {
        printValueLoad(inst->getOperand(2));
        if(f32) printSimpleInstruction("f2d");
    }
    switch(inst->getIntrinsicID()) {
    case Intrinsic::exp:
        printSimpleInstruction("invokestatic", "java/lang/Math/exp(D)D");
        break;
    case Intrinsic::log:
        printSimpleInstruction("invokestatic", "java/lang/Math/log(D)D");
        break;
    case Intrinsic::log10:
        printSimpleInstruction("invokestatic", "java/lang/Math/log10(D)D");
        break;
    case Intrinsic::sqrt:
        printSimpleInstruction("invokestatic", "java/lang/Math/sqrt(D)D");
        break;
    case Intrinsic::pow:
        printSimpleInstruction("invokestatic", "java/lang/Math/pow(DD)D");
        break;
    }
    if(f32) printSimpleInstruction("d2f");
}
Ejemplo n.º 5
0
/**
 * Print an arithmetic instruction.
 *
 * @param op     the opcode for the instruction
 * @param left   the first operand of the instruction
 * @param right  the second operand of the instruction
 */
void JVMWriter::printArithmeticInstruction(unsigned int op,
        const Value *left,
        const Value *right) {
    printValueLoad(left);
    printValueLoad(right);
    std::string typePrefix = getTypePrefix(left->getType(), true);
    std::string typeDescriptor = getTypeDescriptor(left->getType());
    switch(op) {
    case Instruction::Add:
    case Instruction::FAdd:
        printSimpleInstruction(typePrefix + "add");
        break;
    case Instruction::Sub:
    case Instruction::FSub:
        printSimpleInstruction(typePrefix + "sub");
        break;
    case Instruction::Mul:
    case Instruction::FMul:
        printSimpleInstruction(typePrefix + "mul");
        break;
    case Instruction::SDiv:
    case Instruction::FDiv:
        printSimpleInstruction(typePrefix + "div");
        break;
    case Instruction::SRem:
    case Instruction::FRem:
        printSimpleInstruction(typePrefix + "rem");
        break;
    case Instruction::And:
        printSimpleInstruction(typePrefix + "and");
        break;
    case Instruction::Or:
        printSimpleInstruction(typePrefix + "or");
        break;
    case Instruction::Xor:
        printSimpleInstruction(typePrefix + "xor");
        break;
    case Instruction::Shl:
        if(getBitWidth(right->getType()) == 64) printSimpleInstruction("l2i");
        printSimpleInstruction(typePrefix + "shl");
        break;
    case Instruction::LShr:
        if(getBitWidth(right->getType()) == 64) printSimpleInstruction("l2i");
        printSimpleInstruction(typePrefix + "ushr");
        break;
    case Instruction::AShr:
        if(getBitWidth(right->getType()) == 64) printSimpleInstruction("l2i");
        printSimpleInstruction(typePrefix + "shr");
        break;
    case Instruction::UDiv:
        printVirtualInstruction(
            "udiv(" + typeDescriptor + typeDescriptor + ")" + typeDescriptor);
        break;
    case Instruction::URem:
        printVirtualInstruction(
            "urem(" + typeDescriptor + typeDescriptor + ")" + typeDescriptor);
        break;
    }
}
Ejemplo n.º 6
0
/**
 * Print a select instruction.
 * 
 * @param cond      the condition
 * @param trueVal   the return value of the instruction if the condition is
 *                  non-zero
 * @param falseVal  the return value of the instruction if the condition is
 *                  zero
 */
void JVMWriter::printSelectInstruction(const Value *cond,
                                       const Value *trueVal,
                                       const Value *falseVal) {
    std::string labelname = "select" + utostr(getUID());
    printValueLoad(cond);
    printSimpleInstruction("ifeq", labelname + "a");
    printValueLoad(trueVal);
    printSimpleInstruction("goto", labelname + "b");
    printLabel(labelname + "a");
    printValueLoad(falseVal);
    printLabel(labelname + "b");
}
Ejemplo n.º 7
0
/**
 * Load a value from the given address.
 * 
 * @param v  the address
 */
void JVMWriter::printIndirectLoad(const Value *v) {
    printValueLoad(v);
    const Type *ty = v->getType();
    if(const PointerType *p = dyn_cast<PointerType>(ty))
        ty = p->getElementType();
    printIndirectLoad(ty);
}
Ejemplo n.º 8
0
/**
 * Print a branch instruction.
 * 
 * @param inst  the branch instrtuction
 */
void JVMWriter::printBranchInstruction(const BranchInst *inst) {
    if(inst->isUnconditional()) {
        printBranchInstruction(inst->getParent(), inst->getSuccessor(0));
    } else {
        printValueLoad(inst->getCondition());
        printBranchInstruction(
            inst->getParent(), inst->getSuccessor(0), inst->getSuccessor(1));
    }
}
Ejemplo n.º 9
0
/**
 * Replace PHI instructions with copy instructions (load-store pairs).
 * 
 * @param src   the predecessor block
 * @param dest  the destination block
 */
void JVMWriter::printPHICopy(const BasicBlock *src, const BasicBlock *dest) {
    for(BasicBlock::const_iterator i = dest->begin(); isa<PHINode>(i); i++) {
        const PHINode *phi = cast<PHINode>(i);
        const Value *val = phi->getIncomingValueForBlock(src);
        if(isa<UndefValue>(val))
            continue;
        printValueLoad(val);
        printValueStore(phi);
    }
}
Ejemplo n.º 10
0
/**
 * Print a vararg intrinsic function.
 *
 * @param inst  the instruction
 */
void JVMWriter::printVAIntrinsic(const IntrinsicInst *inst) {
    const Type *valistTy = PointerType::getUnqual(
                               IntegerType::get(inst->getContext(), 8));
    switch(inst->getIntrinsicID()) {
    case Intrinsic::vastart:
        printLoadMemoryToStack( );
        printValueLoad(inst->getOperand(1));
        printSimpleInstruction("iload", utostr(vaArgNum) + " ; varargptr");
        printIndirectStore(valistTy);
        break;
    case Intrinsic::vacopy:
        printLoadMemoryToStack( );
        printValueLoad(inst->getOperand(1));
        printValueLoad(inst->getOperand(2));
        printIndirectLoad(valistTy);
        printIndirectStore(valistTy);
        break;
    case Intrinsic::vaend:
        break;
    }
}
Ejemplo n.º 11
0
/**
 * Print a cast instruction.
 *
 * @param op    the opcode for the instruction
 * @param v     the value to be casted
 * @param ty    the destination type
 * @param srcTy the source type
 */
void JVMWriter::printCastInstruction(unsigned int op, const Value *v,
                                     const Type *ty, const Type *srcTy) {
    printValueLoad(v);
    switch(op) {
    case Instruction::SIToFP:
    case Instruction::FPToSI:
    case Instruction::FPTrunc:
    case Instruction::FPExt:
    case Instruction::SExt:
        if(getBitWidth(srcTy) < 32)
            printCastInstruction(getTypePrefix(srcTy), "i");
        printCastInstruction(getTypePrefix(ty, true),
                             getTypePrefix(srcTy, true));
        break;
    case Instruction::Trunc:
        if(getBitWidth(srcTy) == 64 && getBitWidth(ty) < 32) {
            printSimpleInstruction("l2i");
            printCastInstruction(getTypePrefix(ty), "i");
        } else
            printCastInstruction(getTypePrefix(ty),
                                 getTypePrefix(srcTy, true));
        break;
    case Instruction::IntToPtr:
        printCastInstruction("i", getTypePrefix(srcTy, true));
        break;
    case Instruction::PtrToInt:
        printCastInstruction(getTypePrefix(ty), "i");
        break;
    case Instruction::ZExt:
        printVirtualInstruction("zext_" + getTypePostfix(ty, true)
                                + "(" + getTypeDescriptor(srcTy) + ")"
                                + getTypeDescriptor(ty, true));
        break;
    case Instruction::UIToFP:
        printVirtualInstruction("uitofp_" + getTypePostfix(ty)
                                + "(" + getTypeDescriptor(srcTy) + ")" + getTypeDescriptor(ty));
        break;
    case Instruction::FPToUI:
        printVirtualInstruction("fptoui_" + getTypePostfix(ty)
                                + "(" + getTypeDescriptor(srcTy) + ")" + getTypeDescriptor(ty));
        break;
    case Instruction::BitCast:
        printBitCastInstruction(ty, srcTy);
        break;
    default:
        errs() << "Opcode = " << op << '\n';
        llvm_unreachable("Invalid cast instruction");
    }
}
Ejemplo n.º 12
0
/**
 * 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");
}
Ejemplo n.º 13
0
/**
 * Print a switch instruction.
 * 
 * @param inst  the switch instruction
 */
void JVMWriter::printSwitchInstruction(const SwitchInst *inst) {
    // TODO: This method does not handle switch statements when the
    // successor contains phi instructions (the value of the phi instruction
    // should be set before branching to the successor). Therefore, it has
    // been replaced by the switch lowering pass. Once this method is
    // fixed the switch lowering pass should be removed.
    
    std::map<int, unsigned int> cases;
    for(unsigned int i = 1, e = inst->getNumCases(); i < e; i++)
        cases[(int) inst->getCaseValue(i)->getValue().getSExtValue()] = i;
    
    // TODO: tableswitch in cases where it won't increase the size of the
    //       class file
    printValueLoad(inst->getCondition());
    out << "\tlookupswitch\n";
    for(std::map<int, unsigned int>::const_iterator
        i = cases.begin(), e = cases.end(); i != e; i++)
        out << "\t\t" << i->first << " : "
            << getLabelName(inst->getSuccessor(i->second)) << '\n';
    out << "\t\tdefault : " << getLabelName(inst->getDefaultDest()) << '\n';
}
Ejemplo n.º 14
0
/**
 * 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());
}
Ejemplo n.º 15
0
/**
 * Store a value at the given address.
 * 
 * @param ptr  the address at which to store the value
 * @param val  the value to store
 */
void JVMWriter::printIndirectStore(const Value *ptr, const Value *val) {
    printValueLoad(ptr);
    printValueLoad(val);
    printIndirectStore(val->getType());
}
Ejemplo n.º 16
0
/**
 * Print the given instruction.
 * 
 * @param inst  the instruction
 */
void JVMWriter::printInstruction(const Instruction *inst) {
    const Value *left, *right;
    if(inst->getNumOperands() >= 1) left  = inst->getOperand(0);
    if(inst->getNumOperands() >= 2) right = inst->getOperand(1);
    switch(inst->getOpcode()) {
    case Instruction::Ret:
        printStartInvocationTag();
        printEndInvocationTag("lljvm/runtime/Memory/destroyStackFrame()V");
        if(inst->getNumOperands() >= 1) {
            printValueLoad(left);
            printSimpleInstruction(
                getTypePrefix(left->getType(), true) + "return");
        } else {
            printSimpleInstruction("return");
        }
        break;
    case Instruction::Unwind:
        printSimpleInstruction("getstatic",
            "lljvm/runtime/Instruction$Unwind/instance "
            "Llljvm/runtime/Instruction$Unwind;");
        printSimpleInstruction("athrow");
        // TODO: need to destroy stack frames
        break;
    case Instruction::Unreachable:
        printSimpleInstruction("getstatic",
            "lljvm/runtime/Instruction$Unreachable/instance "
            "Llljvm/runtime/Instruction$Unreachable;");
        printSimpleInstruction("athrow");
        break;
    case Instruction::Add:
    case Instruction::FAdd:
    case Instruction::Sub:
    case Instruction::FSub:
    case Instruction::Mul:
    case Instruction::FMul:
    case Instruction::UDiv:
    case Instruction::SDiv:
    case Instruction::FDiv:
    case Instruction::URem:
    case Instruction::SRem:
    case Instruction::FRem:
    case Instruction::And:
    case Instruction::Or:
    case Instruction::Xor:
    case Instruction::Shl:
    case Instruction::LShr:
    case Instruction::AShr:
        printArithmeticInstruction(inst->getOpcode(), left, right);
        break;
    case Instruction::SExt:
    case Instruction::Trunc:
    case Instruction::ZExt:
    case Instruction::FPTrunc:
    case Instruction::FPExt:
    case Instruction::UIToFP:
    case Instruction::SIToFP:
    case Instruction::FPToUI:
    case Instruction::FPToSI:
    case Instruction::PtrToInt:
    case Instruction::IntToPtr:
    case Instruction::BitCast:
        printCastInstruction(inst->getOpcode(), left,
                             cast<CastInst>(inst)->getDestTy(),
                             cast<CastInst>(inst)->getSrcTy()); break;
    case Instruction::ICmp:
    case Instruction::FCmp:
        printCmpInstruction(cast<CmpInst>(inst)->getPredicate(),
                            left, right); break;
    case Instruction::Br:
        printBranchInstruction(cast<BranchInst>(inst)); break;
    case Instruction::Select:
        printSelectInstruction(inst->getOperand(0),
                               inst->getOperand(1),
                               inst->getOperand(2)); break;
    case Instruction::Load:
        printIndirectLoad(inst->getOperand(0)); break;
    case Instruction::Store:
        printIndirectStore(inst->getOperand(1), inst->getOperand(0)); break;
    case Instruction::GetElementPtr:
        printGepInstruction(inst->getOperand(0),
                            gep_type_begin(inst),
                            gep_type_end(inst)); break;
    case Instruction::Call:
        printCallInstruction(cast<CallInst>(inst)); break;
    case Instruction::Invoke:
        printInvokeInstruction(cast<InvokeInst>(inst)); break;
    case Instruction::Switch:
        printSwitchInstruction(cast<SwitchInst>(inst)); break;
    case Instruction::Alloca:
        printAllocaInstruction(cast<AllocaInst>(inst)); break;
    case Instruction::VAArg:
        printVAArgInstruction(cast<VAArgInst>(inst)); break;
    default:
        errs() << "Instruction = " << *inst << '\n';
        llvm_unreachable("Unsupported instruction");
    }
}
Ejemplo n.º 17
0
/**
 * Print the virtual instruction with the given signature.
 * 
 * @param sig      the signature of the instruction
 * @param operand  the operand to the instruction
 */
void JVMWriter::printVirtualInstruction(const std::string &sig,
                                        const Value *operand) {
    printValueLoad(operand);
    printVirtualInstruction(sig);
}