FictionTools/z88dk/src/sccz80/codegen.c
/* Modify the stack pointer to the new value indicated 
 * \param newsp - Where we need to be 
 * \param save - NO or the variable type that we need to preserve
 * \param saveaf - Whether we should save af
 * 
 * \return newsp value
 */
Modify the stack pointer to the new value indicated
\param newsp - Where we need to be
\param save - NO or the variable type that we need to preserve
\param saveaf - Whether we should save af

\return newsp value
Modify the stack pointer to the new value indicated \ param newsp - Where we need to be \ param save - NO or the variable type that we need to preserve \ param saveaf - Whether we should save af \ return newsp value
int modstk(int newsp, Kind save, int saveaf, int usebc)
{
    int k, flag = NO;
    k = newsp - Zsp;
    if (k == 0)
        return newsp;
    if ( (c_cpu & (CPU_GBZ80|CPU_RABBIT)) && abs(k) > 1 && abs(k) <= 127 ) {
        outstr("\tadd\tsp,"); outdec(k); nl();
        return newsp;
    }
#ifdef USEFRAME
    if (c_framepointer_is_ix != -1) {
        if ( saveaf ) {
            if ( c_noaltreg ) {
                zpushflags();
                zpopbc();
            } else {
                doexaf();
            }
        }
        outfmt("\tld\t%s,%d\n",FRAME_REGISTER, k);
        outfmt("\tadd\t%s,sp\n", FRAME_REG);
        outfmt("\tld\tsp,%s\n",FRAME_REGISTER);
        if ( saveaf ) {
            if ( c_noaltreg ) {
                ol("push\tbc");
                Zsp -= 2;
                zpopflags();
            } else {
                doexaf();
            }
        }
        return newsp;
    }
#endif
    if (k > 0) {
        if (k < 11) {
            if (k & 1) {
                ol("inc\tsp");
                --k;
            }
            while (k) {
                if (usebc) {
                    ol("pop\tbc");
                } else {
                    ol("pop\taf");
                }
                k -= 2;
            }
            return newsp;
        }
    } else if (k < 0) {
        if (k > -11) {
            if (k & 1) {
                flag = YES;
                ++k;
            }
            while (k) {
                ol("push\tbc");
                k += 2;
            }
            if (flag)
                ol("dec\tsp");
            return newsp;
        }
    }
    if (save == KIND_CPTR) 
        save = KIND_LONG;
    else if ( save == KIND_DOUBLE ) {
        if ( c_fp_size == 4 ) {
            save = KIND_LONG;
        }
    }
    if ( c_notaltreg ) {
        if ( saveaf ) {
            errorfmt("Cannot generate code for target that returns a value and carry flag\n",1);
        }
        if ( save == KIND_LONG ) {
            ol("ld\tc,l");
            ol("ld\tb,h");
        } else if ( ( save != KIND_NONE && save != KIND_DOUBLE)) {
            swap(); 
        }
        vconst(k);
        ol("add\thl,sp");
        ol("ld\tsp,hl");
        if ( save == KIND_LONG ) {
            ol("ld\tl,c");
            ol("ld\th,b");
        } else if ( ( save != KIND_NONE && save != KIND_DOUBLE)) {
            swap(); 
        }
        return newsp;
    }
    if ( saveaf ) doexaf();
    if ( ( save != KIND_NONE && save != KIND_DOUBLE)) doexx();
    vconst(k);
    ol("add\thl,sp");
    ol("ld\tsp,hl");
    if ( ( save != KIND_NONE && save != KIND_DOUBLE)) doexx();
    if ( saveaf ) doexaf();
    return newsp;
}
int modstk ( int newsp , Kind save , int saveaf , int usebc ) { int k , flag = NO ; k = newsp - Zsp ; if ( k == 0 ) return newsp ; if ( ( c_cpu & ( CPU_GBZ80 | CPU_RABBIT ) ) && abs ( k ) > 1 && abs ( k ) <= 127 ) { outstr ( " \t \t " ) ; outdec ( k ) ; nl ( ) ; return newsp ; } #ifdef USEFRAME if ( c_framepointer_is_ix != -1 ) { if ( saveaf ) { if ( c_noaltreg ) { zpushflags ( ) ; zpopbc ( ) ; } else { doexaf ( ) ; } } outfmt ( " \t \t \n " , FRAME_REGISTER , k ) ; outfmt ( " \t \t \n " , FRAME_REG ) ; outfmt ( " \t \t \n " , FRAME_REGISTER ) ; if ( saveaf ) { if ( c_noaltreg ) { ol ( " \t " ) ; Zsp -= 2 ; zpopflags ( ) ; } else { doexaf ( ) ; } } return newsp ; } #endif if ( k > 0 ) { if ( k < 11 ) { if ( k & 1 ) { ol ( " \t " ) ; -- k ; } while ( k ) { if ( usebc ) { ol ( " \t " ) ; } else { ol ( " \t " ) ; } k -= 2 ; } return newsp ; } } else if ( k < 0 ) { if ( k > -11 ) { if ( k & 1 ) { flag = YES ; ++ k ; } while ( k ) { ol ( " \t " ) ; k += 2 ; } if ( flag ) ol ( " \t " ) ; return newsp ; } } if ( save == KIND_CPTR ) save = KIND_LONG ; else if ( save == KIND_DOUBLE ) { if ( c_fp_size == 4 ) { save = KIND_LONG ; } } if ( c_notaltreg ) { if ( saveaf ) { errorfmt ( " \n " , 1 ) ; } if ( save == KIND_LONG ) { ol ( " \t " ) ; ol ( " \t " ) ; } else if ( ( save != KIND_NONE && save != KIND_DOUBLE ) ) { swap ( ) ; } vconst ( k ) ; ol ( " \t " ) ; ol ( " \t " ) ; if ( save == KIND_LONG ) { ol ( " \t " ) ; ol ( " \t " ) ; } else if ( ( save != KIND_NONE && save != KIND_DOUBLE ) ) { swap ( ) ; } return newsp ; } if ( saveaf ) doexaf ( ) ; if ( ( save != KIND_NONE && save != KIND_DOUBLE ) ) doexx ( ) ; vconst ( k ) ; ol ( " \t " ) ; ol ( " \t " ) ; if ( ( save != KIND_NONE && save != KIND_DOUBLE ) ) doexx ( ) ; if ( saveaf ) doexaf ( ) ; return newsp ; }
Modify the stack pointer to the new value indicated
 \param newsp - Where we need to be
 \param save - NO or the variable type that we need to preserve
 \param saveaf - Whether we should save af
Modify the stack pointer to the new value indicated \ param newsp - Where we need to be \ param save - NO or the variable type that we need to preserve \ param saveaf - Whether we should save af
// Handle short cases // It's a case where modifying sp via hl is easiest /* they are the same in any case! */ // For a 6/8 byte double the value is safely in the exx set or in FA  // We're on 8080 and returning a value // We're on a z80 or other platform with alt registers