JVMWriter Class Reference

A FunctionPass for generating Jasmin-style assembly for the JVM. More...

#include <backend.h>

List of all members.

Public Member Functions

 JVMWriter (const TargetData *td, formatted_raw_ostream &o, const std::string &cls, unsigned int dbg)
 Constructor.

Private Member Functions

void getAnalysisUsage (AnalysisUsage &au) const
 Register required analysis information.
bool runOnFunction (Function &f)
 Process the given function.
bool doInitialization (Module &m)
 Perform per-module initialization.
bool doFinalization (Module &m)
 Perform per-module finalization.
void printBasicBlock (const BasicBlock *block)
 Print the given basic block.
void printInstruction (const Instruction *inst)
 Print the given instruction.
void printPHICopy (const BasicBlock *src, const BasicBlock *dest)
 Replace PHI instructions with copy instructions (load-store pairs).
void printBranchInstruction (const BasicBlock *curBlock, const BasicBlock *destBlock)
 Print an unconditional branch instruction.
void printBranchInstruction (const BasicBlock *curBlock, const BasicBlock *trueBlock, const BasicBlock *falseBlock)
 Print a conditional branch instruction.
void printBranchInstruction (const BranchInst *inst)
 Print a branch instruction.
void printSelectInstruction (const Value *cond, const Value *trueVal, const Value *falseVal)
 Print a select instruction.
void printSwitchInstruction (const SwitchInst *inst)
 Print a switch instruction.
void printLoop (const Loop *l)
 Print a loop.
void printPtrLoad (uint64_t n)
 Load the given pointer.
void printConstLoad (const APInt &i)
 Load the given integer.
void printConstLoad (float f)
 Load the given single-precision floating point value.
void printConstLoad (double d)
 Load the given double-precision floating point value.
void printConstLoad (const Constant *c)
 Load the given constant.
void printConstLoad (const std::string &str, bool cstring)
 Load the given string.
void printStaticConstant (const Constant *c)
 Store the given static constant.
void printConstantExpr (const ConstantExpr *ce)
 Print the given constant expression.
std::string getCallSignature (const FunctionType *ty)
 Return the call signature of the given function type.
void printOperandPack (const Instruction *inst, unsigned int minOperand, unsigned int maxOperand)
 Pack the specified operands of the given instruction into memory.
void printFunctionCall (const Value *functionVal, const Instruction *inst)
 Print a call/invoke instruction.
void printIntrinsicCall (const IntrinsicInst *inst)
 Print a call to an intrinsic function.
void printCallInstruction (const Instruction *inst)
 Print a call instruction.
void printInvokeInstruction (const InvokeInst *inst)
 Print an invoke instruction.
void printLocalVariable (const Function &f, const Instruction *inst)
 Allocate a local variable for the given function.
void printFunctionBody (const Function &f)
 Print the body of the given function.
unsigned int getLocalVarNumber (const Value *v)
 Return the local variable number of the given value.
void printCatchJump (unsigned int numJumps)
 Print the block to catch Jump objects (thrown by longjmp).
void printFunction (const Function &f)
 Print the given function.
void printCmpInstruction (unsigned int predicate, const Value *left, const Value *right)
 Print an icmp/fcmp instruction.
void printArithmeticInstruction (unsigned int op, const Value *left, const Value *right)
 Print an arithmetic instruction.
void printBitCastInstruction (const Type *ty, const Type *srcTy)
 Print a bitcast instruction.
void printCastInstruction (const std::string &typePrefix, const std::string &srcTypePrefix)
 Print a cast instruction.
void printCastInstruction (unsigned int op, const Value *v, const Type *ty, const Type *srcTy)
 Print a cast instruction.
void printGepInstruction (const Value *v, gep_type_iterator i, gep_type_iterator e)
 Print a getelementptr instruction.
void printAllocaInstruction (const AllocaInst *inst)
 Print an alloca instruction.
void printVAArgInstruction (const VAArgInst *inst)
 Print a va_arg instruction.
void printVAIntrinsic (const IntrinsicInst *inst)
 Print a vararg intrinsic function.
void printMemIntrinsic (const MemIntrinsic *inst)
 Print a memory intrinsic function.
void printMallocInstruction (const MallocInst *inst)
 Print a malloc instruction.
void printMathIntrinsic (const IntrinsicInst *inst)
 Print a mathematical intrinsic function.
void printBitIntrinsic (const IntrinsicInst *inst)
 Print a bit manipulation intrinsic function.
void printValueLoad (const Value *v)
 Load the given value.
void printValueStore (const Value *v)
 Store the value currently on top of the stack to the given local variable.
void printIndirectLoad (const Value *v)
 Load a value from the given address.
void printIndirectLoad (const Type *ty)
 Load a value of the given type from the address curently on top of the stack.
void printIndirectStore (const Value *ptr, const Value *val)
 Store a value at the given address.
void printIndirectStore (const Type *ty)
 Indirectly store a value of the given type.
std::string sanitizeName (std::string name)
 Replace any non-alphanumeric characters with underscores.
std::string getValueName (const Value *v)
 Return the name of the given value.
std::string getLabelName (const BasicBlock *block)
 Return the label name of the given block.
void printBinaryInstruction (const char *name, const Value *left, const Value *right)
 Print the given binary instruction.
void printBinaryInstruction (const std::string &name, const Value *left, const Value *right)
 Print the given binary instruction.
void printSimpleInstruction (const char *inst)
 Print the given instruction.
void printSimpleInstruction (const char *inst, const char *operand)
 Print the given instruction.
void printSimpleInstruction (const std::string &inst)
 Print the given instruction.
void printSimpleInstruction (const std::string &inst, const std::string &operand)
 Print the given instruction.
void printVirtualInstruction (const char *sig)
 Print the virtual instruction with the given signature.
void printVirtualInstruction (const char *sig, const Value *operand)
 Print the virtual instruction with the given signature.
void printVirtualInstruction (const char *sig, const Value *left, const Value *right)
 Print the virtual instruction with the given signature.
void printVirtualInstruction (const std::string &sig)
 Print the virtual instruction with the given signature.
void printVirtualInstruction (const std::string &sig, const Value *operand)
 Print the virtual instruction with the given signature.
void printVirtualInstruction (const std::string &sig, const Value *left, const Value *right)
 Print the virtual instruction with the given signature.
void printLabel (const char *label)
 Print the given label.
void printLabel (const std::string &label)
 Print the given label.
void printHeader ()
 Print the header.
void printFields ()
 Print the field declarations.
void printExternalMethods ()
 Print the list of external methods.
void printConstructor ()
 Print the class constructor.
void printClInit ()
 Print the static class initialization method.
void printMainMethod ()
 Print the main method.
unsigned int getBitWidth (const Type *ty, bool expand=false)
 Return the bit width of the given type.
char getTypeID (const Type *ty, bool expand=false)
 Return the ID of the given type.
std::string getTypeName (const Type *ty, bool expand=false)
 Return the name of the given type.
std::string getTypeDescriptor (const Type *ty, bool expand=false)
 Return the type descriptor of the given type.
std::string getTypePostfix (const Type *ty, bool expand=false)
 Return the type postfix of the given type.
std::string getTypePrefix (const Type *ty, bool expand=false)
 Return the type prefix of the given type.

Private Attributes

formatted_raw_ostream & out
 The output stream.
std::string sourcename
 The name of the source file.
std::string classname
 The binary name of the generated class.
unsigned int debug
 The debugging level.
Module * module
 The current module.
const TargetData * targetData
 The target data for the platform.
DenseSet< const Value * > externRefs
 Set of external references.
DenseMap< const BasicBlock
*, unsigned int > 
blockIDs
 Mapping of blocks to unique IDs.
DenseMap< const Value
*, unsigned int > 
localVars
 Mapping of values to local variable numbers.
unsigned int usedRegisters
 Number of registers allocated for the function.
unsigned int vaArgNum
 Local variable number of the pointer to the packed list of varargs.
unsigned int instNum
 Current instruction number.

Static Private Attributes

static char id = 0
 Pass ID.


Detailed Description

A FunctionPass for generating Jasmin-style assembly for the JVM.

Author:
David Roberts

Definition at line 45 of file backend.h.


Constructor & Destructor Documentation

JVMWriter::JVMWriter ( const TargetData *  td,
formatted_raw_ostream &  o,
const std::string &  cls,
unsigned int  dbg 
)

Constructor.

Parameters:
td the target data for the platform
o the output stream to be written to
cls the binary name of the class to generate
dbg the debugging level

Definition at line 35 of file backend.cpp.

00037     : FunctionPass(&id), targetData(td), out(o), classname(cls), debug(dbg) {}


Member Function Documentation

bool JVMWriter::doFinalization ( Module &  m  )  [private]

Perform per-module finalization.

Parameters:
m the module
Returns:
whether the module was modified (always false)

Definition at line 105 of file backend.cpp.

00105                                         {
00106     return false;
00107 }

bool JVMWriter::doInitialization ( Module &  m  )  [private]

Perform per-module initialization.

Parameters:
m the module
Returns:
whether the module was modified (always false)

Definition at line 68 of file backend.cpp.

References classname, instNum, module, printClInit(), printConstructor(), printExternalMethods(), printFields(), printHeader(), printMainMethod(), and sourcename.

00068                                           {
00069     module = &m;
00070     instNum = 0;
00071     
00072     std::string modID = module->getModuleIdentifier();
00073     size_t slashPos = modID.rfind('/');
00074     if(slashPos == std::string::npos)
00075         sourcename = modID;
00076     else
00077         sourcename = modID.substr(slashPos + 1);
00078     
00079     if(!classname.empty()) {
00080         for(std::string::iterator i = classname.begin(),
00081                                   e = classname.end(); i != e; i++)
00082             if(*i == '.') *i = '/';
00083     } else {
00084         classname = sourcename.substr(0, sourcename.rfind('.'));
00085         for(std::string::iterator i = classname.begin(),
00086                                   e = classname.end(); i != e; i++)
00087             if(*i == '.') *i = '_';
00088     }
00089     
00090     printHeader();
00091     printFields();
00092     printExternalMethods();
00093     printConstructor();
00094     printClInit();
00095     printMainMethod();
00096     return false;
00097 }

void JVMWriter::getAnalysisUsage ( AnalysisUsage &  au  )  const [private]

Register required analysis information.

Parameters:
au AnalysisUsage object representing the analysis usage information of this pass.

Definition at line 45 of file backend.cpp.

00045                                                         {
00046     au.addRequired<LoopInfo>();
00047     au.setPreservesAll();
00048 }

unsigned int JVMWriter::getBitWidth ( const Type *  ty,
bool  expand = false 
) [private]

Return the bit width of the given type.

Parameters:
ty the type
expand specifies whether to expand the type to 32 bits
Returns:
the bit width

Definition at line 32 of file types.cpp.

Referenced by getLocalVarNumber(), getTypeID(), getTypePostfix(), printArithmeticInstruction(), printCastInstruction(), printMathIntrinsic(), and printValueStore().

00032                                                                {
00033     if(ty->getTypeID() == Type::ArrayTyID
00034     || ty->getTypeID() == Type::VectorTyID
00035     || ty->getTypeID() == Type::StructTyID
00036     || ty->getTypeID() == Type::PointerTyID)
00037         return 32;
00038 
00039     unsigned int n = ty->getPrimitiveSizeInBits();
00040     switch(n) {
00041     case 1:
00042     case 8:
00043     case 16:
00044     case 32: if(expand) return 32;
00045     case 64: return n;
00046     default:
00047         errs() << "Bits = " << n << '\n';
00048         llvm_unreachable("Unsupported integer width");
00049     }
00050 }

std::string JVMWriter::getCallSignature ( const FunctionType *  ty  )  [private]

Return the call signature of the given function type.

An empty string is returned if the function type appears to be non-prototyped.

Parameters:
ty the function type
Returns:
the call signature

Definition at line 42 of file function.cpp.

References getTypeDescriptor().

Referenced by printExternalMethods(), printFunctionCall(), and printValueLoad().

00042                                                             {
00043     if(ty->isVarArg() && ty->getNumParams() == 0)
00044         // non-prototyped function
00045         return "";
00046     std::string sig;
00047     sig += '(';
00048     for(unsigned int i = 0, e = ty->getNumParams(); i < e; i++)
00049         sig += getTypeDescriptor(ty->getParamType(i));
00050     if(ty->isVarArg()) sig += "I";
00051     sig += ')';
00052     sig += getTypeDescriptor(ty->getReturnType());
00053     return sig;
00054 }

std::string JVMWriter::getLabelName ( const BasicBlock *  block  )  [private]

Return the label name of the given block.

Parameters:
block the block
Returns:
the label

Definition at line 61 of file name.cpp.

References blockIDs, and sanitizeName().

Referenced by printBasicBlock(), printBranchInstruction(), printLoop(), and printSwitchInstruction().

00061                                                          {
00062     if(!blockIDs.count(block))
00063         blockIDs[block] = blockIDs.size() + 1;
00064     return sanitizeName("label" + utostr(blockIDs[block]));
00065 }

unsigned int JVMWriter::getLocalVarNumber ( const Value *  v  )  [private]

Return the local variable number of the given value.

Register/s are allocated for the variable if necessary.

Parameters:
v the value
Returns:
the local variable number

Definition at line 253 of file function.cpp.

References getBitWidth(), localVars, and usedRegisters.

Referenced by getValueName(), printFunction(), printLocalVariable(), printValueLoad(), and printValueStore().

00253                                                         {
00254     if(!localVars.count(v)) {
00255         localVars[v] = usedRegisters++;
00256         if(getBitWidth(v->getType()) == 64)
00257             usedRegisters++; // 64 bit types occupy 2 registers
00258     }
00259     return localVars[v];
00260 }

std::string JVMWriter::getTypeDescriptor ( const Type *  ty,
bool  expand = false 
) [private]

Return the type descriptor of the given type.

Parameters:
ty the type
expand specifies whether to expand the type to 32 bits
Returns:
the type descriptor

Definition at line 112 of file types.cpp.

References getTypeID().

Referenced by getCallSignature(), printArithmeticInstruction(), printBitIntrinsic(), printCastInstruction(), printCmpInstruction(), printFields(), printFunction(), printFunctionCall(), printIndirectLoad(), printIndirectStore(), printLocalVariable(), printMainMethod(), printMemIntrinsic(), printOperandPack(), and printStaticConstant().

00112                                                                   {
00113     return std::string() + getTypeID(ty, expand);
00114 }

char JVMWriter::getTypeID ( const Type *  ty,
bool  expand = false 
) [private]

Return the ID of the given type.

Parameters:
ty the type
expand specifies whether to expand the type to 32 bits
Returns:
the type ID

Definition at line 59 of file types.cpp.

References getBitWidth().

Referenced by getTypeDescriptor(), getTypeName(), getTypePrefix(), and printBitCastInstruction().

00059                                                      {
00060     switch(ty->getTypeID()) {
00061     case Type::VoidTyID:
00062         return 'V';
00063     case Type::IntegerTyID:
00064         switch(getBitWidth(ty, expand)) {
00065         case  1: return 'Z';
00066         case  8: return 'B';
00067         case 16: return 'S';
00068         case 32: return 'I';
00069         case 64: return 'J';
00070         }
00071     case Type::FloatTyID:
00072         return 'F';
00073     case Type::DoubleTyID:
00074         return 'D';
00075     case Type::PointerTyID:
00076     case Type::StructTyID:
00077     case Type::ArrayTyID:
00078     case Type::VectorTyID:
00079         return 'I';
00080     default:
00081         errs() << "Type = " << *ty << '\n';
00082         llvm_unreachable("Invalid type");
00083     }
00084 }

std::string JVMWriter::getTypeName ( const Type *  ty,
bool  expand = false 
) [private]

Return the name of the given type.

Parameters:
ty the type
expand specifies whether to expand the type to 32 bits
Returns:
the type name

Definition at line 92 of file types.cpp.

References getTypeID().

00092                                                             {
00093     switch(getTypeID(ty, expand)) {
00094     case 'V': return "void";
00095     case 'Z': return "boolean";
00096     case 'B': return "byte";
00097     case 'S': return "short";
00098     case 'I': return "int";
00099     case 'J': return "long";
00100     case 'F': return "float";
00101     case 'D': return "double";
00102     }
00103 }

std::string JVMWriter::getTypePostfix ( const Type *  ty,
bool  expand = false 
) [private]

Return the type postfix of the given type.

Parameters:
ty the type
expand specifies whether to expand the type to 32 bits
Returns:
the type postfix

Definition at line 123 of file types.cpp.

References getBitWidth().

Referenced by printCastInstruction(), printFunctionCall(), and printIndirectLoad().

00123                                                                {
00124     switch(ty->getTypeID()) {
00125     case Type::VoidTyID:
00126         return "void";
00127     case Type::IntegerTyID:
00128         return "i" + utostr(getBitWidth(ty, expand));
00129     case Type::FloatTyID:
00130         return "f32";
00131     case Type::DoubleTyID:
00132         return "f64";
00133     case Type::PointerTyID:
00134     case Type::StructTyID:
00135     case Type::ArrayTyID:
00136     case Type::VectorTyID:
00137         return "i32";
00138     default:
00139         errs() << "TypeID = " << ty->getTypeID() << '\n';
00140         llvm_unreachable("Invalid type");
00141     }
00142 }

std::string JVMWriter::getTypePrefix ( const Type *  ty,
bool  expand = false 
) [private]

Return the type prefix of the given type.

Parameters:
ty the type
expand specifies whether to expand the type to 32 bits
Returns:
the type prefix

Definition at line 151 of file types.cpp.

References getTypeID().

Referenced by printArithmeticInstruction(), printCastInstruction(), printInstruction(), printLocalVariable(), printValueLoad(), and printValueStore().

00151                                                               {
00152     switch(getTypeID(ty, expand)) {
00153     case 'Z':
00154     case 'B': return "b";
00155     case 'S': return "s";
00156     case 'I': return "i";
00157     case 'J': return "l";
00158     case 'F': return "f";
00159     case 'D': return "d";
00160     case 'V': llvm_unreachable("void has no prefix");
00161     }
00162 }

std::string JVMWriter::getValueName ( const Value *  v  )  [private]

Return the name of the given value.

Parameters:
v the value
Returns:
the name of the value

Definition at line 46 of file name.cpp.

References getLocalVarNumber(), localVars, and sanitizeName().

Referenced by printClInit(), printExternalMethods(), printFields(), printFunction(), printFunctionCall(), printLocalVariable(), printValueLoad(), and printValueStore().

00046                                                 {
00047     if(const GlobalValue *gv = dyn_cast<GlobalValue>(v))
00048         return sanitizeName(Mangler(*module).getMangledName(gv));
00049     if(v->hasName())
00050         return '_' + sanitizeName(v->getName());
00051     if(localVars.count(v))
00052         return '_' + utostr(getLocalVarNumber(v));
00053     return "_";
00054 }

void JVMWriter::printAllocaInstruction ( const AllocaInst *  inst  )  [private]

Print an alloca instruction.

Parameters:
inst the instruction

Definition at line 290 of file instruction.cpp.

References printPtrLoad(), printSimpleInstruction(), printValueLoad(), and targetData.

Referenced by printInstruction().

00290                                                              {
00291     uint64_t size = targetData->getTypeAllocSize(inst->getAllocatedType());
00292     if(const ConstantInt *c = dyn_cast<ConstantInt>(inst->getOperand(0))) {
00293         // constant optimization
00294         printPtrLoad(c->getZExtValue() * size);
00295     } else {
00296         printPtrLoad(size);
00297         printValueLoad(inst->getOperand(0));
00298         printSimpleInstruction("imul");
00299     }
00300     printSimpleInstruction("invokestatic",
00301                            "lljvm/runtime/Memory/allocateStack(I)I");
00302 }

void JVMWriter::printArithmeticInstruction ( unsigned int  op,
const Value *  left,
const Value *  right 
) [private]

Print an arithmetic instruction.

Parameters:
op the opcode for the instruction
left the first operand of the instruction
right the second operand of the instruction

Definition at line 89 of file instruction.cpp.

References getBitWidth(), getTypeDescriptor(), getTypePrefix(), printSimpleInstruction(), printValueLoad(), and printVirtualInstruction().

Referenced by printConstantExpr(), and printInstruction().

00091                                                                {
00092     printValueLoad(left);
00093     printValueLoad(right);
00094     std::string typePrefix = getTypePrefix(left->getType(), true);
00095     std::string typeDescriptor = getTypeDescriptor(left->getType());
00096     switch(op) {
00097     case Instruction::Add:
00098     case Instruction::FAdd:
00099         printSimpleInstruction(typePrefix + "add"); break;
00100     case Instruction::Sub:
00101     case Instruction::FSub:
00102         printSimpleInstruction(typePrefix + "sub"); break;
00103     case Instruction::Mul:
00104     case Instruction::FMul:
00105         printSimpleInstruction(typePrefix + "mul"); break;
00106     case Instruction::SDiv:
00107     case Instruction::FDiv:
00108         printSimpleInstruction(typePrefix + "div"); break;
00109     case Instruction::SRem:
00110     case Instruction::FRem:
00111         printSimpleInstruction(typePrefix + "rem"); break;
00112     case Instruction::And:
00113         printSimpleInstruction(typePrefix + "and"); break;
00114     case Instruction::Or:
00115         printSimpleInstruction(typePrefix + "or"); break;
00116     case Instruction::Xor:
00117         printSimpleInstruction(typePrefix + "xor"); break;
00118     case Instruction::Shl:
00119         if(getBitWidth(right->getType()) == 64) printSimpleInstruction("l2i");
00120         printSimpleInstruction(typePrefix + "shl"); break;
00121     case Instruction::LShr:
00122         if(getBitWidth(right->getType()) == 64) printSimpleInstruction("l2i");
00123         printSimpleInstruction(typePrefix + "ushr"); break;
00124     case Instruction::AShr:
00125         if(getBitWidth(right->getType()) == 64) printSimpleInstruction("l2i");
00126         printSimpleInstruction(typePrefix + "shr"); break;
00127     case Instruction::UDiv:
00128         printVirtualInstruction(
00129             "udiv(" + typeDescriptor + typeDescriptor + ")" + typeDescriptor);
00130         break;
00131     case Instruction::URem:
00132         printVirtualInstruction(
00133             "urem(" + typeDescriptor + typeDescriptor + ")" + typeDescriptor);
00134         break;
00135     }
00136 }

void JVMWriter::printBasicBlock ( const BasicBlock *  block  )  [private]

Print the given basic block.

Parameters:
block the basic block

Definition at line 30 of file block.cpp.

References debug, getLabelName(), instNum, out, printInstruction(), printLabel(), printSimpleInstruction(), and printValueStore().

Referenced by printFunctionBody(), and printLoop().

00030                                                        {
00031     printLabel(getLabelName(block));
00032     for(BasicBlock::const_iterator i = block->begin(), e = block->end();
00033         i != e; i++) {
00034         instNum++;
00035         if(debug >= 3) {
00036             // print current instruction as comment
00037             // note that this block of code significantly increases
00038             // code generation time
00039             std::string str;
00040             raw_string_ostream ss(str); ss << *i;
00041             std::string::size_type pos = 0;
00042             while((pos = str.find("\n", pos)) != std::string::npos)
00043                 str.replace(pos++, 1, "\n;");
00044             out << ';' << str << '\n';
00045         }
00046         if(debug >= 1)
00047             printSimpleInstruction(".line", utostr(instNum));
00048         
00049         if(i->getOpcode() == Instruction::PHI)
00050             // don't handle phi instruction in current block
00051             continue;
00052         printInstruction(i);
00053         if(i->getType() != Type::getVoidTy(block->getContext())
00054         && i->getOpcode() != Instruction::Invoke)
00055             // instruction doesn't return anything, or is an invoke instruction
00056             // which handles storing the return value itself
00057             printValueStore(i);
00058     }
00059 }

void JVMWriter::printBinaryInstruction ( const std::string &  name,
const Value *  left,
const Value *  right 
) [private]

Print the given binary instruction.

Parameters:
name the name of the instruction
left the first operand
right the second operand

Definition at line 47 of file printinst.cpp.

References out, and printValueLoad().

00049                                                            {
00050     printValueLoad(left);
00051     printValueLoad(right);
00052     out << '\t' << name << '\n';
00053 }

void JVMWriter::printBinaryInstruction ( const char *  name,
const Value *  left,
const Value *  right 
) [private]

Print the given binary instruction.

Parameters:
name the name of the instruction
left the first operand
right the second operand

Definition at line 32 of file printinst.cpp.

References out, and printValueLoad().

00034                                                            {
00035     printValueLoad(left);
00036     printValueLoad(right);
00037     out << '\t' << name << '\n';
00038 }

void JVMWriter::printBitCastInstruction ( const Type *  ty,
const Type *  srcTy 
) [private]

Print a bitcast instruction.

Parameters:
ty the destination type
srcTy the source type

Definition at line 144 of file instruction.cpp.

References getTypeID(), and printSimpleInstruction().

Referenced by printCastInstruction().

00144                                                                          {
00145     char typeID = getTypeID(ty);
00146     char srcTypeID = getTypeID(srcTy);
00147     if(srcTypeID == 'J' && typeID == 'D')
00148         printSimpleInstruction("invokestatic",
00149                                "java/lang/Double/longBitsToDouble(J)D");
00150     else if(srcTypeID == 'I' && typeID == 'F')
00151         printSimpleInstruction("invokestatic",
00152                                "java/lang/Float/intBitsToFloat(I)F");
00153     if(srcTypeID == 'D' && typeID == 'J')
00154         printSimpleInstruction("invokestatic",
00155                                "java/lang/Double/doubleToRawLongBits(D)J");
00156     else if(srcTypeID == 'F' && typeID == 'I')
00157         printSimpleInstruction("invokestatic",
00158                                "java/lang/Float/floatToRawIntBits(F)I");
00159 }

void JVMWriter::printBitIntrinsic ( const IntrinsicInst *  inst  )  [private]

Print a bit manipulation intrinsic function.

Parameters:
inst the instruction

Definition at line 427 of file instruction.cpp.

References getTypeDescriptor(), and printVirtualInstruction().

Referenced by printIntrinsicCall().

00427                                                            {
00428     // TODO: ctpop, ctlz, cttz
00429     const Value *value = inst->getOperand(1);
00430     const std::string typeDescriptor = getTypeDescriptor(value->getType());
00431     switch(inst->getIntrinsicID()) {
00432     case Intrinsic::bswap:
00433         printVirtualInstruction(
00434             "bswap(" + typeDescriptor + ")" + typeDescriptor, value); break;
00435     }
00436 }

void JVMWriter::printBranchInstruction ( const BranchInst *  inst  )  [private]

Print a branch instruction.

Parameters:
inst the branch instrtuction

Definition at line 105 of file branch.cpp.

References printBranchInstruction(), and printValueLoad().

00105                                                              {
00106     if(inst->isUnconditional()) {
00107         printBranchInstruction(inst->getParent(), inst->getSuccessor(0));
00108     } else {
00109         printValueLoad(inst->getCondition());
00110         printBranchInstruction(
00111             inst->getParent(), inst->getSuccessor(0), inst->getSuccessor(1));
00112     }
00113 }

void JVMWriter::printBranchInstruction ( const BasicBlock *  curBlock,
const BasicBlock *  trueBlock,
const BasicBlock *  falseBlock 
) [private]

Print a conditional branch instruction.

Parameters:
curBlock the current block
trueBlock the destination block if the value on top of the stack is non-zero
falseBlock the destination block if the value on top of the stack is zero

Definition at line 73 of file branch.cpp.

References getLabelName(), printBranchInstruction(), printLabel(), printPHICopy(), and printSimpleInstruction().

00075                                                                      {
00076     if(trueBlock == falseBlock) {
00077         printSimpleInstruction("pop");
00078         printBranchInstruction(curBlock, trueBlock);
00079     } else if(!falseBlock) {
00080         printPHICopy(curBlock, trueBlock);
00081         printSimpleInstruction("ifne", getLabelName(trueBlock));
00082     } else {
00083         std::string labelname = getLabelName(trueBlock);
00084         if(isa<PHINode>(trueBlock->begin()))
00085             labelname += "$phi" + utostr(getUID());
00086         printSimpleInstruction("ifne", labelname);
00087         
00088         if(isa<PHINode>(falseBlock->begin()))
00089             printPHICopy(curBlock, falseBlock);
00090         printSimpleInstruction("goto", getLabelName(falseBlock));
00091         
00092         if(isa<PHINode>(trueBlock->begin())) {
00093             printLabel(labelname);
00094             printPHICopy(curBlock, trueBlock);
00095             printSimpleInstruction("goto", getLabelName(trueBlock));
00096         }
00097     }
00098 }

void JVMWriter::printBranchInstruction ( const BasicBlock *  curBlock,
const BasicBlock *  destBlock 
) [private]

Print an unconditional branch instruction.

Parameters:
curBlock the current block
destBlock the destination block

Definition at line 58 of file branch.cpp.

References getLabelName(), printPHICopy(), and printSimpleInstruction().

Referenced by printBranchInstruction(), printInstruction(), and printInvokeInstruction().

00059                                                                     {
00060     printPHICopy(curBlock, destBlock);
00061     printSimpleInstruction("goto", getLabelName(destBlock));
00062 }

void JVMWriter::printCallInstruction ( const Instruction *  inst  )  [private]

Print a call instruction.

Parameters:
inst the instruction

Definition at line 176 of file function.cpp.

References printFunctionCall(), and printIntrinsicCall().

Referenced by printInstruction().

00176                                                             {
00177     if(isa<IntrinsicInst>(inst))
00178         printIntrinsicCall(cast<IntrinsicInst>(inst));
00179     else
00180         printFunctionCall(inst->getOperand(0), inst);
00181 }

void JVMWriter::printCastInstruction ( unsigned int  op,
const Value *  v,
const Type *  ty,
const Type *  srcTy 
) [private]

Print a cast instruction.

Parameters:
op the opcode for the instruction
v the value to be casted
ty the destination type
srcTy the source type

Definition at line 181 of file instruction.cpp.

References getBitWidth(), getTypeDescriptor(), getTypePostfix(), getTypePrefix(), printBitCastInstruction(), printCastInstruction(), printSimpleInstruction(), printValueLoad(), and printVirtualInstruction().

00182                                                                         {
00183     printValueLoad(v);
00184     switch(op) {
00185     case Instruction::SIToFP:
00186     case Instruction::FPToSI:
00187     case Instruction::FPTrunc:
00188     case Instruction::FPExt:
00189     case Instruction::SExt:
00190         if(getBitWidth(srcTy) < 32)
00191             printCastInstruction(getTypePrefix(srcTy), "i");
00192         printCastInstruction(getTypePrefix(ty, true),
00193                              getTypePrefix(srcTy, true)); break;
00194     case Instruction::Trunc:
00195         if(getBitWidth(srcTy) == 64 && getBitWidth(ty) < 32) {
00196             printSimpleInstruction("l2i");
00197             printCastInstruction(getTypePrefix(ty), "i");
00198         } else
00199             printCastInstruction(getTypePrefix(ty),
00200                                  getTypePrefix(srcTy, true));
00201         break;
00202     case Instruction::IntToPtr:
00203         printCastInstruction("i", getTypePrefix(srcTy, true)); break;
00204     case Instruction::PtrToInt:
00205         printCastInstruction(getTypePrefix(ty), "i"); break;
00206     case Instruction::ZExt:
00207         printVirtualInstruction("zext_" + getTypePostfix(ty, true)
00208             + "(" + getTypeDescriptor(srcTy) + ")"
00209             + getTypeDescriptor(ty, true));
00210         break;
00211     case Instruction::UIToFP:
00212         printVirtualInstruction("uitofp_" + getTypePostfix(ty)
00213             + "(" + getTypeDescriptor(srcTy) + ")" + getTypeDescriptor(ty));
00214         break;
00215     case Instruction::FPToUI:
00216         printVirtualInstruction("fptoui_" + getTypePostfix(ty)
00217             + "(" + getTypeDescriptor(srcTy) + ")" + getTypeDescriptor(ty));
00218         break;
00219     case Instruction::BitCast:
00220         printBitCastInstruction(ty, srcTy); break;
00221     default:
00222         errs() << "Opcode = " << op << '\n';
00223         llvm_unreachable("Invalid cast instruction");
00224     }
00225 }

void JVMWriter::printCastInstruction ( const std::string &  typePrefix,
const std::string &  srcTypePrefix 
) [private]

Print a cast instruction.

Parameters:
typePrefix the type prefix of the destination type
srcTypePrefix the type prefix of the source type

Definition at line 167 of file instruction.cpp.

References printSimpleInstruction().

Referenced by printCastInstruction(), printConstantExpr(), printGepInstruction(), and printInstruction().

00168                                                                      {
00169     if(srcTypePrefix != typePrefix)
00170         printSimpleInstruction(srcTypePrefix + "2" + typePrefix);
00171 }

void JVMWriter::printCatchJump ( unsigned int  numJumps  )  [private]

Print the block to catch Jump objects (thrown by longjmp).

Parameters:
numJumps the number of setjmp calls made by the current function

Definition at line 267 of file function.cpp.

References debug, printLabel(), printSimpleInstruction(), and usedRegisters.

Referenced by printFunction().

00267                                                     {
00268     unsigned int jumpVarNum = usedRegisters++;
00269     printSimpleInstruction(".catch lljvm/runtime/Jump "
00270         "from begin_method to catch_jump using catch_jump");
00271     printLabel("catch_jump");
00272     printSimpleInstruction("astore", utostr(jumpVarNum));
00273     printSimpleInstruction("aload", utostr(jumpVarNum));
00274     printSimpleInstruction("getfield", "lljvm/runtime/Jump/value I");
00275     for(unsigned int i = usedRegisters-1 - numJumps,
00276                      e = usedRegisters-1; i < e; i++) {
00277         if(debug >= 2)
00278             printSimpleInstruction(".var " + utostr(i) + " is setjmp_id_"
00279                 + utostr(i) + " I from begin_method to end_method");
00280         printSimpleInstruction("aload", utostr(jumpVarNum));
00281         printSimpleInstruction("getfield", "lljvm/runtime/Jump/id I");
00282         printSimpleInstruction("iload", utostr(i));
00283         printSimpleInstruction("if_icmpeq", "setjmp$" + utostr(i));
00284     }
00285     printSimpleInstruction("pop");
00286     printSimpleInstruction("aload", utostr(jumpVarNum));
00287     printSimpleInstruction("athrow");
00288     if(debug >= 2)
00289         printSimpleInstruction(".var " + utostr(jumpVarNum) + " is jump "
00290             "Llljvm/runtime/Jump; from begin_method to end_method");
00291 }

void JVMWriter::printCmpInstruction ( unsigned int  predicate,
const Value *  left,
const Value *  right 
) [private]

Print an icmp/fcmp instruction.

Parameters:
predicate the predicate for the instruction
left the first operand of the instruction
right the second operand of the instruction

Definition at line 42 of file instruction.cpp.

References getTypeDescriptor(), and printVirtualInstruction().

Referenced by printConstantExpr(), and printInstruction().

00044                                                         {
00045     std::string inst;
00046     switch(predicate) {
00047     case ICmpInst::ICMP_EQ:  inst = "icmp_eq";  break;
00048     case ICmpInst::ICMP_NE:  inst = "icmp_ne";  break;
00049     case ICmpInst::ICMP_ULE: inst = "icmp_ule"; break;
00050     case ICmpInst::ICMP_SLE: inst = "icmp_sle"; break;
00051     case ICmpInst::ICMP_UGE: inst = "icmp_uge"; break;
00052     case ICmpInst::ICMP_SGE: inst = "icmp_sge"; break;
00053     case ICmpInst::ICMP_ULT: inst = "icmp_ult"; break;
00054     case ICmpInst::ICMP_SLT: inst = "icmp_slt"; break;
00055     case ICmpInst::ICMP_UGT: inst = "icmp_ugt"; break;
00056     case ICmpInst::ICMP_SGT: inst = "icmp_sgt"; break;
00057     case FCmpInst::FCMP_UGT: inst = "fcmp_ugt"; break;
00058     case FCmpInst::FCMP_OGT: inst = "fcmp_ogt"; break;
00059     case FCmpInst::FCMP_UGE: inst = "fcmp_uge"; break;
00060     case FCmpInst::FCMP_OGE: inst = "fcmp_oge"; break;
00061     case FCmpInst::FCMP_ULT: inst = "fcmp_ult"; break;
00062     case FCmpInst::FCMP_OLT: inst = "fcmp_olt"; break;
00063     case FCmpInst::FCMP_ULE: inst = "fcmp_ule"; break;
00064     case FCmpInst::FCMP_OLE: inst = "fcmp_ole"; break;
00065     case FCmpInst::FCMP_UEQ: inst = "fcmp_ueq"; break;
00066     case FCmpInst::FCMP_OEQ: inst = "fcmp_oeq"; break;
00067     case FCmpInst::FCMP_UNE: inst = "fcmp_une"; break;
00068     case FCmpInst::FCMP_ONE: inst = "fcmp_one"; break;
00069     case FCmpInst::FCMP_ORD: inst = "fcmp_ord"; break;
00070     case FCmpInst::FCMP_UNO: inst = "fcmp_uno"; break;
00071     default:
00072         errs() << "Predicate = " << predicate << '\n';
00073         llvm_unreachable("Invalid cmp predicate");
00074     }
00075     printVirtualInstruction(
00076         inst + "("
00077         + getTypeDescriptor(left->getType(), true)
00078         + getTypeDescriptor(right->getType(), true)
00079         + ")Z", left, right);
00080 }

void JVMWriter::printConstantExpr ( const ConstantExpr *  ce  )  [private]

Print the given constant expression.

Parameters:
ce the constant expression

Definition at line 237 of file const.cpp.

References printArithmeticInstruction(), printCastInstruction(), printCmpInstruction(), printGepInstruction(), and printSelectInstruction().

Referenced by printStaticConstant(), and printValueLoad().

00237                                                         {
00238     const Value *left, *right;
00239     if(ce->getNumOperands() >= 1) left  = ce->getOperand(0);
00240     if(ce->getNumOperands() >= 2) right = ce->getOperand(1);
00241     switch(ce->getOpcode()) {
00242     case Instruction::Trunc:
00243     case Instruction::ZExt:
00244     case Instruction::SExt:
00245     case Instruction::FPTrunc:
00246     case Instruction::FPExt:
00247     case Instruction::UIToFP:
00248     case Instruction::SIToFP:
00249     case Instruction::FPToUI:
00250     case Instruction::FPToSI:
00251     case Instruction::PtrToInt:
00252     case Instruction::IntToPtr:
00253     case Instruction::BitCast:
00254         printCastInstruction(ce->getOpcode(), left,
00255                              ce->getType(), left->getType()); break;
00256     case Instruction::Add:
00257     case Instruction::FAdd:
00258     case Instruction::Sub:
00259     case Instruction::FSub:
00260     case Instruction::Mul:
00261     case Instruction::FMul:
00262     case Instruction::UDiv:
00263     case Instruction::SDiv:
00264     case Instruction::FDiv:
00265     case Instruction::URem:
00266     case Instruction::SRem:
00267     case Instruction::FRem:
00268     case Instruction::And:
00269     case Instruction::Or:
00270     case Instruction::Xor:
00271     case Instruction::Shl:
00272     case Instruction::LShr:
00273     case Instruction::AShr:
00274         printArithmeticInstruction(ce->getOpcode(), left, right); break;
00275     case Instruction::ICmp:
00276     case Instruction::FCmp:
00277         printCmpInstruction(ce->getPredicate(), left, right); break;
00278     case Instruction::GetElementPtr:
00279         printGepInstruction(ce->getOperand(0),
00280                             gep_type_begin(ce),
00281                             gep_type_end(ce)); break;
00282     case Instruction::Select:
00283         printSelectInstruction(ce->getOperand(0),
00284                                ce->getOperand(1),
00285                                ce->getOperand(2)); break;
00286     default:
00287         errs() << "Expression = " << *ce << '\n';
00288         llvm_unreachable("Invalid constant expression");
00289     }
00290 }

void JVMWriter::printConstLoad ( const std::string &  str,
bool  cstring 
) [private]

Load the given string.

Parameters:
str the string
cstring true iff the string contains a single null character at the end

Definition at line 138 of file const.cpp.

References out.

00138                                                                  {
00139     out << "\tldc \"";
00140     if(cstring)
00141         for(std::string::const_iterator i = str.begin(),
00142                                         e = str.end()-1; i != e; i++)
00143             switch(*i) {
00144             case '\\': out << "\\\\"; break;
00145             case '\b': out << "\\b";  break;
00146             case '\t': out << "\\t";  break;
00147             case '\n': out << "\\n";  break;
00148             case '\f': out << "\\f";  break;
00149             case '\r': out << "\\r";  break;
00150             case '\"': out << "\\\""; break;
00151             case '\'': out << "\\\'"; break;
00152             default:   out << *i;     break;
00153             }
00154     else
00155         for(std::string::const_iterator i = str.begin(),
00156                                         e = str.end(); i != e; i++) {
00157             const char c = *i;
00158             out << "\\u00" << hexdigit((c>>4) & 0xf) << hexdigit(c & 0xf);
00159         }
00160     out << "\"\n";
00161 }

void JVMWriter::printConstLoad ( const Constant *  c  )  [private]

Load the given constant.

Parameters:
c the constant

Definition at line 115 of file const.cpp.

References printConstLoad(), and printPtrLoad().

00115                                                 {
00116     if(const ConstantInt *i = dyn_cast<ConstantInt>(c)) {
00117         printConstLoad(i->getValue());
00118     } else if(const ConstantFP *fp = dyn_cast<ConstantFP>(c)) {
00119         if(fp->getType()->getTypeID() == Type::FloatTyID)
00120             printConstLoad(fp->getValueAPF().convertToFloat());
00121         else
00122             printConstLoad(fp->getValueAPF().convertToDouble());
00123     } else if(isa<UndefValue>(c)) {
00124         printPtrLoad(0);
00125     } else {
00126         errs() << "Constant = " << *c << '\n';
00127         llvm_unreachable("Invalid constant value");
00128     }
00129 }

void JVMWriter::printConstLoad ( double  d  )  [private]

Load the given double-precision floating point value.

Parameters:
d the value

Definition at line 93 of file const.cpp.

References printSimpleInstruction().

00093                                        {
00094     if(d == 0.0)
00095         printSimpleInstruction("dconst_0");
00096     else if(d == 1.0)
00097         printSimpleInstruction("dconst_1");
00098     else if(IsNAN(d))
00099         printSimpleInstruction("getstatic", "java/lang/Double/NaN D");
00100     else if(IsInf(d) > 0)
00101         printSimpleInstruction("getstatic",
00102                                "java/lang/Double/POSITIVE_INFINITY D");
00103     else if(IsInf(d) < 0)
00104         printSimpleInstruction("getstatic",
00105                                "java/lang/Double/NEGATIVE_INFINITY D");
00106     else
00107         printSimpleInstruction("ldc2_w", ftostr(d));
00108 }

void JVMWriter::printConstLoad ( float  f  )  [private]

Load the given single-precision floating point value.

Parameters:
f the value

Definition at line 69 of file const.cpp.

References printSimpleInstruction().

00069                                       {
00070     if(f == 0.0)
00071         printSimpleInstruction("fconst_0");
00072     else if(f == 1.0)
00073         printSimpleInstruction("fconst_1");
00074     else if(f == 2.0)
00075         printSimpleInstruction("fconst_2");
00076     else if(IsNAN(f))
00077         printSimpleInstruction("getstatic", "java/lang/Float/NaN F");
00078     else if(IsInf(f) > 0)
00079         printSimpleInstruction("getstatic",
00080                                "java/lang/Float/POSITIVE_INFINITY F");
00081     else if(IsInf(f) < 0)
00082         printSimpleInstruction("getstatic",
00083                                "java/lang/Float/NEGATIVE_INFINITY F");
00084     else
00085         printSimpleInstruction("ldc", ftostr(f));
00086 }

void JVMWriter::printConstLoad ( const APInt &  i  )  [private]

Load the given integer.

Parameters:
i the integer

Definition at line 41 of file const.cpp.

References printSimpleInstruction().

Referenced by printClInit(), printConstLoad(), printMemIntrinsic(), printPtrLoad(), printStaticConstant(), printVAArgInstruction(), and printValueLoad().

00041                                              {
00042     if(i.getBitWidth() <= 32) {
00043         int64_t value = i.getSExtValue();
00044         if(value == -1)
00045             printSimpleInstruction("iconst_m1");
00046         else if(0 <= value && value <= 5)
00047             printSimpleInstruction("iconst_" + i.toString(10, true));
00048         else if(-0x80 <= value && value <= 0x7f)
00049             printSimpleInstruction("bipush", i.toString(10, true));
00050         else if(-0x8000 <= value && value <= 0x7fff)
00051             printSimpleInstruction("sipush", i.toString(10, true));
00052         else
00053             printSimpleInstruction("ldc", i.toString(10, true));
00054     } else {
00055         if(i == 0)
00056             printSimpleInstruction("lconst_0");
00057         else if(i == 1)
00058             printSimpleInstruction("lconst_1");
00059         else
00060             printSimpleInstruction("ldc2_w", i.toString(10, true));
00061     }
00062 }

void JVMWriter::printFunction ( const Function &  f  )  [private]

Print the given function.

Parameters:
f the function

Definition at line 298 of file function.cpp.

References debug, getLocalVarNumber(), getTypeDescriptor(), getValueName(), localVars, out, printCatchJump(), printFunctionBody(), printLabel(), printLocalVariable(), printSimpleInstruction(), usedRegisters, and vaArgNum.

Referenced by runOnFunction().

00298                                                {
00299     localVars.clear();
00300     usedRegisters = 0;
00301     
00302     out << '\n';
00303     out << ".method " << (f.hasLocalLinkage() ? "private " : "public ")
00304         << "static " << getValueName(&f) << '(';
00305     for(Function::const_arg_iterator i = f.arg_begin(), e = f.arg_end();
00306         i != e; i++)
00307         out << getTypeDescriptor(i->getType());
00308     if(f.isVarArg())
00309         out << "I";
00310     out << ')' << getTypeDescriptor(f.getReturnType()) << '\n';
00311     
00312     for(Function::const_arg_iterator i = f.arg_begin(), e = f.arg_end();
00313         i != e; i++) {
00314         // getLocalVarNumber must be called at least once in each iteration
00315         unsigned int varNum = getLocalVarNumber(i);
00316         if(debug >= 2)
00317             printSimpleInstruction(".var " + utostr(varNum) + " is "
00318                 + getValueName(i) + ' ' + getTypeDescriptor(i->getType())
00319                 + " from begin_method to end_method");
00320     }
00321     if(f.isVarArg()) {
00322         vaArgNum = usedRegisters++;
00323         if(debug >= 2)
00324             printSimpleInstruction(".var " + utostr(vaArgNum)
00325                 + " is varargptr I from begin_method to end_method");
00326     }
00327     
00328     // TODO: better stack depth analysis
00329     unsigned int stackDepth = 8;
00330     unsigned int numJumps = 0;
00331     for(const_inst_iterator i = inst_begin(&f), e = inst_end(&f);
00332         i != e; i++) {
00333         if(stackDepth < i->getNumOperands())
00334             stackDepth = i->getNumOperands();
00335         if(i->getType() != Type::getVoidTy(f.getContext()))
00336             printLocalVariable(f, &*i);
00337         if(const CallInst *inst = dyn_cast<CallInst>(&*i))
00338             if(!isa<IntrinsicInst>(inst)
00339             && getValueName(inst->getOperand(0)) == "setjmp")
00340                 numJumps++;
00341     }
00342     
00343     for(unsigned int i = 0; i < numJumps; i++) {
00344         // initialise jump IDs to prevent class verification errors
00345         printSimpleInstruction("iconst_0");
00346         printSimpleInstruction("istore", utostr(usedRegisters + i));
00347     }
00348     
00349     printLabel("begin_method");
00350     printSimpleInstruction("invokestatic",
00351                            "lljvm/runtime/Memory/createStackFrame()V");
00352     printFunctionBody(f);
00353     if(numJumps) printCatchJump(numJumps);
00354     printSimpleInstruction(".limit stack", utostr(stackDepth * 2));
00355     printSimpleInstruction(".limit locals", utostr(usedRegisters));
00356     printLabel("end_method");
00357     out << ".end method\n";
00358 }

void JVMWriter::printFunctionBody ( const Function &  f  )  [private]

Print the body of the given function.

Parameters:
f the function

Definition at line 236 of file function.cpp.

References printBasicBlock(), and printLoop().

Referenced by printFunction().

00236                                                    {
00237     for(Function::const_iterator i = f.begin(), e = f.end(); i != e; i++) {
00238         if(Loop *l = getAnalysis<LoopInfo>().getLoopFor(i)) {
00239             if(l->getHeader() == i && l->getParentLoop() == 0)
00240                 printLoop(l);
00241         } else
00242             printBasicBlock(i);
00243     }
00244 }

void JVMWriter::printFunctionCall ( const Value *  functionVal,
const Instruction *  inst 
) [private]

Print a call/invoke instruction.

Parameters:
functionVal the function to call
inst the instruction

Definition at line 93 of file function.cpp.

References classname, externRefs, getCallSignature(), getTypeDescriptor(), getTypePostfix(), getValueName(), printLabel(), printOperandPack(), printSimpleInstruction(), printValueLoad(), and usedRegisters.

Referenced by printCallInstruction(), and printInvokeInstruction().

00094                                                            {
00095     unsigned int origin = isa<InvokeInst>(inst) ? 3 : 1;
00096     if(const Function *f = dyn_cast<Function>(functionVal)) { // direct call
00097         const FunctionType *ty = f->getFunctionType();
00098         
00099         //for(unsigned int i = origin, e = inst->getNumOperands(); i < e; i++)
00100         //    printValueLoad(inst->getOperand(i));
00101         
00102         for(unsigned int i = 0, e = ty->getNumParams(); i < e; i++)
00103             printValueLoad(inst->getOperand(i + origin));
00104         if(ty->isVarArg() && inst)
00105             printOperandPack(inst, ty->getNumParams() + origin,
00106                                    inst->getNumOperands());
00107         
00108         if(externRefs.count(f))
00109             printSimpleInstruction("invokestatic",
00110                 getValueName(f) + getCallSignature(ty));
00111         else
00112             printSimpleInstruction("invokestatic",
00113                 classname + "/" + getValueName(f) + getCallSignature(ty));
00114         
00115         if(getValueName(f) == "setjmp") {
00116             unsigned int varNum = usedRegisters++;
00117             printSimpleInstruction("istore", utostr(varNum));
00118             printSimpleInstruction("iconst_0");
00119             printLabel("setjmp$" + utostr(varNum));
00120         }
00121     } else { // indirect call
00122         printValueLoad(functionVal);
00123         const FunctionType *ty = cast<FunctionType>(
00124             cast<PointerType>(functionVal->getType())->getElementType());
00125         printOperandPack(inst, origin, inst->getNumOperands());
00126         printSimpleInstruction("invokestatic",
00127             "lljvm/runtime/Function/invoke_"
00128             + getTypePostfix(ty->getReturnType()) + "(II)"
00129             + getTypeDescriptor(ty->getReturnType()));
00130     }
00131 }

void JVMWriter::printGepInstruction ( const Value *  v,
gep_type_iterator  i,
gep_type_iterator  e 
) [private]

Print a getelementptr instruction.

Parameters:
v the aggregate data structure to index
i an iterator to the first type indexed by the instruction
e an iterator specifying the upper bound on the types indexed by the instruction

Definition at line 235 of file instruction.cpp.

References printCastInstruction(), printPtrLoad(), printSimpleInstruction(), and targetData.

Referenced by printConstantExpr(), and printInstruction().

00237                                                          {
00238     // load address
00239     printCastInstruction(Instruction::IntToPtr, v, NULL, v->getType());
00240     
00241     // calculate offset
00242     for(; i != e; i++){
00243         unsigned int size = 0;
00244         const Value *indexValue = i.getOperand();
00245         
00246         if(const StructType *structTy = dyn_cast<StructType>(*i)) {
00247             for(unsigned int f = 0,
00248                     fieldIndex = cast<ConstantInt>(indexValue)->getZExtValue();
00249                 f < fieldIndex; f++)
00250                 size = alignOffset(
00251                     size + targetData->getTypeAllocSize(
00252                         structTy->getContainedType(f)),
00253                     targetData->getABITypeAlignment(
00254                         structTy->getContainedType(f + 1)));
00255             printPtrLoad(size);
00256             printSimpleInstruction("iadd");
00257         } else {
00258             if(const SequentialType *seqTy = dyn_cast<SequentialType>(*i))
00259                 size = targetData->getTypeAllocSize(seqTy->getElementType());
00260             else
00261                 size = targetData->getTypeAllocSize(*i);
00262             
00263             if(const ConstantInt *c = dyn_cast<ConstantInt>(indexValue)) {
00264                 // constant optimisation
00265                 if(c->isNullValue()) {
00266                     // do nothing
00267                 } else if(c->getValue().isNegative()) {
00268                     printPtrLoad(c->getValue().abs().getZExtValue() * size);
00269                     printSimpleInstruction("isub");
00270                 } else {
00271                     printPtrLoad(c->getZExtValue() * size);
00272                     printSimpleInstruction("iadd");
00273                 }
00274             } else {
00275                 printPtrLoad(size);
00276                 printCastInstruction(Instruction::IntToPtr, indexValue,
00277                                      NULL, indexValue->getType());
00278                 printSimpleInstruction("imul");
00279                 printSimpleInstruction("iadd");
00280             }
00281         }
00282     }
00283 }

void JVMWriter::printIndirectLoad ( const Type *  ty  )  [private]

Load a value of the given type from the address curently on top of the stack.

Parameters:
ty the type of the value

Definition at line 120 of file loadstore.cpp.

References getTypeDescriptor(), getTypePostfix(), and printSimpleInstruction().

00120                                                 {
00121     printSimpleInstruction("invokestatic", "lljvm/runtime/Memory/load_"
00122         + getTypePostfix(ty) + "(I)" + getTypeDescriptor(ty));
00123 }

void JVMWriter::printIndirectLoad ( const Value *  v  )  [private]

Load a value from the given address.

Parameters:
v the address

Definition at line 106 of file loadstore.cpp.

References printValueLoad().

Referenced by printInstruction(), printVAArgInstruction(), and printVAIntrinsic().

00106                                                 {
00107     printValueLoad(v);
00108     const Type *ty = v->getType();
00109     if(const PointerType *p = dyn_cast<PointerType>(ty))
00110         ty = p->getElementType();
00111     printIndirectLoad(ty);
00112 }

void JVMWriter::printIndirectStore ( const Type *  ty  )  [private]

Indirectly store a value of the given type.

Parameters:
ty the type of the value

Definition at line 142 of file loadstore.cpp.

References getTypeDescriptor(), and printSimpleInstruction().

00142                                                  {
00143     printSimpleInstruction("invokestatic",
00144         "lljvm/runtime/Memory/store(I" + getTypeDescriptor(ty) + ")V");
00145 }

void JVMWriter::printIndirectStore ( const Value *  ptr,
const Value *  val 
) [private]

Store a value at the given address.

Parameters:
ptr the address at which to store the value
val the value to store

Definition at line 131 of file loadstore.cpp.

References printValueLoad().

Referenced by printInstruction(), printVAArgInstruction(), and printVAIntrinsic().

00131                                                                      {
00132     printValueLoad(ptr);
00133     printValueLoad(val);
00134     printIndirectStore(val->getType());
00135 }

void JVMWriter::printInstruction ( const Instruction *  inst  )  [private]

Print the given instruction.

Parameters:
inst the instruction

Definition at line 66 of file block.cpp.

References getTypePrefix(), printAllocaInstruction(), printArithmeticInstruction(), printBranchInstruction(), printCallInstruction(), printCastInstruction(), printCmpInstruction(), printGepInstruction(), printIndirectLoad(), printIndirectStore(), printInvokeInstruction(), printMallocInstruction(), printSelectInstruction(), printSimpleInstruction(), printSwitchInstruction(), printVAArgInstruction(), and printValueLoad().

Referenced by printBasicBlock().

00066                                                         {
00067     const Value *left, *right;
00068     if(inst->getNumOperands() >= 1) left  = inst->getOperand(0);
00069     if(inst->getNumOperands() >= 2) right = inst->getOperand(1);
00070     switch(inst->getOpcode()) {
00071     case Instruction::Ret:
00072         printSimpleInstruction("invokestatic",
00073                                "lljvm/runtime/Memory/destroyStackFrame()V");
00074         if(inst->getNumOperands() >= 1) {
00075             printValueLoad(left);
00076             printSimpleInstruction(
00077                 getTypePrefix(left->getType(), true) + "return");
00078         } else {
00079             printSimpleInstruction("return");
00080         }
00081         break;
00082     case Instruction::Unwind:
00083         printSimpleInstruction("getstatic",
00084             "lljvm/runtime/Instruction$Unwind/instance "
00085             "Llljvm/runtime/Instruction$Unwind;");
00086         printSimpleInstruction("athrow");
00087         // TODO: need to destroy stack frames
00088         break;
00089     case Instruction::Unreachable:
00090         printSimpleInstruction("getstatic",
00091             "lljvm/runtime/Instruction$Unreachable/instance "
00092             "Llljvm/runtime/Instruction$Unreachable;");
00093         printSimpleInstruction("athrow");
00094         break;
00095     case Instruction::Free:
00096         // TODO: lowering pass? <http://llvm.org/docs/Passes.html#lowerallocs>
00097         printValueLoad(inst->getOperand(0));
00098         printSimpleInstruction("invokestatic", "lljvm/lib/c/free(I)V");
00099         break;
00100     case Instruction::Add:
00101     case Instruction::FAdd:
00102     case Instruction::Sub:
00103     case Instruction::FSub:
00104     case Instruction::Mul:
00105     case Instruction::FMul:
00106     case Instruction::UDiv:
00107     case Instruction::SDiv:
00108     case Instruction::FDiv:
00109     case Instruction::URem:
00110     case Instruction::SRem:
00111     case Instruction::FRem:
00112     case Instruction::And:
00113     case Instruction::Or:
00114     case Instruction::Xor:
00115     case Instruction::Shl:
00116     case Instruction::LShr:
00117     case Instruction::AShr:
00118         printArithmeticInstruction(inst->getOpcode(), left, right);
00119         break;
00120     case Instruction::SExt:
00121     case Instruction::Trunc:
00122     case Instruction::ZExt:
00123     case Instruction::FPTrunc:
00124     case Instruction::FPExt:
00125     case Instruction::UIToFP:
00126     case Instruction::SIToFP:
00127     case Instruction::FPToUI:
00128     case Instruction::FPToSI:
00129     case Instruction::PtrToInt:
00130     case Instruction::IntToPtr:
00131     case Instruction::BitCast:
00132         printCastInstruction(inst->getOpcode(), left,
00133                              cast<CastInst>(inst)->getDestTy(),
00134                              cast<CastInst>(inst)->getSrcTy()); break;
00135     case Instruction::ICmp:
00136     case Instruction::FCmp:
00137         printCmpInstruction(cast<CmpInst>(inst)->getPredicate(),
00138                             left, right); break;
00139     case Instruction::Malloc:
00140         // TODO: lowering pass? <http://llvm.org/docs/Passes.html#lowerallocs>
00141         printMallocInstruction(cast<MallocInst>(inst)); break;
00142     case Instruction::Br:
00143         printBranchInstruction(cast<BranchInst>(inst)); break;
00144     case Instruction::Select:
00145         printSelectInstruction(inst->getOperand(0),
00146                                inst->getOperand(1),
00147                                inst->getOperand(2)); break;
00148     case Instruction::Load:
00149         printIndirectLoad(inst->getOperand(0)); break;
00150     case Instruction::Store:
00151         printIndirectStore(inst->getOperand(1), inst->getOperand(0)); break;
00152     case Instruction::GetElementPtr:
00153         printGepInstruction(inst->getOperand(0),
00154                             gep_type_begin(inst),
00155                             gep_type_end(inst)); break;
00156     case Instruction::Call:
00157         printCallInstruction(cast<CallInst>(inst)); break;
00158     case Instruction::Invoke:
00159         printInvokeInstruction(cast<InvokeInst>(inst)); break;
00160     case Instruction::Switch:
00161         printSwitchInstruction(cast<SwitchInst>(inst)); break;
00162     case Instruction::Alloca:
00163         printAllocaInstruction(cast<AllocaInst>(inst)); break;
00164     case Instruction::VAArg:
00165         printVAArgInstruction(cast<VAArgInst>(inst)); break;
00166     default:
00167         errs() << "Instruction = " << *inst << '\n';
00168         llvm_unreachable("Unsupported instruction");
00169     }
00170 }

void JVMWriter::printIntrinsicCall ( const IntrinsicInst *  inst  )  [private]

Print a call to an intrinsic function.

Parameters:
inst the instruction

Definition at line 138 of file function.cpp.

References printBitIntrinsic(), printMathIntrinsic(), printMemIntrinsic(), printSimpleInstruction(), and printVAIntrinsic().

Referenced by printCallInstruction().

00138                                                             {
00139     switch(inst->getIntrinsicID()) {
00140     case Intrinsic::vastart:
00141     case Intrinsic::vacopy:
00142     case Intrinsic::vaend:
00143         printVAIntrinsic(inst); break;
00144     case Intrinsic::memcpy:
00145     case Intrinsic::memmove:
00146     case Intrinsic::memset:
00147         printMemIntrinsic(cast<MemIntrinsic>(inst)); break;
00148     case Intrinsic::flt_rounds:
00149         printSimpleInstruction("iconst_m1"); break;
00150     case Intrinsic::dbg_declare:
00151     case Intrinsic::dbg_func_start:
00152     case Intrinsic::dbg_region_end:
00153     case Intrinsic::dbg_region_start:
00154     case Intrinsic::dbg_stoppoint:
00155         // ignore debugging intrinsics
00156         break;
00157     case Intrinsic::pow:
00158     case Intrinsic::exp:
00159     case Intrinsic::log10:
00160     case Intrinsic::log:
00161     case Intrinsic::sqrt:
00162         printMathIntrinsic(inst); break;
00163     case Intrinsic::bswap:
00164         printBitIntrinsic(inst); break;
00165     default:
00166         errs() << "Intrinsic = " << *inst << '\n';
00167         llvm_unreachable("Invalid intrinsic function");
00168     }
00169 }

void JVMWriter::printInvokeInstruction ( const InvokeInst *  inst  )  [private]

Print an invoke instruction.

Parameters:
inst the instruction

Definition at line 188 of file function.cpp.

References printBranchInstruction(), printFunctionCall(), printLabel(), printSimpleInstruction(), and printValueStore().

Referenced by printInstruction().

00188                                                              {
00189     std::string labelname = getUID() + "$invoke";
00190     printLabel(labelname + "_begin");
00191     printFunctionCall(inst->getOperand(0), inst);
00192     printValueStore(inst); // save return value
00193     printLabel(labelname + "_end");
00194     printBranchInstruction(inst->getParent(), inst->getNormalDest());
00195     printLabel(labelname + "_catch");
00196     printSimpleInstruction("pop");
00197     printBranchInstruction(inst->getParent(), inst->getUnwindDest());
00198     printSimpleInstruction(".catch lljvm/runtime/System$Unwind",
00199           "from "  + labelname + "_begin "
00200         + "to "    + labelname + "_end "
00201         + "using " + labelname + "_catch");
00202 }

void JVMWriter::printLabel ( const std::string &  label  )  [private]

Print the given label.

Parameters:
label the label

Definition at line 180 of file printinst.cpp.

References out.

00180                                                  {
00181     out << label << ":\n";
00182 }

void JVMWriter::printLabel ( const char *  label  )  [private]

Print the given label.

Parameters:
label the label

Definition at line 171 of file printinst.cpp.

References out.

Referenced by printBasicBlock(), printBranchInstruction(), printCatchJump(), printFunction(), printFunctionCall(), printInvokeInstruction(), printLoop(), and printSelectInstruction().

00171                                             {
00172     out << label << ":\n";
00173 }

void JVMWriter::printLocalVariable ( const Function &  f,
const Instruction *  inst 
) [private]

Allocate a local variable for the given function.

Variable initialisation and any applicable debugging information is printed.

Parameters:
f the parent function of the variable
inst the instruction assigned to the variable

Definition at line 211 of file function.cpp.

References debug, getLocalVarNumber(), getTypeDescriptor(), getTypePrefix(), getValueName(), and printSimpleInstruction().

Referenced by printFunction().

00212                                                             {
00213     const Type *ty;
00214     if(isa<AllocaInst>(inst) && !isa<GlobalVariable>(inst))
00215         // local variable allocation
00216         ty = PointerType::getUnqual(
00217                  cast<AllocaInst>(inst)->getAllocatedType());
00218     else // operation result
00219         ty = inst->getType();
00220     // getLocalVarNumber must be called at least once in this method
00221     unsigned int varNum = getLocalVarNumber(inst);
00222     if(debug >= 2)
00223         printSimpleInstruction(".var " + utostr(varNum) + " is "
00224             + getValueName(inst) + ' ' + getTypeDescriptor(ty)
00225             + " from begin_method to end_method");
00226     // initialise variable to avoid class verification errors
00227     printSimpleInstruction(getTypePrefix(ty, true) + "const_0");
00228     printSimpleInstruction(getTypePrefix(ty, true) + "store", utostr(varNum));
00229 }

void JVMWriter::printLoop ( const Loop *  l  )  [private]

Print a loop.

Parameters:
l the loop

Definition at line 169 of file branch.cpp.

References getLabelName(), printBasicBlock(), printLabel(), and printSimpleInstruction().

Referenced by printFunctionBody().

00169                                        {
00170     printLabel(getLabelName(l->getHeader()));
00171     for(Loop::block_iterator i = l->block_begin(),
00172                              e = l->block_end(); i != e; i++) {
00173         const BasicBlock *block = *i;
00174         Loop *blockLoop = getAnalysis<LoopInfo>().getLoopFor(block);
00175         if(l == blockLoop)
00176             // the loop is the innermost parent of this block
00177             printBasicBlock(block);
00178         else if(block == blockLoop->getHeader()
00179                  && l == blockLoop->getParentLoop())
00180             // this block is the header of its innermost parent loop,
00181             // and the loop is the parent of that loop
00182             printLoop(blockLoop);
00183     }
00184     printSimpleInstruction("goto", getLabelName(l->getHeader()));
00185 }

void JVMWriter::printMallocInstruction ( const MallocInst *  inst  )  [private]

Print a malloc instruction.

Parameters:
inst the instruction

Definition at line 382 of file instruction.cpp.

References printPtrLoad(), printSimpleInstruction(), printValueLoad(), and targetData.

Referenced by printInstruction().

00382                                                              {
00383     printPtrLoad(targetData->getTypeAllocSize(inst->getAllocatedType()));
00384     printValueLoad(inst->getArraySize());
00385     printSimpleInstruction("imul");
00386     printSimpleInstruction("invokestatic", "lljvm/lib/c/malloc(I)I");
00387 }

void JVMWriter::printMathIntrinsic ( const IntrinsicInst *  inst  )  [private]

Print a mathematical intrinsic function.

Parameters:
inst the instruction

Definition at line 394 of file instruction.cpp.

References getBitWidth(), printSimpleInstruction(), and printValueLoad().

Referenced by printIntrinsicCall().

00394                                                             {
00395     bool f32 = (getBitWidth(inst->getOperand(1)->getType()) == 32);
00396     printValueLoad(inst->getOperand(1));
00397     if(f32) printSimpleInstruction("f2d");
00398     if(inst->getNumOperands() >= 3) {
00399         printValueLoad(inst->getOperand(2));
00400         if(f32) printSimpleInstruction("f2d");
00401     }
00402     switch(inst->getIntrinsicID()) {
00403     case Intrinsic::exp:
00404         printSimpleInstruction("invokestatic", "java/lang/Math/exp(D)D");
00405         break;
00406     case Intrinsic::log:
00407         printSimpleInstruction("invokestatic", "java/lang/Math/log(D)D");
00408         break;
00409     case Intrinsic::log10:
00410         printSimpleInstruction("invokestatic", "java/lang/Math/log10(D)D");
00411         break;
00412     case Intrinsic::sqrt:
00413         printSimpleInstruction("invokestatic", "java/lang/Math/sqrt(D)D");
00414         break;
00415     case Intrinsic::pow:
00416         printSimpleInstruction("invokestatic", "java/lang/Math/pow(DD)D");
00417         break;
00418     }
00419     if(f32) printSimpleInstruction("d2f");
00420 }

void JVMWriter::printMemIntrinsic ( const MemIntrinsic *  inst  )  [private]

Print a memory intrinsic function.

Parameters:
inst the instruction

Definition at line 353 of file instruction.cpp.

References getTypeDescriptor(), printConstLoad(), printSimpleInstruction(), and printValueLoad().

Referenced by printIntrinsicCall().

00353                                                           {
00354     printValueLoad(inst->getDest());
00355     if(const MemTransferInst *minst = dyn_cast<MemTransferInst>(inst))
00356         printValueLoad(minst->getSource());
00357     else if(const MemSetInst *minst = dyn_cast<MemSetInst>(inst))
00358         printValueLoad(minst->getValue());
00359     printValueLoad(inst->getLength());
00360     printConstLoad(inst->getAlignmentCst());
00361     
00362     std::string lenDescriptor = getTypeDescriptor(
00363         inst->getLength()->getType(), true);
00364     switch(inst->getIntrinsicID()) {
00365     case Intrinsic::memcpy:
00366         printSimpleInstruction("invokestatic",
00367             "lljvm/runtime/Memory/memcpy(II" + lenDescriptor + "I)V"); break;
00368     case Intrinsic::memmove:
00369         printSimpleInstruction("invokestatic",
00370             "lljvm/runtime/Memory/memmove(II" + lenDescriptor + "I)V"); break;
00371     case Intrinsic::memset:
00372         printSimpleInstruction("invokestatic",
00373             "lljvm/runtime/Memory/memset(IB" + lenDescriptor + "I)V"); break;
00374     }
00375 }

void JVMWriter::printOperandPack ( const Instruction *  inst,
unsigned int  minOperand,
unsigned int  maxOperand 
) [private]

Pack the specified operands of the given instruction into memory.

The address of the packed values is left on the top of the stack.

Parameters:
inst the given instruction
minOperand the lower bound on the operands to pack (inclusive)
maxOperand the upper bound on the operands to pack (exclusive)

Definition at line 64 of file function.cpp.

References getTypeDescriptor(), printSimpleInstruction(), printValueLoad(), and targetData.

Referenced by printFunctionCall().

00066                                                           {
00067     unsigned int size = 0;
00068     for(unsigned int i = minOperand; i < maxOperand; i++)
00069         size += targetData->getTypeAllocSize(
00070             inst->getOperand(i)->getType());
00071 
00072     printSimpleInstruction("bipush", utostr(size));
00073     printSimpleInstruction("invokestatic",
00074                            "lljvm/runtime/Memory/allocateStack(I)I");
00075     printSimpleInstruction("dup");
00076 
00077     for(unsigned int i = minOperand; i < maxOperand; i++) {
00078         const Value *v = inst->getOperand(i);
00079         printValueLoad(v);
00080         printSimpleInstruction("invokestatic",
00081             "lljvm/runtime/Memory/pack(I"
00082             + getTypeDescriptor(v->getType()) + ")I");
00083     }
00084     printSimpleInstruction("pop");
00085 }

void JVMWriter::printPHICopy ( const BasicBlock *  src,
const BasicBlock *  dest 
) [private]

Replace PHI instructions with copy instructions (load-store pairs).

Parameters:
src the predecessor block
dest the destination block

Definition at line 41 of file branch.cpp.

References printValueLoad(), and printValueStore().

Referenced by printBranchInstruction().

00041                                                                           {
00042     for(BasicBlock::const_iterator i = dest->begin(); isa<PHINode>(i); i++) {
00043         const PHINode *phi = cast<PHINode>(i);
00044         const Value *val = phi->getIncomingValueForBlock(src);
00045         if(isa<UndefValue>(val))
00046             continue;
00047         printValueLoad(val);
00048         printValueStore(phi);
00049     }
00050 }

void JVMWriter::printPtrLoad ( uint64_t  n  )  [private]

Load the given pointer.

Parameters:
n the value of the pointer

Definition at line 30 of file const.cpp.

References module, and printConstLoad().

Referenced by printAllocaInstruction(), printConstLoad(), printGepInstruction(), printMallocInstruction(), printStaticConstant(), and printValueLoad().

00030                                        {
00031     if(module->getPointerSize() != Module::Pointer32)
00032         llvm_unreachable("Only 32-bit pointers are allowed");
00033     printConstLoad(APInt(32, n, false));
00034 }

void JVMWriter::printSelectInstruction ( const Value *  cond,
const Value *  trueVal,
const Value *  falseVal 
) [private]

Print a select instruction.

Parameters:
cond the condition
trueVal the return value of the instruction if the condition is non-zero
falseVal the return value of the instruction if the condition is zero

Definition at line 124 of file branch.cpp.

References printLabel(), printSimpleInstruction(), and printValueLoad().

Referenced by printConstantExpr(), and printInstruction().

00126                                                               {
00127     std::string labelname = "select" + utostr(getUID());
00128     printValueLoad(cond);
00129     printSimpleInstruction("ifeq", labelname + "a");
00130     printValueLoad(trueVal);
00131     printSimpleInstruction("goto", labelname + "b");
00132     printLabel(labelname + "a");
00133     printValueLoad(falseVal);
00134     printLabel(labelname + "b");
00135 }

void JVMWriter::printSimpleInstruction ( const std::string &  inst,
const std::string &  operand 
) [private]

Print the given instruction.

Parameters:
inst the instruction
operand the operand to the instruction

Definition at line 89 of file printinst.cpp.

References out.

00090                                                                  {
00091     out << '\t' << inst << ' ' << operand << '\n';
00092 }

void JVMWriter::printSimpleInstruction ( const std::string &  inst  )  [private]

Print the given instruction.

Parameters:
inst the instruction

Definition at line 79 of file printinst.cpp.

References out.

00079                                                             {
00080     out << '\t' << inst << '\n';
00081 }

void JVMWriter::printSimpleInstruction ( const char *  inst,
const char *  operand 
) [private]

Print the given instruction.

Parameters:
inst the instruction
operand the operand to the instruction

Definition at line 70 of file printinst.cpp.

References out.

00070                                                                             {
00071     out << '\t' << inst << ' ' << operand << '\n';
00072 }

void JVMWriter::printSimpleInstruction ( const char *  inst  )  [private]

void JVMWriter::printStaticConstant ( const Constant *  c  )  [private]

Store the given static constant.

The constant is stored to the address currently on top of the stack, pushing the first address following the constant onto the stack afterwards.

Parameters:
c the constant

Definition at line 170 of file const.cpp.

References getTypeDescriptor(), printConstantExpr(), printConstLoad(), printPtrLoad(), printSimpleInstruction(), printValueLoad(), and targetData.

Referenced by printClInit().

00170                                                      {
00171     if(isa<ConstantAggregateZero>(c) || c->isNullValue()) {
00172         // zero initialised constant
00173         printPtrLoad(targetData->getTypeAllocSize(c->getType()));
00174         printSimpleInstruction("invokestatic",
00175                                "lljvm/runtime/Memory/zero(II)I");
00176         return;
00177     }
00178     std::string typeDescriptor = getTypeDescriptor(c->getType());
00179     switch(c->getType()->getTypeID()) {
00180     case Type::IntegerTyID:
00181     case Type::FloatTyID:
00182     case Type::DoubleTyID:
00183         printConstLoad(c);
00184         printSimpleInstruction("invokestatic",
00185             "lljvm/runtime/Memory/pack(I" + typeDescriptor + ")I");
00186         break;
00187     case Type::ArrayTyID:
00188         if(const ConstantArray *ca = dyn_cast<ConstantArray>(c))
00189             if(ca->isString()) {
00190                 bool cstring = ca->isCString();
00191                 printConstLoad(ca->getAsString(), cstring);
00192                 if(cstring)
00193                     printSimpleInstruction("invokestatic",
00194                         "lljvm/runtime/Memory/pack(ILjava/lang/String;)I");
00195                 else {
00196                     printSimpleInstruction("invokevirtual", 
00197                                            "java/lang/String/toCharArray()[C");
00198                     printSimpleInstruction("invokestatic",
00199                                            "lljvm/runtime/Memory/pack(I[C)I");
00200                 }
00201                 break;
00202             }
00203         // else fall through
00204     case Type::VectorTyID:
00205     case Type::StructTyID:
00206         for(unsigned int i = 0, e = c->getNumOperands(); i < e; i++)
00207             printStaticConstant(cast<Constant>(c->getOperand(i)));
00208         break;
00209     case Type::PointerTyID:
00210         if(const Function *f = dyn_cast<Function>(c))
00211             printValueLoad(f);
00212         else if(const GlobalVariable *g = dyn_cast<GlobalVariable>(c))
00213             // initialise with address of global variable
00214             printValueLoad(g);
00215         else if(isa<ConstantPointerNull>(c) || c->isNullValue())
00216             printSimpleInstruction("iconst_0");
00217         else if(const ConstantExpr *ce = dyn_cast<ConstantExpr>(c))
00218             printConstantExpr(ce);
00219         else {
00220             errs() << "Constant = " << *c << '\n';
00221             llvm_unreachable("Invalid static initializer");
00222         }
00223         printSimpleInstruction("invokestatic",
00224             "lljvm/runtime/Memory/pack(I" + typeDescriptor + ")I");
00225         break;
00226     default:
00227         errs() << "TypeID = " << c->getType()->getTypeID() << '\n';
00228         llvm_unreachable("Invalid type in printStaticConstant()");
00229     }
00230 }

void JVMWriter::printSwitchInstruction ( const SwitchInst *  inst  )  [private]

Print a switch instruction.

Parameters:
inst the switch instruction

Definition at line 142 of file branch.cpp.

References getLabelName(), out, and printValueLoad().

Referenced by printInstruction().

00142                                                              {
00143     // TODO: This method does not handle switch statements when the
00144     // successor contains phi instructions (the value of the phi instruction
00145     // should be set before branching to the successor). Therefore, it has
00146     // been replaced by the switch lowering pass. Once this method is
00147     // fixed the switch lowering pass should be removed.
00148     
00149     std::map<int, unsigned int> cases;
00150     for(unsigned int i = 1, e = inst->getNumCases(); i < e; i++)
00151         cases[(int) inst->getCaseValue(i)->getValue().getSExtValue()] = i;
00152     
00153     // TODO: tableswitch in cases where it won't increase the size of the
00154     //       class file
00155     printValueLoad(inst->getCondition());
00156     out << "\tlookupswitch\n";
00157     for(std::map<int, unsigned int>::const_iterator
00158         i = cases.begin(), e = cases.end(); i != e; i++)
00159         out << "\t\t" << i->first << " : "
00160             << getLabelName(inst->getSuccessor(i->second)) << '\n';
00161     out << "\t\tdefault : " << getLabelName(inst->getDefaultDest()) << '\n';
00162 }

void JVMWriter::printVAArgInstruction ( const VAArgInst *  inst  )  [private]

Print a va_arg instruction.

Parameters:
inst the instruction

Definition at line 310 of file instruction.cpp.

References printConstLoad(), printIndirectLoad(), printIndirectStore(), printSimpleInstruction(), printValueLoad(), and targetData.

Referenced by printInstruction().

00310                                                            {
00311     printIndirectLoad(inst->getOperand(0));
00312     printSimpleInstruction("dup");
00313     printConstLoad(
00314         APInt(32, targetData->getTypeAllocSize(inst->getType()), false));
00315     printSimpleInstruction("iadd");
00316     printValueLoad(inst->getOperand(0));
00317     printSimpleInstruction("swap");
00318     printIndirectStore(PointerType::getUnqual(
00319         IntegerType::get(inst->getContext(), 8)));
00320     printIndirectLoad(inst->getType());
00321 }

void JVMWriter::printVAIntrinsic ( const IntrinsicInst *  inst  )  [private]

Print a vararg intrinsic function.

Parameters:
inst the instruction

Definition at line 328 of file instruction.cpp.

References printIndirectLoad(), printIndirectStore(), printSimpleInstruction(), printValueLoad(), and vaArgNum.

Referenced by printIntrinsicCall().

00328                                                           {
00329     const Type *valistTy = PointerType::getUnqual(
00330         IntegerType::get(inst->getContext(), 8));
00331     switch(inst->getIntrinsicID()) {
00332     case Intrinsic::vastart:
00333         printValueLoad(inst->getOperand(1));
00334         printSimpleInstruction("iload", utostr(vaArgNum) + " ; varargptr");
00335         printIndirectStore(valistTy);
00336         break;
00337     case Intrinsic::vacopy:
00338         printValueLoad(inst->getOperand(1));
00339         printValueLoad(inst->getOperand(2));
00340         printIndirectLoad(valistTy);
00341         printIndirectStore(valistTy);
00342         break;
00343     case Intrinsic::vaend:
00344         break;
00345     }
00346 }

void JVMWriter::printValueLoad ( const Value *  v  )  [private]

Load the given value.

Parameters:
v the value to load

Definition at line 30 of file loadstore.cpp.

References classname, externRefs, getCallSignature(), getLocalVarNumber(), getTypePrefix(), getValueName(), printConstantExpr(), printConstLoad(), printPtrLoad(), and printSimpleInstruction().

Referenced by printAllocaInstruction(), printArithmeticInstruction(), printBinaryInstruction(), printBranchInstruction(), printCastInstruction(), printFunctionCall(), printIndirectLoad(), printIndirectStore(), printInstruction(), printMallocInstruction(), printMathIntrinsic(), printMemIntrinsic(), printOperandPack(), printPHICopy(), printSelectInstruction(), printStaticConstant(), printSwitchInstruction(), printVAArgInstruction(), printVAIntrinsic(), and printVirtualInstruction().

00030                                              {
00031     if(const Function *f = dyn_cast<Function>(v)) {
00032         std::string sig = getValueName(f)
00033                         + getCallSignature(f->getFunctionType());
00034         if(externRefs.count(v))
00035             printSimpleInstruction("CLASSFORMETHOD", sig);
00036         else
00037             printSimpleInstruction("ldc", '"' + classname + '"');
00038         printSimpleInstruction("ldc", '"' + sig + '"');
00039         printSimpleInstruction("invokestatic",
00040             "lljvm/runtime/Function/getFunctionPointer"
00041             "(Ljava/lang/String;Ljava/lang/String;)I");
00042     } else if(isa<GlobalVariable>(v)) {
00043         const Type *ty = cast<PointerType>(v->getType())->getElementType();
00044         if(externRefs.count(v))
00045             printSimpleInstruction("getstatic", getValueName(v) + " I");
00046         else
00047             printSimpleInstruction("getstatic",
00048                 classname + "/" + getValueName(v) + " I");
00049     } else if(isa<ConstantPointerNull>(v)) {
00050         printPtrLoad(0);
00051     } else if(const ConstantExpr *ce = dyn_cast<ConstantExpr>(v)) {
00052         printConstantExpr(ce);
00053     } else if(const Constant *c = dyn_cast<Constant>(v)) {
00054         printConstLoad(c);
00055     } else {
00056         if(getLocalVarNumber(v) <= 3)
00057             printSimpleInstruction(
00058                 getTypePrefix(v->getType(), true) + "load_"
00059                 + utostr(getLocalVarNumber(v))
00060                 + " ; " + getValueName(v));
00061         else
00062             printSimpleInstruction(
00063                 getTypePrefix(v->getType(), true) + "load",
00064                 utostr(getLocalVarNumber(v))
00065                 + " ; " + getValueName(v));
00066     }
00067 }

void JVMWriter::printValueStore ( const Value *  v  )  [private]

Store the value currently on top of the stack to the given local variable.

Parameters:
v the Value representing the local variable

Definition at line 74 of file loadstore.cpp.

References getBitWidth(), getLocalVarNumber(), getTypePrefix(), getValueName(), and printSimpleInstruction().

Referenced by printBasicBlock(), printInvokeInstruction(), and printPHICopy().

00074                                               {
00075     if(isa<Function>(v) || isa<GlobalVariable>(v) || isa<Constant>(v)) {
00076         errs() << "Value  = " << *v << '\n';
00077         llvm_unreachable("Invalid value");
00078     }
00079     unsigned int bitWidth = getBitWidth(v->getType());
00080     // truncate int
00081     if(bitWidth == 16)
00082         printSimpleInstruction("i2s");
00083     else if(bitWidth == 8)
00084         printSimpleInstruction("i2b");
00085     else if(bitWidth == 1) {
00086         printSimpleInstruction("iconst_1");
00087         printSimpleInstruction("iand");
00088     }
00089     if(getLocalVarNumber(v) <= 3)
00090         printSimpleInstruction(
00091             getTypePrefix(v->getType(), true) + "store_"
00092             + utostr(getLocalVarNumber(v))
00093             + " ; " + getValueName(v));
00094     else
00095         printSimpleInstruction(
00096             getTypePrefix(v->getType(), true) + "store",
00097             utostr(getLocalVarNumber(v))
00098             + " ; " + getValueName(v));
00099 }

void JVMWriter::printVirtualInstruction ( const std::string &  sig,
const Value *  left,
const Value *  right 
) [private]

Print the virtual instruction with the given signature.

Parameters:
sig the signature of the instruction
left the first operand
right the second operand

Definition at line 158 of file printinst.cpp.

References printValueLoad(), and printVirtualInstruction().

00160                                                             {
00161     printValueLoad(left);
00162     printValueLoad(right);
00163     printVirtualInstruction(sig);
00164 }

void JVMWriter::printVirtualInstruction ( const std::string &  sig,
const Value *  operand 
) [private]

Print the virtual instruction with the given signature.

Parameters:
sig the signature of the instruction
operand the operand to the instruction

Definition at line 145 of file printinst.cpp.

References printValueLoad(), and printVirtualInstruction().

00146                                                               {
00147     printValueLoad(operand);
00148     printVirtualInstruction(sig);
00149 }

void JVMWriter::printVirtualInstruction ( const std::string &  sig  )  [private]

Print the virtual instruction with the given signature.

Parameters:
sig the signature of the instruction

Definition at line 135 of file printinst.cpp.

References printVirtualInstruction().

00135                                                             {
00136     printVirtualInstruction(sig.c_str());
00137 }

void JVMWriter::printVirtualInstruction ( const char *  sig,
const Value *  left,
const Value *  right 
) [private]

Print the virtual instruction with the given signature.

Parameters:
sig the signature of the instruction
left the first operand
right the second operand

Definition at line 122 of file printinst.cpp.

References printValueLoad(), and printVirtualInstruction().

00124                                                             {
00125     printValueLoad(left);
00126     printValueLoad(right);
00127     printVirtualInstruction(sig);
00128 }

void JVMWriter::printVirtualInstruction ( const char *  sig,
const Value *  operand 
) [private]

Print the virtual instruction with the given signature.

Parameters:
sig the signature of the instruction
operand the operand to the instruction

Definition at line 109 of file printinst.cpp.

References printValueLoad(), and printVirtualInstruction().

00110                                                               {
00111     printValueLoad(operand);
00112     printVirtualInstruction(sig);
00113 }

void JVMWriter::printVirtualInstruction ( const char *  sig  )  [private]

Print the virtual instruction with the given signature.

Parameters:
sig the signature of the instruction

Definition at line 99 of file printinst.cpp.

References out.

Referenced by printArithmeticInstruction(), printBitIntrinsic(), printCastInstruction(), printCmpInstruction(), and printVirtualInstruction().

00099                                                        {
00100     out << '\t' << "invokestatic lljvm/runtime/Instruction/" << sig << '\n';
00101 }

bool JVMWriter::runOnFunction ( Function &  f  )  [private]

Process the given function.

Parameters:
f the function to process
Returns:
whether the function was modified (always false)

Definition at line 56 of file backend.cpp.

References printFunction().

00056                                          {
00057     if(!f.isDeclaration() && !f.hasAvailableExternallyLinkage())
00058         printFunction(f);
00059     return false;
00060 }

std::string JVMWriter::sanitizeName ( std::string  name  )  [private]

Replace any non-alphanumeric characters with underscores.

Parameters:
name the name to sanitize
Returns:
the sanitized name

Definition at line 33 of file name.cpp.

Referenced by getLabelName(), and getValueName().

00033                                                 {
00034     for(std::string::iterator i = name.begin(), e = name.end(); i != e; i++)
00035         if(!isalnum(*i))
00036             *i = '_';
00037     return name;
00038 }


The documentation for this class was generated from the following files:

Generated on Tue Dec 29 17:21:35 2009 for LLJVM Backend by  doxygen 1.5.8