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