Added Sandeep's anatomy lecture
authorjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 10 Feb 2003 17:13:10 +0000 (17:13 +0000)
committerjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 10 Feb 2003 17:13:10 +0000 (17:13 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2239 4a8a32a2-be11-0410-ad9d-d568d2c75423

doc/sdccman.lyx

index 87af54d8abe8ca920b146c659079696d0632631f..97b032ddd1f9ff638d59d0420ea89a9e671ad6c5 100644 (file)
@@ -1305,7 +1305,7 @@ This is the actual compiler, it in turn uses the c-preprocessor and invokes
  the assembler and linkage editor.
 \layout Subsubsection
 
-sdcpp - The C-Preprocessor)
+sdcpp - The C-Preprocessor
 \layout Standard
 
 The preprocessor is a modified version of the GNU preprocessor.
@@ -3489,7 +3489,7 @@ reti\SpecialChar ~
 \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 is is recommended that you stick to inline assembler.
+ and it is recommended that you stick to inline assembler.
 \layout Subsection
 
 Functions using private banks
@@ -7613,34 +7613,1285 @@ cc@sdcc.sourceforge.net'.
  in locating optimization problems.
 \layout Section
 
-Acknowledgments
+The anatomy of the compiler
 \layout Standard
 
-Sandeep Dutta (sandeep.dutta@usa.net) - SDCC, the compiler, MCS51 code generator,
- Debugger, AVR port
+
+\shape italic 
+This is an excerpt from an atricle published in Circuit Cellar MagaZine
+ in august 2000.
+ It's a little outdated (the compiler is much more efficient now and user/devell
+oper friendly), but pretty well exposes the guts of it all.
+\shape default 
+
+\newline 
+
 \newline 
-Alan Baldwin (baldwin@shop-pdp.kent.edu) - Initial version of ASXXXX & ASLINK.
+The current version of SDCC can generate code for Intel 8051 and Z80 MCU.
+ It is fairly easy to retarget for other 8-bit MCU.
+ Here we take a look at some of the internals of the compiler.
+\layout Paragraph*
+
+Parsing 
+\layout Standard
+
+Parsing the input source file and creating an AST (Annotated Syntax Tree).
+ This phase also involves propagating types (annotating each node of the
+ parse tree with type information) and semantic analysis.
+ There are some MCU specific parsing rules.
+ For example the storage classes, the extended storage classes are MCU specific
+ while there may be a xdata storage class for 8051 there is no such storage
+ class for z80 or Atmel AVR.
+ SDCC allows MCU specific storage class extensions, i.e.
+ xdata will be treated as a storage class specifier when parsing 8051 C
+ code but will be treated as a C identifier when parsing z80 or ATMEL AVR
+ C code.
+\layout Paragraph
+
+Generating iCode
+\layout Standard
+
+Intermediate code generation.
+ In this phase the AST is broken down into three-operand form (iCode).
+ These three operand forms are represented as doubly linked lists.
+ ICode is the term given to the intermediate form generated by the compiler.
+ ICode example section shows some examples of iCode generated for some simple
+ C source functions.
+\layout Paragraph
+
+Optimizations.
+\layout Standard
+
+Bulk of the target independent optimizations is performed in this phase.
+ The optimizations include constant propagation, common sub-expression eliminati
+on, loop invariant code movement, strength reduction of loop induction variables
+ and dead-code elimination.
+\layout Paragraph
+
+Live range analysis
+\layout Standard
+
+During intermediate code generation phase, the compiler assumes the target
+ machine has infinite number of registers and generates a lot of temporary
+ variables.
+ The live range computation determines the lifetime of each of these compiler-ge
+nerated temporaries.
+ A picture speaks a thousand words.
+ ICode example sections show the live range annotations for each of the
+ operand.
+ It is important to note here, each iCode is assigned a number in the order
+ of its execution in the function.
+ The live ranges are computed in terms of these numbers.
+ The from number is the number of the iCode which first defines the operand
+ and the to number signifies the iCode which uses this operand last.
+\layout Paragraph
+
+Register Allocation
+\layout Standard
+
+The register allocation determines the type and number of registers needed
+ by each operand.
+ In most MCUs only a few registers can be used for indirect addressing.
+ In case of 8051 for example the registers R0 & R1 can be used to indirectly
+ address the internal ram and DPTR to indirectly address the external ram.
+ The compiler will try to allocate the appropriate register to pointer variables
+ if it can.
+ ICode example section shows the operands annotated with the registers assigned
+ to them.
+ The compiler will try to keep operands in registers as much as possible;
+ there are several schemes the compiler uses to do achieve this.
+ When the compiler runs out of registers the compiler will check to see
+ if there are any live operands which is not used or defined in the current
+ basic block being processed, if there are any found then it will push that
+ operand and use the registers in this block, the operand will then be popped
+ at the end of the basic block.
  
+\layout Standard
+
+There are other MCU specific considerations in this phase.
+ Some MCUs have an accumulator; very short-lived operands could be assigned
+ to the accumulator instead of general-purpose register.
+\layout Paragraph
+
+Code generation
+\layout Standard
+
+Figure II gives a table of iCode operations supported by the compiler.
+ The code generation involves translating these operations into corresponding
+ assembly code for the processor.
+ This sounds overly simple but that is the essence of code generation.
+ Some of the iCode operations are generated on a MCU specific manner for
+ example, the z80 port does not use registers to pass parameters so the
+ SEND and RECV iCode operations will not be generated, and it also does
+ not support JUMPTABLES
+\layout Section*
+
+<Where is Figure II ?>
+\layout Paragraph
+
+ICode Example
+\layout Standard
+
+This section shows some details of iCode.
+ The example C code does not do anything useful; it is used as an example
+ to illustrate the intermediate code generated by the compiler.
 \newline 
-John Hartman (jhartman@compuserve.com) - Porting ASXXX & ASLINK for 8051
+
 \newline 
-Dmitry S.
- Obukhov (dso@usa.net) - malloc & serial i/o routines.
+
+\family typewriter 
+1.\SpecialChar ~
+xdata int * p;
+\newline 
+2.\SpecialChar ~
+int gint;
+\newline 
+3.\SpecialChar ~
+/* This function does nothing useful.
+ It is used
+\newline 
+4.\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+for the purpose of explaining iCode */
+\newline 
+5.\SpecialChar ~
+short function (data int *x)
+\newline 
+6.\SpecialChar ~
+{
+\newline 
+7.\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+short i=10; /* dead initialization eliminated */
+\newline 
+8.\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+short sum=10; /* dead initialization eliminated */
+\newline 
+9.\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+short mul;
+\newline 
+10.\SpecialChar ~
+\SpecialChar ~
+int j ;
+\newline 
+11.\SpecialChar ~
+\SpecialChar ~
+while (*x) *x++ = *p++; 
+\newline 
+12.\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+sum = 0 ; 
+\newline 
+13.\SpecialChar ~
+\SpecialChar ~
+mul = 0;
+\newline 
+14.\SpecialChar ~
+\SpecialChar ~
+/* compiler detects i,j to be induction variables */
+\newline 
+15.\SpecialChar ~
+\SpecialChar ~
+for (i = 0, j = 10 ; i < 10 ; i++, j--) {
+\newline 
+16.\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+sum += i;
+\newline 
+17.\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+mul += i * 3; /* this multiplication remains */
+\newline 
+18.\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+\SpecialChar ~
+gint += j * 3;/* this multiplication changed to addition */
+\newline 
+19.\SpecialChar ~
+\SpecialChar ~
+}
+\newline 
+20.\SpecialChar ~
+\SpecialChar ~
+return sum+mul;
+\newline 
+21.\SpecialChar ~
+}
+\newline 
+
+\newline 
+
+\family default 
+In addition to the operands each iCode contains information about the filename
+ and line it corresponds to in the source file.
+ The first field in the listing should be interpreted as follows:
+\newline 
+
+\shape italic 
+Filename(linenumber: iCode Execution sequence number : ICode hash table
+ key : loop depth of the iCode).
 \newline 
-Daniel Drotos (drdani@mazsola.iit.uni-miskolc.hu) - for his Freeware simulator
+
+\shape default 
+Then follows the human readable form of the ICode operation.
+ Each operand of this triplet form can be of three basic types a) compiler
+ generated temporary b) user defined variable c) a constant value.
+ Note that local variables and parameters are replaced by compiler generated
+ temporaries.
+ Live ranges are computed only for temporaries (i.e.
+ live ranges are not computed for global variables).
+ Registers are allocated for temporaries only.
+ Operands are formatted in the following manner:
+\newline 
+
+\shape italic 
+Operand Name [lr live-from : live-to ] { type information } [ registers
+ allocated ].
+\newline 
+
+\shape default 
+As mentioned earlier the live ranges are computed in terms of the execution
+ sequence number of the iCodes, for example 
 \newline 
-Malini Dutta(malini_dutta@hotmail.com) - my wife for her patience and support.
+the iTemp0 is live from (i.e.
+ first defined in iCode with execution sequence number 3, and is last used
+ in the iCode with sequence number 5).
+ For induction variables such as iTemp21 the live range computation extends
+ the lifetime from the start to the end of the loop.
 \newline 
-Unknown - for the GNU C - preprocessor.
+The register allocator used the live range information to allocate registers,
+ the same registers may be used for different temporaries if their live
+ ranges do not overlap, for example r0 is allocated to both iTemp6 and to
+ iTemp17 since their live ranges do not overlap.
+ In addition the allocator also takes into consideration the type and usage
+ of a temporary, for example itemp6 is a pointer to near space and is used
+ as to fetch data from (i.e.
+ used in GET_VALUE_AT_ADDRESS) so it is allocated a pointer registers (r0).
+ Some short lived temporaries are allocated to special registers which have
+ meaning to the code generator e.g.
+ iTemp13 is allocated to a pseudo register CC which tells the back end that
+ the temporary is used only for a conditional jump the code generation makes
+ use of this information to optimize a compare and jump ICode.
 \newline 
-Michael Hope - The Z80 and Z80GB port, 186 development
+There are several loop optimizations performed by the compiler.
+ It can detect induction variables iTemp21(i) and iTemp23(j).
+ Also note the compiler does selective strength reduction, i.e.
+ the multiplication of an induction variable in line 18 (gint = j * 3) is
+ changed to addition, a new temporary iTemp17 is allocated and assigned
+ a initial value, a constant 3 is then added for each iteration of the loop.
+ The compiler does not change the multiplication in line 17 however since
+ the processor does support an 8 * 8 bit multiplication.
 \newline 
-Kevin Vigor - The DS390 port.
+Note the dead code elimination optimization eliminated the dead assignments
+ in line 7 & 8 to I and sum respectively.
 \newline 
-Johan Knol - Lots of fixes and enhancements, DS390/TINI libs.
+
+\layout Standard
+
+
+\family typewriter 
+Sample.c (5:1:0:0) _entry($9) :
+\layout Standard
+
+
+\family typewriter 
+Sample.c(5:2:1:0) proc _function [lr0:0]{function short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:3:2:0) iTemp0 [lr3:5]{_near * int}[r2] = recv 
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:4:53:0) preHeaderLbl0($11) :
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:5:55:0) iTemp6 [lr5:16]{_near * int}[r0] := iTemp0 [lr3:5]{_near
+ * int}[r2]
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:6:5:1) _whilecontinue_0($1) :
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:7:7:1) iTemp4 [lr7:8]{int}[r2 r3] = @[iTemp6 [lr5:16]{_near *
+ int}[r0]]
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:8:8:1) if iTemp4 [lr7:8]{int}[r2 r3] == 0 goto _whilebreak_0($3)
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:9:14:1) iTemp7 [lr9:13]{_far * int}[DPTR] := _p [lr0:0]{_far
+ * int}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:10:15:1) _p [lr0:0]{_far * int} = _p [lr0:0]{_far * int} + 0x2
+ {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:13:18:1) iTemp10 [lr13:14]{int}[r2 r3] = @[iTemp7 [lr9:13]{_far
+ * int}[DPTR]]
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:14:19:1) *(iTemp6 [lr5:16]{_near * int}[r0]) := iTemp10 [lr13:14]{int
+}[r2 r3]
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:15:12:1) iTemp6 [lr5:16]{_near * int}[r0] = iTemp6 [lr5:16]{_near
+ * int}[r0] + 
+\layout Standard
+
+
+\family typewriter 
+0x2 {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:16:20:1) goto _whilecontinue_0($1)
+\layout Standard
+
+
+\family typewriter 
+Sample.c(11:17:21:0)_whilebreak_0($3) :
+\layout Standard
+
+
+\family typewriter 
+Sample.c(12:18:22:0) iTemp2 [lr18:40]{short}[r2] := 0x0 {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(13:19:23:0) iTemp11 [lr19:40]{short}[r3] := 0x0 {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:20:54:0)preHeaderLbl1($13) :
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:21:56:0) iTemp21 [lr21:38]{short}[r4] := 0x0 {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:22:57:0) iTemp23 [lr22:38]{int}[r5 r6] := 0xa {int}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:23:58:0) iTemp17 [lr23:38]{int}[r7 r0] := 0x1e {int}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:24:26:1)_forcond_0($4) :
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:25:27:1) iTemp13 [lr25:26]{char}[CC] = iTemp21 [lr21:38]{short}[r4]
+ < 0xa {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:26:28:1) if iTemp13 [lr25:26]{char}[CC] == 0 goto _forbreak_0($7)
+\layout Standard
+
+
+\family typewriter 
+Sample.c(16:27:31:1) iTemp2 [lr18:40]{short}[r2] = iTemp2 [lr18:40]{short}[r2]
+ + 
+\layout Standard
+
+
+\family typewriter 
+ITemp21 [lr21:38]{short}[r4]
+\layout Standard
+
+
+\family typewriter 
+Sample.c(17:29:33:1) iTemp15 [lr29:30]{short}[r1] = iTemp21 [lr21:38]{short}[r4]
+ * 0x3 {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(17:30:34:1) iTemp11 [lr19:40]{short}[r3] = iTemp11 [lr19:40]{short}[r3]
+ + 
+\layout Standard
+
+
+\family typewriter 
+iTemp15 [lr29:30]{short}[r1]
+\layout Standard
+
+
+\family typewriter 
+Sample.c(18:32:36:1:1) iTemp17 [lr23:38]{int}[r7 r0]= iTemp17 [lr23:38]{int}[r7
+ r0]- 0x3 {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(18:33:37:1) _gint [lr0:0]{int} = _gint [lr0:0]{int} + iTemp17 [lr23:38]{
+int}[r7 r0]
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:36:42:1) iTemp21 [lr21:38]{short}[r4] = iTemp21 [lr21:38]{short}[r4]
+ + 0x1 {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(15:37:45:1) iTemp23 [lr22:38]{int}[r5 r6]= iTemp23 [lr22:38]{int}[r5
+ r6]- 0x1 {short}
+\layout Standard
+
+
+\family typewriter 
+Sample.c(19:38:47:1) goto _forcond_0($4)
+\layout Standard
+
+
+\family typewriter 
+Sample.c(19:39:48:0)_forbreak_0($7) :
+\layout Standard
+
+
+\family typewriter 
+Sample.c(20:40:49:0) iTemp24 [lr40:41]{short}[DPTR] = iTemp2 [lr18:40]{short}[r2]
+ + 
+\layout Standard
+
+
+\family typewriter 
+ITemp11 [lr19:40]{short}[r3]
+\layout Standard
+
+
+\family typewriter 
+sample.c(20:41:50:0) ret iTemp24 [lr40:41]{short}
+\layout Standard
+
+
+\family typewriter 
+sample.c(20:42:51:0)_return($8) :
+\layout Standard
+
+
+\family typewriter 
+sample.c(20:43:52:0) eproc _function [lr0:0]{ ia0 re0 rm0}{function short}
 \newline 
-Scott Datallo - The PIC port.
+
+\family default 
+
+\newline 
+Finally the code generated for this function:
+\newline 
+
+\layout Standard
+
+
+\family typewriter 
+.area DSEG (DATA)
+\layout Standard
+
+
+\family typewriter 
+_p::
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+.ds 2
+\layout Standard
+
+
+\family typewriter 
+_gint::
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+.ds 2
+\layout Standard
+
+
+\family typewriter 
+; sample.c 5
+\layout Standard
+
+
+\family typewriter 
+; -----------------------------------------
+\layout Standard
+
+
+\family typewriter 
+; function function
+\layout Standard
+
+
+\family typewriter 
+; -----------------------------------------
+\layout Standard
+
+
+\family typewriter 
+_function:
+\layout Standard
+
+
+\family typewriter 
+; iTemp0 [lr3:5]{_near * int}[r2] = recv 
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r2,dpl
+\layout Standard
+
+
+\family typewriter 
+; iTemp6 [lr5:16]{_near * int}[r0] := iTemp0 [lr3:5]{_near * int}[r2]
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov ar0,r2
+\layout Standard
+
+
+\family typewriter 
+;_whilecontinue_0($1) :
+\layout Standard
+
+
+\family typewriter 
+00101$:
+\layout Standard
+
+
+\family typewriter 
+; iTemp4 [lr7:8]{int}[r2 r3] = @[iTemp6 [lr5:16]{_near * int}[r0]]
+\layout Standard
+
+
+\family typewriter 
+; if iTemp4 [lr7:8]{int}[r2 r3] == 0 goto _whilebreak_0($3)
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov ar2,@r0
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+inc r0
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov ar3,@r0
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+dec r0
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r2
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+orl a,r3
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+jz 00103$
+\layout Standard
+
+
+\family typewriter 
+00114$:
+\layout Standard
+
+
+\family typewriter 
+; iTemp7 [lr9:13]{_far * int}[DPTR] := _p [lr0:0]{_far * int}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov dpl,_p
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov dph,(_p + 1)
+\layout Standard
+
+
+\family typewriter 
+; _p [lr0:0]{_far * int} = _p [lr0:0]{_far * int} + 0x2 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,#0x02
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+add a,_p
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov _p,a
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+clr a
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+addc a,(_p + 1)
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov (_p + 1),a
+\layout Standard
+
+
+\family typewriter 
+; iTemp10 [lr13:14]{int}[r2 r3] = @[iTemp7 [lr9:13]{_far * int}[DPTR]]
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+movx a,@dptr
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r2,a
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+inc dptr
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+movx a,@dptr
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r3,a
+\layout Standard
+
+
+\family typewriter 
+; *(iTemp6 [lr5:16]{_near * int}[r0]) := iTemp10 [lr13:14]{int}[r2 r3]
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov @r0,ar2
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+inc r0
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov @r0,ar3
+\layout Standard
+
+
+\family typewriter 
+; iTemp6 [lr5:16]{_near * int}[r0] = 
+\layout Standard
+
+
+\family typewriter 
+; iTemp6 [lr5:16]{_near * int}[r0] + 
+\layout Standard
+
+
+\family typewriter 
+; 0x2 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+inc r0
+\layout Standard
+
+
+\family typewriter 
+; goto _whilecontinue_0($1)
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+sjmp 00101$
+\layout Standard
+
+
+\family typewriter 
+; _whilebreak_0($3) :
+\layout Standard
+
+
+\family typewriter 
+00103$:
+\layout Standard
+
+
+\family typewriter 
+; iTemp2 [lr18:40]{short}[r2] := 0x0 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r2,#0x00
+\layout Standard
+
+
+\family typewriter 
+; iTemp11 [lr19:40]{short}[r3] := 0x0 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r3,#0x00
+\layout Standard
+
+
+\family typewriter 
+; iTemp21 [lr21:38]{short}[r4] := 0x0 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r4,#0x00
+\layout Standard
+
+
+\family typewriter 
+; iTemp23 [lr22:38]{int}[r5 r6] := 0xa {int}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r5,#0x0A
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r6,#0x00
+\layout Standard
+
+
+\family typewriter 
+; iTemp17 [lr23:38]{int}[r7 r0] := 0x1e {int}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r7,#0x1E
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r0,#0x00
+\layout Standard
+
+
+\family typewriter 
+; _forcond_0($4) :
+\layout Standard
+
+
+\family typewriter 
+00104$:
+\layout Standard
+
+
+\family typewriter 
+; iTemp13 [lr25:26]{char}[CC] = iTemp21 [lr21:38]{short}[r4] < 0xa {short}
+\layout Standard
+
+
+\family typewriter 
+; if iTemp13 [lr25:26]{char}[CC] == 0 goto _forbreak_0($7)
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+clr c
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r4
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+xrl a,#0x80
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+subb a,#0x8a
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+jnc 00107$
+\layout Standard
+
+
+\family typewriter 
+00115$:
+\layout Standard
+
+
+\family typewriter 
+; iTemp2 [lr18:40]{short}[r2] = iTemp2 [lr18:40]{short}[r2] + 
+\layout Standard
+
+
+\family typewriter 
+; iTemp21 [lr21:38]{short}[r4]
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r4
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+add a,r2
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r2,a
+\layout Standard
+
+
+\family typewriter 
+; iTemp15 [lr29:30]{short}[r1] = iTemp21 [lr21:38]{short}[r4] * 0x3 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov b,#0x03
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r4
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mul ab
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r1,a
+\layout Standard
+
+
+\family typewriter 
+; iTemp11 [lr19:40]{short}[r3] = iTemp11 [lr19:40]{short}[r3] + 
+\layout Standard
+
+
+\family typewriter 
+; iTemp15 [lr29:30]{short}[r1]
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+add a,r3
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r3,a
+\layout Standard
+
+
+\family typewriter 
+; iTemp17 [lr23:38]{int}[r7 r0]= iTemp17 [lr23:38]{int}[r7 r0]- 0x3 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r7
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+add a,#0xfd
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r7,a
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r0
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+addc a,#0xff
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov r0,a
+\layout Standard
+
+
+\family typewriter 
+; _gint [lr0:0]{int} = _gint [lr0:0]{int} + iTemp17 [lr23:38]{int}[r7 r0]
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r7
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+add a,_gint
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov _gint,a
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r0
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+addc a,(_gint + 1)
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov (_gint + 1),a
+\layout Standard
+
+
+\family typewriter 
+; iTemp21 [lr21:38]{short}[r4] = iTemp21 [lr21:38]{short}[r4] + 0x1 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+inc r4
+\layout Standard
+
+
+\family typewriter 
+; iTemp23 [lr22:38]{int}[r5 r6]= iTemp23 [lr22:38]{int}[r5 r6]- 0x1 {short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+dec r5
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+cjne r5,#0xff,00104$
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+dec r6
+\layout Standard
+
+
+\family typewriter 
+; goto _forcond_0($4)
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+sjmp 00104$
+\layout Standard
+
+
+\family typewriter 
+; _forbreak_0($7) :
+\layout Standard
+
+
+\family typewriter 
+00107$:
+\layout Standard
+
+
+\family typewriter 
+; ret iTemp24 [lr40:41]{short}
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov a,r3
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+add a,r2
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+mov dpl,a
+\layout Standard
+
+
+\family typewriter 
+; _return($8) :
+\layout Standard
+
+
+\family typewriter 
+00108$:
+\layout Standard
+
+
+\family typewriter 
+\SpecialChar ~
+\SpecialChar ~
+ret
+\family default 
+
+\newline 
+
+\layout Section
+
+Acknowledgments
+\layout Standard
+
+
+\begin_inset LatexCommand \url{http://sdcc.sourceforge.net#Who}
+
+\end_inset 
+
+
 \newline 
 
 \newline