// // // The Nimrod Compiler // (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. // unit llvmdata; // this module implements data structures for emitting LLVM. interface {$include 'config.inc'} uses nsystem, ast, astalgo, idents, lists, passes; type VTypeKind = ( VoidTyID, ///< 0: type with no size FloatTyID, ///< 1: 32 bit floating point type DoubleTyID, ///< 2: 64 bit floating point type X86_FP80TyID, ///< 3: 80 bit floating point type (X87) FP128TyID, ///< 4: 128 bit floating point type (112-bit mantissa) PPC_FP128TyID, ///< 5: 128 bit floating point type (two 64-bits) LabelTyID, ///< 6: Labels MetadataTyID, ///< 7: Metadata // Derived types... see DerivedTypes.h file... // Make sure FirstDerivedTyID stays up to date!!! IntegerTyID, ///< 8: Arbitrary bit width integers FunctionTyID, ///< 9: Functions StructTyID, ///< 10: Structures ArrayTyID, ///< 11: Arrays PointerTyID, ///< 12: Pointers OpaqueTyID, ///< 13: Opaque: type with unknown structure VectorTyID, ///< 14: SIMD 'packed' format, or other vector type ); VType = ^VTypeDesc; VTypeSeq = array of VType; VTypeDesc = object(TIdObj) k: VTypeKind; s: VTypeSeq; arrayLen: int; name: string; end; VInstrKind = ( iNone, iAdd, iSub, iMul, iDiv, iMod, ); VLocalVar = record end; VInstr = record k: VInstrKind; end; /// This represents a single basic block in LLVM. A basic block is simply a /// container of instructions that execute sequentially. Basic blocks are Values /// because they are referenced by instructions such as branches and switch /// tables. The type of a BasicBlock is "Type::LabelTy" because the basic block /// represents a label to which a branch can jump. /// VBlock = ^VBlockDesc; VBlockDesc = record // LLVM basic block // list of instructions end; VLinkage = ( ExternalLinkage, // Externally visible function LinkOnceLinkage, // Keep one copy of function when linking (inline) WeakLinkage, // Keep one copy of function when linking (weak) AppendingLinkage, // Special purpose, only applies to global arrays InternalLinkage, // Rename collisions when linking (static functions) DLLImportLinkage, // Function to be imported from DLL DLLExportLinkage, // Function to be accessible from DLL ExternalWeakLinkage, // ExternalWeak linkage description GhostLinkage // Stand-in functions for streaming fns from bitcode ); VVisibility = ( DefaultVisibility, // The GV is visible HiddenVisibility, // The GV is hidden ProtectedVisibility // The GV is protected ); TLLVMCallConv = ( CCallConv = 0, FastCallConv = 8, ColdCallConv = 9, X86StdcallCallConv = 64, X86FastcallCallConv = 65 ); VProc = ^VProcDesc; VProcDesc = record b: VBlock; name: string; sym: PSym; // proc that is generated linkage: VLinkage; vis: VVisibility; callConv: VCallConv; next: VProc; end; VModule = ^VModuleDesc; VModuleDesc = object(TPassContext) // represents a C source file sym: PSym; filename: string; typeCache: TIdTable; // cache the generated types forwTypeCache: TIdTable; // cache for forward declarations of types declaredThings: TIntSet; // things we have declared in this file declaredProtos: TIntSet; // prototypes we have declared in this file headerFiles: TLinkedList; // needed headers to include typeInfoMarker: TIntSet; // needed for generating type information initProc: VProc; // code for init procedure typeStack: TTypeSeq; // used for type generation dataCache: TNodeTable; forwardedProcs: TSymSeq; // keep forwarded procs here typeNodes, nimTypes: int;// used for type info generation typeNodesName, nimTypesName: PRope; // used for type info generation labels: natural; // for generating unique module-scope names next: VModule; // to stack modules end; implementation end.