Ejemplo n.º 1
0
    def __add__(self, other):
        """
        Return the result of an addition.
        """

        other = qy.value_from_any(other).cast_to(self.type_)
        value = RealValue(qy.get().builder.fadd(self._value, other._value))

        if qy.get().test_for_nan:
            qy.assert_(~value.is_nan, "result of %s + %s is not a number", other, self)

        return value
Ejemplo n.º 2
0
    def __eq__(self, other):
        """
        Return the result of an equality comparison.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.icmp(
                    llvm.ICMP_EQ,
                    qy.get().builder.ptrtoint(self._value, qy.iptr_type),
                    qy.value_from_any(other).cast_to(qy.iptr_type)._value,
                    ),
                )
Ejemplo n.º 3
0
    def __mul__(self, other):
        """
        Return the result of a multiplication.
        """

        other = qy.value_from_any(other).cast_to(self.type_)

        return IntegerValue(qy.get().builder.mul(self._value, other._value))
Ejemplo n.º 4
0
    def __div__(self, other):
        """
        Return the result of a division.
        """

        other = qy.value_from_any(other).cast_to(self.type_)

        return IntegerValue(qy.get().builder.sdiv(self._value, other._value))
Ejemplo n.º 5
0
    def __or__(self, other):
        """
        Return the result of a bitwise or.
        """

        other = qy.value_from_any(other).cast_to(self.type_)

        return IntegerValue(qy.get().builder.or_(self._value, other._value))
Ejemplo n.º 6
0
    def __add__(self, other):
        """
        Return the result of an addition.
        """

        other = qy.value_from_any(other).cast_to(self.type_)

        return IntegerValue(qy.get().builder.add(self._value, other._value))
Ejemplo n.º 7
0
    def intrinsic(intrinsic_id, qualifiers=()):
        """
        Return an intrinsic function.
        """

        qualifiers = map(qy.type_from_any, qualifiers)

        return Function(llvm.Function.intrinsic(qy.get().module, intrinsic_id, qualifiers))
Ejemplo n.º 8
0
    def named(name, return_type=llvm.Type.void(), argument_types=()):
        """
        Look up or create a named function.
        """

        type_ = llvm.Type.function(qy.type_from_any(return_type), map(qy.type_from_any, argument_types))

        return Function(qy.get().module.get_or_insert_function(type_, name))
Ejemplo n.º 9
0
    def __sub__(self, other):
        """
        Return the result of a subtraction.
        """

        other = qy.value_from_any(other).cast_to(self.type_)

        return IntegerValue(qy.get().builder.sub(self._value, other._value))
Ejemplo n.º 10
0
    def load(self, name = ""):
        """
        Load the value pointed to by this pointer.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.load(self._value, name = name),
                )
Ejemplo n.º 11
0
    def __mod__(self, other):
        """
        Return the remainder of a division.

        Note that this operation performs C-style, not Python-style, modulo.
        """

        other = qy.value_from_any(other).cast_to(self.type_)

        return IntegerValue(qy.get().builder.srem(self._value, other._value))
Ejemplo n.º 12
0
    def cast_to(self, type_, name = ""):
        """
        Cast this value to the specified type.
        """

        # XXX support more casts

        type_     = qy.type_from_any(type_)
        low_value = None

        if type_.kind == llvm.TYPE_POINTER:
            low_value = qy.get().builder.bitcast(self._value, type_, name)
        elif type_.kind == llvm.TYPE_INTEGER:
            if type_.width == qy.iptr_type.width:
                low_value = qy.get().builder.ptrtoint(self._value, type_, name)

        if low_value is None:
            raise CoercionError(self.type_, type_)
        else:
            return qy.Value.from_any(low_value)
Ejemplo n.º 13
0
    def new_named(name, return_type=llvm.Type.void(), argument_types=(), internal=True):
        """
        Create a named function.
        """

        type_ = llvm.Type.function(qy.type_from_any(return_type), map(qy.type_from_any, argument_types))
        function = qy.get().module.add_function(type_, name)

        if internal:
            function.linkage = llvm.LINKAGE_INTERNAL

        return Function(function)
Ejemplo n.º 14
0
    def gep(self, *indices):
        """
        Return a pointer to a component.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.gep(
                    self._value,
                    [qy.Value.from_any(i)._value for i in indices],
                    ),
                )
Ejemplo n.º 15
0
    def __le__(self, other):
        """
        Return the result of a less-than-or-equal comparison.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.icmp(
                    llvm.ICMP_SLE,
                    self._value,
                    qy.value_from_any(other).cast_to(self.type_)._value,
                    ),
                )
Ejemplo n.º 16
0
    def __eq__(self, other):
        """
        Return the result of an equality comparison.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.fcmp(
                    llvm.FCMP_OEQ,
                    self._value,
                    qy.value_from_any(other)._value,
                    ),
                )
Ejemplo n.º 17
0
    def is_nan(self):
        """
        Test for nan.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.fcmp(
                    llvm.FCMP_UNO,
                    self._value,
                    self._value,
                    ),
                )
Ejemplo n.º 18
0
    def __gt__(self, other):
        """
        Return the result of a greater-than comparison.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.icmp(
                    llvm.ICMP_SGT,
                    self._value,
                    qy.value_from_any(other).cast_to(self.type_)._value,
                    ),
                )
Ejemplo n.º 19
0
    def __ge__(self, other):
        """
        Return the result of a greater-than-or-equal comparison.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.fcmp(
                    llvm.FCMP_OGE,
                    self._value,
                    qy.value_from_any(other).cast_to(self.type_)._value,
                    ),
                )
Ejemplo n.º 20
0
    def __lt__(self, other):
        """
        Return the result of a less-than comparison.
        """

        return \
            qy.Value.from_low(
                qy.get().builder.fcmp(
                    llvm.FCMP_OLT,
                    self._value,
                    qy.value_from_any(other).cast_to(self.type_)._value,
                    ),
                )
Ejemplo n.º 21
0
    def cast_to(self, type_, name = ""):
        """
        Cast this value to the specified type.
        """

        # XXX cleanly handle signedness somehow (explicit "signed" qy value?)

        type_     = qy.type_from_any(type_)
        low_value = None

        if type_.kind == llvm.TYPE_DOUBLE:
            low_value = qy.get().builder.sitofp(self._value, type_, name)
        elif type_.kind == llvm.TYPE_INTEGER:
            if self.type_.width == type_.width:
                low_value = self._value
            elif self.type_.width < type_.width:
                low_value = qy.get().builder.sext(self._value, type_, name)
            elif self.type_.width > type_.width:
                low_value = qy.get().builder.trunc(self._value, type_, name)

        if low_value is None:
            raise CoercionError(self.type_, type_)
        else:
            return qy.Value.from_any(low_value)
Ejemplo n.º 22
0
    def __call__(self, *arguments):
        """
        Emit IR for a function call.
        """

        # sanity
        if len(arguments) != len(self.argument_types):
            raise TypeError(
                "function %s expects %i arguments but received %i"
                % (self._value.name, len(self.argument_types), len(arguments))
            )

        # emit the call
        arguments = map(qy.value_from_any, arguments)
        coerced = [v.cast_to(a) for (v, a) in zip(arguments, self.argument_types)]

        return qy.Value.from_low(qy.get().builder.call(self._value, [c.low for c in coerced]))
Ejemplo n.º 23
0
        def decorator(emit):
            """
            Look up or emit the function.
            """

            if name is None:
                if emit.__name__ == "_":
                    function_name = "function"
                else:
                    function_name = emit.__name__
            else:
                function_name = name

            if function_name in qy.get().module.global_variables:
                return Function.get_named(function_name)
            else:
                define_decorator = Function.define(
                    return_type=return_type, argument_types=argument_types, name=name, internal=internal
                )
                return define_decorator(emit)
Ejemplo n.º 24
0
    def cast_to(self, type_, name = ""):
        """
        Cast this value to the specified type.
        """

        # XXX support more casts

        type_     = qy.type_from_any(type_)
        low_value = None

        if type_.kind == llvm.TYPE_DOUBLE:
            if self.type_.kind == llvm.TYPE_DOUBLE:
                low_value = self._value
        if type_.kind == llvm.TYPE_INTEGER:
            low_value = qy.get().builder.fptosi(self._value, type_, name)

        if low_value is None:
            raise CoercionError(self.type_, type_)
        else:
            return qy.Value.from_low(low_value)
Ejemplo n.º 25
0
    def store(self, pointer):
        """
        Store this value to the specified pointer.
        """

        return qy.get().builder.store(self._value, pointer._value)
Ejemplo n.º 26
0
    def get_named(name):
        """
        Look up a named function.
        """

        return Function(qy.get().module.get_function_named(name))
Ejemplo n.º 27
0
    def __invert__(self):
        """
        Return the result of bitwise inversion.
        """

        return qy.get().builder.xor(self._value, LLVM_Constant.int(self.type_, -1))