+\series bold
+---dumpraw
+\series default
+ This option will cause the compiler to dump the intermediate code into
+ a file of named
+\emph on
+<source filename>.dumpraw
+\emph default
+ just after the intermediate code has been generated for a function, i.e.
+ before any optimizations are done.
+ The basic blocks at this stage ordered in the depth first number, so they
+ may not be in sequence of execution.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+---dumpgcse
+\series default
+ Will create a dump of iCode's, after global subexpression elimination,
+ into a file named
+\emph on
+<source filename>.dumpgcse.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+---dumpdeadcode
+\series default
+ Will create a dump of iCode's, after deadcode elimination, into a file
+ named
+\emph on
+<source filename>.dumpdeadcode.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+---dumploop
+\series default
+\size large
+
+\size default
+Will create a dump of iCode's, after loop optimizations, into a file named
+
+\emph on
+<source filename>.dumploop.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+---dumprange
+\series default
+\size large
+
+\size default
+Will create a dump of iCode's, after live range analysis, into a file named
+
+\emph on
+<source filename>.dumprange.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+---dumlrange
+\series default
+ Will dump the life ranges for all symbols.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+---dumpregassign
+\bar under
+
+\series default
+\bar default
+Will create a dump of iCode's, after register assignment, into a file named
+
+\emph on
+<source filename>.dumprassgn.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+---dumplrange
+\series default
+ Will create a dump of the live ranges of iTemp's
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+---dumpall
+\size large
+\bar under
+
+\series default
+\size default
+\bar default
+Will cause all the above mentioned dumps to be created.
+\layout Subsection
+
+Environment variables
+\layout Standard
+
+SDCC recognizes the following environment variables:
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+SDCC_LEAVE_SIGNALS
+\series default
+ SDCC installs a signal handler to be able to delete temporary files after
+ an user break (^C) or an exception.
+ If this environment variable is set, SDCC won't install the signal handler
+ in order to be able to debug SDCC.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+TMP,\SpecialChar ~
+TEMP,\SpecialChar ~
+TMPDIR
+\series default
+ Path, where temporary files will be created.
+ The order of the variables is the search order.
+ In a standard *nix environment these variables are not set, and there's
+ no need to set them.
+ On Windows it's recommended to set one of them.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+SDCC_HOME
+\series default
+ Path, see
+\begin_inset Quotes sld
+\end_inset
+
+2.3 Install and search paths
+\begin_inset Quotes srd
+\end_inset
+
+.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+SDCC_INCLUDE
+\series default
+ Path, see
+\begin_inset Quotes sld
+\end_inset
+
+2.3 Install and search paths
+\begin_inset Quotes srd
+\end_inset
+
+.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold
+SDCC_LIB
+\series default
+ Path, see
+\begin_inset Quotes sld
+\end_inset
+
+2.3 Install and search paths
+\begin_inset Quotes srd
+\end_inset
+
+.
+\layout Standard
+
+There are some more environment variables recognized by SDCC, but these
+ are solely used for debugging purposes.
+ They can change or disappear very quickly, and will never be documentated.
+\layout Subsection
+
+MCS51/DS390 Storage Class Language Extensions
+\layout Standard
+
+In addition to the ANSI storage classes SDCC allows the following MCS51
+ specific storage classes.
+\layout Subsubsection
+
+xdata
+\layout Standard
+
+Variables declared with this storage class will be placed in the extern
+ RAM.
+ This is the
+\series bold
+default
+\series default
+ storage class for Large Memory model, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+xdata unsigned char xduc;
+\layout Subsubsection
+
+data
+\layout Standard
+
+This is the
+\series bold
+default
+\series default
+ storage class for Small Memory model.
+ Variables declared with this storage class will be allocated in the internal
+ RAM, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+data int iramdata;
+\layout Subsubsection
+
+idata
+\layout Standard
+
+Variables declared with this storage class will be allocated into the indirectly
+ addressable portion of the internal ram of a 8051, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+idata int idi;
+\layout Subsubsection
+
+bit
+\layout Standard
+
+This is a data-type and a storage class specifier.
+ When a variable is declared as a bit, it is allocated into the bit addressable
+ memory of 8051, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+bit iFlag;
+\layout Subsubsection
+
+sfr / sbit
+\layout Standard
+
+Like the bit keyword,
+\emph on
+sfr / sbit
+\emph default
+signifies both a data-type and storage class, they are used to describe
+ the special function registers and special bit variables of a 8051, eg:
+\newline
+
+\newline
+
+\family typewriter
+sfr at 0x80 P0; /* special function register P0 at location 0x80 */
+\newline
+sbit at 0xd7 CY; /* CY (Carry Flag) */
+\layout Subsection
+
+Pointers
+\layout Standard
+
+SDCC allows (via language extensions) pointers to explicitly point to any
+ of the memory spaces of the 8051.
+ In addition to the explicit pointers, the compiler uses (by default) generic
+ pointers which can be used to point to any of the memory spaces.
+\newline
+
+\newline
+Pointer declaration examples:
+\newline
+
+\size small
+
+\newline
+
+\family typewriter
+\size default
+/* pointer physically in xternal ram pointing to object in internal ram
+ */
+\newline
+data unsigned char * xdata p;
+\newline
+
+\newline
+/* pointer physically in code rom pointing to data in xdata space */
+\newline
+xdata unsigned char * code p;
+\newline
+
+\newline
+/* pointer physically in code space pointing to data in code space */
+\newline
+code unsigned char * code p;
+\newline
+
+\newline
+/* the folowing is a generic pointer physically located in xdata space */
+\newline
+char * xdata p;
+\family default
+\size small
+
+\newline
+
+\newline
+
+\size default
+Well you get the idea.
+
+\newline
+
+\newline
+All unqualified pointers are treated as 3-byte (4-byte for the ds390)
+\emph on
+generic
+\emph default
+ pointers.
+
+\size small
+
+\newline
+
+\newline
+
+\size default
+The highest order byte of the
+\emph on
+generic
+\emph default
+ pointers contains the data space information.
+ Assembler support routines are called whenever data is stored or retrieved
+ using
+\emph on
+generic
+\emph default
+ pointers.
+ These are useful for developing reusable library routines.
+ Explicitly specifying the pointer type will generate the most efficient
+ code.
+\layout Subsection
+
+Parameters & Local Variables
+\layout Standard
+
+Automatic (local) variables and parameters to functions can either be placed
+ on the stack or in data-space.
+ The default action of the compiler is to place these variables in the internal
+ RAM (for small model) or external RAM (for large model).
+ This in fact makes them
+\emph on
+static
+\emph default
+ so by default functions are non-reentrant.
+\newline
+
+\newline
+They can be placed on the stack either by using the
+\emph on
+ ---stack-auto
+\emph default
+ option or by using the
+\emph on
+reentrant
+\emph default
+ keyword in the function declaration, e.g.:
+\newline
+
+\size small
+
+\newline
+
+\family typewriter
+\size default
+unsigned char foo(char i) reentrant
+\newline
+{
+\newline
+...
+
+\newline
+}
+\newline
+
+\family default
+
+\newline
+Since stack space on 8051 is limited, the
+\emph on
+reentrant
+\emph default
+keyword or the
+\emph on
+ ---stack-auto
+\emph default
+ option should be used sparingly.
+ Note that the reentrant keyword just means that the parameters & local
+ variables will be allocated to the stack, it
+\emph on
+does not
+\emph default
+ mean that the function is register bank independent.
+\newline
+
+\newline
+Local variables can be assigned storage classes and absolute addresses,
+ e.g.:
+\newline
+
+\newline
+
+\family typewriter
+unsigned char foo() {
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+xdata unsigned char i;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+bit bvar;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+data at 0x31 unsiged char j;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+...
+
+\newline
+}
+\newline
+
+\newline
+
+\family default
+In the above example the variable
+\emph on
+i
+\emph default
+ will be allocated in the external ram,
+\emph on
+bvar
+\emph default
+ in bit addressable space and
+\emph on
+ j
+\emph default
+ in internal ram.
+ When compiled with
+\emph on
+---stack-auto
+\emph default
+ or when a function is declared as
+\emph on
+reentrant
+\emph default
+ this should only be done for static variables.
+\layout Standard
+
+Parameters however are not allowed any storage class, (storage classes for
+ parameters will be ignored), their allocation is governed by the memory
+ model in use, and the reentrancy options.
+\layout Subsection
+
+Overlaying
+\layout Standard
+
+For non-reentrant functions SDCC will try to reduce internal ram space usage
+ by overlaying parameters and local variables of a function (if possible).
+ Parameters and local variables of a function will be allocated to an overlayabl
+e segment if the function has
+\emph on
+no other function calls and the function is non-reentrant and the memory
+ model is small.
+
+\emph default
+ If an explicit storage class is specified for a local variable, it will
+ NOT be overlayed.
+\layout Standard
+
+Note that the compiler (not the linkage editor) makes the decision for overlayin
+g the data items.
+ Functions that are called from an interrupt service routine should be preceded
+ by a #pragma\SpecialChar ~
+NOOVERLAY if they are not reentrant.
+\layout Standard
+
+Also note that the compiler does not do any processing of inline assembler
+ code, so the compiler might incorrectly assign local variables and parameters
+ of a function into the overlay segment if the inline assembler code calls
+ other c-functions that might use the overlay.
+ In that case the #pragma\SpecialChar ~
+NOOVERLAY should be used.
+\layout Standard
+
+Parameters and Local variables of functions that contain 16 or 32 bit multiplica
+tion or division will NOT be overlayed since these are implemented using
+ external functions, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+#pragma SAVE
+\newline
+#pragma NOOVERLAY
+\newline
+void set_error(unsigned char errcd)
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+P3 = errcd;
+\newline
+}
+\newline
+#pragma RESTORE
+\newline
+
+\newline
+void some_isr () interrupt 2 using 1
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+...
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+set_error(10);
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+...
+
+\newline
+}
+\newline
+
+\newline
+
+\family default
+In the above example the parameter
+\emph on
+errcd
+\emph default
+ for the function
+\emph on
+set_error
+\emph default
+ would be assigned to the overlayable segment if the #pragma\SpecialChar ~
+NOOVERLAY was
+ not present, this could cause unpredictable runtime behavior when called
+ from an ISR.
+ The #pragma\SpecialChar ~
+NOOVERLAY ensures that the parameters and local variables for
+ the function are NOT overlayed.
+\layout Subsection
+
+Interrupt Service Routines
+\layout Standard
+
+SDCC allows interrupt service routines to be coded in C, with some extended
+ keywords.
+\newline
+
+\newline
+
+\family typewriter
+void timer_isr (void) interrupt 2 using 1
+\newline
+{
+\newline
+..
+
+\newline
+}
+\newline
+
+\newline
+
+\family default
+The number following the
+\emph on
+interrupt
+\emph default
+ keyword is the interrupt number this routine will service.
+ The compiler will insert a call to this routine in the interrupt vector
+ table for the interrupt number specified.
+ The
+\emph on
+using
+\emph default
+ keyword is used to tell the compiler to use the specified register bank
+ (8051 specific) when generating code for this function.
+ Note that when some function is called from an interrupt service routine
+ it should be preceded by a #pragma\SpecialChar ~
+NOOVERLAY if it is not reentrant.
+ A special note here, int (16 bit) and long (32 bit) integer division, multiplic
+ation & modulus operations are implemented using external support routines
+ developed in ANSI-C, if an interrupt service routine needs to do any of
+ these operations then the support routines (as mentioned in a following
+ section) will have to be recompiled using the
+\emph on
+ ---stack-auto
+\emph default
+ option and the source file will need to be compiled using the
+\emph on
+---int-long-ren
+\emph default
+t compiler option.
+\layout Standard
+
+If you have multiple source files in your project, interrupt service routines
+ can be present in any of them, but a prototype of the isr MUST be present
+ or included in the file that contains the function
+\emph on
+main
+\emph default
+.
+\layout Standard
+
+Interrupt Numbers and the corresponding address & descriptions for the Standard
+ 8051 are listed below.
+ SDCC will automatically adjust the interrupt vector table to the maximum
+ interrupt number specified.
+\newline
+
+\layout Standard
+
+
+\begin_inset Tabular
+<lyxtabular version="3" rows="6" columns="3">
+<features>
+<column alignment="center" valignment="top" leftline="true" width="0in">
+<column alignment="center" valignment="top" leftline="true" width="0in">
+<column alignment="center" valignment="top" leftline="true" rightline="true" width="0in">
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+Interrupt #
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+Description
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+Vector Address
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+External 0
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0x0003
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+1
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+Timer 0
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0x000B
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+2
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+External 1
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0x0013
+\end_inset
+</cell>
+</row>
+<row topline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+3
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+Timer 1
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0x001B
+\end_inset
+</cell>
+</row>
+<row topline="true" bottomline="true">
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+4
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+Serial
+\end_inset
+</cell>
+<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none">
+\begin_inset Text
+
+\layout Standard
+
+0x0023
+\end_inset
+</cell>
+</row>
+</lyxtabular>
+
+\end_inset
+
+
+\newline
+
+\newline
+If the interrupt service routine is defined without
+\emph on
+using
+\emph default
+ a register bank or with register bank 0 (using 0), the compiler will save
+ the registers used by itself on the stack upon entry and restore them at
+ exit, however if such an interrupt service routine calls another function
+ then the entire register bank will be saved on the stack.
+ This scheme may be advantageous for small interrupt service routines which
+ have low register usage.
+\layout Standard
+
+If the interrupt service routine is defined to be using a specific register
+ bank then only
+\emph on
+a, b & dptr
+\emph default
+ are save and restored, if such an interrupt service routine calls another
+ function (using another register bank) then the entire register bank of
+ the called function will be saved on the stack.
+ This scheme is recommended for larger interrupt service routines.
+\layout Standard
+
+Calling other functions from an interrupt service routine is not recommended,
+ avoid it if possible.
+\newline
+
+\newline
+Also see the _naked modifier.
+\layout Subsection
+
+Critical Functions
+\layout Standard
+
+
+\shape italic
+<TODO: this isn't implemented at all!>
+\shape default
+
+\newline
+
+\newline
+A special keyword may be associated with a function declaring it as
+\emph on
+critical
+\emph default
+.
+ SDCC will generate code to disable all interrupts upon entry to a critical
+ function and enable them back before returning.
+ Note that nesting critical functions may cause unpredictable results.
+\newline
+
+\size small
+
+\newline
+
+\family typewriter
+\size default
+int foo () critical
+\newline
+{
+\newline
+...
+
+\newline
+...
+
+\newline
+}
+\newline
+
+\family default
+
+\newline
+The critical attribute maybe used with other attributes like
+\emph on
+reentrant.
+\layout Subsection
+
+Naked Functions
+\layout Standard
+
+A special keyword may be associated with a function declaring it as
+\emph on
+_naked.
+
+\emph default
+The
+\emph on
+_naked
+\emph default
+ function modifier attribute prevents the compiler from generating prologue
+ and epilogue code for that function.
+ This means that the user is entirely responsible for such things as saving
+ any registers that may need to be preserved, selecting the proper register
+ bank, generating the
+\emph on
+return
+\emph default
+ instruction at the end, etc.
+ Practically, this means that the contents of the function must be written
+ in inline assembler.
+ This is particularly useful for interrupt functions, which can have a large
+ (and often unnecessary) prologue/epilogue.
+ For example, compare the code generated by these two functions:
+\newline
+
+\newline
+
+\family typewriter
+data unsigned char counter;
+\newline
+void simpleInterrupt(void) interrupt 1
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+counter++;
+\newline
+}
+\newline
+
+\newline
+void nakedInterrupt(void) interrupt 2 _naked
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_asm
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+inc\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_counter
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+reti\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; MUST explicitly include ret in _naked function.
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_endasm;
+\newline
+}
+\family default
+
+\newline
+
+\newline
+For an 8051 target, the generated simpleInterrupt looks like:
+\newline
+
+\newline
+
+\family typewriter
+_simpleIterrupt:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+acc
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+b
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dpl
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dph
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+push\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+psw
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+psw,#0x00
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+inc\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_counter
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+psw
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dph
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+dpl
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+b
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+pop\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+acc
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+reti
+\family default
+
+\newline
+
+\newline
+whereas nakedInterrupt looks like:
+\newline
+
+\newline
+
+\family typewriter
+_nakedInterrupt:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+inc\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_counter
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+reti\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; MUST explicitly include ret(i) in _naked function.
+\family default
+
+\newline
+
+\newline
+While there is nothing preventing you from writing C code inside a _naked
+ function, there are many ways to shoot yourself in the foot doing this,
+ and it is recommended that you stick to inline assembler.
+\layout Subsection
+
+Functions using private banks
+\layout Standard
+
+The
+\emph on
+using
+\emph default
+ attribute (which tells the compiler to use a register bank other than the
+ default bank zero) should only be applied to
+\emph on
+interrupt
+\emph default
+ functions (see note 1 below).
+ This will in most circumstances make the generated ISR code more efficient
+ since it will not have to save registers on the stack.
+\layout Standard
+
+The
+\emph on
+using
+\emph default
+ attribute will have no effect on the generated code for a
+\emph on
+non-interrupt
+\emph default
+ function (but may occasionally be useful anyway
+\begin_inset Foot
+collapsed true
+
+\layout Standard
+
+possible exception: if a function is called ONLY from 'interrupt' functions
+ using a particular bank, it can be declared with the same 'using' attribute
+ as the calling 'interrupt' functions.
+ For instance, if you have several ISRs using bank one, and all of them
+ call memcpy(), it might make sense to create a specialized version of memcpy()
+ 'using 1', since this would prevent the ISR from having to save bank zero
+ to the stack on entry and switch to bank zero before calling the function
+\end_inset
+
+).
+\newline
+
+\emph on
+(pending: I don't think this has been done yet)
+\layout Standard
+
+An
+\emph on
+interrupt
+\emph default
+ function using a non-zero bank will assume that it can trash that register
+ bank, and will not save it.
+ Since high-priority interrupts can interrupt low-priority ones on the 8051
+ and friends, this means that if a high-priority ISR
+\emph on
+using
+\emph default
+ a particular bank occurs while processing a low-priority ISR
+\emph on
+using
+\emph default
+ the same bank, terrible and bad things can happen.
+ To prevent this, no single register bank should be
+\emph on
+used
+\emph default
+ by both a high priority and a low priority ISR.
+ This is probably most easily done by having all high priority ISRs use
+ one bank and all low priority ISRs use another.
+ If you have an ISR which can change priority at runtime, you're on your
+ own: I suggest using the default bank zero and taking the small performance
+ hit.
+\layout Standard
+
+It is most efficient if your ISR calls no other functions.
+ If your ISR must call other functions, it is most efficient if those functions
+ use the same bank as the ISR (see note 1 below); the next best is if the
+ called functions use bank zero.
+ It is very inefficient to call a function using a different, non-zero bank
+ from an ISR.
+
+\layout Subsection
+
+Absolute Addressing
+\layout Standard
+
+Data items can be assigned an absolute address with the
+\emph on
+at <address>
+\emph default
+ keyword, in addition to a storage class, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+xdata at 0x8000 unsigned char PORTA_8255 ;
+\newline
+
+\family default
+
+\newline
+In the above example the PORTA_8255 will be allocated to the location 0x8000
+ of the external ram.
+ Note that this feature is provided to give the programmer access to
+\emph on
+memory mapped
+\emph default
+ devices attached to the controller.
+ The compiler does not actually reserve any space for variables declared
+ in this way (they are implemented with an equate in the assembler).
+ Thus it is left to the programmer to make sure there are no overlaps with
+ other variables that are declared without the absolute address.
+ The assembler listing file (.lst) and the linker output files (.rst) and
+ (.map) are a good places to look for such overlaps.
+\newline
+
+\newline
+Absolute address can be specified for variables in all storage classes,
+ e.g.:
+\newline
+
+\newline
+
+\family typewriter
+bit at 0x02 bvar;
+\newline
+
+\newline
+
+\family default
+The above example will allocate the variable at offset 0x02 in the bit-addressab
+le space.
+ There is no real advantage to assigning absolute addresses to variables
+ in this manner, unless you want strict control over all the variables allocated.
+\layout Subsection
+
+Startup Code
+\layout Standard
+
+The compiler inserts a call to the C routine
+\emph on
+_sdcc__external__startup()
+\series bold
+\emph default
+
+\series default
+at the start of the CODE area.
+ This routine is in the runtime library.
+ By default this routine returns 0, if this routine returns a non-zero value,
+ the static & global variable initialization will be skipped and the function
+ main will be invoked Other wise static & global variables will be initialized
+ before the function main is invoked.
+ You could add a
+\emph on
+_sdcc__external__startup()
+\emph default
+ routine to your program to override the default if you need to setup hardware
+ or perform some other critical operation prior to static & global variable
+ initialization.
+\layout Subsection
+
+Inline Assembler Code
+\layout Standard
+
+SDCC allows the use of in-line assembler with a few restriction as regards
+ labels.
+ All labels defined within inline assembler code
+\emph on
+has to be
+\emph default
+ of the form
+\emph on
+nnnnn$
+\emph default
+ where nnnn is a number less than 100 (which implies a limit of utmost 100
+ inline assembler labels
+\emph on
+per function
+\emph default
+\noun on
+)
+\noun default
+.
+ It is strongly recommended that each assembly instruction (including labels)
+ be placed in a separate line (as the example shows).
+ When the
+\emph on
+---peep-asm
+\emph default
+ command line option is used, the inline assembler code will be passed through
+ the peephole optimizer.
+ This might cause some unexpected changes in the inline assembler code.
+ Please go throught the peephole optimizer rules defined in file
+\emph on
+SDCCpeeph.def
+\emph default
+ carefully before using this option.
+\newline
+
+\newline
+
+\family typewriter
+_asm
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mov\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+b,#10
+\newline
+00001$:
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+djnz\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+b,00001$
+\newline
+_endasm ;
+\family default
+\size small
+
+\newline
+
+\newline
+
+\size default
+The inline assembler code can contain any valid code understood by the assembler
+, this includes any assembler directives and comment lines.
+ The compiler does not do any validation of the code within the
+\family typewriter
+_asm ...
+ _endasm;
+\family default
+ keyword pair.
+
+\newline
+
+\newline
+Inline assembler code cannot reference any C-Labels, however it can reference
+ labels defined by the inline assembler, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+foo() {
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+/* some c code */
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_asm
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+; some assembler code
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+ljmp $0003
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_endasm;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+/* some more c code */
+\newline
+clabel:\SpecialChar ~
+\SpecialChar ~
+/* inline assembler cannot reference this label */
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_asm
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+$0003: ;label (can be reference by inline assembler only)
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+_endasm ;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+/* some more c code */
+\newline
+}
+\newline
+
+\newline
+
+\family default
+In other words inline assembly code can access labels defined in inline
+ assembly within the scope of the funtion.
+
+\layout Standard
+
+The same goes the other way, ie.
+ labels defines in inline assembly CANNOT be accessed by C statements.
+\layout Subsection
+
+int (16 bit) and long (32 bit) Support
+\layout Standard
+
+For signed & unsigned int (16 bit) and long (32 bit) variables, division,
+ multiplication and modulus operations are implemented by support routines.
+ These support routines are all developed in ANSI-C to facilitate porting
+ to other MCUs, although some model specific assembler optimations are used.
+ The following files contain the described routine, all of them can be found
+ in <installdir>/share/sdcc/lib.
+\newline
+
+\newline
+
+\emph on
+<pending: tabularise this>
+\emph default
+
+\newline
+
+\newline
+_mulsint.c - signed 16 bit multiplication (calls _muluint)
+\newline
+_muluint.c - unsigned 16 bit multiplication
+\newline
+_divsint.c - signed 16 bit division (calls _divuint)
+\newline
+_divuint.c - unsigned 16 bit division
+\newline
+_modsint.c - signed 16 bit modulus (call _moduint)
+\newline
+_moduint.c - unsigned 16 bit modulus
+\newline
+_mulslong.c - signed 32 bit multiplication (calls _mululong)
+\newline
+_mululong.c - unsigned32 bit multiplication
+\newline
+_divslong.c - signed 32 division (calls _divulong)
+\newline
+_divulong.c - unsigned 32 division
+\newline
+_modslong.c - signed 32 bit modulus (calls _modulong)
+\newline
+_modulong.c - unsigned 32 bit modulus
+\size footnotesize
+
+\newline
+
+\newline
+
+\size default
+Since they are compiled as
+\emph on
+non-reentrant
+\emph default
+, interrupt service routines should not do any of the above operations.
+ If this is unavoidable then the above routines will need to be compiled
+ with the
+\emph on
+---stack-auto
+\emph default
+ option, after which the source program will have to be compiled with
+\emph on
+---int-long-rent
+\emph default
+ option.
+\layout Subsection
+
+Floating Point Support
+\layout Standard
+
+SDCC supports IEEE (single precision 4bytes) floating point numbers.The floating
+ point support routines are derived from gcc's floatlib.c and consists of
+ the following routines:
+\newline
+
+\newline
+
+\emph on
+<pending: tabularise this>
+\emph default
+
+\newline
+
+\newline
+_fsadd.c - add floating point numbers
+\newline
+_fssub.c - subtract floating point numbers
+\newline
+_fsdiv.c - divide floating point numbers
+\newline
+_fsmul.c - multiply floating point numbers
+\newline
+_fs2uchar.c - convert floating point to unsigned char
+\newline
+_fs2char.c - convert floating point to signed char
+\newline
+_fs2uint.c - convert floating point to unsigned int
+\newline
+_fs2int.c - convert floating point to signed int
+\newline
+_fs2ulong.c - convert floating point to unsigned long
+\newline
+_fs2long.c - convert floating point to signed long
+\newline
+_uchar2fs.c - convert unsigned char to floating point
+\newline
+_char2fs.c - convert char to floating point number
+\newline
+_uint2fs.c - convert unsigned int to floating point
+\newline
+_int2fs.c - convert int to floating point numbers
+\newline
+_ulong2fs.c - convert unsigned long to floating point number
+\newline
+_long2fs.c - convert long to floating point number
+\size footnotesize
+
+\newline
+
+\newline
+
+\size default
+Note if all these routines are used simultaneously the data space might
+ overflow.
+ For serious floating point usage it is strongly recommended that the large
+ model be used.
+\layout Subsection
+
+MCS51 Memory Models
+\layout Standard
+
+SDCC allows two memory models for MCS51 code, small and large.
+ Modules compiled with different memory models should
+\emph on
+never
+\emph default
+ be combined together or the results would be unpredictable.
+ The library routines supplied with the compiler are compiled as both small
+ and large.
+ The compiled library modules are contained in seperate directories as small
+ and large so that you can link to either set.
+
+\layout Standard
+
+When the large model is used all variables declared without a storage class
+ will be allocated into the external ram, this includes all parameters and
+ local variables (for non-reentrant functions).
+ When the small model is used variables without storage class are allocated
+ in the internal ram.
+\layout Standard
+
+Judicious usage of the processor specific storage classes and the 'reentrant'
+ function type will yield much more efficient code, than using the large
+ model.
+ Several optimizations are disabled when the program is compiled using the
+ large model, it is therefore strongly recommdended that the small model
+ be used unless absolutely required.
+\layout Subsection
+
+DS390 Memory Models
+\layout Standard
+
+The only model supported is Flat 24.
+ This generates code for the 24 bit contiguous addressing mode of the Dallas
+ DS80C390 part.
+ In this mode, up to four meg of external RAM or code space can be directly
+ addressed.
+ See the data sheets at www.dalsemi.com for further information on this part.
+\newline
+
+\newline
+In older versions of the compiler, this option was used with the MCS51 code
+ generator (
+\emph on
+-mmcs51
+\emph default
+).
+ Now, however, the '390 has it's own code generator, selected by the
+\emph on
+-mds390
+\emph default
+ switch.
+
+\newline
+
+\newline
+Note that the compiler does not generate any code to place the processor
+ into 24 bitmode (although
+\emph on
+tinibios
+\emph default
+ in the ds390 libraries will do that for you).
+ If you don't use
+\emph on
+tinibios
+\emph default
+, the boot loader or similar code must ensure that the processor is in 24
+ bit contiguous addressing mode before calling the SDCC startup code.
+\newline
+
+\newline
+Like the
+\emph on
+---model-large
+\emph default
+ option, variables will by default be placed into the XDATA segment.
+
+\newline
+
+\newline
+Segments may be placed anywhere in the 4 meg address space using the usual
+ ---*-loc options.
+ Note that if any segments are located above 64K, the -r flag must be passed
+ to the linker to generate the proper segment relocations, and the Intel
+ HEX output format must be used.
+ The -r flag can be passed to the linker by using the option
+\emph on
+-Wl-r
+\emph default
+ on the sdcc command line.
+ However, currently the linker can not handle code segments > 64k.
+\layout Subsection
+
+Defines Created by the Compiler
+\layout Standard
+
+The compiler creates the following #defines.
+\layout Itemize
+
+SDCC - this Symbol is always defined.
+\layout Itemize
+
+SDCC_mcs51 or SDCC_ds390 or SDCC_z80, etc - depending on the model used
+ (e.g.: -mds390)
+\layout Itemize
+
+__mcs51 or __ds390 or __z80, etc - depending on the model used (e.g.
+ -mz80)
+\layout Itemize
+
+SDCC_STACK_AUTO - this symbol is defined when
+\emph on
+---stack-auto
+\emph default
+ option is used.
+\layout Itemize
+
+SDCC_MODEL_SMALL - when
+\emph on
+---model-small
+\emph default
+ is used.
+\layout Itemize
+
+SDCC_MODEL_LARGE - when
+\emph on
+---model-large
+\emph default
+ is used.
+\layout Itemize
+
+SDCC_USE_XSTACK - when
+\emph on
+---xstack
+\emph default
+ option is used.
+\layout Itemize
+
+SDCC_STACK_TENBIT - when
+\emph on
+-mds390
+\emph default
+ is used
+\layout Itemize
+
+SDCC_MODEL_FLAT24 - when
+\emph on
+-mds390
+\emph default
+ is used
+\layout Section
+
+SDCC Technical Data
+\layout Subsection
+
+Optimizations
+\layout Standard
+
+SDCC performs a host of standard optimizations in addition to some MCU specific
+ optimizations.
+
+\layout Subsubsection
+
+Sub-expression Elimination
+\layout Standard
+
+The compiler does local and global common subexpression elimination, e.g.:
+
+\newline
+
+\newline
+
+\family typewriter
+i = x + y + 1;
+\newline
+j = x + y;
+\family default
+
+\newline
+
+\newline
+will be translated to
+\newline
+
+\newline
+
+\family typewriter
+iTemp = x + y
+\newline
+i = iTemp + 1
+\newline
+j = iTemp
+\newline
+
+\family default
+
+\newline
+Some subexpressions are not as obvious as the above example, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+a->b[i].c = 10;
+\newline
+a->b[i].d = 11;
+\family default
+
+\newline
+
+\newline
+In this case the address arithmetic a->b[i] will be computed only once;
+ the equivalent code in C would be.
+\newline
+
+\newline
+
+\family typewriter
+iTemp = a->b[i];
+\newline
+iTemp.c = 10;
+\newline
+iTemp.d = 11;
+\family default
+
+\newline
+
+\newline
+The compiler will try to keep these temporary variables in registers.
+\layout Subsubsection
+
+Dead-Code Elimination
+\layout Standard
+
+
+\family typewriter
+int global;
+\newline
+void f () {
+\newline
+\SpecialChar ~
+\SpecialChar ~
+int i;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+i = 1; \SpecialChar ~
+/* dead store */
+\newline
+\SpecialChar ~
+\SpecialChar ~
+global = 1;\SpecialChar ~
+/* dead store */
+\newline
+\SpecialChar ~
+\SpecialChar ~
+global = 2;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+return;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+global = 3;\SpecialChar ~
+/* unreachable */
+\newline
+}
+\family default
+
+\newline
+
+\newline
+will be changed to
+\newline
+
+\newline
+
+\family typewriter
+int global; void f ()
+\newline
+{
+\newline
+\SpecialChar ~
+\SpecialChar ~
+global = 2;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+return;
+\newline
+}
+\layout Subsubsection
+
+Copy-Propagation
+\layout Standard
+
+
+\family typewriter
+int f() {
+\newline
+\SpecialChar ~
+\SpecialChar ~
+int i, j;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+i = 10;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+j = i;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+return j;
+\newline
+}
+\family default
+
+\newline
+
+\newline
+will be changed to
+\newline
+
+\newline
+
+\family typewriter
+int f() {
+\newline
+\SpecialChar ~
+ \SpecialChar ~
+ int i,j;
+\newline
+\SpecialChar ~
+ \SpecialChar ~
+ i = 10;
+\newline
+\SpecialChar ~
+ \SpecialChar ~
+ j = 10;
+\newline
+\SpecialChar ~
+ \SpecialChar ~
+ return 10;
+\newline
+}
+\newline
+
+\newline
+
+\family default
+Note: the dead stores created by this copy propagation will be eliminated
+ by dead-code elimination.
+\layout Subsubsection
+
+Loop Optimizations
+\layout Standard
+
+Two types of loop optimizations are done by SDCC loop invariant lifting
+ and strength reduction of loop induction variables.
+ In addition to the strength reduction the optimizer marks the induction
+ variables and the register allocator tries to keep the induction variables
+ in registers for the duration of the loop.
+ Because of this preference of the register allocator, loop induction optimizati
+on causes an increase in register pressure, which may cause unwanted spilling
+ of other temporary variables into the stack / data space.
+ The compiler will generate a warning message when it is forced to allocate
+ extra space either on the stack or data space.
+ If this extra space allocation is undesirable then induction optimization
+ can be eliminated either for the entire source file (with ---noinduction
+ option) or for a given function only using #pragma\SpecialChar ~
+NOINDUCTION.
+\newline
+
+\newline
+Loop Invariant:
+\newline
+
+\newline
+
+\family typewriter
+for (i = 0 ; i < 100 ; i ++)
+\newline
+ \SpecialChar ~
+ \SpecialChar ~
+f += k + l;
+\family default
+
+\newline
+
+\newline
+changed to
+\newline
+
+\newline
+
+\family typewriter
+itemp = k + l;
+\newline
+for (i = 0; i < 100; i++)
+\newline
+\SpecialChar ~
+\SpecialChar ~
+f += itemp;
+\family default
+
+\newline
+
+\newline
+As mentioned previously some loop invariants are not as apparent, all static
+ address computations are also moved out of the loop.
+\newline
+
+\newline
+Strength Reduction, this optimization substitutes an expression by a cheaper
+ expression:
+\newline
+
+\newline
+
+\family typewriter
+for (i=0;i < 100; i++)
+\newline
+\SpecialChar ~
+\SpecialChar ~
+ar[i*5] = i*3;
+\family default
+
+\newline
+
+\newline
+changed to
+\newline
+
+\newline
+
+\family typewriter
+itemp1 = 0;
+\newline
+itemp2 = 0;
+\newline
+for (i=0;i< 100;i++) {
+\newline
+ \SpecialChar ~
+ \SpecialChar ~
+ar[itemp1] = itemp2;
+\newline
+ \SpecialChar ~
+ \SpecialChar ~
+itemp1 += 5;
+\newline
+ \SpecialChar ~
+ \SpecialChar ~
+itemp2 += 3;
+\newline
+}
+\family default
+
+\newline
+
+\newline
+The more expensive multiplication is changed to a less expensive addition.
+\layout Subsubsection
+
+Loop Reversing
+\layout Standard
+
+This optimization is done to reduce the overhead of checking loop boundaries
+ for every iteration.
+ Some simple loops can be reversed and implemented using a
+\begin_inset Quotes eld
+\end_inset
+
+decrement and jump if not zero
+\begin_inset Quotes erd
+\end_inset
+
+ instruction.
+ SDCC checks for the following criterion to determine if a loop is reversible
+ (note: more sophisticated compilers use data-dependency analysis to make
+ this determination, SDCC uses a more simple minded analysis).
+\layout Itemize
+
+The 'for' loop is of the form
+\newline
+
+\newline
+
+\family typewriter
+for (<symbol> = <expression> ; <sym> [< | <=] <expression> ; [<sym>++ |
+ <sym> += 1])
+\newline
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+<for body>
+\layout Itemize
+
+The <for body> does not contain
+\begin_inset Quotes eld
+\end_inset
+
+continue
+\begin_inset Quotes erd
+\end_inset
+
+ or 'break
+\begin_inset Quotes erd
+\end_inset
+
+.
+\layout Itemize
+
+All goto's are contained within the loop.
+\layout Itemize
+
+No function calls within the loop.
+\layout Itemize
+
+The loop control variable <sym> is not assigned any value within the loop
+\layout Itemize
+
+The loop control variable does NOT participate in any arithmetic operation
+ within the loop.
+\layout Itemize
+
+There are NO switch statements in the loop.
+\layout Subsubsection
+
+Algebraic Simplifications
+\layout Standard
+
+SDCC does numerous algebraic simplifications, the following is a small sub-set
+ of these optimizations.
+\newline
+
+\newline
+
+\family typewriter
+i = j + 0 ; /* changed to */ i = j;
+\newline
+i /= 2; /* changed to */ i >>= 1;
+\newline
+i = j - j ; /* changed to */ i = 0;
+\newline
+i = j / 1 ; /* changed to */ i = j;
+\family default
+
+\newline
+
+\newline
+Note the subexpressions given above are generally introduced by macro expansions
+ or as a result of copy/constant propagation.
+\layout Subsubsection
+
+'switch' Statements
+\layout Standard
+
+SDCC changes switch statements to jump tables when the following conditions
+ are true.
+
+\layout Itemize
+
+The case labels are in numerical sequence, the labels need not be in order,
+ and the starting number need not be one or zero.
+\newline
+
+\newline
+
+\family typewriter
+switch(i) {\SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+switch (i) {
+\newline
+case 4:...
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+case 1: ...
+
+\newline
+case 5:...
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+case 2: ...
+
+\newline
+case 3:...
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+case 3: ...
+
+\newline
+case 6:...
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+case 4: ...
+
+\newline
+}\SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+ \SpecialChar ~
+}
+\newline
+
+\newline
+
+\family default
+Both the above switch statements will be implemented using a jump-table.
+\layout Itemize
+
+The number of case labels is at least three, since it takes two conditional
+ statements to handle the boundary conditions.
+\layout Itemize
+
+The number of case labels is less than 84, since each label takes 3 bytes
+ and a jump-table can be utmost 256 bytes long.
+
+\layout Standard
+
+Switch statements which have gaps in the numeric sequence or those that
+ have more that 84 case labels can be split into more than one switch statement
+ for efficient code generation, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+switch (i) {
+\newline
+case 1: ...
+
+\newline
+case 2: ...
+
+\newline
+case 3: ...
+
+\newline
+case 4: ...
+
+\newline
+case 9: ...
+
+\newline
+case 10: ...
+
+\newline
+case 11: ...
+
+\newline
+case 12: ...
+
+\newline
+}
+\family default
+
+\newline
+
+\newline
+If the above switch statement is broken down into two switch statements
+\newline
+
+\newline
+
+\family typewriter
+switch (i) {
+\newline
+case 1: ...
+
+\newline
+case 2: ...
+
+\newline
+case 3: ...
+
+\newline
+case 4: ...
+
+\newline
+}
+\newline
+
+\newline
+
+\family default
+and
+\family typewriter
+
+\newline
+
+\newline
+switch (i) {
+\newline
+case 9: \SpecialChar ~
+...
+
+\newline
+case 10: ...
+
+\newline
+case 11: ...
+
+\newline
+case 12:\SpecialChar ~
+...
+
+\newline
+}
+\newline
+
+\newline
+
+\family default
+then both the switch statements will be implemented using jump-tables whereas
+ the unmodified switch statement will not be.
+\layout Subsubsection
+
+Bit-shifting Operations.
+\layout Standard
+
+Bit shifting is one of the most frequently used operation in embedded programmin
+g.
+ SDCC tries to implement bit-shift operations in the most efficient way
+ possible, e.g.:
+\newline
+
+\family typewriter
+
+\newline
+unsigned char i;
+\newline
+...
+
+\newline
+i>>= 4;
+\newline
+...
+\newline
+
+\family default
+
+\newline
+generates the following code:
+\newline
+
+\family typewriter
+
+\newline
+mov a,_i
+\newline
+swap a
+\newline
+anl a,#0x0f
+\newline
+mov _i,a
+\family default
+
+\newline
+
+\newline
+In general SDCC will never setup a loop if the shift count is known.
+ Another example:
+\newline
+
+\newline
+
+\family typewriter
+unsigned int i;
+\newline
+...
+
+\newline
+i >>= 9;
+\newline
+...
+\family default
+
+\newline
+
+\newline
+will generate:
+\newline
+
+\newline
+
+\family typewriter
+mov a,(_i + 1)
+\newline
+mov (_i + 1),#0x00
+\newline
+clr c
+\newline
+rrc a
+\newline
+mov _i,a
+\family default
+
+\newline
+
+\newline
+Note that SDCC stores numbers in little-endian format (i.e.
+ lowest order first).
+\layout Subsubsection
+
+Bit-rotation
+\layout Standard
+
+A special case of the bit-shift operation is bit rotation, SDCC recognizes
+ the following expression to be a left bit-rotation:
+\newline
+
+\newline
+
+\family typewriter
+unsigned char i;
+\newline
+...
+
+\newline
+i = ((i << 1) | (i >> 7));
+\family default
+
+\newline
+...
+\newline
+
+\newline
+will generate the following code:
+\newline
+
+\newline
+
+\family typewriter
+mov a,_i
+\newline
+rl a
+\newline
+mov _i,a
+\family default
+
+\newline
+
+\newline
+SDCC uses pattern matching on the parse tree to determine this operation.Variatio
+ns of this case will also be recognized as bit-rotation, i.e.:
+\newline
+
+\newline
+
+\family typewriter
+i = ((i >> 7) | (i << 1)); /* left-bit rotation */
+\layout Subsubsection
+
+Highest Order Bit
+\layout Standard
+
+It is frequently required to obtain the highest order bit of an integral
+ type (long, int, short or char types).
+ SDCC recognizes the following expression to yield the highest order bit
+ and generates optimized code for it, e.g.:
+\newline
+
+\newline
+
+\family typewriter
+unsigned int gint;
+\newline
+
+\newline
+foo () {
+\newline
+unsigned char hob;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+...
+
+\newline
+\SpecialChar ~
+\SpecialChar ~
+hob = (gint >> 15) & 1;
+\newline
+\SpecialChar ~
+\SpecialChar ~
+..
+
+\newline
+}
+\family default
+
+\newline
+
+\newline
+will generate the following code:
+\newline
+
+\family typewriter
+
+\newline