STATIC SB_enum
S_backup_one_SB(pTHX_ const U8 * const strbeg, U8 ** curpos, const bool utf8_target)
{
    SB_enum sb;

    PERL_ARGS_ASSERT_BACKUP_ONE_SB;

    if (*curpos < strbeg) {
        return SB_EDGE;
    }

    if (utf8_target) {
        U8 * prev_char_pos = reghopmaybe3(*curpos, -1, strbeg);
        if (! prev_char_pos) {
            return SB_EDGE;
        }

        /* Back up over Extend and Format.  curpos is always just to the right
         * of the characater whose value we are getting */
        do {
            U8 * prev_prev_char_pos;
            if ((prev_prev_char_pos = reghopmaybe3((U8 *) prev_char_pos, -1,
                                                                      strbeg)))
            {
                sb = getSB_VAL_UTF8(prev_prev_char_pos, prev_char_pos);
                *curpos = prev_char_pos;
                prev_char_pos = prev_prev_char_pos;
            }
            else {
                *curpos = (U8 *) strbeg;
                return SB_EDGE;
            }
        } while (sb == SB_Extend || sb == SB_Format);
    }
    else {
        do {
            if (*curpos - 2 < strbeg) {
                *curpos = (U8 *) strbeg;
                return SB_EDGE;
            }
            (*curpos)--;
            sb = getSB_VAL_CP(*(*curpos - 1));
        } while (sb == SB_Extend || sb == SB_Format);
    }

    return sb;
STATIC SB_enum
S_backup_one_SB(pTHX_ const U8 * const strbeg, U8 ** curpos, const bool utf8_target)
{
    SB_enum sb;

    PERL_ARGS_ASSERT_BACKUP_ONE_SB;

    if (*curpos < strbeg) {
        return SB_EDGE;
    }

    if (utf8_target) {
        U8 * prev_char_pos = reghopmaybe3(*curpos, -1, strbeg);
        if (! prev_char_pos) {
            return SB_EDGE;
        }

         
        do {
            U8 * prev_prev_char_pos;
            if ((prev_prev_char_pos = reghopmaybe3((U8 *) prev_char_pos, -1,
                                                                      strbeg)))
            {
                sb = getSB_VAL_UTF8(prev_prev_char_pos, prev_char_pos);
                *curpos = prev_char_pos;
                prev_char_pos = prev_prev_char_pos;
            }
            else {
                *curpos = (U8 *) strbeg;
                return SB_EDGE;
            }
        } while (sb == SB_Extend || sb == SB_Format);
    }
    else {
        do {
            if (*curpos - 2 < strbeg) {
                *curpos = (U8 *) strbeg;
                return SB_EDGE;
            }
            (*curpos)--;
            sb = getSB_VAL_CP(*(*curpos - 1));
        } while (sb == SB_Extend || sb == SB_Format);
    }

    return sb;