From ee76e2f5985c5917392f3f6ea121db57a9e314ce Mon Sep 17 00:00:00 2001 From: borutr Date: Sun, 17 Dec 2006 17:47:57 +0000 Subject: [PATCH] git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4515 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 11 +- doc/sdccman.lyx | 16 +- src/SDCC.lex | 672 +++++++++++++++++++++++++++-------------- src/SDCCutil.c | 65 +++- src/SDCCutil.h | 18 ++ src/pic/main.c | 12 +- src/pic16/main.c | 494 +++++++++++++++++------------- src/port.h | 214 ++++++------- src/z80/main.c | 178 +++++++---- support/Util/SDCCerr.c | 2 + support/Util/SDCCerr.h | 1 + support/Util/dbuf.c | 4 +- 12 files changed, 1061 insertions(+), 626 deletions(-) diff --git a/ChangeLog b/ChangeLog index 014ca6b3..f22c517f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,17 @@ +2006-12-17 Borut Razem + + * doc/sdccman.lyx, src/pic16/main.c, src/pic/main.c, src/port.h, + src/SDCC.lex, src/SDCCutil.[ch], src/z80/main.c, + support/Util/SDCCerr.[ch]: removed deprecated pragmas, + unified table driven pragma handling, pragma argument type checking + * support/Util/dbuf.c: (dbuf_set_size) allow to set size equal to the + current one - version 1.1.3 + 2006-12-13 Raphael Neider * src/pic/device.h: removed AssignedMemory structure and macros * src/pic/device.c: removed global finalMapping (linker assigns - memory locations), + memory locations), (register_map): add SFRs to remembered memRanges (addMemRange,isSFR,dump_map,dump_sfr,mapRegister,assignRegister, assignFixedRegisters,assignRelocatableRegisters): removed, diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index 8aba4206..c4ce3eba 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -10658,7 +10658,7 @@ portmode \end_inset -=z180 (z80) is used to turn on (off) the Z180/HD64180 port addressing instructio + z180 (z80) is used to turn on (off) the Z180/HD64180 port addressing instructio ns \family typewriter in0/out0 @@ -19204,17 +19204,6 @@ If the stack_size field is omitted then a stack is created with the default \layout List \labelwidthstring 00.00.0000 -wparam -\emph on -This pragma is deprecated. - Its use will cause a warning message to be issued. -\emph default - -\newline - -\layout List -\labelwidthstring 00.00.0000 - code \begin_inset LatexCommand \index{PIC16!Pragmas!\#pragma code} @@ -20039,9 +20028,6 @@ void func_wparam(int a) wparam \layout LyX-Code } -\layout Standard - -This keyword replaces the deprecated wparam pragma. \layout List \labelwidthstring 00.00.0000 diff --git a/src/SDCC.lex b/src/SDCC.lex index 4f9b5188..41989a85 100644 --- a/src/SDCC.lex +++ b/src/SDCC.lex @@ -2,24 +2,24 @@ SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for 8/16 bit microcontrollers) Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997) - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ D [0-9] @@ -58,7 +58,7 @@ static struct dbuf_s asmbuff; /* forward declarations */ static char *stringLiteral(void); static void count(void); -static int process_pragma(char *); +static int process_pragma(const char *); static int check_type(void); static int isTargetKeyword(char *s); static int checkCurrFile(char *s); @@ -240,7 +240,7 @@ _?"_asm" { "^" { count(); return('^'); } "|" { count(); return('|'); } "?" { count(); return('?'); } -^#pragma.*"\n" { count(); process_pragma(yytext); } +^#pragma.*$ { count(); process_pragma(yytext); } ^(#line.*"\n")|(#.*"\n") { count(); checkCurrFile(yytext); } ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED, yytext); count(); } @@ -447,7 +447,7 @@ out: } -enum pragma_id { +enum { P_SAVE = 1, P_RESTORE, P_NOINDUCTION, @@ -561,261 +561,474 @@ static void copyAndFreeSDCCERRG(struct SDCCERRG *dest, struct SDCCERRG *src) Safe_free(src); } -static void doPragma(int op, char *cp) +/* + * returns 1 if the pragma was processed, 0 if not + */ +static int doPragma(int id, const char *name, const char *cp) { - int i; + struct pragma_token_s token; + int err = 0; + int processed = 1; - switch (op) { - case P_SAVE: - { - STACK_PUSH(options_stack, cloneOptions(&options)); - STACK_PUSH(optimize_stack, cloneOptimize(&optimize)); - STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG)); - } - break; + init_pragma_token(&token); - case P_RESTORE: + switch (id) { - struct options *optionsp; - struct optimize *optimizep; - struct SDCCERRG *sdccerrgp; + case P_SAVE: + { + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - optionsp = STACK_POP(options_stack); - copyAndFreeOptions(&options, optionsp); + STACK_PUSH(options_stack, cloneOptions(&options)); + STACK_PUSH(optimize_stack, cloneOptimize(&optimize)); + STACK_PUSH(SDCCERRG_stack, cloneSDCCERRG(&_SDCCERRG)); + } + break; - optimizep = STACK_POP(optimize_stack); - copyAndFreeOptimize(&optimize, optimizep); + case P_RESTORE: + { + struct options *optionsp; + struct optimize *optimizep; + struct SDCCERRG *sdccerrgp; + + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - sdccerrgp = STACK_POP(SDCCERRG_stack); - copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp); - } - break; + optionsp = STACK_POP(options_stack); + copyAndFreeOptions(&options, optionsp); + + optimizep = STACK_POP(optimize_stack); + copyAndFreeOptimize(&optimize, optimizep); + + sdccerrgp = STACK_POP(SDCCERRG_stack); + copyAndFreeSDCCERRG(&_SDCCERRG, sdccerrgp); + } + break; - case P_NOINDUCTION: - optimize.loopInduction = 0; - break; + case P_NOINDUCTION: + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - case P_NOINVARIANT: - optimize.loopInvariant = 0; - break; + optimize.loopInduction = 0; + break; - case P_INDUCTION: - optimize.loopInduction = 1; - break; + case P_NOINVARIANT: + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - case P_STACKAUTO: - options.stackAuto = 1; - break; + optimize.loopInvariant = 0; + break; - case P_NOJTBOUND: - optimize.noJTabBoundary = 1; - break; + case P_INDUCTION: + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - case P_NOGCSE: - optimize.global_cse = 0; - break; + optimize.loopInduction = 1; + break; - case P_NOOVERLAY: - options.noOverlay = 1; - break; + case P_STACKAUTO: + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - case P_LESSPEDANTIC: - options.lessPedantic = 1; - setErrorLogLevel(ERROR_LEVEL_WARNING); - break; + options.stackAuto = 1; + break; - case P_CALLEE_SAVES: - /* append to the functions already listed - in callee-saves */ - setParseWithComma(&options.calleeSavesSet, cp); - break; + case P_NOJTBOUND: + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - case P_EXCLUDE: - { - deleteSet(&options.excludeRegsSet); - setParseWithComma(&options.excludeRegsSet, cp); - } - break; + optimize.noJTabBoundary = 1; + break; - case P_NOIV: - options.noiv = 1; - break; + case P_NOGCSE: + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - case P_LOOPREV: - optimize.noLoopReverse = 1; - break; + optimize.global_cse = 0; + break; - case P_OVERLAY_: - break; /* notyet */ + case P_NOOVERLAY: + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - case P_DISABLEWARN: - if (sscanf(cp, "%d", &i) && (i 8) + { + err = 1; + break; + } + else + { + dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1); + options.code_seg = Safe_strdup(get_pragma_string(&token)); + } + } + break; + + case P_CONSTSEG: + { + const char *segname; + + cp = get_pragma_token(cp, &token); + if (token.type == TOKEN_EOL) + { + err = 1; + break; + } + segname = get_pragma_string(&token); + + cp = get_pragma_token(cp, &token); + if (token.type != TOKEN_EOL) + { + err = 1; + break; + } + + if (strlen(segname) > 8) + { + err = 1; + break; + } + else + { + dbuf_append(&token.dbuf, "(CODE)", (sizeof "(CODE)") - 1); + options.code_seg = Safe_strdup(get_pragma_string(&token)); + } + } + break; + + default: + processed = 0; + break; } - break; - } + + get_pragma_token(cp, &token); + + if (1 == err || (0 == err && token.type != TOKEN_EOL)) + werror(W_BAD_PRAGMA_ARGUMENTS, name); + + free_pragma_token(&token); + return processed; } -static int process_pragma(char *s) -{ -#define NELEM(x) (sizeof (x) / sizeof (x)[0]) -#define PRAGMA_STR "#pragma" -#define PRAGMA_LEN ((sizeof PRAGMA_STR) - 1) +static struct pragma_s pragma_tbl[] = { + { "save", P_SAVE, 0, doPragma }, + { "restore", P_RESTORE, 0, doPragma }, + { "noinduction", P_NOINDUCTION, 0, doPragma }, + { "noinvariant", P_NOINVARIANT, 0, doPragma }, + { "noloopreverse", P_LOOPREV, 0, doPragma }, + { "induction", P_INDUCTION, 0, doPragma }, + { "stackauto", P_STACKAUTO, 0, doPragma }, + { "nojtbound", P_NOJTBOUND, 0, doPragma }, + { "nogcse", P_NOGCSE, 0, doPragma }, + { "nooverlay", P_NOOVERLAY, 0, doPragma }, + { "callee_saves", P_CALLEE_SAVES, 0, doPragma }, + { "exclude", P_EXCLUDE, 0, doPragma }, + { "noiv", P_NOIV, 0, doPragma }, + { "overlay", P_OVERLAY_, 0, doPragma }, + { "less_pedantic", P_LESSPEDANTIC, 0, doPragma }, + { "disable_warning",P_DISABLEWARN, 0, doPragma }, + { "opt_code_speed", P_OPTCODESPEED, 0, doPragma }, + { "opt_code_size", P_OPTCODESIZE, 0, doPragma }, + { "opt_code_balanced", P_OPTCODEBALANCED, 0, doPragma }, + { "std_c89", P_STD_C89, 0, doPragma }, + { "std_c99", P_STD_C99, 0, doPragma }, + { "std_sdcc89", P_STD_SDCC89, 0, doPragma }, + { "std_sdcc99", P_STD_SDCC99, 0, doPragma }, + { "codeseg", P_CODESEG, 0, doPragma }, + { "constseg", P_CONSTSEG, 0, doPragma }, + { NULL, 0, 0, NULL }, +}; - static struct pragma_s - { - const char *name; - enum pragma_id id; - char deprecated; - } pragma_tbl[] = { - { "save", P_SAVE, 0 }, - { "restore", P_RESTORE, 0 }, - { "noinduction", P_NOINDUCTION, 0 }, - { "noinvariant", P_NOINVARIANT, 0 }, - { "noloopreverse", P_LOOPREV, 0 }, - { "induction", P_INDUCTION, 0 }, - { "stackauto", P_STACKAUTO, 0 }, - { "nojtbound", P_NOJTBOUND, 0 }, - { "nogcse", P_NOGCSE, 0 }, - { "nooverlay", P_NOOVERLAY, 0 }, - { "callee_saves", P_CALLEE_SAVES, 0 }, - { "exclude", P_EXCLUDE, 0 }, - { "noiv", P_NOIV, 0 }, - { "overlay", P_OVERLAY_, 0 }, - { "less_pedantic", P_LESSPEDANTIC, 0 }, - { "disable_warning",P_DISABLEWARN, 0 }, - { "opt_code_speed", P_OPTCODESPEED, 0 }, - { "opt_code_size", P_OPTCODESIZE, 0 }, - { "opt_code_balanced", P_OPTCODEBALANCED, 0 }, - { "std_c89", P_STD_C89, 0 }, - { "std_c99", P_STD_C99, 0 }, - { "std_sdcc89", P_STD_SDCC89, 0 }, - { "std_sdcc99", P_STD_SDCC99, 0 }, - { "codeseg", P_CODESEG, 0 }, - { "constseg", P_CONSTSEG, 0 }, - - /* - * The following lines are deprecated pragmas, - * only for bacward compatibility. - * They should be removed in next major release after 1.4.0 - */ - - { "SAVE", P_SAVE, 1 }, - { "RESTORE", P_RESTORE, 1 }, - { "NOINDUCTION", P_NOINDUCTION, 1 }, - { "NOINVARIANT", P_NOINVARIANT, 1 }, - { "NOLOOPREVERSE", P_LOOPREV, 1 }, - { "INDUCTION", P_INDUCTION, 1 }, - { "STACKAUTO", P_STACKAUTO, 1 }, - { "NOJTBOUND", P_NOJTBOUND, 1 }, - { "NOGCSE", P_NOGCSE, 1 }, - { "NOOVERLAY", P_NOOVERLAY, 1 }, - { "CALLEE-SAVES", P_CALLEE_SAVES, 1 }, - { "EXCLUDE", P_EXCLUDE, 1 }, - { "NOIV", P_NOIV, 1 }, - { "OVERLAY", P_OVERLAY_, 1 }, - { "LESS_PEDANTIC", P_LESSPEDANTIC, 1 }, - }; - char *cp; +/* + * returns 1 if the pragma was processed, 0 if not + */ +int +process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s) +{ + struct pragma_token_s token; int i; + int ret = 0; - /* find the pragma */ - while (strncmp(s, PRAGMA_STR, PRAGMA_LEN)) - s++; - s += PRAGMA_LEN; - - /* look for the directive */ - while(isspace((unsigned char)*s)) - s++; + init_pragma_token(&token); - cp = s; - /* look for the end of the directive */ - while ((!isspace((unsigned char)*s)) && (*s != '\n')) - s++ ; + s = get_pragma_token(s, &token); /* skip separating whitespace */ - while (isspace((unsigned char)*s) && (*s != '\n')) + while ('\n' != *s && isspace((unsigned char)*s)) s++; - /* First give the port a chance */ - if (port->process_pragma && !port->process_pragma(cp)) - return 0; - - for (i = 0; i < NELEM(pragma_tbl); i++) + for (i = 0; NULL != pragma_tbl[i].name; ++i) { /* now compare and do what needs to be done */ - size_t len = strlen(pragma_tbl[i].name); - - if (strncmp(cp, pragma_tbl[i].name, len) == 0) + if (strcmp(get_pragma_string(&token), pragma_tbl[i].name) == 0) { if (pragma_tbl[i].deprecated != 0) werror(W_DEPRECATED_PRAGMA, pragma_tbl[i].name); - doPragma(pragma_tbl[i].id, s); - return 0; + ret = (*pragma_tbl[i].func)(pragma_tbl[i].id, pragma_tbl[i].name, s); + break; } } - werror(W_UNKNOWN_PRAGMA, cp); - return 0; + free_pragma_token(&token); + return ret; +} + +static int process_pragma(const char *s) +{ + struct pragma_token_s token; + + init_pragma_token(&token); + + s = get_pragma_token(s, &token); + if (0 != strcmp("#pragma", get_pragma_string(&token))) + { + /* Oops, womething went totally wrong - internal error */ + } + + /* skip spaces */ + while ('\n' != *s && isspace((unsigned char)*s)) + ++s; + + /* First give the port a chance */ + if (port->process_pragma && port->process_pragma(s)) + return 1; + + if (process_pragma_tbl(pragma_tbl, s)) + { + return 1; + } + else + { + werror(W_UNKNOWN_PRAGMA, s); + return 0; + } } /* will return 1 if the string is a part @@ -826,7 +1039,7 @@ static int isTargetKeyword(char *s) if (port->keywords == NULL) return 0; - + if (s[0] == '_' && s[1] == '_') { /* Keywords in the port's array have either 0 or 1 underscore, */ @@ -864,16 +1077,13 @@ int yyerror(char *s) { fflush(stdout); - if (mylineno && filename) { - if(options.vc_err_style) - fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n", - filename, mylineno, s, yytext, column); - else - fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n", - filename, mylineno, s ,yytext, column); - fatalError++; - } else { - /* this comes from an empy file, no problem */ - } + if(options.vc_err_style) + fprintf(stderr, "\n%s(%d) : %s: token -> '%s' ; column %d\n", + filename, mylineno, s, yytext, column); + else + fprintf(stderr, "\n%s:%d: %s: token -> '%s' ; column %d\n", + filename, mylineno, s ,yytext, column); + fatalError++; + return 0; } diff --git a/src/SDCCutil.c b/src/SDCCutil.c index da0223f6..4fd50580 100644 --- a/src/SDCCutil.c +++ b/src/SDCCutil.c @@ -23,9 +23,9 @@ -------------------------------------------------------------------------*/ #include +#include #ifdef _WIN32 -#include #include #endif #include @@ -325,5 +325,66 @@ size_t SDCCsnprintf(char *dst, size_t n, const char *fmt, ...) return len; } - #endif + +/** Pragma tokenizer + */ +void +init_pragma_token(struct pragma_token_s *token) +{ + dbuf_init(&token->dbuf, 16); + token->type = TOKEN_UNKNOWN; +} + +char * +get_pragma_token(const char *s, struct pragma_token_s *token) +{ + dbuf_set_size(&token->dbuf, 0); + + /* skip leading spaces */ + while (*s != '\n' && isspace(*s)) + ++s; + + if ('\0' == *s || '\n' == *s) + { + token->type = TOKEN_EOL; + } + else if (isdigit(*s)) + { + char *end; + + long val = strtol(s, &end, 0); + + if (end != s && ('\0' == *end || isspace(*s))) + { + token->val.int_val = val; + token->type = TOKEN_INT; + dbuf_append(&token->dbuf, s, end - s); + } + s = end; + } + else + { + while ('\0' != *s && !isspace(*s)) + { + dbuf_append(&token->dbuf, s, 1); + ++s; + } + + token->type = TOKEN_STR; + } + + return (char *)s; +} + +const char * +get_pragma_string(struct pragma_token_s *token) +{ + return dbuf_c_str(&token->dbuf); +} + +void +free_pragma_token(struct pragma_token_s *token) +{ + dbuf_destroy(&token->dbuf); +} diff --git a/src/SDCCutil.h b/src/SDCCutil.h index d8956d49..6d5f75f9 100644 --- a/src/SDCCutil.h +++ b/src/SDCCutil.h @@ -26,6 +26,7 @@ #define SDCCUTIL_H #include "SDCChasht.h" +#include "dbuf.h" #include /** Given an array of name, value string pairs creates a new hash @@ -112,4 +113,21 @@ size_t SDCCsnprintf(char *, size_t, const char *, ...); # error "Need at least one of snprintf, vsnprintf, vsprintf!" # endif +/** Pragma tokenizer + */ +enum pragma_token_e { TOKEN_UNKNOWN, TOKEN_STR, TOKEN_INT, TOKEN_EOL }; + +struct pragma_token_s { + enum pragma_token_e type; + struct dbuf_s dbuf; + union { + int int_val; + } val; +}; + +void init_pragma_token(struct pragma_token_s *token); +char *get_pragma_token(const char *s, struct pragma_token_s *token); +const char *get_pragma_string(struct pragma_token_s *token); +void free_pragma_token(struct pragma_token_s *token); + #endif diff --git a/src/pic/main.c b/src/pic/main.c index c194fbe3..ad5e3b30 100644 --- a/src/pic/main.c +++ b/src/pic/main.c @@ -99,16 +99,6 @@ _pic14_regparm (sym_link * l, bool reentrant) return 1; } -static int -_process_pragma(const char *sz) -{ -#if 0 - static const char *WHITE = " \t"; - char *ptr = strtok((char *)sz, WHITE); -#endif - return 1; -} - extern char *udata_section_name; static bool @@ -564,7 +554,7 @@ PORT pic_port = NULL, /* genInitStartup */ _pic14_reset_regparm, _pic14_regparm, - _process_pragma, /* process a pragma */ + NULL, /* process a pragma */ NULL, _hasNativeMulFor, hasExtBitOp, /* hasExtBitOp */ diff --git a/src/pic16/main.c b/src/pic16/main.c index 7c9bb831..13f3bc47 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -31,7 +31,6 @@ #include "SDCCutil.h" #include "glue.h" #include "pcode.h" -//#include "gen.h" static char _defaultRules[] = @@ -161,258 +160,347 @@ struct { } libflags = { 0, 0, 0, 0, 0 }; +enum { + P_MAXRAM = 1, + P_STACK, + P_CODE, + P_UDATA, + P_LIBRARY +}; + static int -_process_pragma(const char *sz) +do_pragma(int id, const char *name, const char *cp) { - static const char *WHITE = " \t\n"; - static const char *WHITECOMMA = " \t\n,"; - char *ptr = strtok((char *)sz, WHITE); + struct pragma_token_s token; + int err = 0; + int processed = 1; - /* #pragma maxram [maxram] */ - if (startsWith (ptr, "maxram")) { - char *maxRAM = strtok((char *)NULL, WHITE); + init_pragma_token(&token); - if (maxRAM != (char *)NULL) { - int maxRAMaddress; - value *maxRAMVal; + switch (id) + { + /* #pragma maxram [maxram] */ + case P_MAXRAM: + { + int max_ram; + + cp = get_pragma_token(cp, &token); + if (TOKEN_INT == token.type) + max_ram = token.val.int_val; + else + { + err = 1; + break; + } - maxRAMVal = constVal(maxRAM); - maxRAMaddress = (int)floatFromVal(maxRAMVal); - pic16_setMaxRAM(maxRAMaddress); - } + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - return 0; - } - - /* #pragma stack [stack-position] [stack-len] */ - if(startsWith(ptr, "stack")) { - char *stackPosS = strtok((char *)NULL, WHITE); - char *stackLenS = strtok((char *)NULL, WHITE); - value *stackPosVal; - value *stackLenVal; - regs *reg; - symbol *sym; - - if (!stackPosS) { - fprintf (stderr, "%s:%d: #pragma stack [stack-pos] [stack-length] -- stack-position missing\n", filename, lineno-1); - - return 0; /* considered an error */ + pic16_setMaxRAM(max_ram); } + break; - stackPosVal = constVal( stackPosS ); - stackPos = (unsigned int)floatFromVal( stackPosVal ); - - if(stackLenS) { - stackLenVal = constVal( stackLenS ); - stackLen = (unsigned int)floatFromVal( stackLenVal ); - } + /* #pragma stack [stack-position] [stack-len] */ + case P_STACK: + { + unsigned int stackPos, stackLen; + regs *reg; + symbol *sym; + + cp = get_pragma_token(cp, &token); + if (TOKEN_INT != token.type) + { + err = 1; + break; + } + stackPos = token.val.int_val; - if(stackLen < 1) { - stackLen = 64; - fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n", - filename, lineno-1, stackLen, stackLen); - } + cp = get_pragma_token(cp, &token); + if (TOKEN_INT != token.type) + { + err = 1; + break; + } + stackLen = token.val.int_val; - /* check sanity of stack */ - if ((stackPos >> 8) != ((stackPos+stackLen-1) >> 8)) { - fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n", - filename,lineno-1, stackPos, stackPos+stackLen-1); - } + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - if (pic16) { - if (stackPos < pic16->acsSplitOfs) { - fprintf (stderr, "%s:%u: warning: stack [0x%03X, 0x%03X] intersects with the access bank [0x000,0x%03x] -- this is highly discouraged!\n", - filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->acsSplitOfs); + if (stackLen < 1) { + stackLen = 64; + fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n", + filename, lineno, stackLen, stackLen); } - if (stackPos+stackLen > 0xF00 + pic16->acsSplitOfs) { - fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] intersects with special function registers [0x%03X,0xFFF]-- this is highly discouraged!\n", - filename, lineno-1, stackPos, stackPos+stackLen-1, 0xF00 + pic16->acsSplitOfs); + /* check sanity of stack */ + if ((stackPos >> 8) != ((stackPos + stackLen - 1) >> 8)) { + fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n", + filename, lineno, stackPos, stackPos + stackLen - 1); } - if (stackPos+stackLen > pic16->RAMsize) { - fprintf (stderr, "%s:%u: error: stack [0x%03X,0x%03X] is placed outside available memory [0x000,0x%03X]!\n", - filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->RAMsize-1); - exit(EXIT_FAILURE); - return 1; /* considered an error, but this reports "invalid pragma stack"... */ + if (pic16) { + if (stackPos < pic16->acsSplitOfs) { + fprintf (stderr, "%s:%u: warning: stack [0x%03X, 0x%03X] intersects with the access bank [0x000,0x%03x] -- this is highly discouraged!\n", + filename, lineno, stackPos, stackPos + stackLen - 1, pic16->acsSplitOfs); + } + + if (stackPos+stackLen > 0xF00 + pic16->acsSplitOfs) { + fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] intersects with special function registers [0x%03X,0xFFF]-- this is highly discouraged!\n", + filename, lineno, stackPos, stackPos + stackLen - 1, 0xF00 + pic16->acsSplitOfs); + } + + if (stackPos+stackLen > pic16->RAMsize) { + fprintf (stderr, "%s:%u: error: stack [0x%03X,0x%03X] is placed outside available memory [0x000,0x%03X]!\n", + filename, lineno, stackPos, stackPos + stackLen - 1, pic16->RAMsize-1); + err = 1; + break; + } } - } - reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL); - addSet(&pic16_fix_udata, reg); - - reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL); - addSet(&pic16_fix_udata, reg); - - sym = newSymbol("stack", 0); - sprintf(sym->rname, "_%s", sym->name); - addSet(&publics, sym); + reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL); + addSet(&pic16_fix_udata, reg); - sym = newSymbol("stack_end", 0); - sprintf(sym->rname, "_%s", sym->name); - addSet(&publics, sym); - - initsfpnt = 1; // force glue() to initialize stack/frame pointers */ + reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL); + addSet(&pic16_fix_udata, reg); - return 0; - } - - /* #pragma code [symbol] [location] */ - if(startsWith(ptr, "code")) { - char *symname = strtok((char *)NULL, WHITE); - char *location = strtok((char *)NULL, WHITE); - absSym *absS; - value *addr; - - if (!symname || !location) { - fprintf (stderr, "%s:%d: #pragma code [symbol] [location] -- symbol or location missing\n", filename, lineno-1); - exit (EXIT_FAILURE); - return 1; /* considered an error, but this reports "invalid pragma code"... */ - } + sym = newSymbol("stack", 0); + sprintf(sym->rname, "_%s", sym->name); + addSet(&publics, sym); - absS = Safe_calloc(1, sizeof(absSym)); - sprintf(absS->name, "_%s", symname); + sym = newSymbol("stack_end", 0); + sprintf(sym->rname, "_%s", sym->name); + addSet(&publics, sym); - addr = constVal( location ); - absS->address = (unsigned int)floatFromVal( addr ); - - if((absS->address % 2) != 0) { - absS->address--; - fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n", - filename, lineno-1, absS->address); + initsfpnt = 1; // force glue() to initialize stack/frame pointers */ } + break; - addSet(&absSymSet, absS); -// fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n", -// __FILE__, __LINE__, symname, absS->address); + /* #pragma code [symbol] [location] */ + case P_CODE: + { + absSym *absS; + + cp = get_pragma_token(cp, &token); + if (TOKEN_STR != token.type) + goto code_err; + + absS = Safe_calloc(1, sizeof(absSym)); + sprintf(absS->name, "_%s", get_pragma_string(&token)); + + cp = get_pragma_token(cp, &token); + if (TOKEN_INT != token.type) + { + code_err: + //fprintf (stderr, "%s:%d: #pragma code [symbol] [location] -- symbol or location missing\n", filename, lineno); + err = 1; + break; + } + absS->address = token.val.int_val; - return 0; - } + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } - /* #pragma udata [section-name] [symbol] */ - if(startsWith(ptr, "udata")) { - char *sectname = strtok((char *)NULL, WHITE); - char *symname = strtok((char *)NULL, WHITE); - symbol *nsym; - sectSym *ssym; - sectName *snam; - int found=0; - - if (!symname || !sectname) { - fprintf (stderr, "%s:%d: #pragma udata [section-name] [symbol] -- section-name or symbol missing!\n", filename, lineno-1); - exit (EXIT_FAILURE); - return 1; /* considered an error, but this reports "invalid pragma code"... */ + if ((absS->address % 2) != 0) { + absS->address--; + fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n", + filename, lineno, absS->address); + } + + addSet(&absSymSet, absS); +// fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n", +// __FILE__, __LINE__, symname, absS->address); } - - while(symname) { - ssym = Safe_calloc(1, sizeof(sectSym)); - ssym->name = Safe_calloc(1, strlen(symname)+2); - sprintf(ssym->name, "%s%s", port->fun_prefix, symname); - ssym->reg = NULL; + break; + + /* #pragma udata [section-name] [symbol] */ + case P_UDATA: + { + char *sectname; + const char *symname; + symbol *nsym; + sectSym *ssym; + sectName *snam; + int found = 0; + + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL == token.type) + goto udata_err; + + sectname = Safe_strdup(get_pragma_string(&token)); + + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL == token.type) + { + udata_err: + //fprintf (stderr, "%s:%d: #pragma udata [section-name] [symbol] -- section-name or symbol missing!\n", filename, lineno); + err = 1; + break; + } + symname = get_pragma_string(&token); + + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } + + while (symname) { + ssym = Safe_calloc(1, sizeof(sectSym)); + ssym->name = Safe_calloc(1, strlen(symname) + 2); + sprintf(ssym->name, "%s%s", port->fun_prefix, symname); + ssym->reg = NULL; - addSet(§Syms, ssym); + addSet(§Syms, ssym); - nsym = newSymbol(symname, 0); - strcpy(nsym->rname, ssym->name); + nsym = newSymbol((char *)symname, 0); + strcpy(nsym->rname, ssym->name); #if 0 - checkAddSym(&publics, nsym); + checkAddSym(&publics, nsym); #endif - found = 0; - for(snam=setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) { - if(!strcmp(sectname, snam->name)){ found=1; break; } - } - - if(!found) { - snam = Safe_calloc(1, sizeof(sectName)); - snam->name = Safe_strdup( sectname ); - snam->regsSet = NULL; - - addSet(§Names, snam); - } - - ssym->section = snam; - + found = 0; + for (snam = setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) { + if (!strcmp(sectname, snam->name)){ found=1; break; } + } + + if(!found) { + snam = Safe_calloc(1, sizeof(sectName)); + snam->name = Safe_strdup(sectname); + snam->regsSet = NULL; + + addSet(§Names, snam); + } + + ssym->section = snam; + #if 0 - fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__, - ssym->name, snam->name, snam); + fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__, + ssym->name, snam->name, snam); #endif - symname = strtok((char *)NULL, WHITE); - } + cp = get_pragma_token(cp, &token); + symname = (TOKEN_EOL != token.type) ? get_pragma_string(&token) : NULL; + } - return 0; - } - - /* #pragma wparam function1[, function2[,...]] */ - if(startsWith(ptr, "wparam")) { - char *fname = strtok((char *)NULL, WHITECOMMA); - - - while(fname) { - fprintf(stderr, "PIC16 Warning: `%s' wparam pragma is obsolete. use function attribute `wparam' instead.\n", fname); - addSet(&wparamList, Safe_strdup(fname)); - -// debugf("passing with WREG to %s\n", fname); - fname = strtok((char *)NULL, WHITECOMMA); + Safe_free(sectname); } - - return 0; - } - - /* #pragma library library_module */ - if(startsWith(ptr, "library")) { - char *lmodule = strtok((char *)NULL, WHITE); - - if(lmodule) { - /* lmodule can be: - * c link the C library - * math link the math library - * io link the IO library - * debug link the debug libary - * anything else, will link as-is */ - - if(!strcmp(lmodule, "c"))libflags.want_libc = 1; - else if(!strcmp(lmodule, "math"))libflags.want_libm = 1; - else if(!strcmp(lmodule, "io"))libflags.want_libio = 1; - else if(!strcmp(lmodule, "debug"))libflags.want_libdebug = 1; - else if(!strcmp(lmodule, "ignore"))libflags.ignore = 1; - else { - if(!libflags.ignore) { - fprintf(stderr, "link library %s\n", lmodule); - addSetHead(&libFilesSet, lmodule); - } + break; + + /* #pragma library library_module */ + case P_LIBRARY: + { + const char *lmodule; + + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + lmodule = get_pragma_string(&token); + + /* lmodule can be: + * c link the C library + * math link the math library + * io link the IO library + * debug link the debug libary + * anything else, will link as-is */ + + if(!strcmp(lmodule, "c"))libflags.want_libc = 1; + else if(!strcmp(lmodule, "math")) + libflags.want_libm = 1; + else if(!strcmp(lmodule, "io")) + libflags.want_libio = 1; + else if(!strcmp(lmodule, "debug")) + libflags.want_libdebug = 1; + else if(!strcmp(lmodule, "ignore")) + libflags.ignore = 1; + else + { + if(!libflags.ignore) + { + fprintf(stderr, "link library %s\n", lmodule); + addSetHead(&libFilesSet, (char *)lmodule); + } + } + } + else + { + err = 1; + break; + } + + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } } - } - - return 0; - } - + break; + #if 0 /* This is an experimental code for #pragma inline and is temporarily disabled for 2.5.0 release */ - if(startsWith(ptr, "inline")) { - char *tmp = strtok((char *)NULL, WHITECOMMA); + case P_INLINE: + { + char *tmp = strtok((char *)NULL, WHITECOMMA); - while(tmp) { - addSet(&asmInlineMap, Safe_strdup( tmp )); - tmp = strtok((char *)NULL, WHITECOMMA); - } + while(tmp) { + addSet(&asmInlineMap, Safe_strdup( tmp )); + tmp = strtok((char *)NULL, WHITECOMMA); + } - { - char *s; + { + char *s; for(s = setFirstItem(asmInlineMap); s ; s = setNextItem(asmInlineMap)) { debugf("inline asm: `%s'\n", s); } + } } - - return 0; - } + break; #endif /* 0 */ - return 1; + default: + processed = 0; + break; + } + + get_pragma_token(cp, &token); + + if (1 == err) + werror(W_BAD_PRAGMA_ARGUMENTS, name); + + free_pragma_token(&token); + return processed; +} + +static struct pragma_s pragma_tbl[] = { + { "maxram", P_MAXRAM, 0, do_pragma }, + { "stack", P_STACK, 0, do_pragma }, + { "code", P_CODE, 0, do_pragma }, + { "udata", P_UDATA, 0, do_pragma }, + { "library", P_LIBRARY, 0, do_pragma }, +/*{ "inline", P_INLINE, 0, do_pragma }, */ + { NULL, 0, 0, NULL }, + }; + +static int +_process_pragma(const char *s) +{ + return process_pragma_tbl(pragma_tbl, s); } #define REP_UDATA "--preplace-udata-with=" diff --git a/src/port.h b/src/port.h index c980c607..0b0ae758 100644 --- a/src/port.h +++ b/src/port.h @@ -15,9 +15,9 @@ #define TARGET_ID_AVR 4 #define TARGET_ID_DS390 5 #define TARGET_ID_PIC 6 -#define TARGET_ID_PIC16 7 +#define TARGET_ID_PIC16 7 #define TARGET_ID_XA51 9 -#define TARGET_ID_DS400 10 +#define TARGET_ID_DS400 10 #define TARGET_ID_HC08 11 /* Macro to test the target we are compiling for. @@ -30,22 +30,34 @@ #define TARGET_IS_DS390 (port->id==TARGET_ID_DS390) #define TARGET_IS_DS400 (port->id==TARGET_ID_DS400) #define TARGET_IS_PIC (port->id==TARGET_ID_PIC) -#define TARGET_IS_PIC16 (port->id==TARGET_ID_PIC16) +#define TARGET_IS_PIC16 (port->id==TARGET_ID_PIC16) #define TARGET_IS_XA51 (port->id==TARGET_ID_XA51) #define TARGET_IS_HC08 (port->id==TARGET_ID_HC08) -#define MAX_BUILTIN_ARGS 16 +#define MAX_BUILTIN_ARGS 16 /* definition of builtin functions */ typedef struct builtins -{ - char *name ; /* name of builtin function */ - char *rtype; /* return type as string : see typefromStr */ - int nParms; /* number of parms : max 8 */ + { + char *name; /* name of builtin function */ + char *rtype; /* return type as string : see typefromStr */ + int nParms; /* number of parms : max 8 */ char *parm_types[MAX_BUILTIN_ARGS]; /* each parm type as string : see typeFromStr */ -} builtins ; + } builtins; struct ebbIndex; +/* pragma structure */ +struct pragma_s + { + const char *name; + int id; + char deprecated; + int (*func)(int id, const char *name, const char *cp); + }; + +/* defined in SDCClex.lex */ +int process_pragma_tbl(const struct pragma_s *pragma_tbl, const char *s); + /* Processor specific names */ typedef struct { @@ -64,15 +76,15 @@ typedef struct { /** Pointer to glue function */ void (*do_glue)(void); - /** TRUE if all types of glue functions should be inserted into - the file that also defines main. - We dont want this in cases like the z80 where the startup - code is provided by a seperate module. - */ - bool glue_up_main; - /* OR of MODEL_* */ - int supported_models; - int default_model; + /** TRUE if all types of glue functions should be inserted into + the file that also defines main. + We dont want this in cases like the z80 where the startup + code is provided by a seperate module. + */ + bool glue_up_main; + /* OR of MODEL_* */ + int supported_models; + int default_model; } general; @@ -84,15 +96,15 @@ typedef struct /** Alternate macro based form. */ const char *mcmd; /** Arguments for debug mode. */ - const char *debug_opts; + const char *debug_opts; /** Arguments for normal assembly mode. */ - const char *plain_opts; - /* print externs as global */ - int externGlobal; - /* assembler file extension */ - const char *file_ext; + const char *plain_opts; + /* print externs as global */ + int externGlobal; + /* assembler file extension */ + const char *file_ext; /** If non-null will be used to execute the assembler. */ - void (*do_assemble) (set *); + void (*do_assemble) (set *); } assembler; @@ -100,41 +112,41 @@ typedef struct struct { /** Command to run (eg link-z80) */ - const char **cmd; + const char **cmd; /** Alternate macro based form. */ const char *mcmd; /** If non-null will be used to execute the link. */ - void (*do_link) (void); + void (*do_link) (void); /** Extension for object files (.rel, .obj, ...) */ - const char *rel_ext; + const char *rel_ext; /** 1 if port needs the .lnk file, 0 otherwise */ - const int needLinkerScript; + const int needLinkerScript; } linker; struct { /** Default peephole rules */ - char *default_rules; - int (*getSize)(lineNode *line); - bitVect * (*getRegsRead)(lineNode *line); - bitVect * (*getRegsWritten)(lineNode *line); + char *default_rules; + int (*getSize)(lineNode *line); + bitVect * (*getRegsRead)(lineNode *line); + bitVect * (*getRegsWritten)(lineNode *line); } peep; /** Basic type sizes */ struct { - int char_size; - int short_size; + int char_size; + int short_size; unsigned int int_size; - int long_size; - int ptr_size; //near - int fptr_size; //far - int gptr_size; //generic - int bit_size; - int float_size; - int max_base_size; + int long_size; + int ptr_size; //near + int fptr_size; //far + int gptr_size; //generic + int bit_size; + int float_size; + int max_base_size; } s; @@ -147,37 +159,37 @@ typedef struct int tag_code; } gp_tags; - + /** memory regions related stuff */ struct { - const char *xstack_name; - const char *istack_name; - const char *code_name; - const char *data_name; - const char *idata_name; - const char *pdata_name; - const char *xdata_name; - const char *bit_name; - const char *reg_name; - const char *static_name; - const char *overlay_name; - const char *post_static_name; - const char *home_name; - const char *xidata_name; // initialized xdata - const char *xinit_name; // a code copy of xidata - const char *const_name; // const data (code or not) - const char *cabs_name; // const absolute data (code or not) - struct memmap *default_local_map; // default location for auto vars - struct memmap *default_globl_map; // default location for globl vars - int code_ro; /* code space read-only 1=yes */ + const char *xstack_name; + const char *istack_name; + const char *code_name; + const char *data_name; + const char *idata_name; + const char *pdata_name; + const char *xdata_name; + const char *bit_name; + const char *reg_name; + const char *static_name; + const char *overlay_name; + const char *post_static_name; + const char *home_name; + const char *xidata_name; // initialized xdata + const char *xinit_name; // a code copy of xidata + const char *const_name; // const data (code or not) + const char *cabs_name; // const absolute data (code or not) + struct memmap *default_local_map; // default location for auto vars + struct memmap *default_globl_map; // default location for globl vars + int code_ro; /* code space read-only 1=yes */ } mem; struct { - void (*genExtraAreaDeclaration)(FILE *, bool); - void (*genExtraAreaLinkOptions)(FILE *); + void (*genExtraAreaDeclaration)(FILE *, bool); + void (*genExtraAreaLinkOptions)(FILE *); } extraAreas; @@ -185,18 +197,18 @@ typedef struct struct { /** -1 for grows down (z80), +1 for grows up (mcs51) */ - int direction; + int direction; /** Extra overhead when calling between banks */ - int bank_overhead; + int bank_overhead; /** Extra overhead when the function is an ISR */ - int isr_overhead; + int isr_overhead; /** Standard overhead for a function call */ - int call_overhead; + int call_overhead; /** Re-enterant space */ - int reent_overhead; - /** 'banked' call overhead. - Mild overlap with bank_overhead */ - int banked_overhead; + int reent_overhead; + /** 'banked' call overhead. + Mild overlap with bank_overhead */ + int banked_overhead; } stack; @@ -212,19 +224,19 @@ typedef struct struct { - void (*emitDebuggerSymbol) (char *); - struct - { - int (*regNum) (struct regs *); - bitVect * cfiSame; - bitVect * cfiUndef; - int addressSize; - int regNumRet; - int regNumSP; - int regNumBP; - int offsetSP; - } - dwarf; + void (*emitDebuggerSymbol) (char *); + struct + { + int (*regNum) (struct regs *); + bitVect * cfiSame; + bitVect * cfiUndef; + int addressSize; + int regNumRet; + int regNumSP; + int regNumBP; + int offsetSP; + } + dwarf; } debugger; @@ -243,8 +255,8 @@ typedef struct const char *fun_prefix; /** Called once the processor target has been selected. - First chance to initalise and set any port specific variables. - 'port' is set before calling this. May be NULL. + First chance to initalise and set any port specific variables. + 'port' is set before calling this. May be NULL. */ void (*init) (void); /** Parses one option + its arguments */ @@ -257,13 +269,13 @@ typedef struct /** Called after all the options have been parsed. */ void (*finaliseOptions) (void); /** Called after the port has been selected but before any - options are parsed. */ + options are parsed. */ void (*setDefaultOptions) (void); /** Does the dirty work. */ void (*assignRegisters) (struct ebbIndex *); /** Returns the register name of a symbol. - Used so that 'regs' can be an incomplete type. */ + Used so that 'regs' can be an incomplete type. */ const char *(*getRegName) (struct regs * reg); /* list of keywords that are used by this @@ -287,11 +299,11 @@ typedef struct void (*genInitStartup) (FILE * of); /* parameter passing in register related functions */ - void (*reset_regparms) (void); /* reset the register count */ - int (*reg_parm) (struct sym_link *, bool reentrant); /* will return 1 if can be passed in register */ + void (*reset_regparms) (void); /* reset the register count */ + int (*reg_parm) (struct sym_link *, bool reentrant); /* will return 1 if can be passed in register */ /** Process the pragma string 'sz'. Returns 0 if recognised and - processed, 1 otherwise. May be NULL. + processed, 1 otherwise. May be NULL. */ int (*process_pragma) (const char *sz); @@ -324,18 +336,18 @@ typedef struct bool little_endian; /* condition transformations */ - bool lt_nge; /* transform (a < b) to !(a >= b) */ - bool gt_nle; /* transform (a > b) to !(a <= b) */ - bool le_ngt; /* transform (a <= b) to !(a > b) */ - bool ge_nlt; /* transform (a >= b) to !(a < b) */ - bool ne_neq; /* transform a != b --> ! (a == b) */ - bool eq_nne; /* transform a == b --> ! (a != b) */ + bool lt_nge; /* transform (a < b) to !(a >= b) */ + bool gt_nle; /* transform (a > b) to !(a <= b) */ + bool le_ngt; /* transform (a <= b) to !(a > b) */ + bool ge_nlt; /* transform (a >= b) to !(a < b) */ + bool ne_neq; /* transform a != b --> ! (a == b) */ + bool eq_nne; /* transform a == b --> ! (a != b) */ bool arrayInitializerSuppported; bool (*cseOk) (iCode *ic, iCode *pdic); builtins *builtintable; /* table of builtin functions */ - int unqualified_pointer; /* unqualified pointers type is */ - int reset_labelKey ; /* reset Label no 1 at the start of a function */ + int unqualified_pointer; /* unqualified pointers type is */ + int reset_labelKey ; /* reset Label no 1 at the start of a function */ int globals_allowed ; /* global & static locals not allowed ? 0 ONLY TININative*/ #define PORT_MAGIC 0xAC32 /** Used at runtime to detect if this structure has been completly filled in. */ diff --git a/src/z80/main.c b/src/z80/main.c index 88c6faa1..a5e84064 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -138,78 +138,136 @@ _reg_parm (sym_link * l, bool reentrant) } } } + +enum { + P_BANK = 1, + P_PORTMODE +}; + static int -_process_pragma (const char *sz) +do_pragma(int id, const char *name, const char *cp) { - if( startsWith( sz, "bank=" ) || startsWith( sz, "bank " )) - { - char buffer[128]; - - if (sz[4]=='=') - werror(W_DEPRECATED_PRAGMA, "bank="); - - strncpy (buffer, sz + 5, sizeof (buffer)); - buffer[sizeof (buffer) - 1 ] = '\0'; - chomp (buffer); - if (isdigit ((unsigned char)buffer[0])) - { + struct pragma_token_s token; + int err = 0; + int processed = 1; - } - else if (!strcmp (buffer, "BASE")) - { - strcpy (buffer, "HOME"); - } - if (isdigit ((unsigned char)buffer[0])) + init_pragma_token(&token); + + switch (id) { - /* Arg was a bank number. Handle in an ASM independent - way. */ - char num[128]; - strncpy (num, sz + 5, sizeof (num)); - num[sizeof (num) -1] = '\0'; - chomp (num); - - switch (_G.asmType) + case P_BANK: { - case ASM_TYPE_ASXXXX: - sprintf (buffer, "CODE_%s", num); - break; - case ASM_TYPE_RGBDS: - sprintf (buffer, "CODE,BANK[%s]", num); - break; - case ASM_TYPE_ISAS: - /* PENDING: what to use for ISAS? */ - sprintf (buffer, "CODE,BANK(%s)", num); - break; - default: - wassert (0); + char buffer[128]; + + cp = get_pragma_token(cp, &token); + + switch (token.type) + { + case TOKEN_EOL: + err = 1; + break; + + case TOKEN_INT: + switch (_G.asmType) + { + case ASM_TYPE_ASXXXX: + sprintf(buffer, "CODE_%d", token.val.int_val); + break; + + case ASM_TYPE_RGBDS: + sprintf(buffer, "CODE,BANK[%d]", token.val.int_val); + break; + + case ASM_TYPE_ISAS: + /* PENDING: what to use for ISAS? */ + sprintf (buffer, "CODE,BANK(%d)", token.val.int_val); + break; + + default: + wassert (0); + } + break; + + default: + { + const char *str = get_pragma_string(&token); + + strcpy(buffer, (0 == strcmp("BASE", str)) ? "HOME" : str); + } + break; + } + + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } + + gbz80_port.mem.code_name = Safe_strdup (buffer); + code->sname = gbz80_port.mem.code_name; + options.code_seg = gbz80_port.mem.code_name; } - } - gbz80_port.mem.code_name = Safe_strdup (buffer); - code->sname = gbz80_port.mem.code_name; - options.code_seg = gbz80_port.mem.code_name; - return 0; - } - else if( startsWith( sz, "portmode=" ) || startsWith( sz, "portmode " )) - { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */ - char bfr[128]; + break; - if (sz[8]=='=') - werror(W_DEPRECATED_PRAGMA, "portmode="); + case P_PORTMODE: + { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */ + const char *str; - strncpy( bfr, sz + 9, sizeof (bfr)); - bfr[sizeof (bfr) - 1] = '\0'; - chomp( bfr ); + cp = get_pragma_token(cp, &token); - if ( !strcmp( bfr, "z80" )){ z80_opts.port_mode = 80; } - else if( !strcmp( bfr, "z180" )){ z80_opts.port_mode = 180; } - else if( !strcmp( bfr, "save" )){ z80_opts.port_back = z80_opts.port_mode; } - else if( !strcmp( bfr, "restore" )){ z80_opts.port_mode = z80_opts.port_back; } - else return( 1 ); + if (TOKEN_EOL == token.type) + { + err = 1; + break; + } + + str = get_pragma_string(&token); + + cp = get_pragma_token(cp, &token); + if (TOKEN_EOL != token.type) + { + err = 1; + break; + } + + if (!strcmp(str, "z80")) + { z80_opts.port_mode = 80; } + else if(!strcmp(str, "z180")) + { z80_opts.port_mode = 180; } + else if(!strcmp(str, "save")) + { z80_opts.port_back = z80_opts.port_mode; } + else if(!strcmp(str, "restore" )) + { z80_opts.port_mode = z80_opts.port_back; } + else + err = 1; + } + break; - return( 0 ); + default: + processed = 0; + break; } - return 1; + get_pragma_token(cp, &token); + + if (1 == err) + werror(W_BAD_PRAGMA_ARGUMENTS, name); + + free_pragma_token(&token); + return processed; +} + +static struct pragma_s pragma_tbl[] = { + { "bank", P_BANK, 0, do_pragma }, + { "portmode", P_PORTMODE, 0, do_pragma }, + { NULL, 0, 0, NULL }, + }; + +static int +_process_pragma(const char *s) +{ + return process_pragma_tbl(pragma_tbl, s); } static const char *_gbz80_rgbasmCmd[] = diff --git a/support/Util/SDCCerr.c b/support/Util/SDCCerr.c index 08240025..ef590fb9 100644 --- a/support/Util/SDCCerr.c +++ b/support/Util/SDCCerr.c @@ -434,6 +434,8 @@ struct "flexible array in otherwise empty struct" }, { W_EMPTY_SOURCE_FILE, ERROR_LEVEL_WARNING, "ISO C forbids an empty source file" }, +{ W_BAD_PRAGMA_ARGUMENTS, ERROR_LEVEL_WARNING, + "#pragma %s: bad argument(s); pragma ignored" }, }; /* diff --git a/support/Util/SDCCerr.h b/support/Util/SDCCerr.h index 927998cc..ba829ac0 100644 --- a/support/Util/SDCCerr.h +++ b/support/Util/SDCCerr.h @@ -206,6 +206,7 @@ SDCCERR - SDCC Standard error handler #define E_FLEXARRAY_NOTATEND 188 /* flexible array member not at end of struct */ #define E_FLEXARRAY_INEMPTYSTRCT 189 /* flexible array in otherwise empty struct */ #define W_EMPTY_SOURCE_FILE 190 /* ISO C forbids an empty source file */ +#define W_BAD_PRAGMA_ARGUMENTS 191 /* #pragma %s: bad argument(s); pragma ignored */ #define MAX_ERROR_WARNING 256 /* size of disable warnings array */ diff --git a/support/Util/dbuf.c b/support/Util/dbuf.c index 5ee200ac..44762d8c 100644 --- a/support/Util/dbuf.c +++ b/support/Util/dbuf.c @@ -1,6 +1,6 @@ /* dbuf.c - Dynamic buffer implementation - version 1.1.2, May 22th, 2006 + version 1.1.3, December 17th, 2006 Copyright (c) 2002-2006 Borut Razem @@ -105,7 +105,7 @@ int dbuf_set_size(struct dbuf_s *dbuf, size_t size) { assert(dbuf != NULL); assert(dbuf->alloc != 0); - assert(size < dbuf->len); + assert(size <= dbuf->len); if (size <= dbuf->len) { dbuf->len = size; -- 2.30.2