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 copy XINIT to XISEG */
157 static void _mcs51_genXINIT (FILE * of) {
158 fprintf (of, "; _mcs51_genXINIT() start\n");
159 fprintf (of, " mov r1,#l_XINIT\n");
160 fprintf (of, " mov r2,#(l_XINIT >> 8)\n");
161 fprintf (of, " mov a,r1\n");
162 fprintf (of, " orl a,r2\n");
163 fprintf (of, " jz 00003$\n");
164 fprintf (of, " mov r2,#((l_XINIT+255) >> 8)\n");
165 fprintf (of, " mov dptr,#s_XINIT\n");
166 fprintf (of, " mov r0,#s_XISEG\n");
167 fprintf (of, " mov p2,#(s_XISEG >> 8)\n");
168 fprintf (of, "00001$: clr a\n");
169 fprintf (of, " movc a,@a+dptr\n");
170 fprintf (of, " movx @r0,a\n");
171 fprintf (of, " inc dptr\n");
172 fprintf (of, " inc r0\n");
173 fprintf (of, " cjne r0,#0,00002$\n");
174 fprintf (of, " inc p2\n");
175 fprintf (of, "00002$: djnz r1,00001$\n");
176 fprintf (of, " djnz r2,00001$\n");
177 fprintf (of, " mov p2,#0xFF\n");
178 fprintf (of, "00003$:\n");
179 fprintf (of, "; _mcs51_genXINIT() end\n");
183 /* Do CSE estimation */
184 static bool cseCostEstimation (iCode *ic, iCode *pdic)
186 operand *result = IC_RESULT(ic);
187 sym_link *result_type = operandType(result);
189 /* if it is a pointer then return ok for now */
190 if (IC_RESULT(ic) && IS_PTR(result_type)) return 1;
192 /* if bitwise | add & subtract then no since mcs51 is pretty good at it
193 so we will cse only if they are local (i.e. both ic & pdic belong to
194 the same basic block */
195 if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') {
196 /* then if they are the same Basic block then ok */
197 if (ic->eBBlockNum == pdic->eBBlockNum) return 1;
201 /* for others it is cheaper to do the cse */
205 /* Indicate which extended bit operations this port supports */
207 hasExtBitOp (int op, int size)
212 || (op == SWAP && size <= 2)
219 /* Indicate the expense of an access to an output storage class */
221 oclsExpense (struct memmap *oclass)
223 if (IN_FARSPACE(oclass))
229 /** $1 is always the basename.
230 $2 is always the output file.
232 $l is the list of extra options that should be there somewhere...
233 MUST be terminated with a NULL.
235 static const char *_linkCmd[] =
237 "aslink", "-nf", "\"$1\"", NULL
240 /* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
241 static const char *_asmCmd[] =
243 "asx8051", "$l", "$3", "\"$1.asm\"", NULL
251 "MCU 8051", /* Target name */
252 NULL, /* Processor name */
255 TRUE, /* Emit glue around main */
256 MODEL_SMALL | MODEL_LARGE,
262 "-plosgffc", /* Options with debug */
263 "-plosgff", /* Options without debug */
266 NULL /* no do_assemble function */
278 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
279 1, 2, 2, 4, 1, 2, 3, 1, 4, 4
294 "XISEG (XDATA)", // initialized xdata
295 "XINIT (CODE)", // a code copy of xiseg
304 /* mcs51 has an 8 bit mul */
312 _mcs51_finaliseOptions,
313 _mcs51_setDefaultOptions,
314 mcs51_assignRegisters,
317 _mcs51_genAssemblerPreamble,
318 NULL, /* no genAssemblerEnd */
321 _mcs51_reset_regparm,
326 hasExtBitOp, /* hasExtBitOp */
327 oclsExpense, /* oclsExpense */
329 TRUE, /* little endian */
332 1, /* transform <= to ! > */
333 1, /* transform >= to ! < */
334 1, /* transform != to !(a == b) */
336 FALSE, /* No array initializer support. */
338 NULL, /* no builtin functions */
339 GPOINTER, /* treat unqualified pointers as "generic" pointers */
340 1, /* reset labelKey to 1 */
341 1, /* globals & local static allowed */