From e5cc07203887d0f0a6e70c0cea034379f5c40d2c Mon Sep 17 00:00:00 2001 From: kvigor Date: Wed, 9 Feb 2000 18:09:01 +0000 Subject: [PATCH] First pass at DS80C390 flat mode support git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@91 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- device/lib/incl.mk | 2 +- src/SDCCerr.c | 3 +- src/SDCCerr.h | 1 + src/SDCCglobl.h | 7 +++- src/SDCCglue.c | 31 ++++++++++++---- src/SDCCmain.c | 89 ++++++++++++++++++++++++++++++++++++---------- src/common.h | 1 + src/mcs51/gen.c | 53 +++++++++++++++++++++------ src/mcs51/main.c | 60 ++++++++++++++++++++++++++++--- src/mcs51/ralloc.c | 6 ++-- src/port.h | 11 +++++- src/z80/main.c | 6 ++-- 12 files changed, 222 insertions(+), 48 deletions(-) diff --git a/device/lib/incl.mk b/device/lib/incl.mk index e1cae0c3..18caa5eb 100644 --- a/device/lib/incl.mk +++ b/device/lib/incl.mk @@ -1 +1 @@ -MODELS = small large +MODELS = small large flat24 diff --git a/src/SDCCerr.c b/src/SDCCerr.c index de85badc..61f0b5e4 100644 --- a/src/SDCCerr.c +++ b/src/SDCCerr.c @@ -142,7 +142,8 @@ struct { { WARNING,"warning *** unreachable code %s(%d)\n"}, { WARNING,"warning *** non-pointer type cast to _generic pointer\n"}, { WARNING,"warning *** possible code generation error at line %d,\n send source to sandeep.dutta@usa.net\n"}, -{ WARNING,"warning *** pointer types incompatible \n" } +{ WARNING,"warning *** pointer types incompatible \n" }, +{ WARNING,"warning *** unknown memory model at %s : %d\n" }, }; /****************************************************************************/ diff --git a/src/SDCCerr.h b/src/SDCCerr.h index 61207652..136d7a5f 100644 --- a/src/SDCCerr.h +++ b/src/SDCCerr.h @@ -130,4 +130,5 @@ #define W_NONPTR2_GENPTR 127 /* non pointer cast to generic pointer */ #define W_POSSBUG 128 /* possible code generation error */ #define W_PTR_ASSIGN 129 /* incampatible pointer assignment */ +#define W_UNKNOWN_MODEL 130 /* Unknown memory model */ void werror(int, ...); diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h index 4b9e21cc..3f0c4bdd 100644 --- a/src/SDCCglobl.h +++ b/src/SDCCglobl.h @@ -163,9 +163,14 @@ struct optimize { unsigned noLoopReverse :1; } ; +/* Values for options.model. */ +#define MODEL_SMALL 0 +#define MODEL_LARGE 1 +#define MODEL_FLAT24 2 + /* other command line options */ struct options { - int model : 1 ; /* LARGE == 1 */ + int model : 3 ; /* see MODEL_* defines above */ int stackAuto : 3 ; /* Stack Automatic */ int useXstack : 3 ; /* use Xternal Stack */ int genericPtr: 1 ; /* use generic pointers */ diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 22db18f9..131a958f 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -30,6 +30,8 @@ symbol *interrupts[256]; void printIval (symbol *, link *, initList *, FILE *); extern int noAlloc; set *publics = NULL; /* public variables */ + +/* TODO: this should be configurable (DS803C90 uses more than 6) */ int maxInterrupts = 6; extern int maxRegBank ; symbol *mainf; @@ -719,16 +721,25 @@ void createInterruptVect (FILE * vFile) fprintf (vFile, "\t.area\t%s\n", CODE_NAME); fprintf (vFile, "__interrupt_vect:\n"); + - fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n"); + if (!port->genIVT || ! (port->genIVT(vFile, interrupts, maxInterrupts))) + { + /* "generic" interrupt table header (if port doesn't specify one). + * + * Look suspiciously like 8051 code to me... + */ + fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n"); - /* now for the other interrupts */ - for (; i < maxInterrupts; i++) { - if (interrupts[i]) - fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname); - else - fprintf (vFile, "\treti\n\t.ds\t7\n"); + + /* now for the other interrupts */ + for (; i < maxInterrupts; i++) { + if (interrupts[i]) + fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname); + else + fprintf (vFile, "\treti\n\t.ds\t7\n"); + } } } @@ -902,6 +913,12 @@ void glue () /* print module name */ fprintf (asmFile, "\t.module %s\n", moduleName); + /* Let the port generate any global directives, etc. */ + if (port->genAssemblerPreamble) + { + port->genAssemblerPreamble(asmFile); + } + /* print the global variables in this module */ printPublics (asmFile); diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 12d340da..65ddc3c4 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -71,6 +71,7 @@ char *preOutName; #define OPTION_LARGE_MODEL "-model-large" #define OPTION_SMALL_MODEL "-model-small" +#define OPTION_FLAT24_MODEL "-model-flat24" #define OPTION_STACK_AUTO "-stack-auto" #define OPTION_XSTACK "-xstack" #define OPTION_GENERIC "-generic" @@ -296,8 +297,8 @@ static void setDefaultOptions() int i ; for ( i = 0 ; i < 128 ; i++) - preArgv[i] = linkOptions [i] = - asmOptions[i] = relFiles[i] = libFiles[i] = + preArgv[i] = asmOptions [i] = + linkOptions[i] = relFiles[i] = libFiles[i] = libPaths[i] = NULL ; /* first the options part */ @@ -439,14 +440,19 @@ int parseCmdLine ( int argc, char **argv ) } if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) { - options.model = 1; + options.model = MODEL_LARGE; continue; } if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) { - options.model = 0; + options.model = MODEL_SMALL; continue; } + + if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) { + options.model = MODEL_FLAT24; + continue; + } if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) { options.stackAuto = 1; @@ -716,8 +722,14 @@ int parseCmdLine ( int argc, char **argv ) continue; } - if (!port->parseOption(&argc, argv)) + if (!port->parseOption(&argc, argv, &i)) + { werror(W_UNKNOWN_OPTION,argv[i]); + } + else + { + continue; + } } /* these are undocumented options */ @@ -904,13 +916,13 @@ int parseCmdLine ( int argc, char **argv ) break ; default: - if (!port->parseOption(&argc, argv)) + if (!port->parseOption(&argc, argv, &i)) werror(W_UNKNOWN_OPTION,argv[i]); } continue ; } - if (!port->parseOption(&argc, argv)) { + if (!port->parseOption(&argc, argv, &i)) { /* no option must be a filename */ processFile(argv[i]); } @@ -979,6 +991,7 @@ static void linkEdit (char **envp) { FILE *lnkfile ; char *argv[128]; + char *segName, *c; int i; if (!srcFileName) @@ -1000,24 +1013,50 @@ static void linkEdit (char **envp) /*if (options.debug) */ fprintf(lnkfile,"-z\n"); + +#define WRITE_SEG_LOC(N, L) \ + segName = strdup(N); \ + c = strtok(segName, " \t"); \ + fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \ + if (segName) { free(segName); } + /* code segment start */ - fprintf (lnkfile,"-b CODE = 0x%04x\n",options.code_loc); - /* data segment start */ - fprintf (lnkfile,"-b DSEG = 0x%04x\n",options.data_loc); + WRITE_SEG_LOC(CODE_NAME, options.code_loc); + + /* data segment start */ + WRITE_SEG_LOC(DATA_NAME, options.data_loc); + /* xdata start */ - fprintf (lnkfile,"-b XSEG = 0x%04x\n",options.xdata_loc); + WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc); + /* indirect data */ - fprintf (lnkfile,"-b ISEG = 0x%04x\n",options.idata_loc); + WRITE_SEG_LOC(IDATA_NAME, options.idata_loc); + /* bit segment start */ - fprintf (lnkfile,"-b BSEG = 0x%04x\n",0); + WRITE_SEG_LOC(BIT_NAME, 0); /* add the extra linker options */ for (i=0; linkOptions[i] ; i++) fprintf(lnkfile,"%s\n",linkOptions[i]); /* standard library path */ - fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/, - ( (options.model==0) ? "small": "large")); + switch(options.model) + { + case MODEL_SMALL: + c = "small"; + break; + case MODEL_LARGE: + c = "large"; + break; + case MODEL_FLAT24: + c = "flat24"; + break; + default: + werror(W_UNKNOWN_MODEL, __FILE__, __LINE__); + c = "unknown"; + break; + } + fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c); /* other library paths if specified */ for (i = 0 ; i < nlibPaths ; i++ ) @@ -1096,10 +1135,22 @@ static int preProcess (char **envp) _addToList(preArgv, "-DSDCC_STACK_AUTO"); /* set the macro for large model */ - if ( options.model ) - _addToList(preArgv, "-DSDCC_MODEL_LARGE"); - else - _addToList(preArgv, "-DSDCC_MODEL_SMALL"); + switch(options.model) + { + case MODEL_LARGE: + _addToList(preArgv, "-DSDCC_MODEL_LARGE"); + break; + case MODEL_SMALL: + _addToList(preArgv, "-DSDCC_MODEL_SMALL"); + break; + case MODEL_FLAT24: + _addToList(preArgv, "-DSDCC_MODEL_FLAT24"); + break; + default: + werror(W_UNKNOWN_MODEL, __FILE__, __LINE__); + break; + } + /* add port (processor information to processor */ sprintf(procDef,"-DSDCC_%s",port->target); diff --git a/src/common.h b/src/common.h index 30872eae..ea5ac522 100644 --- a/src/common.h +++ b/src/common.h @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "SDCCglobl.h" diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 47758e70..6f3190ff 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -145,8 +145,9 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) instruction, in which case we are in trouble */ if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) && (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) + { goto endOfWorld; - + } r0ou = bitVectBitValue(ic->rMask,R0_IDX); r1ou = bitVectBitValue(ic->rMask,R1_IDX); @@ -155,6 +156,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) if (!r0iu && !r0ou) { ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX); (*aopp)->type = AOP_R0; + return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx(R0_IDX); } @@ -162,6 +164,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) if (!r1iu && !r1ou) { ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX); (*aopp)->type = AOP_R1; + return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx(R1_IDX); } @@ -174,7 +177,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) mcs51_regWithIdx(R0_IDX)->dname); _G.r0Pushed++ ; } - + ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX); (*aopp)->type = AOP_R0; @@ -190,16 +193,15 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) mcs51_regWithIdx(R1_IDX)->dname); _G.r1Pushed++ ; } - + ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX); (*aopp)->type = AOP_R1; return mcs51_regWithIdx(R1_IDX); } - endOfWorld : /* I said end of world but not quite end of world yet */ - /* if this is a result then we canpush it on the stack*/ + /* if this is a result then we can push it on the stack*/ if (result) { (*aopp)->type = AOP_STK; return NULL; @@ -1904,7 +1906,8 @@ static void genFunction (iCode *ic) emitcode ("push","dpl"); if (!inExcludeList("dph")) emitcode ("push","dph"); - + if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) + emitcode ("push", "dpx"); /* if this isr has no bank i.e. is going to run with bank 0 , then we need to save more registers :-) */ @@ -2068,6 +2071,8 @@ static void genEndFunction (iCode *ic) } } + if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) + emitcode ("pop", "dpx"); if (!inExcludeList("dph")) emitcode ("pop","dph"); if (!inExcludeList("dpl")) @@ -5910,6 +5915,10 @@ static void genFarPointerGet (operand *left, else { /* we need to get it byte by byte */ emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); + if (options.model == MODEL_FLAT24) + { + emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE)); + } } } /* so dptr know contains the address */ @@ -5954,6 +5963,10 @@ static void emitcodePointerGet (operand *left, else { /* we need to get it byte by byte */ emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); + if (options.model == MODEL_FLAT24) + { + emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE)); + } } } /* so dptr know contains the address */ @@ -6001,7 +6014,15 @@ static void genGenPointerGet (operand *left, else { /* we need to get it byte by byte */ emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE)); emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE)); - emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE)); + if (options.model == MODEL_FLAT24) + { + emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE)); + emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE)); + } + else + { + emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE)); + } } } /* so dptr know contains the address */ @@ -6463,6 +6484,10 @@ static void genFarPointerSet (operand *right, else { /* we need to get it byte by byte */ emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE)); emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE)); + if (options.model == MODEL_FLAT24) + { + emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE)); + } } } /* so dptr know contains the address */ @@ -6510,7 +6535,15 @@ static void genGenPointerSet (operand *right, else { /* we need to get it byte by byte */ emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE)); emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE)); - emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE)); + if (options.model == MODEL_FLAT24) + { + emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE)); + emitcode("mov","b,%s",aopGet(AOP(result),3,FALSE,FALSE)); + } + else + { + emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE)); + } } } /* so dptr know contains the address */ @@ -6928,7 +6961,7 @@ static void genCast (iCode *ic) } /* the first two bytes are known */ - size = 2; + size = GPTRSIZE - 1; offset = 0 ; while (size--) { aopPut(AOP(result), @@ -6958,7 +6991,7 @@ static void genCast (iCode *ic) "got unknown pointer type"); exit(1); } - aopPut(AOP(result),l,2); + aopPut(AOP(result),l, GPTRSIZE - 1); goto release ; } diff --git a/src/mcs51/main.c b/src/mcs51/main.c index 1e487e92..2f22fd76 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -38,17 +38,28 @@ static char *_mcs51_keywords[] = { void mcs51_assignRegisters (eBBlock **ebbs, int count); -static bool _mcs51_parseOptions(int *pargc, char **argv) +static bool _mcs51_parseOptions(int *pargc, char **argv, int *i) { + /* TODO: allow port-specific command line options to specify + * segment names here. + */ return FALSE; } static void _mcs51_finaliseOptions(void) { + /* Hack-o-matic: if we are using the flat24 model, + * adjust pointer sizes. + */ + if (options.model == MODEL_FLAT24) + { + port->s.fptr_size = 3; + port->s.gptr_size = 4; + } } static void _mcs51_setDefaultOptions(void) -{ +{ } static const char *_mcs51_getRegName(struct regs *reg) @@ -58,6 +69,45 @@ static const char *_mcs51_getRegName(struct regs *reg) return "err"; } +static void _mcs51_genAssemblerPreamble(FILE *of) +{ + if (options.model == MODEL_FLAT24) + { + fputs(".flat24 on\t\t; 24 bit flat addressing\n", of); + fputs("dpx = 0x93\t\t; dpx register unknown to assembler\n", of); + + } +} + +/* Generate interrupt vector table. */ +static int _mcs51_genIVT(FILE *of, symbol **interrupts, int maxInterrupts) +{ + int i; + + if (options.model != MODEL_FLAT24) + { + /* Let the default code handle it. */ + return FALSE; + } + + fprintf (of, "\tajmp\t__sdcc_gsinit_startup\n"); + + /* now for the other interrupts */ + for (i = 0; i < maxInterrupts; i++) + { + if (interrupts[i]) + { + fprintf(of, "\tljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname); + } + else + { + fprintf(of, "\treti\n\t.ds\t7\n"); + } + } + + return TRUE; +} + /** $1 is always the basename. $2 is always the output file. $3 varies @@ -112,6 +162,8 @@ PORT mcs51_port = { _mcs51_setDefaultOptions, mcs51_assignRegisters, _mcs51_getRegName , - _mcs51_keywords - + _mcs51_keywords, + _mcs51_genAssemblerPreamble, + _mcs51_genIVT }; + diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 93117905..11d2216b 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -768,7 +768,7 @@ static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym) if (!mcs51_ptrRegReq) if ((reg = allocReg(REG_PTR))) return reg ; - + /* we have to spil */ if (!spilSomething (ic,ebp,sym)) return NULL ; @@ -1069,7 +1069,9 @@ static void serialRegAssign (eBBlock **ebbs, int count) /* if we need ptr regs for the right side then mark it */ - if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) { + if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) + <= PTRSIZE) + { mcs51_ptrRegReq++; ptrRegSet = 1; } diff --git a/src/port.h b/src/port.h index 87c6a905..6c998372 100644 --- a/src/port.h +++ b/src/port.h @@ -79,7 +79,7 @@ typedef struct { } muldiv; /** Parses one option + its arguments */ - bool (*parseOption)(int *pargc, char **argv); + bool (*parseOption)(int *pargc, char **argv, int *i); /** Called after all the options have been parsed. */ void (*finaliseOptions)(void); /** Called after the port has been selected but before any @@ -95,6 +95,15 @@ typedef struct { /* list of keywords that are used by this target (used by lexer) */ char **keywords; + + /* Write any port specific assembler output. */ + void (*genAssemblerPreamble)(FILE *of); + + /* Write the port specific IVT. If genIVT is NULL or if + * it returns zero, default (8051) IVT generation code + * will be used. + */ + int (*genIVT)(FILE *of, symbol **intTable, int intCount); } PORT; extern PORT *port; diff --git a/src/z80/main.c b/src/z80/main.c index 9bd1d14c..c508a6ba 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -5,7 +5,7 @@ static char *_z80_keywords[] = { NULL }; void z80_assignRegisters (eBBlock **ebbs, int count); -static bool _z80_parseOptions(int *pargc, char **argv) +static bool _z80_parseOptions(int *pargc, char **argv, int *i) { return FALSE; } @@ -95,6 +95,8 @@ PORT z80_port = { _z80_setDefaultOptions, z80_assignRegisters, _z80_getRegName, - _z80_keywords + _z80_keywords, + 0, /* no assembler preamble */ + 0, /* no local IVT generation code */ }; -- 2.39.2