1.TH SCC-IR 7 scc\-VERSION2.SH NAME3scc-ir \- scc intermediate representation4.SH DESCRIPTION5The scc intermediate representation (IR) is a text-based format6used to communicate between the compiler frontend7.RB ( cc1 )8and the compiler backend9.RB ( cc2 ).10It is designed to be simple and easily parseable:11all types and operators are represented by one or two characters,12so parsing tables can be used to process it.13.PP14The language is composed of lines representing statements.15Each line is composed of tab-separated fields.16Declarations begin in column 0;17expressions and control flow statements begin with a tab character.18When the frontend detects an error,19it closes the output stream.20.SH TYPES21Types are represented with single characters:22.PP23.TS24l l.25B bool26C signed 8-bit integer27K unsigned 8-bit integer28I signed 16-bit integer29N unsigned 16-bit integer30W signed 32-bit integer31Z unsigned 32-bit integer32Q signed 64-bit integer33O unsigned 64-bit integer34J float35D double36H long double370 void38P pointer39F function40E function with ellipsis41V array (vector)42U union43S struct441 \fI__builtin_va_arg\fR45.TE46.PP47Aggregate and composed types48.RB ( S ,49.BR U ,50.BR V )51are followed by a numeric identifier52to distinguish between multiple types of the same kind:53.BR S3 ,54.BR V5 ,55.BR U2 .56.PP57The sizes in the table above are nominal.58Actual sizes depend on the target architecture.59For example, on amd64-sysv,60.B int61is 32-bit and uses62.BR W ,63while on z80-scc it is 16-bit and uses64.BR I .65.SH STORAGE CLASSES66Storage classes are represented with uppercase letters:67.PP68.TS69l l.70A automatic (local variable)71R register72G global (public, defined in this module)73X extern (declared in another module)74Y private (file-scope static)75T local (function-scope static)76M struct/union member77L label78.TE79.PP80A variable name in the IR is composed of a storage class letter81followed by a numeric identifier, for example:82.BR A1 ,83.BR G2 ,84.BR T3 ,85.BR L4 .86.SH DECLARATIONS87.SS Variable declarations88A variable declaration consists of a variable name,89its type, and a quoted source name:90.PP91.RS92.I var93.B \et94.I type95.B \et "96.I name97.RE98.PP99For example:100.PP101.RS102.nf103A4 W "i104G2 W "g105X3 P "ptr106.fi107.RE108.SS Function declarations109Function declarations include the return type110and use111.B F112for the function type113.RB ( E114if the function has an ellipsis parameter):115.PP116.RS117.I var118.B \et119.I return-type120.B \et F \et "121.I name122.RE123.PP124For example:125.PP126.RS127.nf128.ta 8n 16n 24n129G2 W F "main130X3 W E "printf131T4 0 F "helper132.fi133.RE134.PP135.B G136marks a public function,137.B T138a file-scope static function, and139.B X140an extern declaration.141.SS Function definitions142A function definition starts with the function declaration,143followed by144.B {145on its own line.146Function parameters are declared inside the body.147A148.B \e149(backslash) on its own line separates150parameters from local variable declarations.151The body ends with152.BR } .153.PP154For example, the C source:155.PP156.RS157.nf158int func(int a, int b) {159 int c;160 return a + b;161}162.fi163.RE164.PP165generates:166.PP167.RS168.nf169.ta 8n 16n 24n170G2 W F "func171{172A3 W "a173A4 W "b174\e175A6 W "c176 h A3 A4 +W177}178.fi179.RE180.SS Struct and union declarations181A struct or union type declaration starts with a header line182containing the type letter and identifier,183a quoted tag name,184a hex-encoded size and a hex-encoded alignment:185.PP186.RS187.I type-id188.B \et "189.I tag190.B \et #191.IR size-letter size192.B \et #193.IR size-letter align194.RE195.PP196Member declarations follow, each including an offset field:197.PP198.RS199.I member-var200.B \et201.I type202.B \et "203.I name204.B \et #205.IR size-letter offset206.RE207.PP208For example, the C source:209.PP210.RS211.nf212struct point {213 int x;214 int y;215};216struct point p;217.fi218.RE219.PP220generates (on amd64-sysv):221.PP222.RS223.nf224.ta 8n 16n 24n225S3 "point #O8 #O4226M4 W "x #O0227M5 W "y #O4228G6 S3 "p229.fi230.RE231.PP232Unions use233.B U234instead of235.BR S .236Members of a union typically share offset 0.237.SS Array type declarations238Array types are declared with239.BR V ,240the element type,241and the number of elements in hexadecimal:242.PP243.RS244.nf245.ta 8n 16n 24n246V5 W #OA247.fi248.RE249.PP250This declares array type V5 with element type251.B W252(signed 32-bit integer) and 0xA (10) elements.253Array variable declarations reference the array type:254.PP255.RS256.nf257.ta 8n 16n 24n258A4 V5 "a259.fi260.RE261.SS Enum declarations262Enumerations are not emitted as types.263Enum variables are emitted with their underlying integer type264(typically265.BR W ):266.PP267.RS268.nf269G7 W "c270.fi271.RE272.SH INITIALIZERS273When a variable has an initializer,274the declaration line ends without a newline and is followed by275.B (276on the same line.277The initializer expressions follow,278one per line,279and the initializer is closed with280.B )281on its own line.282.PP283For example:284.PP285.RS286.nf287int g = 42;288.fi289.RE290.PP291generates:292.PP293.RS294.nf295.ta 8n 16n 24n296G2 W "g (297 #W2A298)299.fi300.RE301.PP302Array and struct initializers list each element:303.PP304.RS305.nf306int a[3] = {1, 2, 3};307.fi308.RE309.PP310generates:311.PP312.RS313.nf314.ta 8n 16n 24n315V3 W #O3316G2 V3 "a (317 #W1318 #W2319 #W3320)321.fi322.RE323.PP324String initializers use a quoted form for printable runs325and individual byte constants for non-printable characters:326.PP327.RS328.nf329.ta 8n 16n 24n330 #"hello331 #C0332.fi333.RE334.SH EXPRESSIONS335Expressions are emitted in reverse Polish notation (RPN),336with tab-separated tokens on a single line.337Every operator is followed by a type letter.338.SS Constants339Constants are introduced with340.BR # ,341followed by a type letter and a hexadecimal value:342.PP343.RS344.nf345#W2A346.fi347.RE348.PP349This represents the integer constant 42 (0x2A) of type350.BR W .351.PP352Floating-point constants are emitted as the hexadecimal encoding353of their IEEE 754 representation:354.PP355.RS356.nf357#J3FC00000358#D4004000000000000359.fi360.RE361.PP362These represent float 1.5 and double 2.5, respectively.363.PP364String constants are emitted using365.B #"366for printable character runs:367.PP368.RS369.nf370#"hello371.fi372.RE373.SS Arithmetic operators374.TS375l l.376+ addition377\- subtraction378* multiplication379/ division380% modulo381l left shift382r right shift383.TE384.SS Comparison operators385.TS386l l.387< less than388> greater than389[ less or equal390] greater or equal391\&= equal392! not equal393.TE394.SS Bitwise operators395.TS396l l.397& bitwise and398| bitwise or399^ bitwise xor400~ bitwise complement (unary)401.TE402.SS Logical operators403.TS404l l.405a logical and (short-circuit)406o logical or (short-circuit)407n logical negation408.TE409.SS Unary operators410.TS411l l.412\&_ arithmetic negation413~ bitwise complement414n logical negation415\&' address-of416@ pointer dereference417.TE418.SS Assignment419.TS420l l.421: assignment422:* multiply and assign423:/ divide and assign424:% modulo and assign425:+ add and assign426:\- subtract and assign427:l left shift and assign428:r right shift and assign429:& bitwise and and assign430:^ bitwise xor and assign431:| bitwise or and assign432:i post-increment433:d post-decrement434.TE435.SS Other operators436.TS437l l.438, comma439? ternary (conditional)440\&. struct/union field access441g type cast (followed by target type letter)442.TE443.SS Function calls444Function calls use445.B p446to push each argument,447.B c448for the call itself,449and450.B z451for calls to variadic functions.452Each is followed by the type of the result:453.PP454.RS455.nf456.ta 8n 16n 24n 32n 40n 48n457 X2 Y9 'P pP #W2A pW zW458.fi459.RE460.PP461This pushes a pointer argument462.RB ( pP ),463pushes an integer argument464.RB ( pW ),465and calls a variadic function returning466.BR W467.RB ( zW ).468.SS Builtin functions469Builtin function calls use470.B m471as the operator,472preceded by a quoted builtin name:473.PP474.RS475.nf476"__builtin_va_arg m477.fi478.RE479.SS Expression example480The C expression:481.PP482.RS483.nf484i = j + 2 * 3;485.fi486.RE487.PP488generates (on amd64-sysv):489.PP490.RS491.nf492.ta 8n 16n 24n 32n 40n493 A4 A5 #W6 +W :W494.fi495.RE496.PP497Note that constant folding has reduced498.I 2*3499to500.IR 6 .501The expression is in RPN:502push A4, push A5, push #W6, add (yielding W), assign (yielding W).503.SS Type casts504Casts are emitted as the operator505.B g506followed by the target type letter.507A cast to508.B void509is not emitted.510For example:511.PP512.RS513.nf514j = (long)i;515.fi516.RE517.PP518generates (on amd64-sysv):519.PP520.RS521.nf522.ta 8n 16n 24n 32n523 A5 A4 gQ :Q524.fi525.RE526.SH STATEMENTS527.SS Labels528Labels begin in column 0 and consist of529.B L530followed by a numeric identifier:531.PP532.RS533.nf534L3535.fi536.RE537.SS Unconditional jumps538An unconditional jump uses539.B j540followed by a label:541.PP542.RS543.nf544.ta 8n 16n545 j L3546.fi547.RE548.SS Conditional branches549A conditional branch uses550.BR y ,551followed by a label.552The expression to evaluate follows on the next line.553If the expression evaluates to true (non-zero), the branch is taken:554.PP555.RS556.nf557.ta 8n 16n 24n 32n558 y L5 A4 #W5 <W559.fi560.RE561.PP562Note that the frontend negates the condition:563the C code564.I "if (i > 5)"565is emitted as a branch on566.IR "i <= 5" ,567jumping past the then-block when the original condition is false.568.SS Return569The return statement uses570.BR h .571If the function returns a value,572the expression follows on the same line:573.PP574.RS575.nf576.ta 8n 16n 24n 32n577 h A3 A4 +W578.fi579.RE580.PP581A void return is emitted as582.B h583alone, followed by a blank expression line.584.SS Loops585Two markers indicate loop boundaries to the backend:586.PP587.TS588l l.589b beginning of loop body590e end of loop body591.TE592.PP593For example, a594.B while595loop:596.PP597.RS598.nf599while (i < 10) { ++i; }600.fi601.RE602.PP603generates:604.PP605.RS606.nf607.ta 8n 16n 24n 32n608 j L5609L4610 b611 A4 #W1 :+W612L5613 e614 y L4 A4 #WA <W615L6616.fi617.RE618.SS Switch statements619A switch statement is bracketed by620.B s621(begin) and622.B t623(end).624The625.B s626marker is followed by the switch expression.627Case entries are emitted with628.BR v ,629and the default entry with630.BR f .631The632.B t633marker takes the label where execution continues after the switch.634.PP635For example:636.PP637.RS638.nf639switch (n+1) {640case 1:641case 2:642case 3:643default:644 ++n;645}646.fi647.RE648.PP649generates:650.PP651.RS652.nf653.ta 8n 16n 24n 32n654 s A3 #W1 +W655 v L6 #W1656L6657 v L7 #W2658L7659 v L8 #W3660L8661 f L9662L9663 A3 #W1 :+W664 t L5665L5666.fi667.RE668.PP669Each670.B v671entry is followed by a label and a constant value.672The673.B f674(default) entry is followed by a label only.675.SH SEE ALSO676.BR scc-cc (1)