# Path: core.py
# class ADDR(SimpleExpr):
# 
#     resolver = staticmethod(lambda x: x)
# 
#     def __init__(self, addr):
#         self.addr = addr
# 
#     def __repr__(self):
#         return self.comment + "ADDR(%s)" % self.addr
# 
#     def __str__(self):
#         return self.comment + self.resolver(self.addr)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.addr == other.addr
# 
#     def __lt__(self, other):
#         if type(self) != type(other):
#             return type_sort(type(self)) < type_sort(type(other))
#         return self.addr < other.addr
# 
#     def __contains__(self, other):
#         return self == other
# 
#     def __hash__(self):
#         return hash(self.addr)
# 
# class REG(SimpleExpr):
# 
#     def __init__(self, name):
#         #assert isinstance(name, str)
#         self.name = name
#         self.signed = False
# 
#     def __repr__(self):
#         if self.simple_repr:
#             return self.__str__()
#         type = "REG_S" if self.signed else "REG"
#         return self.comment + type + "(%s)" % self.name
# 
#     def __str__(self):
#         cast = "(i32)" if self.signed else ""
#         return self.comment + cast + "$" + str(self.name)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.name == other.name
# 
#     def __lt__(self, other):
#         if type(self) != type(other):
#             return type_sort(type(self)) < type_sort(type(other))
# 
#         n1 = utils.natural_sort_key(self.name)
#         n2 = utils.natural_sort_key(other.name)
#         return n1 < n2
# 
#     def __contains__(self, other):
#         return self == other
# 
#     def __hash__(self):
#         return hash(self.name)
# 
#     def regs(self):
#         return {self}


from core import ADDR, REG
from archutils import *


def call_params(addr):
    return reg_range("a", 2, 7)


def param_filter(regs):
    #return regs
    #return regs & reg_range("a", 2, 7)
    # van Emmerik p.143
    # We know that for Xtensa params are passed in regs, and ignore case
    # of passing extra regs on stack so far.
    return reg_continuous_subrange(regs, reg_range("a", 2, 7))


def call_ret(addr):
    return reg_range("a", 2, 5)


def ret_filter(regs):
    # Simple filter
    #return regs & reg_range("a", 2, 5)

    # Ordered filter: if we know that returns should use a2, a3, a4, a5
    # in order, then if we have a2, a4 as potential returns, we known that
    # a4 is spurious.
    return reg_continuous_subrange(regs, reg_range("a", 2, 5))


def call_save(addr):

# Path: core.py
# class ADDR(SimpleExpr):
# 
#     resolver = staticmethod(lambda x: x)
# 
#     def __init__(self, addr):
#         self.addr = addr
# 
#     def __repr__(self):
#         return self.comment + "ADDR(%s)" % self.addr
# 
#     def __str__(self):
#         return self.comment + self.resolver(self.addr)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.addr == other.addr
# 
#     def __lt__(self, other):
#         if type(self) != type(other):
#             return type_sort(type(self)) < type_sort(type(other))
#         return self.addr < other.addr
# 
#     def __contains__(self, other):
#         return self == other
# 
#     def __hash__(self):
#         return hash(self.addr)
# 
# class REG(SimpleExpr):
# 
#     def __init__(self, name):
#         #assert isinstance(name, str)
#         self.name = name
#         self.signed = False
# 
#     def __repr__(self):
#         if self.simple_repr:
#             return self.__str__()
#         type = "REG_S" if self.signed else "REG"
#         return self.comment + type + "(%s)" % self.name
# 
#     def __str__(self):
#         cast = "(i32)" if self.signed else ""
#         return self.comment + cast + "$" + str(self.name)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.name == other.name
# 
#     def __lt__(self, other):
#         if type(self) != type(other):
#             return type_sort(type(self)) < type_sort(type(other))
# 
#         n1 = utils.natural_sort_key(self.name)
#         n2 = utils.natural_sort_key(other.name)
#         return n1 < n2
# 
#     def __contains__(self, other):
#         return self == other
# 
#     def __hash__(self):
#         return hash(self.name)
# 
#     def regs(self):
#         return {self}


# Path: arch_xtensa.py
from core import ADDR, REG
from archutils import *



def call_params(addr):
    return reg_range("a", 2, 7)


def param_filter(regs):
    #return regs
    #return regs & reg_range("a", 2, 7)
    # van Emmerik p.143
    # We know that for Xtensa params are passed in regs, and ignore case
    # of passing extra regs on stack so far.
    return reg_continuous_subrange(regs, reg_range("a", 2, 7))


def call_ret(addr):
    return reg_range("a", 2, 5)


def ret_filter(regs):
    # Simple filter
    #return regs & reg_range("a", 2, 5)

    # Ordered filter: if we know that returns should use a2, a3, a4, a5
    # in order, then if we have a2, a4 as potential returns, we known that
    # a4 is spurious.
    return reg_continuous_subrange(regs, reg_range("a", 2, 5))


def call_save(addr):

    return reg_range("a", 12, 15) | {REG("sp")}