X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcodegen.c;h=88cebe9a4b734ead469354eb1fb8d466a06a88f9;hb=9fc71c5e93f7e8270dd6f8fc3810b7b731bf1259;hp=ff44514abb6941d0ff628545fc6ee9989f0276eb;hpb=f9af6ebf8844db5681e431290f395411cb475eb7;p=cc65 diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index ff44514ab..88cebe9a4 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -6,8 +6,8 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* (C) 1998-2004 Ullrich von Bassewitz */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -54,23 +54,13 @@ #include "error.h" #include "global.h" #include "segments.h" +#include "stackptr.h" #include "textseg.h" #include "util.h" #include "codegen.h" -/*****************************************************************************/ -/* Data */ -/*****************************************************************************/ - - - -/* Compiler relative stack pointer */ -int oursp = 0; - - - /*****************************************************************************/ /* Helpers */ /*****************************************************************************/ @@ -165,10 +155,18 @@ void g_preamble (void) VER_MAJOR, VER_MINOR, VER_PATCH); /* If we're producing code for some other CPU, switch the command set */ - if (CPU == CPU_65C02) { - AddTextLine ("\t.setcpu\t\t\"65C02\""); + switch (CPU) { + case CPU_6502: AddTextLine ("\t.setcpu\t\t\"6502\""); break; + case CPU_6502X: AddTextLine ("\t.setcpu\t\t\"6502X\""); break; + case CPU_65SC02: AddTextLine ("\t.setcpu\t\t\"65SC02\""); break; + case CPU_65C02: AddTextLine ("\t.setcpu\t\t\"65C02\""); break; + case CPU_65816: AddTextLine ("\t.setcpu\t\t\"65816\""); break; + default: Internal ("Unknown CPU: %d", CPU); } + /* Use smart mode */ + AddTextLine ("\t.smart\t\ton"); + /* Allow auto import for runtime library routines */ AddTextLine ("\t.autoimport\ton"); @@ -230,15 +228,11 @@ void g_usebss (void) -void g_segname (segment_t Seg, const char* Name) -/* Set the name of a segment */ +void g_segname (segment_t Seg) +/* Emit the name of a segment if necessary */ { - DataSeg* S; - - /* Remember the new name */ - NewSegName (Seg, Name); - /* Emit a segment directive for the data style segments */ + DataSeg* S; switch (Seg) { case SEG_RODATA: S = CS->ROData; break; case SEG_DATA: S = CS->Data; break; @@ -246,7 +240,7 @@ void g_segname (segment_t Seg, const char* Name) default: S = 0; break; } if (S) { - DS_AddLine (S, ".segment\t\"%s\"", Name); + DS_AddLine (S, ".segment\t\"%s\"", GetSegName (Seg)); } } @@ -287,7 +281,7 @@ unsigned sizeofarg (unsigned flags) int pop (unsigned flags) /* Pop an argument of the given size */ { - return oursp += sizeofarg (flags); + return StackPtr += sizeofarg (flags); } @@ -295,7 +289,7 @@ int pop (unsigned flags) int push (unsigned flags) /* Push an argument of the given size */ { - return oursp -= sizeofarg (flags); + return StackPtr -= sizeofarg (flags); } @@ -460,21 +454,22 @@ void g_leave (void) /* Function epilogue */ { /* How many bytes of locals do we have to drop? */ - int k = -oursp; + unsigned k = (unsigned) -StackPtr; /* If we didn't have a variable argument list, don't call leave */ if (funcargs >= 0) { - /* Drop stackframe if needed */ + /* Drop stackframe if needed. We can only drop 255 bytes at a time. */ k += funcargs; - if (k > 0) { - if (k <= 8) { - AddCodeLine ("jsr incsp%d", k); + while (k > 0) { + unsigned ToDrop = (k > 255)? 255 : k; + if (ToDrop <= 8) { + AddCodeLine ("jsr incsp%d", k); } else { - CheckLocalOffs (k); - ldyconst (k); - AddCodeLine ("jsr addysp"); + ldyconst (ToDrop); + AddCodeLine ("jsr addysp"); } + k -= ToDrop; } } else { @@ -484,6 +479,11 @@ void g_leave (void) AddCodeLine ("jsr leave"); } else { /* We've a stack frame to drop */ + while (k > 255) { + ldyconst (255); + AddCodeLine ("jsr addysp"); + k -= 255; + } ldyconst (k); AddCodeLine ("jsr leavey"); } @@ -505,7 +505,7 @@ void g_swap_regvars (int StackOffs, int RegOffs, unsigned Bytes) /* Swap a register variable with a location on the stack */ { /* Calculate the actual stack offset and check it */ - StackOffs -= oursp; + StackOffs -= StackPtr; CheckLocalOffs (StackOffs); /* Generate code */ @@ -573,7 +573,7 @@ void g_save_regvars (int RegOffs, unsigned Bytes) } /* We pushed stuff, correct the stack pointer */ - oursp -= Bytes; + StackPtr -= Bytes; } @@ -582,7 +582,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) /* Restore register variables */ { /* Calculate the actual stack offset and check it */ - StackOffs -= oursp; + StackOffs -= StackPtr; CheckLocalOffs (StackOffs); /* Don't loop for up to two bytes */ @@ -613,17 +613,38 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) AddCodeLine ("lda (sp),y"); AddCodeLine ("sta regbank%+d", RegOffs+2); + } else if (StackOffs <= RegOffs) { + + /* More bytes, but the relation between the register offset in the + * register bank and the stack offset allows us to generate short + * code that uses just one index register. + */ + unsigned Label = GetLocalLabel (); + ldyconst (StackOffs); + g_defcodelabel (Label); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta regbank%+d,y", RegOffs - StackOffs); + AddCodeLine ("iny"); + AddCodeLine ("cpy #$%02X", StackOffs + Bytes); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } else { - /* More bytes - loop */ + /* Ok, this is the generic code. We need to save X because the + * caller will only save A. + */ unsigned Label = GetLocalLabel (); - ldyconst (StackOffs); + AddCodeLine ("stx tmp1"); + ldyconst (StackOffs + Bytes - 1); + ldxconst (Bytes - 1); g_defcodelabel (Label); - AddCodeLine ("lda (sp),y"); - AddCodeLine ("sta regbank%+d,y", RegOffs - StackOffs); - AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", StackOffs + Bytes); - AddCodeLine ("bne %s", LocalLabelName (Label)); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta regbank%+d,x", RegOffs); + AddCodeLine ("dey"); + AddCodeLine ("dex"); + AddCodeLine ("bpl %s", LocalLabelName (Label)); + AddCodeLine ("ldx tmp1"); + } } @@ -782,7 +803,7 @@ void g_getstatic (unsigned flags, unsigned long label, long offs) void g_getlocal (unsigned flags, int offs) /* Fetch specified local object (local var). */ { - offs -= oursp; + offs -= StackPtr; CheckLocalOffs (offs); switch (flags & CF_TYPE) { @@ -887,7 +908,7 @@ void g_leasp (int offs) /* Fetch the address of the specified symbol into the primary register */ { /* Calculate the offset relative to sp */ - offs -= oursp; + offs -= StackPtr; /* For value 0 we do direct code */ if (offs == 0) { @@ -899,7 +920,7 @@ void g_leasp (int offs) AddCodeLine ("jsr leaasp"); /* Load effective address */ } else { unsigned L = GetLocalLabel (); - if (CPU == CPU_65C02 && offs == 1) { + if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && offs == 1) { AddCodeLine ("lda sp"); AddCodeLine ("ldx sp+1"); AddCodeLine ("ina"); @@ -928,13 +949,13 @@ void g_leavariadic (int Offs) unsigned ArgSizeOffs; /* Calculate the offset relative to sp */ - Offs -= oursp; + Offs -= StackPtr; /* Get the offset of the parameter which is stored at sp+0 on function * entry and check if this offset is reachable with a byte offset. */ - CHECK (oursp <= 0); - ArgSizeOffs = -oursp; + CHECK (StackPtr <= 0); + ArgSizeOffs = -StackPtr; CheckLocalOffs (ArgSizeOffs); /* Get the size of all parameters. */ @@ -1008,7 +1029,7 @@ void g_putstatic (unsigned flags, unsigned long label, long offs) void g_putlocal (unsigned Flags, int Offs, long Val) /* Put data into local object. */ { - Offs -= oursp; + Offs -= StackPtr; CheckLocalOffs (Offs); switch (Flags & CF_TYPE) { @@ -1527,7 +1548,7 @@ void g_addlocal (unsigned flags, int offs) unsigned L; /* Correct the offset and check it */ - offs -= oursp; + offs -= StackPtr; CheckLocalOffs (offs); switch (flags & CF_TYPE) { @@ -1734,7 +1755,7 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val) /* Emit += for a local variable */ { /* Calculate the true offset, check it, load it into Y */ - offs -= oursp; + offs -= StackPtr; CheckLocalOffs (offs); /* Check the size and determine operation */ @@ -1965,7 +1986,7 @@ void g_subeqlocal (unsigned flags, int offs, unsigned long val) /* Emit -= for a local variable */ { /* Calculate the true offset, check it, load it into Y */ - offs -= oursp; + offs -= StackPtr; CheckLocalOffs (offs); /* Check the size and determine operation */ @@ -2088,7 +2109,7 @@ void g_addaddr_local (unsigned flags attribute ((unused)), int offs) unsigned L = 0; /* Add the offset */ - offs -= oursp; + offs -= StackPtr; if (offs != 0) { /* We cannot address more then 256 bytes of locals anyway */ L = GetLocalLabel(); @@ -2413,7 +2434,7 @@ void g_call (unsigned Flags, const char* Label, unsigned ArgSize) ldyconst (ArgSize); } AddCodeLine ("jsr _%s", Label); - oursp += ArgSize; /* callee pops args */ + StackPtr += ArgSize; /* callee pops args */ } @@ -2430,7 +2451,7 @@ void g_callind (unsigned Flags, unsigned ArgSize, int Offs) AddCodeLine ("jsr callax"); } else { /* The address is on stack, offset is on Val */ - Offs -= oursp; + Offs -= StackPtr; CheckLocalOffs (Offs); AddCodeLine ("pha"); AddCodeLine ("ldy #$%02X", Offs); @@ -2444,7 +2465,7 @@ void g_callind (unsigned Flags, unsigned ArgSize, int Offs) } /* Callee pops args */ - oursp += ArgSize; + StackPtr += ArgSize; } @@ -2751,36 +2772,52 @@ void g_or (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - if ((val & 0xFF) != 0xFF) { + if ((val & 0xFF) != 0) { AddCodeLine ("ora #$%02X", (unsigned char)val); } return; } /* FALLTHROUGH */ - case CF_INT: - if (val <= 0xFF) { - AddCodeLine ("ora #$%02X", (unsigned char)val); - return; - } - break; - - case CF_LONG: - if (val <= 0xFF) { - AddCodeLine ("ora #$%02X", (unsigned char)val); - return; - } - break; + case CF_INT: + if (val <= 0xFF) { + if ((val & 0xFF) != 0) { + AddCodeLine ("ora #$%02X", (unsigned char)val); + } + } else if ((val & 0xFF00) == 0xFF00) { + if ((val & 0xFF) != 0) { + AddCodeLine ("ora #$%02X", (unsigned char)val); + } + ldxconst (0xFF); + } else if (val != 0) { + AddCodeLine ("ora #$%02X", (unsigned char)val); + AddCodeLine ("pha"); + AddCodeLine ("txa"); + AddCodeLine ("ora #$%02X", (unsigned char)(val >> 8)); + AddCodeLine ("tax"); + AddCodeLine ("pla"); + } + return; - default: - typeerror (flags); - } + case CF_LONG: + if (val <= 0xFF) { + if ((val & 0xFF) != 0) { + AddCodeLine ("ora #$%02X", (unsigned char)val); + } + return; + } + break; - /* If we go here, we didn't emit code. Push the lhs on stack and fall - * into the normal, non-optimized stuff. - */ - g_push (flags & ~CF_CONST, 0); + default: + typeerror (flags); + } + /* If we go here, we didn't emit code. Push the lhs on stack and fall + * into the normal, non-optimized stuff. Note: The standard stuff will + * always work with ints. + */ + flags &= ~CF_FORCECHAR; + g_push (flags & ~CF_CONST, 0); } /* Use long way over the stack */ @@ -2821,16 +2858,17 @@ void g_xor (unsigned flags, unsigned long val) if (val != 0) { AddCodeLine ("eor #$%02X", (unsigned char)val); } - return; - } else if ((val & 0xFF) == 0) { + } else if (val != 0) { + if ((val & 0xFF) != 0) { + AddCodeLine ("eor #$%02X", (unsigned char)val); + } AddCodeLine ("pha"); AddCodeLine ("txa"); AddCodeLine ("eor #$%02X", (unsigned char)(val >> 8)); AddCodeLine ("tax"); AddCodeLine ("pla"); - return; } - break; + return; case CF_LONG: if (val <= 0xFF) { @@ -2845,11 +2883,12 @@ void g_xor (unsigned flags, unsigned long val) typeerror (flags); } - /* If we go here, we didn't emit code. Push the lhs on stack and fall - * into the normal, non-optimized stuff. - */ - g_push (flags & ~CF_CONST, 0); - + /* If we go here, we didn't emit code. Push the lhs on stack and fall + * into the normal, non-optimized stuff. Note: The standard stuff will + * always work with ints. + */ + flags &= ~CF_FORCECHAR; + g_push (flags & ~CF_CONST, 0); } /* Use long way over the stack */ @@ -2858,68 +2897,70 @@ void g_xor (unsigned flags, unsigned long val) -void g_and (unsigned flags, unsigned long val) +void g_and (unsigned Flags, unsigned long Val) /* Primary = TOS & Primary */ { static char* ops [12] = { - 0, "tosanda0", "tosandax", - 0, "tosanda0", "tosandax", - 0, 0, "tosandeax", - 0, 0, "tosandeax", + 0, "tosanda0", "tosandax", + 0, "tosanda0", "tosandax", + 0, 0, "tosandeax", + 0, 0, "tosandeax", }; /* If the right hand side is const, the lhs is not on stack but still * in the primary register. */ - if (flags & CF_CONST) { + if (Flags & CF_CONST) { - switch (flags & CF_TYPE) { + switch (Flags & CF_TYPE) { case CF_CHAR: - if (flags & CF_FORCECHAR) { - AddCodeLine ("and #$%02X", (unsigned char)val); - return; - } - /* FALLTHROUGH */ + if (Flags & CF_FORCECHAR) { + if ((Val & 0xFF) != 0xFF) { + AddCodeLine ("and #$%02X", (unsigned char)Val); + } + return; + } + /* FALLTHROUGH */ case CF_INT: - if ((val & 0xFFFF) != 0xFFFF) { - if (val <= 0xFF) { - ldxconst (0); - if (val == 0) { - ldaconst (0); - } else if (val != 0xFF) { - AddCodeLine ("and #$%02X", (unsigned char)val); - } - } else if ((val & 0xFF00) == 0xFF00) { - AddCodeLine ("and #$%02X", (unsigned char)val); - } else if ((val & 0x00FF) == 0x0000) { - AddCodeLine ("txa"); - AddCodeLine ("and #$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("tax"); - ldaconst (0); + if ((Val & 0xFFFF) != 0xFFFF) { + if (Val <= 0xFF) { + ldxconst (0); + if (Val == 0) { + ldaconst (0); + } else if (Val != 0xFF) { + AddCodeLine ("and #$%02X", (unsigned char)Val); + } + } else if ((Val & 0xFF00) == 0xFF00) { + AddCodeLine ("and #$%02X", (unsigned char)Val); + } else if ((Val & 0x00FF) == 0x0000) { + AddCodeLine ("txa"); + AddCodeLine ("and #$%02X", (unsigned char)(Val >> 8)); + AddCodeLine ("tax"); + ldaconst (0); } else { - AddCodeLine ("tay"); - AddCodeLine ("txa"); - AddCodeLine ("and #$%02X", (unsigned char)(val >> 8)); - AddCodeLine ("tax"); - AddCodeLine ("tya"); - if ((val & 0x00FF) != 0x00FF) { - AddCodeLine ("and #$%02X", (unsigned char)val); - } - } - } + AddCodeLine ("tay"); + AddCodeLine ("txa"); + AddCodeLine ("and #$%02X", (unsigned char)(Val >> 8)); + AddCodeLine ("tax"); + AddCodeLine ("tya"); + if ((Val & 0x00FF) != 0x00FF) { + AddCodeLine ("and #$%02X", (unsigned char)Val); + } + } + } return; case CF_LONG: - if (val <= 0xFF) { + if (Val <= 0xFF) { ldxconst (0); AddCodeLine ("stx sreg+1"); AddCodeLine ("stx sreg"); - if ((val & 0xFF) != 0xFF) { - AddCodeLine ("and #$%02X", (unsigned char)val); + if ((Val & 0xFF) != 0xFF) { + AddCodeLine ("and #$%02X", (unsigned char)Val); } return; - } else if (val == 0xFF00) { + } else if (Val == 0xFF00) { ldaconst (0); AddCodeLine ("sta sreg+1"); AddCodeLine ("sta sreg"); @@ -2928,18 +2969,19 @@ void g_and (unsigned flags, unsigned long val) break; default: - typeerror (flags); + typeerror (Flags); } - /* If we go here, we didn't emit code. Push the lhs on stack and fall - * into the normal, non-optimized stuff. - */ - g_push (flags & ~CF_CONST, 0); - + /* If we go here, we didn't emit code. Push the lhs on stack and fall + * into the normal, non-optimized stuff. Note: The standard stuff will + * always work with ints. + */ + Flags &= ~CF_FORCECHAR; + g_push (Flags & ~CF_CONST, 0); } /* Use long way over the stack */ - oper (flags, val, ops); + oper (Flags, Val, ops); } @@ -3021,10 +3063,11 @@ void g_asr (unsigned flags, unsigned long val) } /* If we go here, we didn't emit code. Push the lhs on stack and fall - * into the normal, non-optimized stuff. + * into the normal, non-optimized stuff. Note: The standard stuff will + * always work with ints. */ - g_push (flags & ~CF_CONST, 0); - + flags &= ~CF_FORCECHAR; + g_push (flags & ~CF_CONST, 0); } /* Use long way over the stack */ @@ -3102,11 +3145,12 @@ void g_asl (unsigned flags, unsigned long val) typeerror (flags); } - /* If we go here, we didn't emit code. Push the lhs on stack and fall - * into the normal, non-optimized stuff. - */ - g_push (flags & ~CF_CONST, 0); - + /* If we go here, we didn't emit code. Push the lhs on stack and fall + * into the normal, non-optimized stuff. Note: The standard stuff will + * always work with ints. + */ + flags &= ~CF_FORCECHAR; + g_push (flags & ~CF_CONST, 0); } /* Use long way over the stack */ @@ -3115,12 +3159,20 @@ void g_asl (unsigned flags, unsigned long val) -void g_neg (unsigned flags) +void g_neg (unsigned Flags) /* Primary = -Primary */ { - switch (flags & CF_TYPE) { + switch (Flags & CF_TYPE) { case CF_CHAR: + if (Flags & CF_FORCECHAR) { + AddCodeLine ("eor #$FF"); + AddCodeLine ("clc"); + AddCodeLine ("adc #$01"); + return; + } + /* FALLTHROUGH */ + case CF_INT: AddCodeLine ("jsr negax"); break; @@ -3130,7 +3182,7 @@ void g_neg (unsigned flags) break; default: - typeerror (flags); + typeerror (Flags); } } @@ -3160,12 +3212,18 @@ void g_bneg (unsigned flags) -void g_com (unsigned flags) +void g_com (unsigned Flags) /* Primary = ~Primary */ { - switch (flags & CF_TYPE) { + switch (Flags & CF_TYPE) { case CF_CHAR: + if (Flags & CF_FORCECHAR) { + AddCodeLine ("eor #$FF"); + return; + } + /* FALLTHROUGH */ + case CF_INT: AddCodeLine ("jsr complax"); break; @@ -3175,7 +3233,7 @@ void g_com (unsigned flags) break; default: - typeerror (flags); + typeerror (Flags); } } @@ -3195,7 +3253,7 @@ void g_inc (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - if (CPU == CPU_65C02 && val <= 2) { + if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && val <= 2) { while (val--) { AddCodeLine ("ina"); } @@ -3208,7 +3266,7 @@ void g_inc (unsigned flags, unsigned long val) /* FALLTHROUGH */ case CF_INT: - if (CPU == CPU_65C02 && val == 1) { + if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && val == 1) { unsigned L = GetLocalLabel(); AddCodeLine ("ina"); AddCodeLine ("bne %s", LocalLabelName (L)); @@ -3289,7 +3347,7 @@ void g_dec (unsigned flags, unsigned long val) case CF_CHAR: if (flags & CF_FORCECHAR) { - if (CPU == CPU_65C02 && val <= 2) { + if ((CPUIsets[CPU] & CPU_ISET_65SC02) != 0 && val <= 2) { while (val--) { AddCodeLine ("dea"); } @@ -3498,7 +3556,8 @@ void g_lt (unsigned flags, unsigned long val) if (flags & CF_CONST) { /* Because the handling of the overflow flag is too complex for - * inlining, we can handle only unsigned compares here. + * inlining, we can handle only unsigned compares, and signed + * compares against zero here. */ if (flags & CF_UNSIGNED) { @@ -3548,6 +3607,34 @@ void g_lt (unsigned flags, unsigned long val) typeerror (flags); } + } else if (val == 0) { + + /* Look at the type */ + switch (flags & CF_TYPE) { + + case CF_CHAR: + if (flags & CF_FORCECHAR) { + AddCodeLine ("tax"); + AddCodeLine ("jsr boollt"); + return; + } + /* FALLTHROUGH */ + + case CF_INT: + /* Just check the high byte */ + AddCodeLine ("txa"); + AddCodeLine ("jsr boollt"); + return; + + case CF_LONG: + /* Just check the high byte */ + AddCodeLine ("lda sreg+1"); + AddCodeLine ("jsr boollt"); + return; + + default: + typeerror (flags); + } } /* If we go here, we didn't emit code. Push the lhs on stack and fall @@ -3833,7 +3920,8 @@ void g_ge (unsigned flags, unsigned long val) if (flags & CF_CONST) { /* Because the handling of the overflow flag is too complex for - * inlining, we can handle only unsigned compares here. + * inlining, we can handle only unsigned compares, and signed + * compares against zero here. */ if (flags & CF_UNSIGNED) { @@ -3883,8 +3971,37 @@ void g_ge (unsigned flags, unsigned long val) typeerror (flags); } + } else if (val == 0) { + + /* Look at the type */ + switch (flags & CF_TYPE) { + + case CF_CHAR: + if (flags & CF_FORCECHAR) { + AddCodeLine ("tax"); + AddCodeLine ("jsr boolge"); + return; + } + /* FALLTHROUGH */ + + case CF_INT: + /* Just test the high byte */ + AddCodeLine ("txa"); + AddCodeLine ("jsr boolge"); + return; + + case CF_LONG: + /* Just test the high byte */ + AddCodeLine ("lda sreg+1"); + AddCodeLine ("jsr boolge"); + return; + + default: + typeerror (flags); + } } + /* If we go here, we didn't emit code. Push the lhs on stack and fall * into the normal, non-optimized stuff. Note: The standard stuff will * always work with ints. @@ -4164,53 +4281,3 @@ void g_asmcode (struct StrBuf* B) -/*****************************************************************************/ -/* Inlined known functions */ -/*****************************************************************************/ - - - -void g_strlen (unsigned flags, unsigned long val, long offs) -/* Inline the strlen() function */ -{ - /* We need a label in both cases */ - unsigned label = GetLocalLabel (); - - /* Two different encodings */ - if (flags & CF_CONST) { - - /* The address of the string is constant. Create the correct label name */ - const char* lbuf = GetLabelName (flags, val, offs); - - /* Generate the strlen code */ - AddCodeLine ("ldy #$FF"); - g_defcodelabel (label); - AddCodeLine ("iny"); - AddCodeLine ("lda %s,y", lbuf); - AddCodeLine ("bne %s", LocalLabelName (label)); - AddCodeLine ("tax"); - AddCodeLine ("tya"); - - } else { - - /* Address not constant but in primary */ - if (CodeSizeFactor < 400) { - /* This is too much code, so call strlen instead of inlining */ - AddCodeLine ("jsr _strlen"); - } else { - /* Inline the function */ - AddCodeLine ("sta ptr1"); - AddCodeLine ("stx ptr1+1"); - AddCodeLine ("ldy #$FF"); - g_defcodelabel (label); - AddCodeLine ("iny"); - AddCodeLine ("lda (ptr1),y"); - AddCodeLine ("bne %s", LocalLabelName (label)); - AddCodeLine ("tax"); - AddCodeLine ("tya"); - } - } -} - - -