diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/hc08/main.c | |
| download | sdcc-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.c | 1058 |
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 +}; + |
