X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Favr%2Fmain.c;h=efde4d2beaef53048b1dd4eb7b1471ae7c74d8be;hb=5a1d5e778e85664f4e6657019348b4756b16eacb;hp=e7b3f4121ca9c2cb432e7457936e8092d083803f;hpb=390c2efea588d5379a4eec3f5c904547d45142dc;p=fw%2Fsdcc diff --git a/src/avr/main.c b/src/avr/main.c index e7b3f412..efde4d2b 100644 --- a/src/avr/main.c +++ b/src/avr/main.c @@ -1,7 +1,7 @@ /** @file main.c - mcs51 specific general functions. + avr specific general functions. - Note that mlh prepended _mcs51_ on the static functions. Makes + Note that mlh prepended _avr_ on the static functions. Makes it easier to set a breakpoint using the debugger. */ #include "common.h" @@ -9,119 +9,149 @@ #include "ralloc.h" #include "gen.h" -static char _defaultRules[] = -{ +static char _defaultRules[] = { #include "peeph.rul" }; /* list of key words used by msc51 */ -static char *_mcs51_keywords[] = { - "at", - "bit", - "code", - "critical", - "data", - "far", - "idata", - "interrupt", - "near", - "pdata", - "reentrant", - "sfr", - "sbit", - "using", - "xdata", - "_data", - "_code", - "_generic", - "_near", - "_xdata", - "_pdata", - "_idata", - NULL +static char *_avr_keywords[] = { + "at", + "code", + "critical", + "eeprom", + "interrupt", + "sfr", + "xdata", + "_code", + "_eeprom", + "_generic", + "_xdata", + "sram", + "_sram", + "flash", + "_flash", + NULL }; +static int regParmFlg = 0; /* determine if we can register a parameter */ -void mcs51_assignRegisters (eBBlock **ebbs, int count); +static void +_avr_init (void) +{ + asm_addTree (&asm_asxxxx_mapping); +} -static bool _mcs51_parseOptions(int *pargc, char **argv, int *i) +static void +_avr_reset_regparm (void) { - /* TODO: allow port-specific command line options to specify - * segment names here. - */ - return FALSE; + regParmFlg = 0; } -static void _mcs51_finaliseOptions(void) +static int +_avr_regparm (sym_link * l, bool reentrant) { - /* 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; - port->stack.isr_overhead++; /* Will save dpx on ISR entry. */ - #if 1 - port->stack.call_overhead++; /* This acounts for the extra byte - * of return addres on the stack. - * but is ugly. There must be a - * better way. - */ - #endif - fReturn = fReturn390; - fReturnSize = 5; - } + /* the first eight bytes will be passed in + registers r16-r23. but we won't split variables + i.e. if not enough registers left to hold + the parameter then the whole parameter along + with rest of the parameters go onto the stack */ + if (regParmFlg < 8) { + int size; + if ((size = getSize (l)) > (8 - regParmFlg)) { + /* all remaining go on stack */ + regParmFlg = 8; + return 0; + } + regParmFlg += size; + return 1; + } + + return 0; } -static void _mcs51_setDefaultOptions(void) +void avr_assignRegisters (ebbIndex *); + +static bool +_avr_parseOptions (int *pargc, char **argv, int *i) { + /* TODO: allow port-specific command line options to specify + * segment names here. + */ + return FALSE; } -static const char *_mcs51_getRegName(struct regs *reg) +static void +_avr_finaliseOptions (void) { - if (reg) - return reg->name; - return "err"; + port->mem.default_local_map = port->mem.default_globl_map = xdata; + /* change stack to be in far space */ + /* internal stack segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'B' + POINTER-TYPE - FPOINTER + */ + istack = + allocMap (0, 1, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, + 'B', FPOINTER); + + /* also change xdata to be direct space since we can use lds/sts */ + xdata->direct = 1; + } -static void _mcs51_genAssemblerPreamble(FILE *of) +static void +_avr_setDefaultOptions (void) +{ + options.stackAuto = 1; +} + +static const char * +_avr_getRegName (struct regs *reg) +{ + if (reg) + return reg->name; + return "err"; +} + +static void +_avr_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) +static int +_avr_genIVT (struct dbuf_s * oBuf, 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; +} + +/* Indicate which extended bit operations this port supports */ +static bool +hasExtBitOp (int op, int size) +{ + if (op == RRC + || op == RLC + || op == GETHBIT + ) return TRUE; + else + return FALSE; +} + +/* Indicate the expense of an access to an output storage class */ +static int +oclsExpense (struct memmap *oclass) +{ + if (IN_FARSPACE(oclass)) + return 1; + + return 0; } /** $1 is always the basename. @@ -131,63 +161,129 @@ static int _mcs51_genIVT(FILE *of, symbol **interrupts, int maxInterrupts) MUST be terminated with a NULL. */ static const char *_linkCmd[] = { - "aslink", "-nf", "$1", NULL + "linkavr", "", "\"$1\"", NULL }; +/* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */ static const char *_asmCmd[] = { - "asx8051", "-plosgffc", "$1.asm", NULL + "asavr", "$l" , "$3", "\"$1.s\"", NULL }; /* Globals */ -PORT mcs51_port = { - "mcs51", - "MCU 8051", /* Target name */ - { - TRUE, /* Emit glue around main */ - }, - { - _asmCmd, - "-plosgffc", /* Options with debug */ - "-plosgff", /* Options without debug */ - }, - { - _linkCmd - }, - { - _defaultRules - }, - { - /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */ - 1, 1, 2, 4, 1, 2, 3, 1, 4, 4 - }, - { - "XSEG (XDATA)", - "STACK (DATA)", - "CSEG (CODE)", - "DSEG (DATA)", - "ISEG (DATA)", - "XSEG (XDATA)", - "BSEG (BIT)", - "RSEG (DATA)", - "GSINIT (CODE)", - "OSEG (OVR,DATA)", - "GSFINAL (CODE)" - }, - { - +1, 1, 4, 1, 1 - }, - /* mcs51 has an 8 bit mul */ - { - 1 - }, - NULL, - _mcs51_parseOptions, - _mcs51_finaliseOptions, - _mcs51_setDefaultOptions, - mcs51_assignRegisters, - _mcs51_getRegName , - _mcs51_keywords, - _mcs51_genAssemblerPreamble, - _mcs51_genIVT +PORT avr_port = { + TARGET_ID_AVR, + "avr", + "ATMEL AVR", /* Target name */ + NULL, /* processor */ + { + glue, + TRUE, /* Emit glue around main */ + MODEL_LARGE | MODEL_SMALL, + MODEL_SMALL + }, + { + _asmCmd, + NULL, + "-plosgff", /* Options with debug */ + "-plosgff", /* Options without debug */ + 0, + ".s", + NULL, /* no do_assemble */ + }, + { + _linkCmd, + NULL, + NULL, + ".rel", + 1}, + { + _defaultRules}, + { + /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */ + 1, 2, 2, 4, 2, 2, 3, 1, 4, 4}, + + /* tags for generic pointers */ + { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */ + + { + "XSEG", + "STACK", + "CSEG", + "DSEG", + "ISEG", + NULL, //PSEG + "XSEG", + "BSEG", + "RSEG", + "GSINIT", + "OSEG", + "GSFINAL", + "HOME", + NULL, // initialized xdata + NULL, // a code copy of xiseg + "CONST (CODE)", // const_name - const data (code or not) + "CABS (ABS,CODE)", // cabs_name - const absolute data (code or not) + "XABS (ABS,XDATA)", // xabs_name - absolute xdata/pdata + "IABS (ABS,DATA)", // iabs_name - absolute idata/data + NULL, + NULL, + 0, + }, + { NULL, NULL }, + { + -1, 1, 4, 1, 1, 0}, + /* avr has an 8 bit mul */ + { + 1, -1 + }, + { + avr_emitDebuggerSymbol + }, + { + 255/3, /* maxCount */ + 3, /* sizeofElement */ + /* The rest of these costs are bogus. They approximate */ + /* the behavior of src/SDCCicode.c 1.207 and earlier. */ + {4,4,4}, /* sizeofMatchJump[] */ + {0,0,0}, /* sizeofRangeCompare[] */ + 0, /* sizeofSubtract */ + 3, /* sizeofDispatch */ + }, + "_", + _avr_init, + _avr_parseOptions, + NULL, + NULL, + _avr_finaliseOptions, + _avr_setDefaultOptions, + avr_assignRegisters, + _avr_getRegName, + _avr_keywords, + _avr_genAssemblerPreamble, + NULL, /* no genAssemblerEnd */ + _avr_genIVT, + NULL, // _avr_genXINIT + NULL, /* genInitStartup */ + _avr_reset_regparm, + _avr_regparm, + NULL, + NULL, + NULL, + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ + FALSE, + TRUE, /* little endian */ + 0, /* leave lt */ + 1, /* transform gt ==> not le */ + 0, /* leave le */ + 0, /* leave ge */ + 0, /* leave != */ + 0, /* leave == */ + FALSE, /* No array initializer support. */ + 0, /* no CSE cost estimation yet */ + NULL, /* no builtin functions */ + GPOINTER, /* treat unqualified pointers as "generic" pointers */ + 1, /* reset labelKey to 1 */ + 1, /* globals & local static allowed */ + PORT_MAGIC }; -