ae09159413b05a947a1dc19709fe5b848277ed54
[fw/sdcc] / src / avr / gen.c
1 /*-------------------------------------------------------------------------
2   gen.c - source file for code generation for AVR
3   
4   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
6   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7   
8   This program is free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License as published by the
10   Free Software Foundation; either version 2, or (at your option) any
11   later version.
12   
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17   
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21   
22   In other words, you are welcome to use, share and improve this program.
23   You are forbidden to forbid anyone else to use, share and improve
24   what you give them.   Help stamp out software-hoarding!
25   
26   Notes:
27   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
28                 Made everything static
29 -------------------------------------------------------------------------*/
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include "SDCCglobl.h"
36
37 #ifdef HAVE_SYS_ISA_DEFS_H
38 #include <sys/isa_defs.h>
39 #else
40 #ifdef HAVE_ENDIAN_H
41 #include <endian.h>
42 #else
43 #ifndef __BORLANDC__
44 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
45 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
46 #endif
47 #endif
48 #endif
49
50 #include "common.h"
51 #include "SDCCpeeph.h"
52 #include "ralloc.h"
53 #include "gen.h"
54
55 char *aopLiteral (value *val, int offset);
56
57 /* this is the down and dirty file with all kinds of 
58    kludgy & hacky stuff. This is what it is all about
59    CODE GENERATION for a specific MCU . some of the
60    routines may be reusable, will have to see */
61
62 static char *zero = "#0x00";
63 static char *one  = "#0x01";
64
65 static struct {
66     short r0Pushed;
67     short r1Pushed;
68     short accInUse;
69     short inLine;
70     short debugLine;
71     short nRegsSaved;
72     set *sendSet;
73 } _G;
74
75 extern FILE *codeOutFile;
76
77 static lineNode *lineHead = NULL;
78 static lineNode *lineCurr = NULL;
79
80 /*-----------------------------------------------------------------*/
81 /* emitcode - writes the code into a file : for now it is simple    */
82 /*-----------------------------------------------------------------*/
83 static void emitcode (char *inst,char *fmt, ...)
84 {
85     va_list ap;
86     char lb[MAX_INLINEASM];  
87     char *lbp = lb;
88
89     va_start(ap,fmt);   
90
91     if (inst && *inst) {
92         if (fmt && *fmt)
93             sprintf(lb,"%s\t",inst);
94         else
95             sprintf(lb,"%s",inst);
96         vsprintf(lb+(strlen(lb)),fmt,ap);
97     }  else
98         vsprintf(lb,fmt,ap);
99
100     while (isspace(*lbp)) lbp++;
101
102     if (lbp && *lbp) 
103         lineCurr = (lineCurr ?
104                     connectLine(lineCurr,newLineNode(lb)) :
105                     (lineHead = newLineNode(lb)));
106     lineCurr->isInline = _G.inLine;
107     lineCurr->isDebug  = _G.debugLine;
108     va_end(ap);
109 }
110
111 /*-----------------------------------------------------------------*/
112 /* genAVRCode - generate code forAVR  based controllers            */
113 /*-----------------------------------------------------------------*/
114 void genAVRCode (iCode *lic)
115 {
116     iCode *ic;
117     int cln = 0;
118
119     lineHead = lineCurr = NULL;
120
121     /* if debug information required */
122 /*     if (options.debug && currFunc) { */
123     if (currFunc) {
124         cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
125         _G.debugLine = 1;
126         if (IS_STATIC(currFunc->etype))
127             emitcode("","F%s$%s$0$0 ==.",moduleName,currFunc->name); 
128         else
129             emitcode("","G$%s$0$0 ==.",currFunc->name);
130         _G.debugLine = 0;
131     }
132  
133     for (ic = lic ; ic ; ic = ic->next ) {
134         piCode(ic,stdout);
135     }
136
137     /* now we are ready to call the 
138        peep hole optimizer */
139     if (!options.nopeep)
140         peepHole (&lineHead);
141
142     /* now do the actual printing */
143     printLine (lineHead,codeOutFile);
144     return;
145 }