TSD PIC port
[fw/sdcc] / src / pic / main.c
1 /** @file main.c
2     pic14 specific general functions.
3
4     Note that mlh prepended _pic14_ on the static functions.  Makes
5     it easier to set a breakpoint using the debugger.
6 */
7 #include "common.h"
8 #include "main.h"
9 #include "ralloc.h"
10 #include "gen.h"
11
12 static char _defaultRules[] =
13 {
14 #include "peeph.rul"
15 };
16
17 /* list of key words used by msc51 */
18 static char *_pic14_keywords[] =     {
19     "at",
20     "bit",
21     "code",
22     "critical",
23     "data",
24     "far",
25     "idata",
26     "interrupt",
27     "near",
28     "pdata",
29     "reentrant",
30     "sfr",
31     "sbit",
32     "using",
33     "xdata",
34     "_data",
35     "_code",
36     "_generic",
37     "_near",
38     "_xdata",
39     "_pdata",
40     "_idata",
41     NULL
42 };
43
44
45 void pic14_assignRegisters (eBBlock **ebbs, int count);
46
47 static int regParmFlg = 0; /* determine if we can register a parameter */
48
49 static void _pic14_init(void)
50 {
51     asm_addTree(&asm_asxxxx_mapping);
52 }
53
54 static void _pic14_reset_regparm()
55 {
56     regParmFlg = 0;
57 }
58
59 static int _pic14_regparm( link *l)
60 {
61     /* for this processor it is simple
62        can pass only the first parameter in a register */
63     if (regParmFlg)
64         return 0;
65
66     regParmFlg = 1;
67     return 1;
68 }
69
70 static bool _pic14_parseOptions(int *pargc, char **argv, int *i)
71 {
72     /* TODO: allow port-specific command line options to specify
73      * segment names here.
74      */
75     return FALSE;
76 }
77
78 static void _pic14_finaliseOptions(void)
79 {
80     /* Hack-o-matic: if we are using the flat24 model,
81      * adjust pointer sizes.
82      */
83     if (options.model == MODEL_FLAT24)
84     {
85         
86         fprintf(stderr, "*** WARNING: you should use the '-mds390' option "
87                         "for DS80C390 support. This code generator is "
88                         "badly out of date and probably broken.\n");
89         
90         port->s.fptr_size = 3;
91         port->s.gptr_size = 4;
92         port->stack.isr_overhead++;   /* Will save dpx on ISR entry. */
93         #if 1
94         port->stack.call_overhead++;       /* This acounts for the extra byte 
95                                             * of return addres on the stack.
96                                             * but is ugly. There must be a 
97                                             * better way.
98                                             */
99         #endif
100         fReturn = fReturn390;
101         fReturnSize = 5;
102     } 
103
104     if (options.model == MODEL_LARGE) {
105         port->mem.default_local_map = xdata;
106         port->mem.default_globl_map = xdata;
107     } else {
108         port->mem.default_local_map = data;
109         port->mem.default_globl_map = data;
110     }
111     
112     if (options.stack10bit)
113     {
114         if (options.model != MODEL_FLAT24)
115         {
116             fprintf(stderr, 
117                     "*** warning: 10 bit stack mode is only supported in flat24 model.\n");
118             fprintf(stderr, "\t10 bit stack mode disabled.\n");
119             options.stack10bit = 0;
120         }
121         else
122         {
123             /* Fixup the memory map for the stack; it is now in
124              * far space and requires a FPOINTER to access it.
125              */
126             istack->fmap = 1;
127             istack->ptrType = FPOINTER; 
128         }
129     }
130 }
131
132 static void _pic14_setDefaultOptions(void)
133 {
134 }
135
136 static const char *_pic14_getRegName(struct regs *reg)
137 {
138     if (reg)
139         return reg->name;
140     return "err";
141 }
142
143 static void _pic14_genAssemblerPreamble(FILE *of)
144 {
145   fprintf(of,"\tlist\tp=16c84\n");
146   fprintf(of,"\t__config _wdt_off\n");
147   fprintf(of,"\ninclude \"p16c84.inc\"\n");
148 }
149
150 /* Generate interrupt vector table. */
151 static int _pic14_genIVT(FILE *of, symbol **interrupts, int maxInterrupts)
152 {
153     int i;
154     
155     if (options.model != MODEL_FLAT24)
156     {
157         /* Let the default code handle it. */
158         return FALSE;
159     }
160     
161     fprintf (of, "\t;ajmp\t__sdcc_gsinit_startup\n");
162     
163     /* now for the other interrupts */
164     for (i = 0; i < maxInterrupts; i++) 
165     {
166         if (interrupts[i])
167         {
168             fprintf(of, "\t;ljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
169         }
170         else
171         {
172             fprintf(of, "\t;reti\n\t.ds\t7\n");
173         }
174     }
175     
176     return TRUE;
177 }
178
179 /** $1 is always the basename.
180     $2 is always the output file.
181     $3 varies
182     $l is the list of extra options that should be there somewhere...
183     MUST be terminated with a NULL.
184 */
185 static const char *_linkCmd[] = {
186     "aslink", "-nf", "$1", NULL
187 };
188
189 static const char *_asmCmd[] = {
190  "gpasm", NULL, NULL, NULL
191
192 };
193
194 /* Globals */
195 PORT pic14_port = {
196     "pic14",
197     "MCU pic",                  /* Target name */
198     {
199         TRUE,                   /* Emit glue around main */
200         MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
201         MODEL_SMALL
202     },
203     {   
204       _asmCmd,
205         NULL,
206         NULL,
207         //"-plosgffc",          /* Options with debug */
208         //"-plosgff",           /* Options without debug */
209         0
210     },
211     {
212         _linkCmd,
213         NULL,
214         ".rel"
215     },
216     {
217         _defaultRules
218     },
219     {
220         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
221         1, 1, 2, 4, 1, 2, 3, 1, 4, 4
222     },
223     {
224         "XSEG    (XDATA)",
225         "STACK   (DATA)",
226         "CSEG    (CODE)",
227         "DSEG    (DATA)",
228         "ISEG    (DATA)",
229         "XSEG    (XDATA)",
230         "BSEG    (BIT)",
231         "RSEG    (DATA)",
232         "GSINIT  (CODE)",
233         "OSEG    (OVR,DATA)",
234         "GSFINAL (CODE)",
235         "HOME    (CODE)",
236         NULL,
237         NULL,
238         1
239     },
240     { 
241         +1, 1, 4, 1, 1, 0
242     },
243     /* pic14 has an 8 bit mul */
244     {
245         1, 0
246     },
247     "_",
248     _pic14_init,
249     _pic14_parseOptions,
250     _pic14_finaliseOptions,
251     _pic14_setDefaultOptions,
252     pic14_assignRegisters,
253     _pic14_getRegName ,
254     _pic14_keywords,
255     _pic14_genAssemblerPreamble,
256     _pic14_genIVT ,
257     _pic14_reset_regparm,
258     _pic14_regparm,
259     NULL,
260     FALSE,
261     0,  /* leave lt */
262     0,  /* leave gt */
263     1,  /* transform <= to ! > */
264     1,  /* transform >= to ! < */
265     1,  /* transform != to !(a == b) */
266     0   /* leave == */
267 };
268