1import itertools 2 3from llvmlite import ir 4from llvmlite import binding as llvm 5 6CallOrInvokeInstruction = ir.CallInstr 7 8 9class LLVMException(Exception): 10 pass 11 12 13_icmp_ct = itertools.count() 14 15 16def _icmp_get(): 17 return next(_icmp_ct) 18 19 20ICMP_EQ = _icmp_get() 21ICMP_NE = _icmp_get() 22ICMP_SLT = _icmp_get() 23ICMP_SLE = _icmp_get() 24ICMP_SGT = _icmp_get() 25ICMP_SGE = _icmp_get() 26ICMP_ULT = _icmp_get() 27ICMP_ULE = _icmp_get() 28ICMP_UGT = _icmp_get() 29ICMP_UGE = _icmp_get() 30 31FCMP_OEQ = _icmp_get() 32FCMP_OGT = _icmp_get() 33FCMP_OGE = _icmp_get() 34FCMP_OLT = _icmp_get() 35FCMP_OLE = _icmp_get() 36FCMP_ONE = _icmp_get() 37FCMP_ORD = _icmp_get() 38 39FCMP_UEQ = _icmp_get() 40FCMP_UGT = _icmp_get() 41FCMP_UGE = _icmp_get() 42FCMP_ULT = _icmp_get() 43FCMP_ULE = _icmp_get() 44FCMP_UNE = _icmp_get() 45FCMP_UNO = _icmp_get() 46 47INTR_FABS = "llvm.fabs" 48INTR_EXP = "llvm.exp" 49INTR_LOG = "llvm.log" 50INTR_LOG10 = "llvm.log10" 51INTR_SIN = "llvm.sin" 52INTR_COS = "llvm.cos" 53INTR_POWI = 'llvm.powi' 54INTR_POW = 'llvm.pow' 55INTR_FLOOR = 'llvm.floor' 56 57LINKAGE_EXTERNAL = 'external' 58LINKAGE_INTERNAL = 'internal' 59LINKAGE_LINKONCE_ODR = 'linkonce_odr' 60 61ATTR_NO_CAPTURE = 'nocapture' 62 63 64class Type(object): 65 @staticmethod 66 def int(width=32): 67 return ir.IntType(width) 68 69 @staticmethod 70 def float(): 71 return ir.FloatType() 72 73 @staticmethod 74 def half(): 75 return ir.HalfType() 76 77 @staticmethod 78 def double(): 79 return ir.DoubleType() 80 81 @staticmethod 82 def pointer(ty, addrspace=0): 83 return ir.PointerType(ty, addrspace) 84 85 @staticmethod 86 def function(res, args, var_arg=False): 87 return ir.FunctionType(res, args, var_arg=var_arg) 88 89 @staticmethod 90 def struct(members): 91 return ir.LiteralStructType(members) 92 93 @staticmethod 94 def array(element, count): 95 return ir.ArrayType(element, count) 96 97 @staticmethod 98 def void(): 99 return ir.VoidType() 100 101 102class Constant(object): 103 @staticmethod 104 def all_ones(ty): 105 if isinstance(ty, ir.IntType): 106 return Constant.int(ty, int('1' * ty.width, 2)) 107 else: 108 raise NotImplementedError(ty) 109 110 @staticmethod 111 def int(ty, n): 112 return ir.Constant(ty, n) 113 114 @staticmethod 115 def int_signextend(ty, n): 116 return ir.Constant(ty, n) 117 118 @staticmethod 119 def real(ty, n): 120 return ir.Constant(ty, n) 121 122 @staticmethod 123 def struct(elems): 124 return ir.Constant.literal_struct(elems) 125 126 @staticmethod 127 def null(ty): 128 return ir.Constant(ty, None) 129 130 @staticmethod 131 def undef(ty): 132 return ir.Constant(ty, ir.Undefined) 133 134 @staticmethod 135 def stringz(string): 136 n = (len(string) + 1) 137 buf = bytearray((' ' * n).encode('ascii')) 138 buf[-1] = 0 139 buf[:-1] = string.encode('utf-8') 140 return ir.Constant(ir.ArrayType(ir.IntType(8), n), buf) 141 142 @staticmethod 143 def array(typ, val): 144 return ir.Constant(ir.ArrayType(typ, len(val)), val) 145 146 @staticmethod 147 def bitcast(const, typ): 148 return const.bitcast(typ) 149 150 @staticmethod 151 def inttoptr(const, typ): 152 return const.inttoptr(typ) 153 154 @staticmethod 155 def gep(const, indices): 156 return const.gep(indices) 157 158 159class Module(ir.Module): 160 161 def get_or_insert_function(self, fnty, name): 162 if name in self.globals: 163 return self.globals[name] 164 else: 165 return ir.Function(self, fnty, name) 166 167 def verify(self): 168 llvm.parse_assembly(str(self)) 169 170 def add_function(self, fnty, name): 171 return ir.Function(self, fnty, name) 172 173 def add_global_variable(self, ty, name, addrspace=0): 174 return ir.GlobalVariable(self, ty, self.get_unique_name(name), 175 addrspace) 176 177 def get_global_variable_named(self, name): 178 try: 179 return self.globals[name] 180 except KeyError: 181 raise LLVMException(name) 182 183 def get_or_insert_named_metadata(self, name): 184 try: 185 return self.get_named_metadata(name) 186 except KeyError: 187 return self.add_named_metadata(name) 188 189 190class Function(ir.Function): 191 192 @classmethod 193 def new(cls, module_obj, functy, name=''): 194 return cls(module_obj, functy, name) 195 196 @staticmethod 197 def intrinsic(module, intrinsic, tys): 198 return module.declare_intrinsic(intrinsic, tys) 199 200 201_icmp_umap = { 202 ICMP_EQ: '==', 203 ICMP_NE: '!=', 204 ICMP_ULT: '<', 205 ICMP_ULE: '<=', 206 ICMP_UGT: '>', 207 ICMP_UGE: '>=', 208} 209 210_icmp_smap = { 211 ICMP_SLT: '<', 212 ICMP_SLE: '<=', 213 ICMP_SGT: '>', 214 ICMP_SGE: '>=', 215} 216 217_fcmp_omap = { 218 FCMP_OEQ: '==', 219 FCMP_OGT: '>', 220 FCMP_OGE: '>=', 221 FCMP_OLT: '<', 222 FCMP_OLE: '<=', 223 FCMP_ONE: '!=', 224 FCMP_ORD: 'ord', 225} 226 227_fcmp_umap = { 228 FCMP_UEQ: '==', 229 FCMP_UGT: '>', 230 FCMP_UGE: '>=', 231 FCMP_ULT: '<', 232 FCMP_ULE: '<=', 233 FCMP_UNE: '!=', 234 FCMP_UNO: 'uno', 235} 236 237 238class Builder(ir.IRBuilder): 239 240 def icmp(self, pred, lhs, rhs, name=''): 241 if pred in _icmp_umap: 242 return self.icmp_unsigned(_icmp_umap[pred], lhs, rhs, name=name) 243 else: 244 return self.icmp_signed(_icmp_smap[pred], lhs, rhs, name=name) 245 246 def fcmp(self, pred, lhs, rhs, name=''): 247 if pred in _fcmp_umap: 248 return self.fcmp_unordered(_fcmp_umap[pred], lhs, rhs, name=name) 249 else: 250 return self.fcmp_ordered(_fcmp_omap[pred], lhs, rhs, name=name) 251 252 253class MetaDataString(ir.MetaDataString): 254 @staticmethod 255 def get(module, text): 256 return MetaDataString(module, text) 257 258 259class MetaData(object): 260 @staticmethod 261 def get(module, values): 262 return module.add_metadata(values) 263 264 265class InlineAsm(ir.InlineAsm): 266 @staticmethod 267 def get(*args, **kwargs): 268 return InlineAsm(*args, **kwargs) 269