X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcodegen.c;h=a611f4f6a809ec0789c5c975bfc7876104e10b8e;hb=58484449b4842517d09618bc1c5dad59373250ef;hp=6143b09fe9b6033e9610345e207887965282a6ea;hpb=0390c34e88e9512b81ce35a9ba36d137d1c80c44;p=cc65 diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 6143b09fe..a611f4f6a 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -40,6 +40,7 @@ /* common */ #include "check.h" #include "cpu.h" +#include "inttypes.h" #include "strbuf.h" #include "xmalloc.h" #include "xsprintf.h" @@ -55,6 +56,7 @@ #include "global.h" #include "segments.h" #include "stackptr.h" +#include "stdfunc.h" #include "textseg.h" #include "util.h" #include "codegen.h" @@ -91,7 +93,7 @@ static void CheckLocalOffs (unsigned Offs) -static const char* GetLabelName (unsigned Flags, unsigned long Label, long Offs) +static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs) { static char Buf [256]; /* Label name */ @@ -118,7 +120,7 @@ static const char* GetLabelName (unsigned Flags, unsigned long Label, long Offs) case CF_ABSOLUTE: /* Absolute address */ - xsprintf (Buf, sizeof (Buf), "$%04X", (int)((Label+Offs) & 0xFFFF)); + xsprintf (Buf, sizeof (Buf), "$%04X", (unsigned)((Label+Offs) & 0xFFFF)); break; case CF_REGVAR: @@ -728,7 +730,7 @@ void g_getimmed (unsigned Flags, unsigned long Val, long Offs) -void g_getstatic (unsigned flags, unsigned long label, long offs) +void g_getstatic (unsigned flags, uintptr_t label, long offs) /* Fetch an static memory cell into the primary register */ { /* Create the correct label name */ @@ -1007,7 +1009,7 @@ void g_leavariadic (int Offs) -void g_putstatic (unsigned flags, unsigned long label, long offs) +void g_putstatic (unsigned flags, uintptr_t label, long offs) /* Store the primary register into the specified static memory cell */ { /* Create the correct label name */ @@ -1226,26 +1228,34 @@ void g_tosint (unsigned flags) -void g_regint (unsigned Flags) -/* Make sure, the value in the primary register an int. Convert if necessary */ +static void g_regchar (unsigned Flags) +/* Make sure, the value in the primary register is in the range of char. Truncate if necessary */ { unsigned L; + AddCodeLine ("ldx #$00"); + + if ((Flags & CF_UNSIGNED) == 0) { + /* Sign extend */ + L = GetLocalLabel(); + AddCodeLine ("cmp #$80"); + AddCodeLine ("bcc %s", LocalLabelName (L)); + AddCodeLine ("dex"); + g_defcodelabel (L); + } +} + + + +void g_regint (unsigned Flags) +/* Make sure, the value in the primary register an int. Convert if necessary */ +{ switch (Flags & CF_TYPEMASK) { case CF_CHAR: if (Flags & CF_FORCECHAR) { /* Conversion is from char */ - if (Flags & CF_UNSIGNED) { - AddCodeLine ("ldx #$00"); - } else { - L = GetLocalLabel(); - AddCodeLine ("ldx #$00"); - AddCodeLine ("cmp #$80"); - AddCodeLine ("bcc %s", LocalLabelName (L)); - AddCodeLine ("dex"); - g_defcodelabel (L); - } + g_regchar (Flags); } /* FALLTHROUGH */ @@ -1263,8 +1273,6 @@ void g_regint (unsigned Flags) void g_reglong (unsigned Flags) /* Make sure, the value in the primary register a long. Convert if necessary */ { - unsigned L; - switch (Flags & CF_TYPEMASK) { case CF_CHAR: @@ -1280,12 +1288,7 @@ void g_reglong (unsigned Flags) } } else { if (IS_Get (&CodeSizeFactor) >= 366) { - L = GetLocalLabel(); - AddCodeLine ("ldx #$00"); - AddCodeLine ("cmp #$80"); - AddCodeLine ("bcc %s", LocalLabelName (L)); - AddCodeLine ("dex"); - g_defcodelabel (L); + g_regchar (Flags); AddCodeLine ("stx sreg"); AddCodeLine ("stx sreg+1"); } else { @@ -1374,20 +1377,27 @@ unsigned g_typecast (unsigned lhs, unsigned rhs) ** by the lhs value. Return the result value. */ { - unsigned ltype, rtype; - - /* Get the type spec from the flags */ - ltype = lhs & CF_TYPEMASK; - rtype = rhs & CF_TYPEMASK; - /* Check if a conversion is needed */ if ((rhs & CF_CONST) == 0) { - if (ltype == CF_LONG && rtype != CF_LONG) { - /* We must promote the primary register to long */ - g_reglong (rhs); - } else if (ltype == CF_INT && rtype != CF_INT) { - /* We must promote the primary register to int */ - g_regint (rhs); + switch (lhs & CF_TYPEMASK) { + + case CF_LONG: + /* We must promote the primary register to long */ + g_reglong (rhs); + break; + + case CF_INT: + /* We must promote the primary register to int */ + g_regint (rhs); + break; + + case CF_CHAR: + /* We must truncate the primary register to char */ + g_regchar (lhs); + break; + + default: + typeerror (lhs); } } @@ -1575,7 +1585,7 @@ void g_addlocal (unsigned flags, int offs) -void g_addstatic (unsigned flags, unsigned long label, long offs) +void g_addstatic (unsigned flags, uintptr_t label, long offs) /* Add a static variable to ax */ { unsigned L; @@ -1625,7 +1635,7 @@ void g_addstatic (unsigned flags, unsigned long label, long offs) -void g_addeqstatic (unsigned flags, unsigned long label, long offs, +void g_addeqstatic (unsigned flags, uintptr_t label, long offs, unsigned long val) /* Emit += for a static variable */ { @@ -1848,7 +1858,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val) -void g_subeqstatic (unsigned flags, unsigned long label, long offs, +void g_subeqstatic (unsigned flags, uintptr_t label, long offs, unsigned long val) /* Emit -= for a static variable */ { @@ -2084,7 +2094,7 @@ void g_addaddr_local (unsigned flags attribute ((unused)), int offs) -void g_addaddr_static (unsigned flags, unsigned long label, long offs) +void g_addaddr_static (unsigned flags, uintptr_t label, long offs) /* Add the address of a static variable to ax */ { /* Create the correct label name */ @@ -2202,7 +2212,7 @@ void g_cmp (unsigned flags, unsigned long val) -static void oper (unsigned Flags, unsigned long Val, const char** Subs) +static void oper (unsigned Flags, unsigned long Val, const char* const* Subs) /* Encode a binary operation. subs is a pointer to four strings: ** 0 --> Operate on ints ** 1 --> Operate on unsigneds @@ -2415,6 +2425,19 @@ void g_falsejump (unsigned flags attribute ((unused)), unsigned label) } +void g_lateadjustSP (unsigned label) +/* Adjust stack based on non-immediate data */ +{ + AddCodeLine ("pha"); + AddCodeLine ("lda %s", LocalLabelName (label)); + AddCodeLine ("clc"); + AddCodeLine ("adc sp"); + AddCodeLine ("sta sp"); + AddCodeLine ("lda %s+1", LocalLabelName (label)); + AddCodeLine ("adc sp+1"); + AddCodeLine ("sta sp+1"); + AddCodeLine ("pla"); +} void g_drop (unsigned Space) /* Drop space allocated on the stack */ @@ -2490,7 +2513,7 @@ void g_stackcheck (void) void g_add (unsigned flags, unsigned long val) /* Primary = TOS + Primary */ { - static const char* ops[12] = { + static const char* const ops[4] = { "tosaddax", "tosaddax", "tosaddeax", "tosaddeax" }; @@ -2506,8 +2529,8 @@ void g_add (unsigned flags, unsigned long val) void g_sub (unsigned flags, unsigned long val) /* Primary = TOS - Primary */ { - static const char* ops[12] = { - "tossubax", "tossubax", "tossubeax", "tossubeax", + static const char* const ops[4] = { + "tossubax", "tossubax", "tossubeax", "tossubeax" }; if (flags & CF_CONST) { @@ -2522,8 +2545,8 @@ void g_sub (unsigned flags, unsigned long val) void g_rsub (unsigned flags, unsigned long val) /* Primary = Primary - TOS */ { - static const char* ops[12] = { - "tosrsubax", "tosrsubax", "tosrsubeax", "tosrsubeax", + static const char* const ops[4] = { + "tosrsubax", "tosrsubax", "tosrsubeax", "tosrsubeax" }; oper (flags, val, ops); } @@ -2533,8 +2556,8 @@ void g_rsub (unsigned flags, unsigned long val) void g_mul (unsigned flags, unsigned long val) /* Primary = TOS * Primary */ { - static const char* ops[12] = { - "tosmulax", "tosumulax", "tosmuleax", "tosumuleax", + static const char* const ops[4] = { + "tosmulax", "tosumulax", "tosmuleax", "tosumuleax" }; int p2; @@ -2640,8 +2663,8 @@ void g_mul (unsigned flags, unsigned long val) void g_div (unsigned flags, unsigned long val) /* Primary = TOS / Primary */ { - static const char* ops[12] = { - "tosdivax", "tosudivax", "tosdiveax", "tosudiveax", + static const char* const ops[4] = { + "tosdivax", "tosudivax", "tosdiveax", "tosudiveax" }; /* Do strength reduction if the value is constant and a power of two */ @@ -2665,8 +2688,8 @@ void g_div (unsigned flags, unsigned long val) void g_mod (unsigned flags, unsigned long val) /* Primary = TOS % Primary */ { - static const char* ops[12] = { - "tosmodax", "tosumodax", "tosmodeax", "tosumodeax", + static const char* const ops[4] = { + "tosmodax", "tosumodax", "tosmodeax", "tosumodeax" }; int p2; @@ -2690,8 +2713,8 @@ void g_mod (unsigned flags, unsigned long val) void g_or (unsigned flags, unsigned long val) /* Primary = TOS | Primary */ { - static const char* ops[12] = { - "tosorax", "tosorax", "tosoreax", "tosoreax", + static const char* const ops[4] = { + "tosorax", "tosorax", "tosoreax", "tosoreax" }; /* If the right hand side is const, the lhs is not on stack but still @@ -2760,8 +2783,8 @@ void g_or (unsigned flags, unsigned long val) void g_xor (unsigned flags, unsigned long val) /* Primary = TOS ^ Primary */ { - static const char* ops[12] = { - "tosxorax", "tosxorax", "tosxoreax", "tosxoreax", + static const char* const ops[4] = { + "tosxorax", "tosxorax", "tosxoreax", "tosxoreax" }; @@ -2828,8 +2851,8 @@ void g_xor (unsigned flags, unsigned long val) void g_and (unsigned Flags, unsigned long Val) /* Primary = TOS & Primary */ { - static const char* ops[12] = { - "tosandax", "tosandax", "tosandeax", "tosandeax", + static const char* const ops[4] = { + "tosandax", "tosandax", "tosandeax", "tosandeax" }; /* If the right hand side is const, the lhs is not on stack but still @@ -2920,8 +2943,8 @@ void g_and (unsigned Flags, unsigned long Val) void g_asr (unsigned flags, unsigned long val) /* Primary = TOS >> Primary */ { - static const char* ops[12] = { - "tosasrax", "tosshrax", "tosasreax", "tosshreax", + static const char* const ops[4] = { + "tosasrax", "tosshrax", "tosasreax", "tosshreax" }; /* If the right hand side is const, the lhs is not on stack but still @@ -3051,8 +3074,8 @@ void g_asr (unsigned flags, unsigned long val) void g_asl (unsigned flags, unsigned long val) /* Primary = TOS << Primary */ { - static const char* ops[12] = { - "tosaslax", "tosshlax", "tosasleax", "tosshleax", + static const char* const ops[4] = { + "tosaslax", "tosshlax", "tosasleax", "tosshleax" }; @@ -3429,8 +3452,8 @@ void g_dec (unsigned flags, unsigned long val) void g_eq (unsigned flags, unsigned long val) /* Test for equal */ { - static const char* ops[12] = { - "toseqax", "toseqax", "toseqeax", "toseqeax", + static const char* const ops[4] = { + "toseqax", "toseqax", "toseqeax", "toseqeax" }; unsigned L; @@ -3483,8 +3506,8 @@ void g_eq (unsigned flags, unsigned long val) void g_ne (unsigned flags, unsigned long val) /* Test for not equal */ { - static const char* ops[12] = { - "tosneax", "tosneax", "tosneeax", "tosneeax", + static const char* const ops[4] = { + "tosneax", "tosneax", "tosneeax", "tosneeax" }; unsigned L; @@ -3537,8 +3560,8 @@ void g_ne (unsigned flags, unsigned long val) void g_lt (unsigned flags, unsigned long val) /* Test for less than */ { - static const char* ops[12] = { - "tosltax", "tosultax", "toslteax", "tosulteax", + static const char* const ops[4] = { + "tosltax", "tosultax", "toslteax", "tosulteax" }; unsigned Label; @@ -3699,8 +3722,8 @@ void g_lt (unsigned flags, unsigned long val) void g_le (unsigned flags, unsigned long val) /* Test for less than or equal to */ { - static const char* ops[12] = { - "tosleax", "tosuleax", "tosleeax", "tosuleeax", + static const char* const ops[4] = { + "tosleax", "tosuleax", "tosleeax", "tosuleeax" }; @@ -3814,8 +3837,8 @@ void g_le (unsigned flags, unsigned long val) void g_gt (unsigned flags, unsigned long val) /* Test for greater than */ { - static const char* ops[12] = { - "tosgtax", "tosugtax", "tosgteax", "tosugteax", + static const char* const ops[4] = { + "tosgtax", "tosugtax", "tosgteax", "tosugteax" }; @@ -3945,8 +3968,8 @@ void g_gt (unsigned flags, unsigned long val) void g_ge (unsigned flags, unsigned long val) /* Test for greater than or equal to */ { - static const char* ops[12] = { - "tosgeax", "tosugeax", "tosgeeax", "tosugeeax", + static const char* const ops[4] = { + "tosgeax", "tosugeax", "tosgeeax", "tosugeeax" }; unsigned Label; @@ -4233,7 +4256,7 @@ void g_initauto (unsigned Label, unsigned Size) AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0)); AddCodeLine ("sta (sp),y"); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) Size); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); } } @@ -4258,16 +4281,16 @@ void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size) AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, InitLabel, 0)); AddCodeLine ("sta %s,y", GetLabelName (CF_STATIC, VarLabel, 0)); AddCodeLine ("iny"); - AddCodeLine ("cpy #$%02X", (unsigned char) Size); + AddCmpCodeIfSizeNot256 ("cpy #$%02X", Size); AddCodeLine ("bne %s", LocalLabelName (CodeLabel)); } else { - /* Use the easy way here: memcpy */ + /* Use the easy way here: memcpy() */ g_getimmed (CF_STATIC, VarLabel, 0); AddCodeLine ("jsr pushax"); g_getimmed (CF_STATIC, InitLabel, 0); AddCodeLine ("jsr pushax"); g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, Size, 0); - AddCodeLine ("jsr %s", GetLabelName (CF_EXTERNAL, (unsigned long) "memcpy", 0)); + AddCodeLine ("jsr %s", GetLabelName (CF_EXTERNAL, (uintptr_t) "memcpy", 0)); } }