* as/link/mcs51/lkarea.c (lnkarea2): handle absolute areas, restructured
[fw/sdcc] / src / hc08 / main.c
index 86e75757910960334e85cc174a2f8c2daf4284e0..cd6eb0c021496647b5155a011f06c2407a6af886 100644 (file)
@@ -12,6 +12,8 @@
 
 void copyFile(FILE *dest, FILE *src);
 extern char * iComments2;
+extern DEBUGFILE dwarf2DebugFile;
+extern int dwarf2FinalizeFile(FILE *);
 
 static char _defaultRules[] =
 {
@@ -49,7 +51,7 @@ static char *_hc08_keywords[] =
 };
 
 
-void hc08_assignRegisters (eBBlock ** ebbs, int count);
+void hc08_assignRegisters (ebbIndex *);
 
 static int regParmFlg = 0;     /* determine if we can register a parameter */
 
@@ -60,13 +62,13 @@ _hc08_init (void)
 }
 
 static void
-_hc08_reset_regparm ()
+_hc08_reset_regparm (void)
 {
   regParmFlg = 0;
 }
 
 static int
-_hc08_regparm (sym_link * l)
+_hc08_regparm (sym_link * l, bool reentrant)
 {
   int size = getSize(l);
     
@@ -96,9 +98,22 @@ _hc08_regparm (sym_link * l)
 static bool
 _hc08_parseOptions (int *pargc, char **argv, int *i)
 {
+  if (!strcmp (argv[*i], "--out-fmt-elf"))
+    {
+      options.out_fmt = 2;
+      debugFile = &dwarf2DebugFile;
+      return TRUE;
+    }
+    
   return FALSE;
 }
 
+static OPTION _hc08_options[] = 
+  {
+    {  0,   "--out-fmt-elf", NULL, "Output executable in ELF format" },
+    {  0, NULL }
+  };
+
 static void
 _hc08_finaliseOptions (void)
 {
@@ -116,6 +131,7 @@ _hc08_finaliseOptions (void)
       port->mem.default_globl_map = data;
     }
 
+  istack->ptrType = FPOINTER;
 }
 
 static void
@@ -123,7 +139,7 @@ _hc08_setDefaultOptions (void)
 {
   options.code_loc = 0x8000;
   options.data_loc = 0x80;
-  options.xdata_loc = 0x100;
+  options.xdata_loc = 0;       /* 0 means immediately following data */
   options.stack_loc = 0x7fff;
   options.out_fmt = 1;         /* use motorola S19 output */
 
@@ -143,14 +159,18 @@ _hc08_getRegName (struct regs *reg)
 static void
 _hc08_genAssemblerPreamble (FILE * of)
 {
-   int i;
+  int i;
+  int needOrg = 1;
   symbol *mainExists=newSymbol("main", 0);
   mainExists->block=0;
 
-  fprintf (of, "\t.area %s\n",port->mem.code_name);
+  fprintf (of, "\t.area %s\n",HOME_NAME);
+  fprintf (of, "\t.area GSINIT0 (CODE)\n");
   fprintf (of, "\t.area %s\n",port->mem.static_name);
   fprintf (of, "\t.area %s\n",port->mem.post_static_name);
+  fprintf (of, "\t.area %s\n",CODE_NAME);
   fprintf (of, "\t.area %s\n",port->mem.xinit_name);
+  fprintf (of, "\t.area %s\n",port->mem.const_name);
   fprintf (of, "\t.area %s\n",port->mem.data_name);
   fprintf (of, "\t.area %s\n",port->mem.overlay_name);
   fprintf (of, "\t.area %s\n",port->mem.bit_name);
@@ -161,22 +181,30 @@ _hc08_genAssemblerPreamble (FILE * of)
     {
       // generate interrupt vector table
       fprintf (of, "\t.area\tCODEIVT (ABS)\n");
-      fprintf (of, "\t.org\t0x%4x\n", (0xfffe - (maxInterrupts * 2)));
       
       for (i=maxInterrupts;i>0;i--)
         {
           if (interrupts[i])
-            fprintf (of, "\t.dw\t%s\n", interrupts[i]->rname);
+           {
+             if (needOrg)
+               {
+                 fprintf (of, "\t.org\t0x%04x\n", (0xfffe - (i * 2)));
+                 needOrg = 0;
+               }
+             fprintf (of, "\t.dw\t%s\n", interrupts[i]->rname);
+           }
           else
-            fprintf (of, "\t.dw\t0\n");
+           needOrg = 1;
         }
+      if (needOrg)
+       fprintf (of, "\t.org\t0xfffe\n");
       fprintf (of, "\t.dw\t%s", "__sdcc_gs_init_startup\n\n");
         
-      fprintf (of, "\t.area GSINIT\n");
+      fprintf (of, "\t.area GSINIT0\n");
       fprintf (of, "__sdcc_gs_init_startup:\n");
       if (options.stack_loc)
         {
-          fprintf (of, "\tldhx\t#0x%4x\n", options.stack_loc+1);
+          fprintf (of, "\tldhx\t#0x%04x\n", options.stack_loc+1);
           fprintf (of, "\ttxs\n");
         }
       else
@@ -209,11 +237,20 @@ _hc08_genAssemblerPreamble (FILE * of)
     }
 }
 
+static void
+_hc08_genAssemblerEnd (FILE * of)
+{
+  if (options.out_fmt == 2 && options.debug)
+    {
+      dwarf2FinalizeFile (of);
+    }
+}
+
 static void
 _hc08_genExtraAreas (FILE * asmFile, bool mainExists)
 {
     fprintf (asmFile, "%s", iComments2);
-    fprintf (asmFile, "; external ram data\n");
+    fprintf (asmFile, "; extended address mode data\n");
     fprintf (asmFile, "%s", iComments2);
     copyFile (asmFile, xdata->oFile);
 }
@@ -226,7 +263,7 @@ _hc08_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
   int i;
   
   fprintf (of, "\t.area\tCODEIVT (ABS)\n");
-  fprintf (of, "\t.org\t0x%4x\n",
+  fprintf (of, "\t.org\t0x%04x\n",
     (0xfffe - (maxInterrupts * 2)));
   
   for (i=maxInterrupts;i>0;i--)
@@ -234,7 +271,7 @@ _hc08_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
       if (interrupts[i])
         fprintf (of, "\t.dw\t%s\n", interrupts[i]->rname);
       else
-        fprintf (of, "\t.dw\t0\n");
+        fprintf (of, "\t.dw\t0xffff\n");
     }
   fprintf (of, "\t.dw\t%s", "__sdcc_gs_init_startup\n");
         
@@ -308,6 +345,26 @@ oclsExpense (struct memmap *oclass)
 }
 
 
+/*----------------------------------------------------------------------*/
+/* hc08_dwarfRegNum - return the DWARF register number for a register.  */
+/*   These are defined for the HC08 in "Motorola 8- and 16-bit Embedded */
+/*   Application Binary Interface (M8/16EABI)"                          */
+/*----------------------------------------------------------------------*/
+static int
+hc08_dwarfRegNum (regs * reg)
+{
+  switch (reg->rIdx)
+    {
+    case A_IDX: return 0;
+    case H_IDX: return 1;
+    case X_IDX: return 2;
+    case CND_IDX: return 17;
+    case SP_IDX: return 15;
+    }
+  return -1;
+}
+
+
 
 /** $1 is always the basename.
     $2 is always the output file.
@@ -352,7 +409,8 @@ PORT hc08_port =
     _linkCmd,
     NULL,
     NULL,
-    ".rel"
+    ".rel",
+    1
   },
   {
     _defaultRules
@@ -361,21 +419,29 @@ PORT hc08_port =
        /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
     1, 2, 2, 4, 2, 2, 2, 1, 4, 4
   },
+  /* tags for generic pointers */
+  { 0x00, 0x40, 0x60, 0x80 },          /* far, near, xstack, code */
+  
   {
     "XSEG",
     "STACK",
-    "CSEG",
+    "CSEG (CODE)",
     "DSEG",
     NULL, /* "ISEG" */
+    NULL, /* "PSEG" */
     "XSEG",
     "BSEG",
     "RSEG",
-    "GSINIT",
+    "GSINIT (CODE)",
     "OSEG    (OVR)",
-    "GSFINAL",
-    "HOME",
+    "GSFINAL (CODE)",
+    "HOME (CODE)",
     "XISEG", // initialized xdata
     "XINIT", // 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)",      // xabs_name - absolute xdata
+    "IABS    (ABS)",      // iabs_name - absolute data
     NULL,
     NULL,
     1
@@ -383,15 +449,42 @@ PORT hc08_port =
   { _hc08_genExtraAreas,
     NULL },
   {
-    -1, 0, 4, 2, 0, 0
+    -1,                /* direction (-1 = stack grows down) */
+    0,         /* bank_overhead (switch between register banks) */
+    4,         /* isr_overhead */
+    2,         /* call_overhead */
+    0,         /* reent_overhead */
+    0          /* banked_overhead (switch between code banks) */
   },
     /* hc08 has an 8 bit mul */
   {
     1, -1
   },
+  {
+    hc08_emitDebuggerSymbol,
+    {
+      hc08_dwarfRegNum,
+      NULL,
+      NULL,
+      4,                               /* addressSize */
+      14,                      /* regNumRet */
+      15,                      /* regNumSP */
+      -1,                      /* regNumBP */
+      1,                       /* offsetSP */
+    },
+  },
+  {
+    256,        /* maxCount */
+    2,          /* sizeofElement */
+    {8,16,32},  /* sizeofMatchJump[] */
+    {8,16,32},  /* sizeofRangeCompare[] */
+    5,          /* sizeofSubtract */
+    10,         /* sizeofDispatch */
+  },
   "_",
   _hc08_init,
   _hc08_parseOptions,
+  _hc08_options,
   NULL,
   _hc08_finaliseOptions,
   _hc08_setDefaultOptions,
@@ -399,9 +492,10 @@ PORT hc08_port =
   _hc08_getRegName,
   _hc08_keywords,
   _hc08_genAssemblerPreamble,
-  NULL,                                /* no genAssemblerEnd */
+  _hc08_genAssemblerEnd,       /* no genAssemblerEnd */
   _hc08_genIVT,
   _hc08_genXINIT,
+  NULL,                        /* genInitStartup */
   _hc08_reset_regparm,
   _hc08_regparm,
   NULL,                                /* process_pragma */