strcat (buf, "y");
} else {
/* Y register no longer used */
- AddCodeHint ("y:-");
+ AddCodeHint ("y:-");
}
if (flags & CF_CONST) {
if ((flags & CF_TYPE) != CF_LONG) {
/* Create or drop space on the stack */
{
if (space < 0) {
- mod_internal (-space, "inc", "addy");
+ mod_internal (-space, "inc", "addy");
} else if (space > 0) {
- mod_internal (space, "dec", "suby");
+ mod_internal (space, "dec", "suby");
}
}
+void g_stackcheck (void)
+/* Check for a stack overflow */
+{
+ AddCodeLine ("\tjsr\tstkchk");
+}
+
+
+
void g_add (unsigned flags, unsigned long val)
/* Primary = TOS + Primary */
{
void DeclareLocals (void)
/* Declare local variables and types. */
{
+ /* Remember the current stack pointer */
+ int InitialStack = oursp;
+
/* Loop until we don't find any more variables */
while (1) {
/* In case we switched away from code segment, switch back now */
g_usecode ();
+
+ /* In case we've allocated local variables in this block, emit a call to
+ * the stack checking routine if stack checks are enabled.
+ */
+ if (CheckStack && InitialStack != oursp) {
+ g_stackcheck ();
+ }
}
"Long options:\n"
" --ansi\t\tStrict ANSI mode\n"
" --bss-name seg\tSet the name of the BSS segment\n"
+ " --check-stack\tGenerate stack overflow checks\n"
" --code-name seg\tSet the name of the CODE segment\n"
" --cpu type\t\tSet cpu type\n"
" --data-name seg\tSet the name of the DATA segment\n"
+static void OptCheckStack (const char* Opt, const char* Arg)
+/* Handle the --check-stack option */
+{
+ CheckStack = 1;
+}
+
+
+
static void OptCodeName (const char* Opt, const char* Arg)
/* Handle the --code-name option */
{
{ "--add-source", 0, OptAddSource },
{ "--ansi", 0, OptAnsi },
{ "--bss-name", 1, OptBssName },
+ { "--check-stack", 0, OptCheckStack },
{ "--code-name", 1, OptCodeName },
{ "--create-dep", 0, OptCreateDep },
{ "--cpu", 1, OptCPU },
{ "--help", 0, OptHelp },
{ "--include-dir", 1, OptIncludeDir },
{ "--rodata-name", 1, OptRodataName },
- { "--signed-chars", 0, OptSignedChars },
- { "--static-locals", 0, OptStaticLocals },
- { "--target", 1, OptTarget },
- { "--verbose", 0, OptVerbose },
- { "--version", 0, OptVersion },
+ { "--signed-chars", 0, OptSignedChars },
+ { "--static-locals", 0, OptStaticLocals },
+ { "--target", 1, OptTarget },
+ { "--verbose", 0, OptVerbose },
+ { "--version", 0, OptVersion },
};
int I;
/* Tokens for the #pragmas */
typedef enum {
PR_BSSSEG,
+ PR_CHECKSTACK,
PR_CODESEG,
PR_DATASEG,
PR_REGVARADDR,
pragma_t Tok; /* Token */
} Pragmas[] = {
{ "bssseg", PR_BSSSEG },
+ { "checkstack", PR_CHECKSTACK },
{ "codeseg", PR_CODESEG },
{ "dataseg", PR_DATASEG },
{ "regvaraddr", PR_REGVARADDR },
SegNamePragma (g_bssname);
break;
+ case PR_CHECKSTACK:
+ FlagPragma (&CheckStack);
+ break;
+
case PR_CODESEG:
SegNamePragma (g_codename);
break;