def generate_sysbus_registration(address, shadow_base, size=None,
                                 skip_braces=False, region=None):
    """ Generates system bus registration information
    consisting of base aaddress and optional shadow
    address.

    Args:
        address (int): peripheral's base address
        shadow_base (int or None): shadow base address
        size (int or None): peripheral's size, if None the value provided
                            by the peripheral in runtime is taken
        skip_braces (bool): determines if the registration info should
                            be put in braces
        region (str or None): name of the region, if None the default
                              one is assumed

    Returns:
        string: registration information
    """

    def generate_registration_entry(address, size=None, name=None):
        if name:
            if not size:
                raise Exception('Size must be provided when registering non-default region')
            return 'sysbus new Bus.BusMultiRegistration {{ address: {}; size: {}; region: "{}" }}'.format(hex(address), hex(size), name)
        if size:
            return "sysbus <{}, +{}>".format(hex(address), hex(size))
        return "sysbus {}".format(hex(address))

    if shadow_base:
        shadowed_address = address | int(shadow_base, 0)

        if shadowed_address == address:
            address &= ~int(shadow_base, 0)

        result = "{}; {}".format(
            generate_registration_entry(address, size, region),
            generate_registration_entry(shadowed_address, size, region))
    else:
        result = generate_registration_entry(address, size, region)

    if not skip_braces:
        result = "{{ {} }}".format(result)

    return result