/* common */
#include "check.h"
#include "cpu.h"
+#include "inttypes.h"
#include "strbuf.h"
#include "xmalloc.h"
#include "xsprintf.h"
#include "global.h"
#include "segments.h"
#include "stackptr.h"
+#include "stdfunc.h"
#include "textseg.h"
#include "util.h"
#include "codegen.h"
-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 */
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:
-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 */
-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 */
-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 */
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:
}
} 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 {
** 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);
}
}
-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;
-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 */
{
-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 */
{
-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 */
-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
}
+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 */
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"
};
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) {
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);
}
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;
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 */
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;
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
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"
};
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
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
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"
};
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;
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;
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;
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"
};
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"
};
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;
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));
}
}
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));
}
}