summaryrefslogtreecommitdiff
path: root/src/hc08/main.c
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/hc08/main.c
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'src/hc08/main.c')
-rw-r--r--src/hc08/main.c1058
1 files changed, 1058 insertions, 0 deletions
diff --git a/src/hc08/main.c b/src/hc08/main.c
new file mode 100644
index 0000000..85656f5
--- /dev/null
+++ b/src/hc08/main.c
@@ -0,0 +1,1058 @@
+/*-------------------------------------------------------------------------
+ main.h - hc08 specific general function
+
+ Copyright (C) 2003, Erik Petrich
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+-------------------------------------------------------------------------*/
+/*
+ Note that mlh prepended _hc08_ on the static functions. Makes
+ it easier to set a breakpoint using the debugger.
+*/
+#include "common.h"
+#include "hc08.h"
+#include "main.h"
+#include "ralloc.h"
+#include "gen.h"
+#include "dbuf_string.h"
+
+extern char * iComments2;
+extern DEBUGFILE dwarf2DebugFile;
+extern int dwarf2FinalizeFile(FILE *);
+
+static char _hc08_defaultRules[] =
+{
+#include "peeph.rul"
+};
+
+static char _s08_defaultRules[] =
+{
+#include "peeph.rul"
+};
+
+HC08_OPTS hc08_opts;
+
+/* list of key words used by msc51 */
+static char *_hc08_keywords[] =
+{
+ "at",
+ //"bit",
+ "code",
+ "critical",
+ "data",
+ "far",
+ //"idata",
+ "interrupt",
+ "near",
+ //"pdata",
+ "reentrant",
+ //"sfr",
+ //"sbit",
+ //"using",
+ "xdata",
+ "_data",
+ "_code",
+ "_generic",
+ "_near",
+ "_xdata",
+ //"_pdata",
+ //"_idata",
+ "_naked",
+ "_overlay",
+ NULL
+};
+
+
+void hc08_assignRegisters (ebbIndex *);
+
+static int regParmFlg = 0; /* determine if we can register a parameter */
+
+static void
+_hc08_init (void)
+{
+ hc08_opts.sub = SUB_HC08;
+ asm_addTree (&asm_asxxxx_mapping);
+}
+
+static void
+_s08_init (void)
+{
+ hc08_opts.sub = SUB_S08;
+ asm_addTree (&asm_asxxxx_mapping);
+}
+
+static void
+_hc08_reset_regparm (struct sym_link *funcType)
+{
+ regParmFlg = 0;
+}
+
+static int
+_hc08_regparm (sym_link * l, bool reentrant)
+{
+ int size = getSize(l);
+
+ /* If they fit completely, the first two bytes of parameters can go */
+ /* into A and X, otherwise, they go on the stack. Examples: */
+ /* foo(char p1) A <- p1 */
+ /* foo(char p1, char p2) A <- p1, X <- p2 */
+ /* foo(char p1, char p2, char p3) A <- p1, X <- p2, stack <- p3 */
+ /* foo(int p1) XA <- p1 */
+ /* foo(long p1) stack <- p1 */
+ /* foo(char p1, int p2) A <- p1, stack <- p2 */
+ /* foo(int p1, char p2) XA <- p1, stack <- p2 */
+
+ if (regParmFlg>=2)
+ return 0;
+
+ if ((regParmFlg+size)>2)
+ {
+ regParmFlg = 2;
+ return 0;
+ }
+
+ regParmFlg += size;
+ return 1+regParmFlg-size;
+}
+
+static bool
+_hc08_parseOptions (int *pargc, char **argv, int *i)
+{
+ if (!strcmp (argv[*i], "--out-fmt-elf"))
+ {
+ options.out_fmt = 'E';
+ debugFile = &dwarf2DebugFile;
+ return TRUE;
+ }
+
+ if (!strcmp (argv[*i], "--oldralloc"))
+ {
+ options.oldralloc = TRUE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#define OPTION_SMALL_MODEL "--model-small"
+#define OPTION_LARGE_MODEL "--model-large"
+
+static OPTION _hc08_options[] =
+ {
+ {0, OPTION_SMALL_MODEL, NULL, "8-bit address space for data"},
+ {0, OPTION_LARGE_MODEL, NULL, "16-bit address space for data (default)"},
+ {0, "--out-fmt-elf", NULL, "Output executable in ELF format" },
+ {0, "--oldralloc", NULL, "Use old register allocator"},
+ {0, NULL }
+ };
+
+static void
+_hc08_finaliseOptions (void)
+{
+ if (options.noXinitOpt)
+ port->genXINIT = 0;
+
+ if (options.model == MODEL_LARGE) {
+ port->mem.default_local_map = xdata;
+ port->mem.default_globl_map = xdata;
+ }
+ else
+ {
+ port->mem.default_local_map = data;
+ port->mem.default_globl_map = data;
+ }
+
+ istack->ptrType = FPOINTER;
+}
+
+static void
+_hc08_setDefaultOptions (void)
+{
+ options.code_loc = 0x8000;
+ options.data_loc = 0x80;
+ options.xdata_loc = 0; /* 0 means immediately following data */
+ options.stack_loc = 0x7fff;
+ options.out_fmt = 's'; /* use motorola S19 output */
+
+ options.omitFramePtr = 1; /* no frame pointer (we use SP */
+ /* offsets instead) */
+}
+
+static const char *
+_hc08_getRegName (const struct reg_info *reg)
+{
+ if (reg)
+ return reg->name;
+ return "err";
+}
+
+static void
+_hc08_genAssemblerPreamble (FILE * of)
+{
+ int i;
+ int needOrg = 1;
+ symbol *mainExists=newSymbol("main", 0);
+ mainExists->block=0;
+
+ 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.xdata_name);
+ fprintf (of, "\t.area %s\n",port->mem.xidata_name);
+
+ if ((mainExists=findSymWithLevel(SymbolTab, mainExists)))
+ {
+ // generate interrupt vector table
+ fprintf (of, "\t.area\tCODEIVT (ABS)\n");
+
+ for (i=maxInterrupts;i>0;i--)
+ {
+ if (interrupts[i])
+ {
+ 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
+ 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 GSINIT0\n");
+ fprintf (of, "__sdcc_gs_init_startup:\n");
+ if (options.stack_loc)
+ {
+ fprintf (of, "\tldhx\t#0x%04x\n", options.stack_loc+1);
+ fprintf (of, "\ttxs\n");
+ }
+ else
+ fprintf (of, "\trsp\n");
+ fprintf (of, "\tjsr\t__sdcc_external_startup\n");
+ fprintf (of, "\tbeq\t__sdcc_init_data\n");
+ fprintf (of, "\tjmp\t__sdcc_program_startup\n");
+ fprintf (of, "__sdcc_init_data:\n");
+
+ fprintf (of, "; _hc08_genXINIT() start\n");
+ fprintf (of, " ldhx #0\n");
+ fprintf (of, "00001$:\n");
+ fprintf (of, " cphx #l_XINIT\n");
+ fprintf (of, " beq 00002$\n");
+ fprintf (of, " lda s_XINIT,x\n");
+ fprintf (of, " sta s_XISEG,x\n");
+ fprintf (of, " aix #1\n");
+ fprintf (of, " bra 00001$\n");
+ fprintf (of, "00002$:\n");
+ fprintf (of, "; _hc08_genXINIT() end\n");
+
+ fprintf (of, "\t.area GSFINAL\n");
+ fprintf (of, "\tjmp\t__sdcc_program_startup\n\n");
+
+ fprintf (of, "\t.area CSEG\n");
+ fprintf (of, "__sdcc_program_startup:\n");
+ fprintf (of, "\tjsr\t_main\n");
+ fprintf (of, "\tbra\t.\n");
+
+ }
+}
+
+static void
+_hc08_genAssemblerEnd (FILE * of)
+{
+ if (options.out_fmt == 'E' && options.debug)
+ {
+ dwarf2FinalizeFile (of);
+ }
+}
+
+static void
+_hc08_genExtraAreas (FILE * asmFile, bool mainExists)
+{
+ fprintf (asmFile, "%s", iComments2);
+ fprintf (asmFile, "; extended address mode data\n");
+ fprintf (asmFile, "%s", iComments2);
+ dbuf_write_and_destroy (&xdata->oBuf, asmFile);
+}
+
+/* Generate interrupt vector table. */
+static int
+_hc08_genIVT (struct dbuf_s * oBuf, symbol ** interrupts, int maxInterrupts)
+{
+ int i;
+
+ dbuf_printf (oBuf, "\t.area\tCODEIVT (ABS)\n");
+ dbuf_printf (oBuf, "\t.org\t0x%04x\n",
+ (0xfffe - (maxInterrupts * 2)));
+
+ for (i=maxInterrupts;i>0;i--)
+ {
+ if (interrupts[i])
+ dbuf_printf (oBuf, "\t.dw\t%s\n", interrupts[i]->rname);
+ else
+ dbuf_printf (oBuf, "\t.dw\t0xffff\n");
+ }
+ dbuf_printf (oBuf, "\t.dw\t%s", "__sdcc_gs_init_startup\n");
+
+ return TRUE;
+}
+
+/* Generate code to copy XINIT to XISEG */
+static void _hc08_genXINIT (FILE * of) {
+ fprintf (of, "; _hc08_genXINIT() start\n");
+ fprintf (of, "; _hc08_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 (ic->op == ADDRESS_OF)
+ return 0;
+
+ /* if bitwise | add & subtract then no since hc08 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;
+}
+
+/* Indicate which extended bit operations this port supports */
+static bool
+hasExtBitOp (int op, int size)
+{
+ if (op == RRC
+ || op == RLC
+ || (op == SWAP && size <= 2)
+ || op == GETABIT
+ || op == GETBYTE
+ || op == GETWORD
+ )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* Indicate the expense of an access to an output storage class */
+static int
+oclsExpense (struct memmap *oclass)
+{
+ /* The hc08's addressing modes allow access to all storage classes */
+ /* inexpensively (<=0) */
+
+ if (IN_DIRSPACE (oclass)) /* direct addressing mode is fastest */
+ return -2;
+ if (IN_FARSPACE (oclass)) /* extended addressing mode is almost at fast */
+ return -1;
+ if (oclass == istack) /* stack is the slowest, but still faster than */
+ return 0; /* trying to copy to a temp location elsewhere */
+
+ return 0; /* anything we missed */
+}
+
+/*----------------------------------------------------------------------*/
+/* 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 (const struct reg_info *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;
+}
+
+static bool
+_hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
+{
+ return getSize (left) == 1 && getSize (right) == 1;
+}
+
+typedef struct asmLineNode
+ {
+ int size;
+ }
+asmLineNode;
+
+static asmLineNode *
+newAsmLineNode (void)
+{
+ asmLineNode *aln;
+
+ aln = Safe_alloc ( sizeof (asmLineNode));
+ aln->size = 0;
+
+ return aln;
+}
+
+typedef struct hc08opcodedata
+ {
+ char name[6];
+ char adrmode;
+ /* info for registers used and/or modified by an instruction will be added here */
+ }
+hc08opcodedata;
+
+#define HC08OP_STD 1
+#define HC08OP_RMW 2
+#define HC08OP_INH 3
+#define HC08OP_IM1 4
+#define HC08OP_BR 5
+#define HC08OP_BTB 6
+#define HC08OP_BSC 7
+#define HC08OP_MOV 8
+#define HC08OP_CBEQ 9
+#define HC08OP_CPHX 10
+#define HC08OP_LDHX 11
+#define HC08OP_STHX 12
+#define HC08OP_DBNZ 13
+
+/* These must be kept sorted by opcode name */
+static hc08opcodedata hc08opcodeDataTable[] =
+ {
+ {".db", HC08OP_INH}, /* used by the code generator only in the jump table */
+ {"adc", HC08OP_STD},
+ {"add", HC08OP_STD},
+ {"ais", HC08OP_IM1},
+ {"aix", HC08OP_IM1},
+ {"and", HC08OP_STD},
+ {"asl", HC08OP_RMW},
+ {"asla", HC08OP_INH},
+ {"aslx", HC08OP_INH},
+ {"asr", HC08OP_RMW},
+ {"asra", HC08OP_INH},
+ {"asrx", HC08OP_INH},
+ {"bcc", HC08OP_BR,},
+ {"bclr", HC08OP_BSC},
+ {"bcs", HC08OP_BR},
+ {"beq", HC08OP_BR},
+ {"bge", HC08OP_BR},
+ {"bgnd", HC08OP_INH},
+ {"bgt", HC08OP_BR},
+ {"bhcc", HC08OP_BR},
+ {"bhcs", HC08OP_BR},
+ {"bhi", HC08OP_BR},
+ {"bhs", HC08OP_BR},
+ {"bih", HC08OP_BR},
+ {"bil", HC08OP_BR},
+ {"bit", HC08OP_STD},
+ {"ble", HC08OP_BR},
+ {"blo", HC08OP_BR},
+ {"bls", HC08OP_BR},
+ {"blt", HC08OP_BR},
+ {"bmc", HC08OP_BR},
+ {"bmi", HC08OP_BR},
+ {"bms", HC08OP_BR},
+ {"bne", HC08OP_BR},
+ {"bpl", HC08OP_BR},
+ {"bra", HC08OP_BR},
+ {"brclr", HC08OP_BTB},
+ {"brn", HC08OP_BR},
+ {"brset", HC08OP_BTB},
+ {"bset", HC08OP_BSC},
+ {"bsr", HC08OP_BR},
+ {"cbeq", HC08OP_CBEQ},
+ {"cbeqa", HC08OP_CBEQ},
+ {"cbeqx", HC08OP_CBEQ},
+ {"clc", HC08OP_INH},
+ {"cli", HC08OP_INH},
+ {"clr", HC08OP_RMW},
+ {"clra", HC08OP_INH},
+ {"clrh", HC08OP_INH},
+ {"clrx", HC08OP_INH},
+ {"cmp", HC08OP_STD},
+ {"com", HC08OP_RMW},
+ {"coma", HC08OP_INH},
+ {"comx", HC08OP_INH},
+ {"cphx", HC08OP_CPHX},
+ {"cpx", HC08OP_STD},
+ {"daa", HC08OP_INH},
+ {"dbnz", HC08OP_DBNZ},
+ {"dbnza", HC08OP_BR},
+ {"dbnzx", HC08OP_BR},
+ {"dec", HC08OP_RMW},
+ {"deca", HC08OP_INH},
+ {"decx", HC08OP_INH},
+ {"div", HC08OP_INH},
+ {"eor", HC08OP_STD},
+ {"inc", HC08OP_RMW},
+ {"inca", HC08OP_INH},
+ {"incx", HC08OP_INH},
+ {"jmp", HC08OP_STD},
+ {"jsr", HC08OP_STD},
+ {"lda", HC08OP_STD},
+ {"ldhx", HC08OP_LDHX},
+ {"ldx", HC08OP_STD},
+ {"lsl", HC08OP_RMW},
+ {"lsla", HC08OP_INH},
+ {"lslx", HC08OP_INH},
+ {"lsr", HC08OP_RMW},
+ {"lsra", HC08OP_INH},
+ {"lsrx", HC08OP_INH},
+ {"mov", HC08OP_MOV},
+ {"mul", HC08OP_INH},
+ {"neg", HC08OP_RMW},
+ {"nega", HC08OP_INH},
+ {"negx", HC08OP_INH},
+ {"nop", HC08OP_INH},
+ {"nsa", HC08OP_INH},
+ {"ora", HC08OP_STD},
+ {"psha", HC08OP_INH},
+ {"pshh", HC08OP_INH},
+ {"pshx", HC08OP_INH},
+ {"pula", HC08OP_INH},
+ {"pulh", HC08OP_INH},
+ {"pulx", HC08OP_INH},
+ {"rol", HC08OP_RMW},
+ {"rola", HC08OP_INH},
+ {"rolx", HC08OP_INH},
+ {"ror", HC08OP_RMW},
+ {"rora", HC08OP_INH},
+ {"rorx", HC08OP_INH},
+ {"rsp", HC08OP_INH},
+ {"rti", HC08OP_INH},
+ {"rts", HC08OP_INH},
+ {"sbc", HC08OP_STD},
+ {"sec", HC08OP_INH},
+ {"sei", HC08OP_INH},
+ {"sta", HC08OP_STD},
+ {"sthx", HC08OP_STHX},
+ {"stop", HC08OP_INH},
+ {"stx", HC08OP_STD},
+ {"sub", HC08OP_STD},
+ {"swi", HC08OP_INH},
+ {"tap", HC08OP_INH},
+ {"tax", HC08OP_INH},
+ {"tpa", HC08OP_INH},
+ {"tst", HC08OP_RMW},
+ {"tsta", HC08OP_INH},
+ {"tstx", HC08OP_INH},
+ {"tsx", HC08OP_INH},
+ {"txa", HC08OP_INH},
+ {"txs", HC08OP_INH},
+ {"wait", HC08OP_INH}
+ };
+
+static int
+hc08_opcodeCompare (const void *key, const void *member)
+{
+ return strcmp((const char *)key, ((hc08opcodedata *)member)->name);
+}
+
+/*--------------------------------------------------------------------*/
+/* Given an instruction and its first two operands, compute the */
+/* instruction size. There are a few cases where it's too complicated */
+/* to distinguish between an 8-bit offset and 16-bit offset; in these */
+/* cases we conservatively assume the 16-bit offset size. */
+/*--------------------------------------------------------------------*/
+static int
+hc08_instructionSize(const char *inst, const char *op1, const char *op2)
+{
+ hc08opcodedata *opcode;
+ int size;
+ long offset;
+ char * endnum = NULL;
+
+ opcode = bsearch (inst, hc08opcodeDataTable,
+ sizeof(hc08opcodeDataTable)/sizeof(hc08opcodedata),
+ sizeof(hc08opcodedata), hc08_opcodeCompare);
+
+ if (!opcode)
+ return 999;
+ switch (opcode->adrmode)
+ {
+ case HC08OP_INH: /* Inherent addressing mode */
+ return 1;
+
+ case HC08OP_BSC: /* Bit set/clear direct addressing mode */
+ case HC08OP_BR: /* Branch (1 byte signed offset) */
+ case HC08OP_IM1: /* 1 byte immediate addressing mode */
+ return 2;
+
+ case HC08OP_BTB: /* Bit test direct addressing mode and branch */
+ return 3;
+
+ case HC08OP_RMW: /* read/modify/write instructions */
+ if (!op2[0]) /* if not ,x or ,sp must be direct addressing mode */
+ return 2;
+ if (!op1[0]) /* if ,x with no offset */
+ return 1;
+ if (op2[0] == 'x') /* if ,x with offset */
+ return 2;
+ return 3; /* Otherwise, must be ,sp with offset */
+
+ case HC08OP_STD: /* standard instruction */
+ if (!op2[0])
+ {
+ if (op1[0] == '#') /* Immediate addressing mode */
+ return 2;
+ if (op1[0] == '*') /* Direct addressing mode */
+ return 2;
+ return 3; /* Otherwise, must be extended addressing mode */
+ }
+ else
+ {
+ if (!op1[0]) /* if ,x with no offset */
+ return 1;
+ size = 2;
+ if (op2[0] == 's')
+ size++;
+ offset = strtol (op1, &endnum, 0) & 0xffff;
+ if (endnum && *endnum)
+ size++;
+ else if (offset > 0xff)
+ size++;
+ return size;
+ }
+ case HC08OP_MOV:
+ if (op2[0] == 'x')
+ return 2;
+ return 3;
+ case HC08OP_CBEQ:
+ if (op2[0] == 'x' && !op1[0])
+ return 2; /* cbeq ,x+,rel */
+ if (op2[0] == 's')
+ return 4; /* cbeq oprx8,sp,rel */
+ return 3;
+ case HC08OP_CPHX:
+ if (op1[0] == '*')
+ return 2;
+ return 3;
+ case HC08OP_DBNZ:
+ if (!op2[0])
+ return 2;
+ if (!op1[0] && op2[0] == 'x')
+ return 2;
+ if (op2[0] == 's')
+ return 4;
+ return 3;
+ case HC08OP_LDHX:
+ case HC08OP_STHX:
+ if (op1[0] == '*')
+ return 2;
+ if (!op1[0] && op2[0] == 'x')
+ return 2;
+ if (op2[0] == 's' || op1[0] == '#' || !op2[0])
+ return 3;
+ size = 3;
+ offset = strtol (op1, &endnum, 0) & 0xffff;
+ if (endnum && *endnum)
+ size++;
+ else if (offset > 0xff)
+ size++;
+ return size;
+ default:
+ return 4;
+ }
+}
+
+
+static asmLineNode *
+hc08_asmLineNodeFromLineNode (lineNode *ln)
+{
+ asmLineNode *aln = newAsmLineNode();
+ char *op, op1[256], op2[256];
+ int opsize;
+ const char *p;
+ char inst[8];
+
+ p = ln->line;
+
+ while (*p && isspace(*p)) p++;
+ for (op = inst, opsize=1; *p; p++)
+ {
+ if (isspace(*p) || *p == ';' || *p == ':' || *p == '=')
+ break;
+ else
+ if (opsize < sizeof(inst))
+ *op++ = tolower(*p), opsize++;
+ }
+ *op = '\0';
+
+ if (*p == ';' || *p == ':' || *p == '=')
+ return aln;
+
+ while (*p && isspace(*p)) p++;
+ if (*p == '=')
+ return aln;
+
+ for (op = op1, opsize=1; *p && *p != ','; p++)
+ {
+ if (!isspace(*p) && opsize < sizeof(op1))
+ *op++ = tolower(*p), opsize++;
+ }
+ *op = '\0';
+
+ if (*p == ',') p++;
+ for (op = op2, opsize=1; *p && *p != ','; p++)
+ {
+ if (!isspace(*p) && opsize < sizeof(op2))
+ *op++ = tolower(*p), opsize++;
+ }
+ *op = '\0';
+
+ aln->size = hc08_instructionSize(inst, op1, op2);
+
+ return aln;
+}
+
+static int
+hc08_getInstructionSize (lineNode *line)
+{
+ if (!line->aln)
+ line->aln = (asmLineNodeBase *) hc08_asmLineNodeFromLineNode (line);
+
+ return line->aln->size;
+}
+
+/** $1 is always the basename.
+ $2 is always the output file.
+ $3 varies
+ $l is the list of extra options that should be there somewhere...
+ MUST be terminated with a NULL.
+*/
+static const char *_linkCmd[] =
+{
+ "sdld6808", "-nf", "$1", NULL
+};
+
+/* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
+static const char *_asmCmd[] =
+{
+ "sdas6808", "$l", "$3", "$2", "$1.asm", NULL
+};
+
+static const char * const _libs_hc08[] = { "hc08", NULL, };
+static const char * const _libs_s08[] = { "s08", NULL, };
+
+/* Globals */
+PORT hc08_port =
+{
+ TARGET_ID_HC08,
+ "hc08",
+ "HC08", /* Target name */
+ NULL, /* Processor name */
+ {
+ glue,
+ FALSE, /* Emit glue around main */
+ MODEL_SMALL | MODEL_LARGE,
+ MODEL_LARGE,
+ NULL, /* model == target */
+ },
+ {
+ _asmCmd,
+ NULL,
+ "-plosgffwy", /* Options with debug */
+ "-plosgffw", /* Options without debug */
+ 0,
+ ".asm",
+ NULL /* no do_assemble function */
+ },
+ { /* Linker */
+ _linkCmd,
+ NULL,
+ NULL,
+ ".rel",
+ 1,
+ NULL, /* crt */
+ _libs_hc08, /* libs */
+ },
+ { /* Peephole optimizer */
+ _hc08_defaultRules,
+ hc08_getInstructionSize,
+ },
+ {
+ /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float */
+ 1, 2, 2, 4, 8, 2, 2, 2, 2, 0, 1, 4
+ },
+ /* tags for generic pointers */
+ { 0x00, 0x00, 0x00, 0x00 }, /* far, near, xstack, code */
+ {
+ "XSEG",
+ "STACK",
+ "CSEG (CODE)",
+ "DSEG (PAG)",
+ NULL, /* "ISEG" */
+ NULL, /* "PSEG" */
+ "XSEG",
+ NULL, /* "BSEG" */
+ "RSEG (ABS)",
+ "GSINIT (CODE)",
+ "OSEG (PAG, OVR)",
+ "GSFINAL (CODE)",
+ "HOME (CODE)",
+ "XISEG", // initialized xdata
+ "XINIT (CODE)", // 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, // name of segment for initialized variables
+ NULL, // name of segment for copies of initialized variables in code space
+ NULL,
+ NULL,
+ 1,
+ 1 // No fancy alignments supported.
+ },
+ { _hc08_genExtraAreas,
+ NULL },
+ {
+ -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) */
+ 1 /* sp is offset by 1 from last item pushed */
+ },
+ {
+ 5, FALSE
+ },
+ {
+ 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,
+ hc08_assignRegisters,
+ _hc08_getRegName,
+ 0,
+ NULL,
+ _hc08_keywords,
+ _hc08_genAssemblerPreamble,
+ _hc08_genAssemblerEnd, /* no genAssemblerEnd */
+ _hc08_genIVT,
+ _hc08_genXINIT,
+ NULL, /* genInitStartup */
+ _hc08_reset_regparm,
+ _hc08_regparm,
+ NULL, /* process_pragma */
+ NULL, /* getMangledFunctionName */
+ _hasNativeMulFor, /* hasNativeMulFor */
+ hasExtBitOp, /* hasExtBitOp */
+ oclsExpense, /* oclsExpense */
+ TRUE, /* use_dw_for_init */
+ FALSE, /* little_endian */
+ 0, /* leave lt */
+ 0, /* leave gt */
+ 1, /* transform <= to ! > */
+ 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 statics allowed */
+ 3, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
+ PORT_MAGIC
+};
+
+PORT s08_port =
+{
+ TARGET_ID_S08,
+ "s08",
+ "S08", /* Target name */
+ NULL, /* Processor name */
+ {
+ glue,
+ FALSE, /* Emit glue around main */
+ MODEL_SMALL | MODEL_LARGE,
+ MODEL_LARGE,
+ NULL, /* model == target */
+ },
+ {
+ _asmCmd,
+ NULL,
+ "-plosgffwy", /* Options with debug */
+ "-plosgffw", /* Options without debug */
+ 0,
+ ".asm",
+ NULL /* no do_assemble function */
+ },
+ { /* Linker */
+ _linkCmd,
+ NULL,
+ NULL,
+ ".rel",
+ 1,
+ NULL, /* crt */
+ _libs_s08, /* libs */
+ },
+ { /* Peephole optimizer */
+ _s08_defaultRules,
+ hc08_getInstructionSize,
+ },
+ {
+ /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float */
+ 1, 2, 2, 4, 8, 2, 2, 2, 2, 0, 1, 4
+ },
+ /* tags for generic pointers */
+ { 0x00, 0x00, 0x00, 0x00 }, /* far, near, xstack, code */
+ {
+ "XSEG",
+ "STACK",
+ "CSEG (CODE)",
+ "DSEG (PAG)",
+ NULL, /* "ISEG" */
+ NULL, /* "PSEG" */
+ "XSEG",
+ NULL, /* "BSEG" */
+ "RSEG (ABS)",
+ "GSINIT (CODE)",
+ "OSEG (PAG, OVR)",
+ "GSFINAL (CODE)",
+ "HOME (CODE)",
+ "XISEG", // initialized xdata
+ "XINIT (CODE)", // 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, // name of segment for initialized variables
+ NULL, // name of segment for copies of initialized variables in code space
+ NULL,
+ NULL,
+ 1,
+ 1 // No fancy alignments supported.
+ },
+ { _hc08_genExtraAreas,
+ NULL },
+ {
+ -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) */
+ 1 /* sp is offset by 1 from last item pushed */
+ },
+ {
+ 5, FALSE
+ },
+ {
+ 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 */
+ },
+ "_",
+ _s08_init,
+ _hc08_parseOptions,
+ _hc08_options,
+ NULL,
+ _hc08_finaliseOptions,
+ _hc08_setDefaultOptions,
+ hc08_assignRegisters,
+ _hc08_getRegName,
+ 0,
+ NULL,
+ _hc08_keywords,
+ _hc08_genAssemblerPreamble,
+ _hc08_genAssemblerEnd, /* no genAssemblerEnd */
+ _hc08_genIVT,
+ _hc08_genXINIT,
+ NULL, /* genInitStartup */
+ _hc08_reset_regparm,
+ _hc08_regparm,
+ NULL, /* process_pragma */
+ NULL, /* getMangledFunctionName */
+ _hasNativeMulFor, /* hasNativeMulFor */
+ hasExtBitOp, /* hasExtBitOp */
+ oclsExpense, /* oclsExpense */
+ TRUE, /* use_dw_for_init */
+ FALSE, /* little_endian */
+ 0, /* leave lt */
+ 0, /* leave gt */
+ 1, /* transform <= to ! > */
+ 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 statics allowed */
+ 3, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
+ PORT_MAGIC
+};
+