]> git.sur5r.net Git - cc65/blobdiff - src/cc65/codegen.c
remove TABs
[cc65] / src / cc65 / codegen.c
index 6143b09fe9b6033e9610345e207887965282a6ea..a611f4f6a809ec0789c5c975bfc7876104e10b8e 100644 (file)
@@ -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));
     }
 }