# 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 *
BITNESS = 32
ENDIANNESS = "big"

ALL_REGS = {REG("r0"), REG("sp"), REG("rtoc")} | reg_range("r", 3, 31)


def call_params(addr):
    return reg_range("r", 3, 10)


def param_filter(regs):
    # Assume for now that all parameters will be passed in registers.
    # This must be good enough to cover the most usage cases.
    # The following cases will break it:
    # - functions accepting more then 8 params
    # - functions accepting floating-point params
    # - variadic functions
    return reg_continuous_subrange(regs, reg_range("r", 3, 10))


def call_ret(addr):
    return {REG("r3")}


def ret_filter(regs):
    # Assuming there is no floating-point stuff
    return {REG("r3")}


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_ppc32.py
from core import ADDR, REG
from archutils import *

BITNESS = 32
ENDIANNESS = "big"

ALL_REGS = {REG("r0"), REG("sp"), REG("rtoc")} | reg_range("r", 3, 31)


def call_params(addr):
    return reg_range("r", 3, 10)


def param_filter(regs):
    # Assume for now that all parameters will be passed in registers.
    # This must be good enough to cover the most usage cases.
    # The following cases will break it:
    # - functions accepting more then 8 params
    # - functions accepting floating-point params
    # - variadic functions
    return reg_continuous_subrange(regs, reg_range("r", 3, 10))


def call_ret(addr):
    return {REG("r3")}


def ret_filter(regs):
    # Assuming there is no floating-point stuff
    return {REG("r3")}


def call_save(addr):

    return reg_range("r", 13, 31) | {REG("sp")}