Applied patch #2762516
[fw/sdcc] / src / avr / main.c
index e7b3f4121ca9c2cb432e7457936e8092d083803f..efde4d2beaef53048b1dd4eb7b1471ae7c74d8be 100644 (file)
@@ -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"
 #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
 };
-