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)
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)