Beispiel #1
0
    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)
Beispiel #2
0
 def load_reg(self, reg_type, reg_name, name=""):
     """
     Load a register value into an LLVM value.
       Example: v = load_reg(IntType(32), "eax")
     """
     ftype = types.FunctionType(reg_type, [])
     return self.asm(ftype, "", "={%s}" % reg_name, [], False, name)
Beispiel #3
0
 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)
Beispiel #4
0
        def wrapped(self, lhs, rhs, name=""):
            if lhs.type != rhs.type:
                raise ValueError(
                    "Operands must be the same type, got (%s, %s)" %
                    (lhs.type, rhs.type))
            ty = lhs.type
            if not isinstance(ty, types.IntType):
                raise TypeError("expected an integer type, got %s" % (ty, ))
            bool_ty = types.IntType(1)

            mod = self.module
            fnty = types.FunctionType(types.LiteralStructType([ty, bool_ty]),
                                      [ty, ty])
            fn = mod.declare_intrinsic("llvm.%s.with.overflow" % (opname, ),
                                       [ty], fnty)
            ret = self.call(fn, [lhs, rhs], name=name)
            return ret