X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fmain.c;h=b1ca1f2998027469a02908f5f2a8a6e4dda89e59;hb=6b5e433931b8b1ba61bb6c694f74f42f48c3acf5;hp=f2ced3e291068338e2cbc6f0f864309109398178;hpb=994605ba5c8b657fac1563cd44707f679a85967e;p=fw%2Fsdcc diff --git a/src/mcs51/main.c b/src/mcs51/main.c index f2ced3e2..b1ca1f29 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -8,6 +8,8 @@ #include "main.h" #include "ralloc.h" #include "gen.h" +#include "../SDCCutil.h" +extern const char *preArgv[128]; /* pre-processor arguments */ static char _defaultRules[] = { @@ -40,6 +42,7 @@ static char *_mcs51_keywords[] = "_pdata", "_idata", "_naked", + "_overlay", NULL }; @@ -63,13 +66,31 @@ _mcs51_reset_regparm () static int _mcs51_regparm (sym_link * l) { - /* for this processor it is simple - can pass only the first parameter in a register */ - if (regParmFlg) - return 0; + if (options.parms_in_bank1 == 0) { + /* simple can pass only the first parameter in a register */ + if (regParmFlg) + return 0; - regParmFlg = 1; - return 1; + regParmFlg = 1; + return 1; + } else { + int size = getSize(l); + int remain ; + + /* first one goes the usual way to DPTR */ + if (regParmFlg == 0) { + regParmFlg += 4 ; + return 1; + } + /* second one onwards goes to RB1_0 thru RB1_7 */ + remain = regParmFlg - 4; + if (size > (8 - remain)) { + regParmFlg = 12 ; + return 0; + } + regParmFlg += size ; + return regParmFlg - size + 1; + } } static bool @@ -84,6 +105,10 @@ _mcs51_parseOptions (int *pargc, char **argv, int *i) static void _mcs51_finaliseOptions (void) { + if (noXinitOpt /* || options.model==MODEL_SMALL */) { + port->genXINIT=0; + } + if (options.model == MODEL_LARGE) { port->mem.default_local_map = xdata; port->mem.default_globl_map = xdata; @@ -93,6 +118,10 @@ _mcs51_finaliseOptions (void) port->mem.default_local_map = data; port->mem.default_globl_map = data; } + + if (options.parms_in_bank1) { + addToList (preArgv, "-DSDCC_PARMS_IN_BANK1"); + } } static void @@ -111,6 +140,11 @@ _mcs51_getRegName (struct regs *reg) static void _mcs51_genAssemblerPreamble (FILE * of) { + if (options.parms_in_bank1) { + int i ; + for (i=0; i < 8 ; i++ ) + fprintf (of,"b1_%d = 0x%x \n",i,8+i); + } } /* Generate interrupt vector table. */ @@ -120,6 +154,60 @@ _mcs51_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts) return FALSE; } +/* Generate code to copy XINIT to XISEG */ +static void _mcs51_genXINIT (FILE * of) { + fprintf (of, "; _mcs51_genXINIT() start\n"); + fprintf (of, " mov a,#l_XINIT\n"); + fprintf (of, " orl a,#l_XINIT>>8\n"); + fprintf (of, " jz 00003$\n"); + fprintf (of, " mov a,#s_XINIT\n"); + fprintf (of, " add a,#l_XINIT\n"); + fprintf (of, " mov r1,a\n"); + fprintf (of, " mov a,#s_XINIT>>8\n"); + fprintf (of, " addc a,#l_XINIT>>8\n"); + fprintf (of, " mov r2,a\n"); + fprintf (of, " mov dptr,#s_XINIT\n"); + fprintf (of, " mov r0,#s_XISEG\n"); + fprintf (of, " mov p2,#(s_XISEG >> 8)\n"); + fprintf (of, "00001$: clr a\n"); + fprintf (of, " movc a,@a+dptr\n"); + fprintf (of, " movx @r0,a\n"); + fprintf (of, " inc dptr\n"); + fprintf (of, " inc r0\n"); + fprintf (of, " cjne r0,#0,00002$\n"); + fprintf (of, " inc p2\n"); + fprintf (of, "00002$: mov a,dpl\n"); + fprintf (of, " cjne a,ar1,00001$\n"); + fprintf (of, " mov a,dph\n"); + fprintf (of, " cjne a,ar2,00001$\n"); + fprintf (of, " mov p2,#0xFF\n"); + fprintf (of, "00003$:\n"); + fprintf (of, "; _mcs51_genXINIT() end\n"); +} + + +/* Do CSE estimation */ +static bool cseCostEstimation (iCode *ic, iCode *pdic) +{ + operand *result = IC_RESULT(ic); + sym_link *result_type = operandType(result); + + /* if it is a pointer then return ok for now */ + if (IC_RESULT(ic) && IS_PTR(result_type)) return 1; + + /* if bitwise | add & subtract then no since mcs51 is pretty good at it + so we will cse only if they are local (i.e. both ic & pdic belong to + the same basic block */ + if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') { + /* then if they are the same Basic block then ok */ + if (ic->eBBlockNum == pdic->eBBlockNum) return 1; + else return 0; + } + + /* for others it is cheaper to do the cse */ + return 1; +} + /** $1 is always the basename. $2 is always the output file. $3 varies @@ -131,9 +219,10 @@ static const char *_linkCmd[] = "aslink", "-nf", "$1", NULL }; +/* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */ static const char *_asmCmd[] = { - "asx8051", "$l", "-plosgffc", "$1.asm", NULL + "asx8051", "$l", "$3", "$1.asm", NULL }; /* Globals */ @@ -142,6 +231,7 @@ PORT mcs51_port = TARGET_ID_MCS51, "mcs51", "MCU 8051", /* Target name */ + NULL, /* Processor name */ { TRUE, /* Emit glue around main */ MODEL_SMALL | MODEL_LARGE, @@ -149,14 +239,17 @@ PORT mcs51_port = }, { _asmCmd, + NULL, "-plosgffc", /* Options with debug */ "-plosgff", /* Options without debug */ 0, - ".asm" + ".asm", + NULL /* no do_assemble function */ }, { _linkCmd, NULL, + NULL, ".rel" }, { @@ -178,7 +271,9 @@ PORT mcs51_port = "GSINIT (CODE)", "OSEG (OVR,DATA)", "GSFINAL (CODE)", - "HOME (CODE)", + "HOME (CODE)", + "XISEG (XDATA)", // initialized xdata + "XINIT (CODE)", // a code copy of xiseg NULL, NULL, 1 @@ -188,21 +283,26 @@ PORT mcs51_port = }, /* mcs51 has an 8 bit mul */ { - 1, 0 + 1, -1 }, "_", _mcs51_init, _mcs51_parseOptions, + NULL, _mcs51_finaliseOptions, _mcs51_setDefaultOptions, mcs51_assignRegisters, _mcs51_getRegName, _mcs51_keywords, _mcs51_genAssemblerPreamble, + NULL, /* no genAssemblerEnd */ _mcs51_genIVT, + _mcs51_genXINIT, _mcs51_reset_regparm, _mcs51_regparm, NULL, + NULL, + NULL, FALSE, 0, /* leave lt */ 0, /* leave gt */ @@ -210,5 +310,11 @@ PORT mcs51_port = 1, /* transform >= to ! < */ 1, /* transform != to !(a == b) */ 0, /* leave == */ + FALSE, /* No array initializer support. */ + cseCostEstimation, + NULL, /* no builtin functions */ + GPOINTER, /* treat unqualified pointers as "generic" pointers */ + 1, /* reset labelKey to 1 */ + 1, /* globals & local static allowed */ PORT_MAGIC };