Go to single file .html
[fw/sdcc] / doc / SDCCUdoc-25.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2 <HTML>
3 <HEAD>
4  <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.7">
5  <TITLE>SDCC Compiler User Guide: TIPS</TITLE>
6  <LINK HREF="SDCCUdoc-26.html" REL=next>
7  <LINK HREF="SDCCUdoc-24.html" REL=previous>
8  <LINK HREF="SDCCUdoc.html#toc25" REL=contents>
9 </HEAD>
10 <BODY>
11 <A HREF="SDCCUdoc-26.html">Next</A>
12 <A HREF="SDCCUdoc-24.html">Previous</A>
13 <A HREF="SDCCUdoc.html#toc25">Contents</A>
14 <HR>
15 <H2><A NAME="Tips"></A> <A NAME="s25">25. TIPS</A> </H2>
16
17 <P>Here are a few guide-lines that will help the compiler generate more efficient
18 code, some of the tips are specific to this compiler others are generally good
19 programming practice.
20 <P>
21 <UL>
22 <LI>Use the smallest data type to represent your data-value. If it is known
23 in advance that the value is going to be less than 256 then use a 'short' or
24 'char' instead of an 'int'.</LI>
25 <LI>Use unsigned when it is known in advance that the value is not going to
26 be negative. This helps especially if you are doing division or multiplication.</LI>
27 <LI>NEVER jump into a LOOP.</LI>
28 <LI>Declare the variables to be local whenever possible, especially loop control
29 variables (induction).</LI>
30 <LI>Since the compiler does not do implicit integral promotion, the programmer
31 should do an explicit cast when integral promotion is required.</LI>
32 <LI>Reducing the size of division , multiplication &amp; modulus operations
33 can reduce code size substantially. Take the following code for example.
34 <PRE>
35 foobar( unsigned int p1, unsigned char ch)
36 {
37     unsigned char ch1
38  = p1 % ch ;
39     ....    
40 }
41   
42 </PRE>
43
44 <P>For the modulus operation the variable ch will be promoted to unsigned
45 int first then the modulus operation will be performed (this will lead to a
46 call to a support routine). If the code is changed to 
47
48 <P>
49 <PRE>
50 foobar( unsigned int p1, unsigned char ch)
51 {
52     unsigned char ch1
53  = (unsigned char)p1 % ch ;
54     ....    
55 }
56   
57 </PRE>
58 <P>It would substantially reduce the code generated (future versions of the
59 compiler will be smart enough to detect such optimization oppurtunities).
60 </LI>
61 </UL>
62 <P><B>Notes from an USER ( Trefor@magera.freeserve.co.uk )</B>
63 <P>The 8051 family of micro controller have a minimum of 128 bytes of internal
64 memory which is structured as follows
65 <P>- Bytes 00-1F - 32 bytes to hold up to 4 banks of the registers R7 to R7
66 <P>
67 <P>- Bytes 20-2F - 16 bytes to hold 128 bit variables and 
68 <P>- Bytes 30-7F - 60 bytes for general purpose use.
69 <P>Normally the SDCC compiler will only utilise the first bank of registers,
70 but it is possible to specify that other banks of registers should be used
71 in interrupt routines. By default, the compiler will place the stack after
72 the last bank of used registers, i.e. if the first 2 banks of registers are
73 used, it will position the base of the internal stack at address 16 (0X10).
74 This implies that as the stack grows, it will use up the remaining register
75 banks, and the 16 bytes used by the 128 bit variables, and 60 bytes for general
76 purpose use.
77 <P>By default, the compiler uses the 60 general purpose bytes to hold &quot;near
78 data&quot;. The compiler/optimiser may also declare some Local Variables in
79 this area to hold local data. 
80 <P>If any of the 128 bit variables are used, or near data is being used then
81 care needs to be taken to ensure that the stack does not grow so much that
82 it starts to over write either your bit variables or &quot;near data&quot;.
83 There is no runtime checking to prevent this from happening.
84 <P>The amount of stack being used is affected by the use of the &quot;internal
85 stack&quot; to save registers before a subroutine call is made, - --stack-auto
86 will declare parameters and local variables on the stack - the number of nested
87 subroutines.
88 <P>If you detect that the stack is over writing you data, then the following
89 can be done. --xstack will cause an external stack to be used for saving registers
90 and (if --stack-auto is being used) storing parameters and local variables.
91 However this will produce more and code which will be slower to execute. 
92 <P>--stack-loc will allow you specify the start of the stack, i.e. you could
93 start it after any data in the general purpose area. However this may waste
94 the memory not used by the register banks and if the size of the &quot;near
95 data&quot; increases, it may creep into the bottom of the stack.
96 <P>--stack-after-data, similar to the --stack-loc, but it automatically places
97 the stack after the end of the &quot;near data&quot;. Again this could waste
98 any spare register space.
99 <P>--data-loc allows you to specify the start address of the near data. This
100 could be used to move the &quot;near data&quot; further away from the stack
101 giving it more room to grow. This will only work if no bit variables are being
102 used and the stack can grow to use the bit variable space.
103 <P>Conclusion.
104 <P>If you find that the stack is over writing your bit variables or &quot;near
105 data&quot; then the approach which best utilised the internal memory is to
106 position the &quot;near data&quot; after the last bank of used registers
107 or, if you use bit variables, after the last bit variable by using the --data-loc,
108 e.g. if two register banks are being used and no data variables, --data-loc
109 16, and - use the --stack-after-data option.
110 <P>If bit variables are being used, another method would be to try and squeeze
111 the data area in the unused register banks if it will fit, and start the stack
112 after the last bit variable.
113 <HR>
114 <A HREF="SDCCUdoc-26.html">Next</A>
115 <A HREF="SDCCUdoc-24.html">Previous</A>
116 <A HREF="SDCCUdoc.html#toc25">Contents</A>
117 </BODY>
118 </HTML>