scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  1.TH SCC-IR 7 scc\-VERSION
  2.SH NAME
  3scc-ir \- scc intermediate representation
  4.SH DESCRIPTION
  5The scc intermediate representation (IR) is a text-based format
  6used to communicate between the compiler frontend
  7.RB ( cc1 )
  8and the compiler backend
  9.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.PP
 14The 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 TYPES
 21Types are represented with single characters:
 22.PP
 23.TS
 24l l.
 25B	bool
 26C	signed 8-bit integer
 27K	unsigned 8-bit integer
 28I	signed 16-bit integer
 29N	unsigned 16-bit integer
 30W	signed 32-bit integer
 31Z	unsigned 32-bit integer
 32Q	signed 64-bit integer
 33O	unsigned 64-bit integer
 34J	float
 35D	double
 36H	long double
 370	void
 38P	pointer
 39F	function
 40E	function with ellipsis
 41V	array (vector)
 42U	union
 43S	struct
 441	\fI__builtin_va_arg\fR
 45.TE
 46.PP
 47Aggregate and composed types
 48.RB ( S ,
 49.BR U ,
 50.BR V )
 51are followed by a numeric identifier
 52to distinguish between multiple types of the same kind:
 53.BR S3 ,
 54.BR V5 ,
 55.BR U2 .
 56.PP
 57The sizes in the table above are nominal.
 58Actual sizes depend on the target architecture.
 59For example, on amd64-sysv,
 60.B int
 61is 32-bit and uses
 62.BR W ,
 63while on z80-scc it is 16-bit and uses
 64.BR I .
 65.SH STORAGE CLASSES
 66Storage classes are represented with uppercase letters:
 67.PP
 68.TS
 69l l.
 70A	automatic (local variable)
 71R	register
 72G	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 member
 77L	label
 78.TE
 79.PP
 80A variable name in the IR is composed of a storage class letter
 81followed by a numeric identifier, for example:
 82.BR A1 ,
 83.BR G2 ,
 84.BR T3 ,
 85.BR L4 .
 86.SH DECLARATIONS
 87.SS Variable declarations
 88A variable declaration consists of a variable name,
 89its type, and a quoted source name:
 90.PP
 91.RS
 92.I var
 93.B \et
 94.I type
 95.B \et "
 96.I name
 97.RE
 98.PP
 99For example:
100.PP
101.RS
102.nf
103A4	W	"i
104G2	W	"g
105X3	P	"ptr
106.fi
107.RE
108.SS Function declarations
109Function declarations include the return type
110and use
111.B F
112for the function type
113.RB ( E
114if the function has an ellipsis parameter):
115.PP
116.RS
117.I var
118.B \et
119.I return-type
120.B \et F \et "
121.I name
122.RE
123.PP
124For example:
125.PP
126.RS
127.nf
128.ta 8n 16n 24n
129G2	W	F	"main
130X3	W	E	"printf
131T4	0	F	"helper
132.fi
133.RE
134.PP
135.B G
136marks a public function,
137.B T
138a file-scope static function, and
139.B X
140an extern declaration.
141.SS Function definitions
142A function definition starts with the function declaration,
143followed by
144.B {
145on its own line.
146Function parameters are declared inside the body.
147A
148.B \e
149(backslash) on its own line separates
150parameters from local variable declarations.
151The body ends with
152.BR } .
153.PP
154For example, the C source:
155.PP
156.RS
157.nf
158int func(int a, int b) {
159	int c;
160	return a + b;
161}
162.fi
163.RE
164.PP
165generates:
166.PP
167.RS
168.nf
169.ta 8n 16n 24n
170G2	W	F	"func
171{
172A3	W	"a
173A4	W	"b
174\e
175A6	W	"c
176	h	A3	A4	+W
177}
178.fi
179.RE
180.SS Struct and union declarations
181A struct or union type declaration starts with a header line
182containing the type letter and identifier,
183a quoted tag name,
184a hex-encoded size and a hex-encoded alignment:
185.PP
186.RS
187.I type-id
188.B \et "
189.I tag
190.B \et #
191.IR size-letter size
192.B \et #
193.IR size-letter align
194.RE
195.PP
196Member declarations follow, each including an offset field:
197.PP
198.RS
199.I member-var
200.B \et
201.I type
202.B \et "
203.I name
204.B \et #
205.IR size-letter offset
206.RE
207.PP
208For example, the C source:
209.PP
210.RS
211.nf
212struct point {
213	int x;
214	int y;
215};
216struct point p;
217.fi
218.RE
219.PP
220generates (on amd64-sysv):
221.PP
222.RS
223.nf
224.ta 8n 16n 24n
225S3	"point	#O8	#O4
226M4	W	"x	#O0
227M5	W	"y	#O4
228G6	S3	"p
229.fi
230.RE
231.PP
232Unions use
233.B U
234instead of
235.BR S .
236Members of a union typically share offset 0.
237.SS Array type declarations
238Array types are declared with
239.BR V ,
240the element type,
241and the number of elements in hexadecimal:
242.PP
243.RS
244.nf
245.ta 8n 16n 24n
246V5	W	#OA
247.fi
248.RE
249.PP
250This declares array type V5 with element type
251.B W
252(signed 32-bit integer) and 0xA (10) elements.
253Array variable declarations reference the array type:
254.PP
255.RS
256.nf
257.ta 8n 16n 24n
258A4	V5	"a
259.fi
260.RE
261.SS Enum declarations
262Enumerations are not emitted as types.
263Enum variables are emitted with their underlying integer type
264(typically
265.BR W ):
266.PP
267.RS
268.nf
269G7	W	"c
270.fi
271.RE
272.SH INITIALIZERS
273When a variable has an initializer,
274the declaration line ends without a newline and is followed by
275.B (
276on the same line.
277The initializer expressions follow,
278one per line,
279and the initializer is closed with
280.B )
281on its own line.
282.PP
283For example:
284.PP
285.RS
286.nf
287int g = 42;
288.fi
289.RE
290.PP
291generates:
292.PP
293.RS
294.nf
295.ta 8n 16n 24n
296G2	W	"g	(
297	#W2A
298)
299.fi
300.RE
301.PP
302Array and struct initializers list each element:
303.PP
304.RS
305.nf
306int a[3] = {1, 2, 3};
307.fi
308.RE
309.PP
310generates:
311.PP
312.RS
313.nf
314.ta 8n 16n 24n
315V3	W	#O3
316G2	V3	"a	(
317	#W1
318	#W2
319	#W3
320)
321.fi
322.RE
323.PP
324String initializers use a quoted form for printable runs
325and individual byte constants for non-printable characters:
326.PP
327.RS
328.nf
329.ta 8n 16n 24n
330	#"hello
331	#C0
332.fi
333.RE
334.SH EXPRESSIONS
335Expressions 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 Constants
339Constants are introduced with
340.BR # ,
341followed by a type letter and a hexadecimal value:
342.PP
343.RS
344.nf
345#W2A
346.fi
347.RE
348.PP
349This represents the integer constant 42 (0x2A) of type
350.BR W .
351.PP
352Floating-point constants are emitted as the hexadecimal encoding
353of their IEEE 754 representation:
354.PP
355.RS
356.nf
357#J3FC00000
358#D4004000000000000
359.fi
360.RE
361.PP
362These represent float 1.5 and double 2.5, respectively.
363.PP
364String constants are emitted using
365.B #"
366for printable character runs:
367.PP
368.RS
369.nf
370#"hello
371.fi
372.RE
373.SS Arithmetic operators
374.TS
375l l.
376+	addition
377\-	subtraction
378*	multiplication
379/	division
380%	modulo
381l	left shift
382r	right shift
383.TE
384.SS Comparison operators
385.TS
386l l.
387<	less than
388>	greater than
389[	less or equal
390]	greater or equal
391\&=	equal
392!	not equal
393.TE
394.SS Bitwise operators
395.TS
396l l.
397&	bitwise and
398|	bitwise or
399^	bitwise xor
400~	bitwise complement (unary)
401.TE
402.SS Logical operators
403.TS
404l l.
405a	logical and (short-circuit)
406o	logical or (short-circuit)
407n	logical negation
408.TE
409.SS Unary operators
410.TS
411l l.
412\&_	arithmetic negation
413~	bitwise complement
414n	logical negation
415\&'	address-of
416@	pointer dereference
417.TE
418.SS Assignment
419.TS
420l l.
421:	assignment
422:*	multiply and assign
423:/	divide and assign
424:%	modulo and assign
425:+	add and assign
426:\-	subtract and assign
427:l	left shift and assign
428:r	right shift and assign
429:&	bitwise and and assign
430:^	bitwise xor and assign
431:|	bitwise or and assign
432:i	post-increment
433:d	post-decrement
434.TE
435.SS Other operators
436.TS
437l l.
438,	comma
439?	ternary (conditional)
440\&.	struct/union field access
441g	type cast (followed by target type letter)
442.TE
443.SS Function calls
444Function calls use
445.B p
446to push each argument,
447.B c
448for the call itself,
449and
450.B z
451for calls to variadic functions.
452Each is followed by the type of the result:
453.PP
454.RS
455.nf
456.ta 8n 16n 24n 32n 40n 48n
457	X2	Y9	'P	pP	#W2A	pW	zW
458.fi
459.RE
460.PP
461This pushes a pointer argument
462.RB ( pP ),
463pushes an integer argument
464.RB ( pW ),
465and calls a variadic function returning
466.BR W
467.RB ( zW ).
468.SS Builtin functions
469Builtin function calls use
470.B m
471as the operator,
472preceded by a quoted builtin name:
473.PP
474.RS
475.nf
476"__builtin_va_arg	m
477.fi
478.RE
479.SS Expression example
480The C expression:
481.PP
482.RS
483.nf
484i = j + 2 * 3;
485.fi
486.RE
487.PP
488generates (on amd64-sysv):
489.PP
490.RS
491.nf
492.ta 8n 16n 24n 32n 40n
493	A4	A5	#W6	+W	:W
494.fi
495.RE
496.PP
497Note that constant folding has reduced
498.I 2*3
499to
500.IR 6 .
501The expression is in RPN:
502push A4, push A5, push #W6, add (yielding W), assign (yielding W).
503.SS Type casts
504Casts are emitted as the operator
505.B g
506followed by the target type letter.
507A cast to
508.B void
509is not emitted.
510For example:
511.PP
512.RS
513.nf
514j = (long)i;
515.fi
516.RE
517.PP
518generates (on amd64-sysv):
519.PP
520.RS
521.nf
522.ta 8n 16n 24n 32n
523	A5	A4	gQ	:Q
524.fi
525.RE
526.SH STATEMENTS
527.SS Labels
528Labels begin in column 0 and consist of
529.B L
530followed by a numeric identifier:
531.PP
532.RS
533.nf
534L3
535.fi
536.RE
537.SS Unconditional jumps
538An unconditional jump uses
539.B j
540followed by a label:
541.PP
542.RS
543.nf
544.ta 8n 16n
545	j	L3
546.fi
547.RE
548.SS Conditional branches
549A conditional branch uses
550.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.PP
555.RS
556.nf
557.ta 8n 16n 24n 32n
558	y	L5	A4	#W5	<W
559.fi
560.RE
561.PP
562Note that the frontend negates the condition:
563the C code
564.I "if (i > 5)"
565is emitted as a branch on
566.IR "i <= 5" ,
567jumping past the then-block when the original condition is false.
568.SS Return
569The return statement uses
570.BR h .
571If the function returns a value,
572the expression follows on the same line:
573.PP
574.RS
575.nf
576.ta 8n 16n 24n 32n
577	h	A3	A4	+W
578.fi
579.RE
580.PP
581A void return is emitted as
582.B h
583alone, followed by a blank expression line.
584.SS Loops
585Two markers indicate loop boundaries to the backend:
586.PP
587.TS
588l l.
589b	beginning of loop body
590e	end of loop body
591.TE
592.PP
593For example, a
594.B while
595loop:
596.PP
597.RS
598.nf
599while (i < 10) { ++i; }
600.fi
601.RE
602.PP
603generates:
604.PP
605.RS
606.nf
607.ta 8n 16n 24n 32n
608	j	L5
609L4
610	b
611	A4	#W1	:+W
612L5
613	e
614	y	L4	A4	#WA	<W
615L6
616.fi
617.RE
618.SS Switch statements
619A switch statement is bracketed by
620.B s
621(begin) and
622.B t
623(end).
624The
625.B s
626marker is followed by the switch expression.
627Case entries are emitted with
628.BR v ,
629and the default entry with
630.BR f .
631The
632.B t
633marker takes the label where execution continues after the switch.
634.PP
635For example:
636.PP
637.RS
638.nf
639switch (n+1) {
640case 1:
641case 2:
642case 3:
643default:
644	++n;
645}
646.fi
647.RE
648.PP
649generates:
650.PP
651.RS
652.nf
653.ta 8n 16n 24n 32n
654	s	A3	#W1	+W
655	v	L6	#W1
656L6
657	v	L7	#W2
658L7
659	v	L8	#W3
660L8
661	f	L9
662L9
663	A3	#W1	:+W
664	t	L5
665L5
666.fi
667.RE
668.PP
669Each
670.B v
671entry is followed by a label and a constant value.
672The
673.B f
674(default) entry is followed by a label only.
675.SH SEE ALSO
676.BR scc-cc (1)