def declare_intrinsic(self, intrinsic, tys=(), fnty=None): def _error(): raise NotImplementedError("unknown intrinsic %r with %d types" % (intrinsic, len(tys))) if intrinsic in {'llvm.cttz', 'llvm.ctlz', 'llvm.fma'}: suffixes = [tys[0].intrinsic_name] else: suffixes = [t.intrinsic_name for t in tys] name = '.'.join([intrinsic] + suffixes) if name in self.globals: return self.globals[name] if fnty is not None: # General case: function type is given pass # Compute function type if omitted for common cases elif len(tys) == 0 and intrinsic == 'llvm.assume': fnty = types.FunctionType(types.VoidType(), [types.IntType(1)]) elif len(tys) == 1: if intrinsic == 'llvm.powi': fnty = types.FunctionType(tys[0], [tys[0], types.IntType(32)]) elif intrinsic == 'llvm.pow': fnty = types.FunctionType(tys[0], tys * 2) elif intrinsic == 'llvm.convert.from.fp16': fnty = types.FunctionType(tys[0], [types.IntType(16)]) elif intrinsic == 'llvm.convert.to.fp16': fnty = types.FunctionType(types.IntType(16), tys) else: fnty = types.FunctionType(tys[0], tys) elif len(tys) == 2: if intrinsic == 'llvm.memset': tys = [tys[0], types.IntType(8), tys[1], types.IntType(1)] fnty = types.FunctionType(types.VoidType(), tys) elif intrinsic in {'llvm.cttz', 'llvm.ctlz'}: tys = [tys[0], types.IntType(1)] fnty = types.FunctionType(tys[0], tys) else: _error() elif len(tys) == 3: if intrinsic in ('llvm.memcpy', 'llvm.memmove'): tys = tys + [types.IntType(1)] fnty = types.FunctionType(types.VoidType(), tys) elif intrinsic == 'llvm.fma': tys = [tys[0]] * 3 fnty = types.FunctionType(tys[0], tys) else: _error() else: _error() return values.Function(self, fnty, name=name)
def store_reg(self, value, reg_type, reg_name, name=""): """ Store an LLVM value inside a register Example: store_reg(Constant(IntType(32), 0xAAAAAAAA), IntType(32), "eax") """ ftype = types.FunctionType(types.VoidType(), [reg_type]) return self.asm(ftype, "", "{%s}" % reg_name, [value], True, name)
def __init__(self, parent, ordering, targetscope=None, name=''): super(Fence, self).__init__(parent, types.VoidType(), "fence", (), name=name) if ordering not in self.VALID_FENCE_ORDERINGS: msg = "Invalid fence ordering \"{0}\"! Should be one of {1}." raise ValueError(msg .format(ordering, ", ".join(self.VALID_FENCE_ORDERINGS))) self.ordering = ordering self.targetscope = targetscope
def __init__(self, parent): super(Unreachable, self).__init__(parent, types.VoidType(), "unreachable", (), name='')
def __init__(self, parent, val, ptr, ordering, align): super(StoreAtomicInstr, self).__init__(parent, types.VoidType(), "store atomic", [val, ptr]) self.ordering = ordering self.align = align
def __init__(self, parent, val, ptr): super(StoreInstr, self).__init__(parent, types.VoidType(), "store", [val, ptr])
def __init__(self, parent, opname, operands): super(Terminator, self).__init__(parent, types.VoidType(), opname, operands)