"void" { count(); return(VOID); }
"volatile" { count(); return(VOLATILE); }
"using" { count(); TKEYWORD(USING); }
+"_naked" { count(); TKEYWORD(NAKED); }
"while" { count(); return(WHILE); }
"xdata" { count(); TKEYWORD(XDATA); }
"_data" { count(); TKEYWORD(_NEAR); }
%token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
%token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
-%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
+%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
+%token NAKED
%token <yyinline> INLINEASM
%token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
%token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
$$->class = SPECIFIER ;
SPEC_CRTCL($$) = 1;
}
+ | NAKED { $$ = newLink ();
+ $$->class = SPECIFIER ;
+ SPEC_NAKED($$) = 1;
+ }
| NONBANKED {$$ = newLink ();
$$->class = SPECIFIER ;
SPEC_NONBANKED($$) = 1;
SPEC_BSTR (dest) |= SPEC_BSTR (src);
SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
SPEC_NONBANKED (dest) |= SPEC_NONBANKED (src);
+ SPEC_NAKED (dest) |= SPEC_NAKED (src);
if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
SPEC_STRUCT (dest) = SPEC_STRUCT (src);
unsigned _volatile:1; /* is marked as volatile */
unsigned _const:1; /* is a constant */
unsigned _critical:1; /* critical function */
+ unsigned _naked:1; /* naked function */
unsigned _typedef:1; /* is typedefed */
unsigned _isregparm:1; /* is the first parameter */
unsigned _isenum:1; /* is an enumerated type */
#define SPEC_BNKF(x) x->select.s._rbank
#define SPEC_INTRTN(x) x->select.s._intrtn
#define SPEC_CRTCL(x) x->select.s._critical
+#define SPEC_NAKED(x) x->select.s._naked
#define SPEC_VOLATILE(x) x->select.s._volatile
#define SPEC_CONST(x) x->select.s._const
#define SPEC_STRUCT(x) x->select.s.v_struct
emitcode ("", "%s:", sym->rname);
fetype = getSpec (operandType (IC_LEFT (ic)));
+ if (SPEC_NAKED(fetype))
+ {
+ emitcode(";", "naked function: no prologue.");
+ return;
+ }
+
/* if critical function then turn interrupts off */
if (SPEC_CRTCL (fetype))
emitcode ("clr", "ea");
D (emitcode (";", "genEndFunction "););
+ if (SPEC_NAKED(sym->etype))
+ {
+ emitcode(";", "naked function: no epilogue.");
+ return;
+ }
+
if (IS_RENT (sym->etype) || options.stackAuto)
{
emitcode ("mov", "%s,_bp", spname);
emitcode ("setb", "ea");
/* if debug then send end of function */
-/* if (options.debug && currFunc) { */
+/* if (options.debug && currFunc) */
if (currFunc)
{
_G.debugLine = 1;
"_xdata",
"_pdata",
"_idata",
+ "_naked",
NULL
};
emitcode ("", "%s:", sym->rname);
fetype = getSpec (operandType (IC_LEFT (ic)));
+ if (SPEC_NAKED(fetype))
+ {
+ emitcode(";", "naked function: no prologue.");
+ return;
+ }
+
/* if critical function then turn interrupts off */
if (SPEC_CRTCL (fetype))
emitcode ("clr", "ea");
{
symbol *sym = OP_SYMBOL (IC_LEFT (ic));
+ if (SPEC_NAKED(sym->etype))
+ {
+ emitcode(";", "naked function: no epilogue.");
+ return;
+ }
+
if (IS_RENT (sym->etype) || options.stackAuto)
{
emitcode ("mov", "%s,_bp", spname);
emitcode ("setb", "ea");
/* if debug then send end of function */
-/* if (options.debug && currFunc) { */
+/* if (options.debug && currFunc) */
if (currFunc)
{
_G.debugLine = 1;
"_xdata",
"_pdata",
"_idata",
+ "_naked",
NULL
};