-void AddCodeHint (const char* Hint)
-/* Add an optimizer hint */
-{
- /* ### AddCodeLine ("+%s", Hint); */
-}
-
-
-
CodeMark GetCodePos (void)
/* Get a marker pointing to the current output position */
{
-void AddCodeHint (const char* Hint);
-/* Add an optimizer hint */
-
CodeMark GetCodePos (void);
/* Get a marker pointing to the current output position */
+static void OutputDataLine (DataSeg* S, const char* Format, ...)
+/* Add a line to the current data segment */
+{
+ va_list ap;
+ va_start (ap, Format);
+ AddDataEntry (S, Format, ap);
+ va_end (ap);
+}
+
+
+
+void g_segname (segment_t Seg, const char* Name)
+/* Set the name of a segment */
+{
+ DataSeg* S;
+
+ /* Remember the new name */
+ NewSegName (Seg, Name);
+
+ /* Emit a segment directive for the data style segments */
+ switch (Seg) {
+ case SEG_RODATA: S = CS->ROData; break;
+ case SEG_DATA: S = CS->Data; break;
+ case SEG_BSS: S = CS->BSS; break;
+ default: S = 0; break;
+ }
+ if (S) {
+ OutputDataLine (S, ".segment\t\"%s\"", Name);
+ }
+}
+
+
+
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
AddCodeLine ("clc");
if ((val & 0xFF) != 0) {
AddCodeLine ("adc #$%02X", (unsigned char) val);
- /* Tell the optimizer that the X register may be invalid */
- AddCodeHint ("x:!");
}
AddCodeLine ("pha");
AddCodeLine ("txa");
AddCodeLine ("sec");
if ((val & 0xFF) != 0) {
AddCodeLine ("sbc #$%02X", (unsigned char) val);
- /* Tell the optimizer that the X register may be invalid */
- AddCodeHint ("x:!");
}
AddCodeLine ("pha");
AddCodeLine ("txa");
void g_usebss (void);
/* Switch to the bss segment */
+void g_segname (segment_t Seg, const char* Name);
+/* Set the name of a segment */
+
/*****************************************************************************/
-/* Functions handling local labels */
+/* Functions handling local labels */
/*****************************************************************************/
if (E && E->Owner->PrevTab == 0 && IsTypeFunc (E->Type)) {
/* A function may use the A or A/X registers if it is a fastcall
- * function. Otherwise it does not use any registers passed by
- * the caller. However, we assume that any function will destroy
- * all registers.
+ * function. If it is not a fastcall function but a variadic one,
+ * it will use the Y register (the parameter size is passed here).
+ * In all other cases, no registers are used. However, we assume
+ * that any function will destroy all registers.
*/
FuncDesc* D = E->V.F.Func;
if ((D->Flags & FD_FASTCALL) != 0 && D->ParamCount > 0) {
} else {
*Use = REG_AX;
}
- } else {
+ } else if ((D->Flags & FD_VARIADIC) != 0) {
+ *Use = REG_Y;
+ } else {
/* Will not use any registers */
*Use = REG_NONE;
}
}
if (lval->e_test & E_FORCETEST) { /* we testing this value? */
/* debug... */
- AddCodeHint ("forcetest");
flags |= TypeOf (lval->e_tptr);
g_test (flags); /* yes, force a test */
lval->e_test &= ~E_FORCETEST;
unsigned CFlags;
unsigned Flags;
- /* Add a hint for the optimizer */
- AddCodeHint ("param:start");
-
/* Count arguments */
++ParamCount;
ParamSize += ArgSize;
}
- /* Add an optimizer hint */
- AddCodeHint ("param:end");
-
/* Check for end of argument list */
if (curtok != TOK_COMMA) {
break;
OutputFile = MakeFilename (InputFile, ".s");
}
-
-
-
/* Go! */
Compile ();
#include <string.h>
/* cc65 */
+#include "codegen.h"
#include "error.h"
#include "expr.h"
#include "global.h"
/*****************************************************************************/
-/* data */
+/* data */
/*****************************************************************************/
if (ValidSegName (Name)) {
/* Set the new name */
- NewSegName (Seg, Name);
+ g_segname (Seg, Name);
} else {
return;
}
- /* Do we know this pragma? */
+ /* Search for the name, then skip the identifier */
Pragma = FindPragma (CurTok.Ident);
+ NextToken ();
+
+ /* Do we know this pragma? */
if (Pragma == PR_ILLEGAL) {
- /* According to the ANSI standard, we're not allowed to generate errors
- * for unknown pragmas, however, we're allowed to warn - and we will
- * do so. Otherwise one typo may give you hours of bug hunting...
- */
- Warning ("Unknown #pragma `%s'", CurTok.Ident);
- return;
+ /* According to the ANSI standard, we're not allowed to generate errors
+ * for unknown pragmas, however, we're allowed to warn - and we will
+ * do so. Otherwise one typo may give you hours of bug hunting...
+ */
+ Warning ("Unknown #pragma `%s'", CurTok.Ident);
+ return;
}
- /* Skip the identifier and check for an open paren */
- NextToken ();
+ /* Check for an open paren */
ConsumeLParen ();
/* Switch for the different pragmas */
g_defdata (CF_INT | CF_CONST, -((int)lcount)-1, 0);
/* Create the case selector table */
- AddCodeHint ("casetable");
p = swtab;
while (lcount) {
g_case (Flags, p->sw_lab, p->sw_const); /* Create one label */
break;
default:
- AddCodeHint ("stmt:start");
expression (&lval);
- AddCodeHint ("stmt:end");
ConsumeSemi ();
}
}