From: johanknol Date: Mon, 10 Feb 2003 17:13:10 +0000 (+0000) Subject: Added Sandeep's anatomy lecture X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=de4b0bbe4ecee17661bdfcb850ec5d734c7ce4c4;p=fw%2Fsdcc Added Sandeep's anatomy lecture git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2239 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index 87af54d8..97b032dd 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -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* + + +\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