示例#1
0
文件: pseudo.py 项目: Rinoahu/PeachPy
    def __init__(self, *args, **kwargs):
        from peachpy.x86_64.function import active_function
        from peachpy.x86_64.registers import GeneralPurposeRegister, MMXRegister, XMMRegister, YMMRegister

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level() > 0:
            origin = inspect.stack()
        super(RETURN, self).__init__("RETURN", origin=origin)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) == 0:
            # It is not an error to return nothing from a function with a return type
            self.in_regs = tuple()
            self.out_regs = tuple()
            self.out_operands = tuple()
        elif len(self.operands) == 1:
            # It is an error to return something from a void function
            from peachpy.util import is_int64, int_size
            if active_function.result_type is None:
                raise ValueError("Void function should not return a value")
            if active_function.result_type.is_integer or active_function.result_type.is_pointer:
                if is_int64(self.operands[0]):
                    if active_function.result_type.size is None and int_size(self.operands[0]) > 4 or\
                        active_function.result_type.size is not None and \
                            active_function.result_type.size < int_size(self.operands[0]):
                        raise ValueError("Value {0} can not be represented with return type {1}".
                                         format(str(self.operands[0]), str(active_function.result_type)))
                    self.in_regs = (False,)
                    self.out_regs = (False,)
                    self.out_operands = (False,)
                elif isinstance(self.operands[0], GeneralPurposeRegister):
                    if active_function.result_type.size < self.operands[0].size:
                        raise ValueError("Register {0} can not be converted to return type {1}".
                                         format(str(self.operands[0]), str(active_function.result_type)))
                    self.in_regs = (True,)
                    self.out_regs = (False,)
                    self.out_operands = (False,)
                else:
                    raise TypeError("Invalid operand type: RETURN {0} for {1} function".
                                    format(str(self.operands[0]), str(active_function.result_type)))
            elif active_function.result_type.is_floating_point:
                if isinstance(self.operands[0], XMMRegister):
                    self.in_regs = (True,)
                    self.out_regs = (False,)
                    self.out_operands = (False,)
                else:
                    raise TypeError("Invalid operand type: RETURN {0} for {1} function".
                                    format(str(self.operands[0]), str(active_function.result_type)))
            elif active_function.result_type.is_vector:
                if isinstance(self.operands[0], (MMXRegister, XMMRegister, YMMRegister)) and \
                        active_function.result_type.size == self.operands[0].size:
                    self.in_regs = (True,)
                    self.out_regs = (False,)
                    self.out_operands = (False,)
                else:
                    raise TypeError("Invalid operand type: RETURN {0} for {1} function".
                                    format(str(self.operands[0]), str(active_function.result_type)))
            else:
                raise SyntaxError("Invalid operand type: RETURN " + ", ".join(map(format_operand_type, self.operands)))
        else:
            raise SyntaxError("Pseudo-instruction \"RETURN\" requires 0 or 1 operands")
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)
示例#2
0
    def __init__(self, *args, **kwargs):
        from peachpy.x86_64.function import active_function
        from peachpy.x86_64.registers import GeneralPurposeRegister, MMXRegister, XMMRegister, YMMRegister

        origin = kwargs.get("origin")
        prototype = kwargs.get("prototype")
        if origin is None and prototype is None and peachpy.x86_64.options.get_debug_level(
        ) > 0:
            origin = inspect.stack()
        super(RETURN, self).__init__("RETURN", origin=origin)
        self.operands = tuple(map(check_operand, args))
        if len(self.operands) == 0:
            # It is not an error to return nothing from a function with a return type
            self.in_regs = tuple()
            self.out_regs = tuple()
            self.out_operands = tuple()
        elif len(self.operands) == 1:
            # It is an error to return something from a void function
            from peachpy.util import is_int64, int_size
            if active_function.result_type is None:
                raise ValueError("Void function should not return a value")
            if active_function.result_type.is_integer or active_function.result_type.is_pointer:
                if is_int64(self.operands[0]):
                    if active_function.result_type.size < int_size(
                            self.operands[0]):
                        raise ValueError(
                            "Value {0} can not be represented with return type {1}"
                            .format(str(self.operands[0]),
                                    str(active_function.result_type)))
                    self.in_regs = (False, )
                    self.out_regs = (False, )
                    self.out_operands = (False, )
                elif isinstance(self.operands[0], GeneralPurposeRegister):
                    if active_function.result_type.size < self.operands[0].size:
                        raise ValueError(
                            "Register {0} can not be converted to return type {1}"
                            .format(str(self.operands[0]),
                                    str(active_function.result_type)))
                    self.in_regs = (True, )
                    self.out_regs = (False, )
                    self.out_operands = (False, )
                else:
                    raise TypeError(
                        "Invalid operand type: RETURN {0} for {1} function".
                        format(str(self.operands[0]),
                               str(active_function.result_type)))
            elif active_function.result_type.is_floating_point:
                if isinstance(self.operands[0], XMMRegister):
                    self.in_regs = (True, )
                    self.out_regs = (False, )
                    self.out_operands = (False, )
                else:
                    raise TypeError(
                        "Invalid operand type: RETURN {0} for {1} function".
                        format(str(self.operands[0]),
                               str(active_function.result_type)))
            elif active_function.result_type.is_vector:
                if isinstance(self.operands[0], (MMXRegister, XMMRegister, YMMRegister)) and \
                        active_function.result_type.size == self.operands[0].size:
                    self.in_regs = (True, )
                    self.out_regs = (False, )
                    self.out_operands = (False, )
                else:
                    raise TypeError(
                        "Invalid operand type: RETURN {0} for {1} function".
                        format(str(self.operands[0]),
                               str(active_function.result_type)))
            else:
                raise SyntaxError(
                    "Invalid operand type: RETURN " +
                    ", ".join(map(format_operand_type, self.operands)))
        else:
            raise SyntaxError(
                "Pseudo-instruction \"RETURN\" requires 0 or 1 operands")
        if peachpy.stream.active_stream is not None:
            peachpy.stream.active_stream.add_instruction(self)