AVR specific changes
[fw/sdcc] / src / avr / main.c
1 /** @file main.c
2     avr specific general functions.
3
4     Note that mlh prepended _avr_ 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 *_avr_keywords[] =
19 {
20   "at",
21   "code",
22   "critical",
23   "eeprom",
24   "interrupt",
25   "sfr",
26   "xdata",
27   "_code",
28   "_eeprom",
29   "_generic",
30   "_xdata",
31   "sram",
32   "_sram",
33   "flash",
34   "_flash",
35   NULL
36 };
37
38 static int regParmFlg = 0;      /* determine if we can register a parameter */
39
40 static void
41 _avr_init (void)
42 {
43   asm_addTree (&asm_gas_mapping);
44 }
45
46 static void
47 _avr_reset_regparm ()
48 {
49   regParmFlg = 0;
50 }
51
52 static int
53 _avr_regparm (sym_link * l)
54 {
55   /* the first eight bytes will be passed in
56      registers r16-r23. but we won't split variables
57      i.e. if not enough registers left to hold
58      the parameter then the whole parameter along
59      with rest of the parameters go onto the stack */
60   if (regParmFlg < 8)
61     {
62       int size;
63       if ((size = getSize (l)) > (8 - regParmFlg))
64         {
65           /* all remaining go on stack */
66           regParmFlg = 8;
67           return 0;
68         }
69       regParmFlg += size;
70       return 1;
71     }
72
73   return 0;
74 }
75
76 void avr_assignRegisters (eBBlock ** ebbs, int count);
77
78 static bool
79 _avr_parseOptions (int *pargc, char **argv, int *i)
80 {
81   /* TODO: allow port-specific command line options to specify
82    * segment names here.
83    */
84   return FALSE;
85 }
86
87 static void
88 _avr_finaliseOptions (void)
89 {
90   port->mem.default_local_map =
91     port->mem.default_globl_map = xdata;
92   /* change stack to be in far space */
93   /* internal stack segment ;   
94      SFRSPACE       -   NO
95      FAR-SPACE      -   YES
96      PAGED          -   NO
97      DIRECT-ACCESS  -   NO
98      BIT-ACCESS     -   NO
99      CODE-ACESS     -   NO 
100      DEBUG-NAME     -   'B'
101      POINTER-TYPE   -   FPOINTER
102    */
103   istack = allocMap (0, 1, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', FPOINTER);
104
105   /* also change xdata to be direct space since we can use lds/sts */
106   xdata->direct = 1;
107
108 }
109
110 static void
111 _avr_setDefaultOptions (void)
112 {
113   options.stackAuto = 1;
114 }
115
116 static const char *
117 _avr_getRegName (struct regs *reg)
118 {
119   if (reg)
120     return reg->name;
121   return "err";
122 }
123
124 static void
125 _avr_genAssemblerPreamble (FILE * of)
126 {
127
128 }
129
130 /* Generate interrupt vector table. */
131 static int
132 _avr_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
133 {
134   return TRUE;
135 }
136
137 /** $1 is always the basename.
138     $2 is always the output file.
139     $3 varies
140     $l is the list of extra options that should be there somewhere...
141     MUST be terminated with a NULL.
142 */
143 static const char *_linkCmd[] =
144 {
145   "avr-ld", "", "$1", NULL
146 };
147
148 static const char *_asmCmd[] =
149 {
150   "avr-as", "", "$1.asm", NULL
151 };
152
153 /* Globals */
154 PORT avr_port =
155 {
156   "avr",
157   "ATMEL AVR",                  /* Target name */
158   {
159     TRUE,                       /* Emit glue around main */
160     MODEL_LARGE | MODEL_SMALL,
161     MODEL_SMALL
162   },
163   {
164     _asmCmd,
165     "-plosgffc",                /* Options with debug */
166     "-plosgff",                 /* Options without debug */
167     0
168   },
169   {
170     _linkCmd,
171     NULL,
172     ".rel"
173   },
174   {
175     _defaultRules
176   },
177   {
178         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
179     1, 1, 2, 4, 2, 2, 3, 1, 4, 4
180   },
181   {
182     "XSEG    (XDATA)",
183     "STACK   (DATA)",
184     "CSEG    (CODE)",
185     "DSEG    (DATA)",
186     "ISEG    (DATA)",
187     "XSEG    (XDATA)",
188     "BSEG    (BIT)",
189     "RSEG    (DATA)",
190     "GSINIT  (CODE)",
191     "OSEG    (OVR,DATA)",
192     "GSFINAL (CODE)",
193     "HOME        (CODE)",
194     NULL,
195     NULL,
196     0,
197   },
198   {
199     -1, 1, 4, 1, 1, 0
200   },
201     /* avr has an 8 bit mul */
202   {
203     1, 0
204   },
205   "_",
206   _avr_init,
207   _avr_parseOptions,
208   _avr_finaliseOptions,
209   _avr_setDefaultOptions,
210   avr_assignRegisters,
211   _avr_getRegName,
212   _avr_keywords,
213   _avr_genAssemblerPreamble,
214   _avr_genIVT,
215   _avr_reset_regparm,
216   _avr_regparm,
217   NULL,
218   FALSE,
219   0,                            /* leave lt */
220   1,                            /* transform gt ==> not le */
221   0,                            /* leave le */
222   0,                            /* leave ge */
223   0,                            /* leave !=  */
224   0,                            /* leave == */
225   PORT_MAGIC
226 };