/** * 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; } }
/** * 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"); } }
/** * 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); }
/** * Print a bit manipulation intrinsic function. * * @param inst the instruction */ void JVMWriter::printBitIntrinsic(const IntrinsicInst *inst) { // TODO: ctpop, ctlz, cttz const Value *value = inst->getOperand(1); const std::string typeDescriptor = getTypeDescriptor(value->getType()); switch(inst->getIntrinsicID()) { case Intrinsic::bswap: printVirtualInstruction( "bswap(" + typeDescriptor + ")" + typeDescriptor, value); break; } }
/** * Print an icmp/fcmp instruction. * * @param predicate the predicate for the instruction * @param left the first operand of the instruction * @param right the second operand of the instruction */ void JVMWriter::printCmpInstruction(unsigned int predicate, const Value *left, const Value *right) { std::string inst; switch(predicate) { case ICmpInst::ICMP_EQ: inst = "icmp_eq"; break; case ICmpInst::ICMP_NE: inst = "icmp_ne"; break; case ICmpInst::ICMP_ULE: inst = "icmp_ule"; break; case ICmpInst::ICMP_SLE: inst = "icmp_sle"; break; case ICmpInst::ICMP_UGE: inst = "icmp_uge"; break; case ICmpInst::ICMP_SGE: inst = "icmp_sge"; break; case ICmpInst::ICMP_ULT: inst = "icmp_ult"; break; case ICmpInst::ICMP_SLT: inst = "icmp_slt"; break; case ICmpInst::ICMP_UGT: inst = "icmp_ugt"; break; case ICmpInst::ICMP_SGT: inst = "icmp_sgt"; break; case FCmpInst::FCMP_UGT: inst = "fcmp_ugt"; break; case FCmpInst::FCMP_OGT: inst = "fcmp_ogt"; break; case FCmpInst::FCMP_UGE: inst = "fcmp_uge"; break; case FCmpInst::FCMP_OGE: inst = "fcmp_oge"; break; case FCmpInst::FCMP_ULT: inst = "fcmp_ult"; break; case FCmpInst::FCMP_OLT: inst = "fcmp_olt"; break; case FCmpInst::FCMP_ULE: inst = "fcmp_ule"; break; case FCmpInst::FCMP_OLE: inst = "fcmp_ole"; break; case FCmpInst::FCMP_UEQ: inst = "fcmp_ueq"; break; case FCmpInst::FCMP_OEQ: inst = "fcmp_oeq"; break; case FCmpInst::FCMP_UNE: inst = "fcmp_une"; break; case FCmpInst::FCMP_ONE: inst = "fcmp_one"; break; case FCmpInst::FCMP_ORD: inst = "fcmp_ord"; break; case FCmpInst::FCMP_UNO: inst = "fcmp_uno"; break; default: errs() << "Predicate = " << predicate << '\n'; llvm_unreachable("Invalid cmp predicate"); } printVirtualInstruction( inst + "(" + getTypeDescriptor(left->getType(), true) + getTypeDescriptor(right->getType(), true) + ")Z", left, right); }
/** * 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); }
/** * Print the virtual instruction with the given signature. * * @param sig the signature of the instruction */ void JVMWriter::printVirtualInstruction(const std::string &sig) { printVirtualInstruction(sig.c_str()); }