2 mcs51 specific general functions.
4 Note that mlh prepended _mcs51_ on the static functions. Makes
5 it easier to set a breakpoint using the debugger.
11 #include "../SDCCutil.h"
13 static char _defaultRules[] =
18 /* list of key words used by msc51 */
19 static char *_mcs51_keywords[] =
49 void mcs51_assignRegisters (eBBlock ** ebbs, int count);
51 static int regParmFlg = 0; /* determine if we can register a parameter */
56 asm_addTree (&asm_asxxxx_mapping);
60 _mcs51_reset_regparm ()
66 _mcs51_regparm (sym_link * l)
68 if (options.parms_in_bank1 == 0) {
69 /* simple can pass only the first parameter in a register */
76 int size = getSize(l);
79 /* first one goes the usual way to DPTR */
80 if (regParmFlg == 0) {
84 /* second one onwards goes to RB1_0 thru RB1_7 */
85 remain = regParmFlg - 4;
86 if (size > (8 - remain)) {
91 return regParmFlg - size + 1;
96 _mcs51_parseOptions (int *pargc, char **argv, int *i)
98 /* TODO: allow port-specific command line options to specify
105 _mcs51_finaliseOptions (void)
107 if (options.noXinitOpt) {
111 if (options.model == MODEL_LARGE) {
112 port->mem.default_local_map = xdata;
113 port->mem.default_globl_map = xdata;
117 port->mem.default_local_map = data;
118 port->mem.default_globl_map = data;
121 if (options.parms_in_bank1) {
122 addSet(&preArgvSet, Safe_strdup("-DSDCC_PARMS_IN_BANK1"));
127 _mcs51_setDefaultOptions (void)
132 _mcs51_getRegName (struct regs *reg)
140 _mcs51_genAssemblerPreamble (FILE * of)
142 if (options.parms_in_bank1) {
144 for (i=0; i < 8 ; i++ )
145 fprintf (of,"b1_%d = 0x%x \n",i,8+i);
149 /* Generate interrupt vector table. */
151 _mcs51_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
156 /* Generate code to clear XSEG and idata memory.
157 This clears XSEG, DSEG, BSEG, OSEG, SSEG */
158 static void _mcs51_genRAMCLEAR (FILE * of) {
159 fprintf (of, "; _mcs51_genRAMCLEAR() start\n");
160 fprintf (of, " mov r0,#l_XSEG\n");
161 fprintf (of, " mov a,r0\n");
162 fprintf (of, " orl a,#(l_XSEG >> 8)\n");
163 fprintf (of, " jz 00005$\n");
164 fprintf (of, " mov r1,#((l_XSEG + 255) >> 8)\n");
165 fprintf (of, " mov dptr,#s_XSEG\n");
166 fprintf (of, " clr a\n");
167 fprintf (of, "00004$: movx @dptr,a\n");
168 fprintf (of, " inc dptr\n");
169 fprintf (of, " djnz r0,00004$\n");
170 fprintf (of, " djnz r1,00004$\n");
171 /* r0 is zero now. Clearing 256 byte assuming 128 byte devices don't mind */
172 fprintf (of, "00005$: mov @r0,a\n");
173 fprintf (of, " djnz r0,00005$\n");
174 fprintf (of, "; _mcs51_genRAMCLEAR() end\n");
177 /* Generate code to copy XINIT to XISEG */
178 static void _mcs51_genXINIT (FILE * of) {
179 fprintf (of, "; _mcs51_genXINIT() start\n");
180 fprintf (of, " mov r1,#l_XINIT\n");
181 fprintf (of, " mov a,r1\n");
182 fprintf (of, " orl a,#(l_XINIT >> 8)\n");
183 fprintf (of, " jz 00003$\n");
184 fprintf (of, " mov r2,#((l_XINIT+255) >> 8)\n");
185 fprintf (of, " mov dptr,#s_XINIT\n");
186 fprintf (of, " mov r0,#s_XISEG\n");
187 fprintf (of, " mov p2,#(s_XISEG >> 8)\n");
188 fprintf (of, "00001$: clr a\n");
189 fprintf (of, " movc a,@a+dptr\n");
190 fprintf (of, " movx @r0,a\n");
191 fprintf (of, " inc dptr\n");
192 fprintf (of, " inc r0\n");
193 fprintf (of, " cjne r0,#0,00002$\n");
194 fprintf (of, " inc p2\n");
195 fprintf (of, "00002$: djnz r1,00001$\n");
196 fprintf (of, " djnz r2,00001$\n");
197 fprintf (of, " mov p2,#0xFF\n");
198 fprintf (of, "00003$:\n");
199 fprintf (of, "; _mcs51_genXINIT() end\n");
201 if (!getenv("SDCC_NOGENRAMCLEAR")) _mcs51_genRAMCLEAR (of);
205 /* Do CSE estimation */
206 static bool cseCostEstimation (iCode *ic, iCode *pdic)
208 operand *result = IC_RESULT(ic);
209 sym_link *result_type = operandType(result);
211 /* if it is a pointer then return ok for now */
212 if (IC_RESULT(ic) && IS_PTR(result_type)) return 1;
214 /* if bitwise | add & subtract then no since mcs51 is pretty good at it
215 so we will cse only if they are local (i.e. both ic & pdic belong to
216 the same basic block */
217 if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') {
218 /* then if they are the same Basic block then ok */
219 if (ic->eBBlockNum == pdic->eBBlockNum) return 1;
223 /* for others it is cheaper to do the cse */
227 /* Indicate which extended bit operations this port supports */
229 hasExtBitOp (int op, int size)
234 || (op == SWAP && size <= 2)
241 /* Indicate the expense of an access to an output storage class */
243 oclsExpense (struct memmap *oclass)
245 if (IN_FARSPACE(oclass))
251 /** $1 is always the basename.
252 $2 is always the output file.
254 $l is the list of extra options that should be there somewhere...
255 MUST be terminated with a NULL.
257 static const char *_linkCmd[] =
259 "aslink", "-nf", "\"$1\"", NULL
262 /* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
263 static const char *_asmCmd[] =
265 "asx8051", "$l", "$3", "\"$1.asm\"", NULL
273 "MCU 8051", /* Target name */
274 NULL, /* Processor name */
277 TRUE, /* Emit glue around main */
278 MODEL_SMALL | MODEL_LARGE,
284 "-plosgffc", /* Options with debug */
285 "-plosgff", /* Options without debug */
288 NULL /* no do_assemble function */
300 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
301 1, 2, 2, 4, 1, 2, 3, 1, 4, 4
316 "XISEG (XDATA)", // initialized xdata
317 "XINIT (CODE)", // a code copy of xiseg
326 /* mcs51 has an 8 bit mul */
334 _mcs51_finaliseOptions,
335 _mcs51_setDefaultOptions,
336 mcs51_assignRegisters,
339 _mcs51_genAssemblerPreamble,
340 NULL, /* no genAssemblerEnd */
343 _mcs51_reset_regparm,
348 hasExtBitOp, /* hasExtBitOp */
349 oclsExpense, /* oclsExpense */
351 TRUE, /* little endian */
354 1, /* transform <= to ! > */
355 1, /* transform >= to ! < */
356 1, /* transform != to !(a == b) */
358 FALSE, /* No array initializer support. */
360 NULL, /* no builtin functions */
361 GPOINTER, /* treat unqualified pointers as "generic" pointers */
362 1, /* reset labelKey to 1 */
363 1, /* globals & local static allowed */