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