Index: sdcc/src/pic16/device.h
===================================================================
--- sdcc/src/pic16/device.h	(révision 6452)
+++ sdcc/src/pic16/device.h	(copie de travail)
@@ -98,6 +98,8 @@
   int gstack;
   unsigned int debgen;
   int xinst;
+  /* squalyl-2011apr20: function return addresses in software stack */
+  int stack_ret_address;
 } pic16_options_t;
 
 extern pic16_options_t pic16_options;
@@ -105,6 +107,9 @@
 #define STACK_MODEL_SMALL       (pic16_options.stack_model == 0)
 #define STACK_MODEL_LARGE       (pic16_options.stack_model == 1)
 
+  /* squalyl-2011apr20: function return addresses in software stack */
+#define STACK_FOR_RETADDR       (pic16_options.stack_ret_address == 1)
+
 extern set *fix_idataSymSet;
 extern set *rel_idataSymSet;
 
Index: sdcc/src/pic16/gen.c
===================================================================
--- sdcc/src/pic16/gen.c	(révision 6452)
+++ sdcc/src/pic16/gen.c	(copie de travail)
@@ -3092,6 +3092,14 @@
       }
     }
 
+	/* squalyl-2011apr20: push the function's return address if required */
+	if(STACK_FOR_RETADDR) {
+		DEBUGpic16_emitcode("; **", "squalyl-2011apr20: saving return address in stack");
+		pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_tosu));
+		pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_tosh));
+		pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_tosl));
+	}
+
     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
           && sym->stack) {
 
@@ -3233,6 +3241,13 @@
       }
     }
 
+	/* squalyl-2011apr20: pop the function's return address if required */
+	if(STACK_FOR_RETADDR) {
+		pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_tosl ));
+		pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_tosh ));
+		pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_tosu ));
+	}
+
     if(strcmp(sym->name, "main")) {
       if(0
         || !options.omitFramePtr
Index: sdcc/src/pic16/main.c
===================================================================
--- sdcc/src/pic16/main.c	(révision 6452)
+++ sdcc/src/pic16/main.c	(copie de travail)
@@ -490,6 +490,10 @@
 #define REP_UDATA         "--preplace-udata-with="
 
 #define STACK_MODEL       "--pstack-model="
+
+//squalyl-2011apr20: use software stack to store function return addresses (3 more byte per call)
+#define SOFT_CALL_STACK   "--soft-call-stack"
+
 #define OPT_BANKSEL       "--obanksel="
 
 #define ALT_ASM           "--asm="
@@ -520,6 +524,7 @@
 OPTION pic16_optionsTable[]= {
     /* code generation options */
     { 0, STACK_MODEL,        NULL, "use stack model 'small' (default) or 'large'"},
+    { 0, SOFT_CALL_STACK,    NULL, "squalyl: use software stack for function calls (default=no)"},
 #if XINST
     { 'y', "--extended",     &pic16_options.xinst, "enable Extended Instruction Set/Literal Offset Addressing mode"},
 #endif
@@ -586,6 +591,12 @@
       return TRUE;
     }
 
+    /* squalyl-2011apr20: decode software-stack-for-function-calls option */
+    if(ISOPT(SOFT_CALL_STACK)) {
+        pic16_options.stack_ret_address = 1;
+        return TRUE;
+    }
+
     if(ISOPT(IVT_LOC)) {
       pic16_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc);
       fprintf(stderr, "%s:%d setting interrupt vector addresses 0x%x\n", __FILE__, __LINE__, pic16_options.ivt_loc);
@@ -819,6 +830,9 @@
   pic16_options.ip_stack = 1;       /* set to 1 to enable ipop/ipush for stack */
   pic16_options.gstack = 0;
   pic16_options.debgen = 0;
+
+  /* squalyl-2011apr20: default is to disable function return address on stack */
+  pic16_options.stack_ret_address = 0;
 }
 
 static const char *
