.CH "Extended Examples" These examples should illustrate some global aspects of using the code generator. They include a segment of C source code, the (annotated) intermediate form code produced by the C front end, and the (annotated) assembly language generated by the VCG. .nf .MH "Basic VCG Input" .SH "C Code" .ti extern int e1, e2; /* defined outside this module */ int v1, v2; /* defined here, visible outside */ static int s1, s2; /* defined here, not visible outside */ proc1 () /* procedure defined here, visible outside */ { } proc2 () /* more of the same */ { } .SH "IMF Stream 1" .ti 32 A MODULE_OP; begins the input module 59 SEQ_OP; initiates the sequence of entry points 7 Object number 7 is an entry point... 5 whose name is 5 characters long... 240 p 242 r 239 o 227 c 177 1 59 SEQ_OP; next member of the list of entry points 8 Object number 8 is an entry point... 5 whose name is 5 characters long... 240 p 242 r 239 o 227 c 178 2 59 SEQ_OP; next member of the list of entry points 3 Object number 3 is an entry point... 2 whose name is 2 characters long... 246 v 177 1 59 SEQ_OP; next member of the list of entry points 4 Object number 4 is an entry point... 2 whose name is 2 characters long... 246 v 178 2 39 NULL_OP; terminates the list of entries in this module 39 NULL_OP; terminates the list of modules in the input .SH "IMF Stream 2" .ti 32 MODULE_OP; beginning of this input module 59 SEQ_OP; beginning of static data declarations list 14 DEFINE_STAT_OP; reserve space for an object 3 Object ID is 3 39 NULL_OP; there are no initializers for this object 1 Its size is 1 word 59 SEQ_OP; next element of declarations list 14 DEFINE_STAT_OP; reserve space for an object 4 Object ID is 4 39 NULL_OP; there are no initializers for this object 1 Its size is 1 word 59 SEQ_OP; next element of declarations list 14 DEFINE_STAT_OP; reserve space for an object 5 Object ID is 5 39 NULL_OP; there are no initializers for this object 1 Its size is 1 word 59 SEQ_OP; next element of declarations list 14 DEFINE_STAT_OP; reserve space for an object 6 Object ID is 6 39 NULL_OP; there are no initializers for this object 1 Its size is 1 word 59 SEQ_OP; next element of declarations list 11 DECLARE_STAT_OP; declare object defined outside this module 1 Object ID is 1 2 Name has 2 characters... 229 e 177 1 59 SEQ_OP; next element of declarations list 11 DECLARE_STAT_OP; declare object defined outside this module 2 Object ID is 2 2 Name has 2 characters... 229 e 178 2 39 NULL_OP; end of static data definition/declaration list 39 NULL_OP; end of modules in input stream .SH "IMF Stream 3" .ti 32 MODULE_OP; beginning of next module in input stream 59 SEQ_OP; first element of procedure definitions list 50 PROC_DEFN_OP; procedure definition follows 7 Procedure is object number 7 0 Procedure has no arguments 5 Procedure name is 5 characters long... 240 p 242 r 239 o 227 c 177 1 39 NULL_OP; empty argument description list 39 NULL_OP; no code for this procedure 59 SEQ_OP; next element of procedure definitions list 50 PROC_DEFN_OP; procedure definition follows 8 Procedure is object number 8 0 Procedure has no arguments 5 Procedure name is 5 characters long... 240 p 242 r 239 o 227 c 178 2 39 NULL_OP; empty argument description list 39 NULL_OP; no code for this procedure 39 NULL_OP; end of procedure definitions list (and this module) 39 NULL_OP; end of modules in this input stream .SH "PMA Code" .ti SEG Assemble in 64V mode RLIT Place literals in procedure frame SYML Allow 8-character external names ENT PROC1,L7_ PROC1 is an entry point with address L7_ ENT PROC2,L8_ Similarly for PROC2, ENT V1,L3_ V1, ENT V2,L4_ and V2 LINK Output data in link (static) frame L3_ EQU * BSZ '1 Reserve one word for L3_, init to zero PROC Output data in proc (procedure) frame LINK L4_ EQU * BSZ '1 Reserve one word for L4_, init to zero PROC LINK L5_ EQU * BSZ '1 Reserve one word for L5_, init to zero PROC LINK L6_ EQU * BSZ '1 Reserve one word for L6_, init to zero PROC LINK EXT E1 Declare symbol E1 external to this module L1_ EQU * IP E1 Generate a pointer for the loader to fill in PROC LINK EXT E2 Declare symbol E2 external to this module L2_ EQU * IP E2 Generate a pointer for the loader PROC PROC L65535_ EQU * Beginning of a procedure EAL L7_ Set up stack frame owner pointer for debugging STL SB%+18 LDA ='4000 STA% SB% PRTN "Procedure Return" at end of procedure L7_ ECB L65535_,,SB%+'0,0,'24 Entry control block for procedure DATA '5 PL/I character varying form procedure name DATA '170362 DATA '167743 DATA '130405 PROC L65534_ EQU * Beginning of second procedure EAL L8_ Set up stack frame owner pointer STL SB%+18 LDA ='4000 STA% SB% PRTN L8_ ECB L65534_,,SB%+'0,0,'24 Entry control block DATA '5 Procedure name DATA '170362 DATA '167743 DATA '131370 END End of this module .bp .MH "Storage Allocation" .SH "C Code" .ti int i, /* a static integer variable */ ii [10]; /* a static integer array */ struct { int f1, f2; } s; /* a static structure with two integer fields */ main (argc, argv) /* a non-trivial procedure, with arguments */ int argc; /* integer argument */ char **argv; /* pointer-to-pointer-to-character argument */ { int li, /* a local integer variable */ lii [10]; /* a local integer array */ struct { int m1, m2; } ls; /* a local structure with two integer fields */ i; /* use of various things in expressions */ ii [0]; s.f1; li; lii [0]; ls.m1; argv; argc; } .SH "IMF Stream 1" .ti 32 MODULE_OP; beginning of next module in input stream 59 SEQ_OP; beginning of entry point declaration list 1 Object number 1 is an entry point... 1 whose name is 1 character long... 233 i 59 SEQ_OP; next member of entry point list 3 Object number 3 is an entry point... 1 whose name is 1 character long... 243 s 59 SEQ_OP; next member of entry point list 4 Object number 4 is an entry point... 4 whose name is 4 characters long... 237 m 225 a 233 i 238 n 59 SEQ_OP; next member of entry point list 2 Object number 2 is an entry point... 2 whose name is 2 characters long... 233 i 233 i 39 NULL_OP; end of entry point list (and this module) 39 NULL_OP; end of modules in this input stream .SH "IMF Stream 2" .ti 32 MODULE_OP; beginning of next module 59 SEQ_OP; beginning of static data declarations/definitions 14 DEFINE_STAT_OP; reserve space for a static variable 1 Object ID is 1 39 NULL_OP; no initializers for this variable 1 Object size is 1 word 59 SEQ_OP; next member of static data list 14 DEFINE_STAT_OP; reserve space for a static variable 2 Object ID is 2 39 NULL_OP; no initializers for this variable 10 Object size is 10 words 59 SEQ_OP; next member of static data list 14 DEFINE_STAT_OP; reserve space for a static variable 3 Object ID is 3 39 NULL_OP; no initializers for this variable 2 Object size is 2 words 39 NULL_OP; end of static data list 39 NULL_OP; end of modules in this input stream .SH "IMF Stream 3" .ti 32 MODULE_OP; beginning of next module in input stream 59 SEQ_OP; beginning of procedure definition list 50 PROC_DEFN_OP; procedure definition follows 4 Object ID of procedure is 4 2 Procedure has 2 arguments 4 Procedure name is 4 characters long... 237 m 225 a 233 i 238 n 49 PROC_DEFN_ARG_OP; description of first argument 5 Argument has object ID 5 1 Argument has mode 1 (INTEGER) 0 Argument has disposition 0 (pass-by-value) 1 Argument is 1 word long 49 PROC_DEFN_ARG_OP; description of second argument 6 Argument has object ID 6 4 Argument has mode 4 (LONG UNSIGNED, or pointer) 1 Argument has disposition 1 (pass-by-reference) 2 Argument is 2 words long 39 NULL_OP; end of argument descriptor list 59 SEQ_OP; beginning of procedure code 13 DEFINE_DYNM_OP; reserve space for local variable 7 Object ID 7 39 NULL_OP; no initializers 1 Size 1 word 59 SEQ_OP; next element of procedure code 13 DEFINE_DYNM_OP; reserve space for local variable 8 Object ID 8 39 NULL_OP; no initializers 10 Size 10 words 59 SEQ_OP; next element of procedure code 13 DEFINE_DYNM_OP; reserve space for local variable 9 Object ID 9 39 NULL_OP; no initializers 2 Size 2 words 59 SEQ_OP; next element of procedure code 40 OBJECT_OP; (this is actually an expression subtree) 1 Mode 1 (INTEGER) 1 Object ID 1 59 SEQ_OP; next element of procedure code 25 INDEX_OP; again, the top of an expression subtree 1 Mode 1 (INTEGER) 40 OBJECT_OP; this one is the base address of the array 7 Mode 7 (STOWED) 2 Object ID 2 9 CONST_OP; this one is the index expression 1 Mode 1 (INTEGER) 1 Length is 1 word 0 Value of word is 0 1 Array element size is 1 word 59 SEQ_OP; next element of procedure code 58 SELECT_OP; again, the top of an expression subtree 1 Mode 1 (INTEGER) 0 Field to be selected has word offset 0 from base 40 OBJECT_OP; the base address of the structure 7 Mode 7 (STOWED) 3 Object ID 3 59 SEQ_OP; next element of procedure code 40 OBJECT_OP; an expression, again 1 Mode 1 (INTEGER) 7 Object ID is 7 59 SEQ_OP; next element of procedure code 25 INDEX_OP; using an array element as an expression 1 Mode 1 (INTEGER) 40 OBJECT_OP; this is the base of the array being indexed 7 Mode 7 (STOWED) 8 Object ID is 8 9 CONST_OP; this is the subscript expression 1 MODE 1 (INTEGER) 1 Length of constant is 1 word 0 Value of constant is 0 1 Array element size is 1 word 59 SEQ_OP; next element of procedure code 58 SELECT_OP; using struct field as an expression 1 Mode 1 (INTEGER) 0 Offset of selected field is 0 words from base 40 OBJECT_OP; this is the base address of the structure 7 Mode 7 (STOWED) 9 Object ID is 9 59 SEQ_OP; next element of procedure code 40 OBJECT_OP; just the top of an expression tree 4 Mode 4 (LONG_UNSIGNED, or pointer) 6 Object ID is 6 59 SEQ_OP; next element of procedure code 40 OBJECT_OP; an expression, again 1 Mode 1 (INTEGER) 5 Object ID is 5 39 NULL_OP; end of procedure body code (and proc defn) 39 NULL_OP; end of procedure defn list (and this module) 39 NULL_OP; end of this input stream .SH "PMA Code" .ti SEG Assemble in 64V mode RLIT Place literals in procedure frame SYML Allow 8-character external symbols ENT I,L1_ I is an entry point, with address L1_ ENT S,L3_ S is an entry point, with address L3_ ENT MAIN,L4_ MAIN is an entry point, with address L4_ ENT II,L2_ II is an entry point, with address L2_ LINK Emit data in link (static data) frame L1_ EQU * BSZ '1 Reserve 1 word for L1_ PROC LINK L2_ EQU * BSZ '12 Reserve 10 words ('12 octal) for L2_ PROC LINK L3_ EQU * BSZ '2 Reserve 2 words for L3_ PROC PROC L65535_ EQU * Beginning of a procedure ARGT Transfer arguments from caller EAL L4_ Set up stack frame owner pointer for debugging STL SB%+18 LDA ='4000 STA% SB% LDA SB%+'24,* Make copy of pass-by-value arguments STA SB%+'24 LDA LB%+'400 Evaluate expression 1, LDA LB%+'401 2, LDA LB%+'413 3, LDA SB%+'25 4, LDA SB%+'32 5, LDA SB%+'44 6, LDL SB%+'27 7, LDA SB%+'24 8 PRTN Return from the procedure L4_ ECB L65535_,,SB%+'24,2,'46 Entry control block DATA '4 PL/I char varying procedure name DATA '166741 DATA '164756 END End of this PMA module .bp .MH "String Copy" .SH "C Code" .ti strcpy (s, t) /* copy string s to string t */ char s[], t[]; { int i; /* a local integer variable, for indexing */ i = 0; /* start at first char */ while ((t[i] = s[i]) != '\0') /* copy until a zero char is seen */ i += 1; /* incrementing the index each time */ } .SH "IMF Stream 1" .ti 32 MODULE_OP; begins the input module 59 SEQ_OP; begins sequence of entry points 1 Object number 1 is an entry point 6 whose name is 6 characters long... 243 s 244 t 242 r 227 c 240 p 249 y 39 NULL_OP; terminates entry point list 39 NULL_OP; terminates list of modules in the input .SH "IMF Stream 2" .ti 32 MODULE_OP; begins the input module 39 NULL_OP; terminates the sequence of static data definitions 39 NULL_OP; terminates list of modules in the input .SH "IMF Stream 3" .ti 32 MODULE_OP; begins next module in the input stream 59 SEQ_OP; first procedure definition follows 50 PROC_DEFN_OP; procedure definition follows 1 Procedure is object number 1 2 There are 2 arguments, described below. 6 Procedure name is 6 characters long... 243 s 244 t 242 r 227 c 240 p 249 y 49 PROC_DEFN_ARG_OP; description of argument number 1 2 Argument is object number 2 4 LONG_UNS_MODE; argument is a pointer 1 REF_DISP; argument is passed-by-reference 2 Argument is 2 words long 49 PROC_DEFN_ARG_OP; description of argument number 2 3 Argument is object number 3 4 LONG_UNS_MODE; argument is a pointer 1 REF_DISP; argument is passed-by-reference 2 Argument is 2 words long 39 NULL_OP; end of argument descriptions 59 SEQ_OP; beginning of procedure code list 13 DEFINE_DYNM_OP; declare a local variable 4 Variable has object id 4 39 No initializers 1 Variable is 1 word in length 59 SEQ_OP; next element of code list 5 ASSIGN_OP 1 INT_MODE 40 OBJECT_OP 1 INT_MODE 4 Object id is 4 9 CONST_OP 1 INT_MODE 1 Constant has length 1 0 Constant has value 0 1 Assignment transfers 1 word 59 SEQ_OP; next element of code list 65 WHILE_OP 37 NE_OP 1 INT_MODE 5 ASSIGN_OP 1 INT_MODE 25 INDEX_OP; the LHS of the assignment 1 INT_MODE 15 DEREF_OP; this is the base address 7 STOWED_MODE 40 OBJECT_OP 4 LONG_UNS_MODE 3 Object id is 3 40 OBJECT_OP; this is the subscript 1 INT_MODE 4 Object id is 4 1 Array element size is 1 word 25 INDEX_OP; the RHS of the assignment 1 INT_MODE 15 DEREF_OP; the base address expression 7 STOWED_MODE 40 OBJECT_OP 4 LONG_UNS_MODE 2 Object id is 2 40 OBJECT_OP; the subscript, again 1 INT_MODE 4 Object id is 4 1 Array element size is 1 word 1 Assignment transfers 1 word 9 CONST_OP; the right operand of the NE_OP 1 INT_MODE 1 Constant is 1 word long 0 Constant has value 0 59 SEQ_OP; beginning of the body of the WHILE loop 1 ADDAA_OP 1 INT_MODE 40 OBJECT_OP 1 INT_MODE 4 Object id is 4 9 CONST_OP 1 INT_MODE 1 Length is 1 word 1 Value is 1 39 NULL_OP; end of the body of the WHILE loop 39 NULL_OP; end of the statements for the current procedure 39 NULL_OP; end of the procedure definitions in this module 39 NULL_OP; end of this input stream .SH "PMA Code" .ti SEG RLIT SYML ENT STRCPY,L1_ PROC L65535_ EQU * ARGT Transfer arguments from caller EAL L1_ Set up stack frame owner pointer for debugging STL SB%+18 LDA ='4000 STA% SB% CRA Load A with zero STA SB%+'32 Store in i JMP L65533_ Enter the WHILE loop at the test FIN (dump literals here) L65532_ EQU * Top of the WHILE loop body IRS SB%+'32 Increment i RCB (takes two instructions on this turkey machine) L65533_ EQU * WHILE loop test starts here LDX SB%+'32 Load index register with i LDA SB%+'24,*X Load next character in string s STA SB%+'27,*X Store it in next position in string t BNE L65532_ If it's non-zero, go back for more characters L65534_ EQU * Exit label for the WHILE loop PRTN Return from string copy procedure L1_ ECB L65535_,,SB%+'24,2,'33 DATA '6 DATA '171764 DATA '171343 DATA '170371 END .bp .MH "Tree Print" .SH "C Code" .ti /* recursive tree-printing routine */ #define NULL 0 /* a nil pointer */ struct TNODE /* the data structure out of which the tree is built */ { int value; struct TNODE *left, *right; }; typedef struct TNODE tnode; /* create a new type, for convenience */ treeprint (t) tnode *t; { if (t != NULL) { treeprint (t->left); printf ("%4d\n", t->value); /* output the 'value' field */ treeprint (t->right); } } .SH "IMF Stream 1" .ti 32 MODULE_OP; beginning of next module in input stream 59 SEQ_OP; beginning of list of entry point declarations 1 Object number 1 is an entry point 9 whose name is 9 characters long... 244 t 242 r 229 e 229 e 240 p 242 r 233 i 238 n 244 t 39 NULL_OP; end of entry point list for this module 39 NULL_OP; end of modules in this input stream .SH "IMF Stream 2" .ti 32 MODULE_OP; beginning of next module in this input stream 59 SEQ_OP; beginning of list of static data definitions 11 DECLARE_STAT_OP; declare an externally-defined object 3 Object has object id 3 6 Name of object is 6 characters long... 240 p 242 r 233 i 238 n 244 t 230 f 39 NULL_OP; end of static data for this module 39 NULL_OP; end of modules in this input stream .SH "IMF Stream 3" .ti 32 MODULE_OP; beginning of next module in input stream 59 SEQ_OP; beginning of list of procedure definitions 50 PROC_DEFN_OP; procedure definition follows 1 Procedure has object id 1 1 Procedure has 1 argument 9 Procedure name is 9 characters long... 244 t 242 r 229 e 229 e 240 p 242 r 233 i 238 n 244 t 49 PROC_DEFN_ARG_OP; description of procedure argument 2 Argument has object id 2 4 Argument has mode LONG_UNS (it's a pointer) 1 Argument has REF disposition (pass-by-reference) 2 Argument is 2 words long 39 NULL_OP; no further argument descriptions 59 SEQ_OP; beginning of statement list 24 IF_OP 1 INT_MODE 37 NE_OP 4 LONG_UNS_MODE 40 OBJECT_OP 4 LONG_UNS_MODE 2 Object has id 2 9 CONST_OP 4 LONG_UNS_MODE 2 Constant has length 2 0 First word of constant is 0 0 Second word of constant is 0 59 SEQ_OP; then-part of IF statement follows 48 PROC_CALL_OP (for treeprint) 1 INT_MODE 40 OBJECT_OP; this is the base address 7 STOWED_MODE; arbitrary, for procs. 1 Object id of procedure is 1 47 PROC_CALL_ARG_OP 7 STOWED_MODE 15 DEREF_OP 7 STOWED_MODE 58 SELECT_OP 4 LONG_UNS_MODE 1 Field offset is 1 word 15 DEREF_OP 7 STOWED_MODE 40 OBJECT_OP 4 LONG_UNS_MODE 2 Object id is 2 39 NULL_OP; end of argument list 59 SEQ_OP; next element of IF body follows 48 PROC_CALL_OP (for printf) 1 INT_MODE 40 OBJECT_OP; the base address 7 STOWED_MODE; ignored in this case 3 Object id of procedure is 3 47 PROC_CALL_ARG_OP 1 INT_MODE 15 DEREF_OP 1 INT_MODE 51 REFTO_OP 4 LONG_UNS_MODE (pointer to char) 9 CONST_OP; this is the string 7 STOWED_MODE 5 Length is 5 words 165 Value is % 180 4 228 d 138 newline 0 0 47 PROC_CALL_ARG_OP 1 INT_MODE 58 SELECT_OP 1 INT_MODE 0 Field is at offset 0 15 DEREF_OP; base address of struct 7 STOWED_MODE 40 OBJECT_OP 4 LONG_UNS_MODE 2 Object id is 2 39 NULL_OP; end of argument list 59 SEQ_OP; next element of body of IF follows 48 PROC_CALL_OP 1 INT_MODE (ignored) 40 OBJECT_OP; the procedure address 7 STOWED_MODE 1 Object id is 1 47 PROC_CALL_ARG_OP 7 STOWED_MODE 15 DEREF_OP 7 STOWED_MODE 58 SELECT_OP 4 LONG_UNS_MODE 3 Field has offset 3 words 15 DEREF_OP 7 STOWED_MODE 40 OBJECT_OP 4 LONG_UNS_MODE 2 Object id is 2 39 NULL_OP; end of treeprint args 39 NULL_OP; end of then-part of IF 39 NULL_OP; omitted else-part of the IF 39 NULL_OP; end of statements in this procedure 39 NULL_OP; end of procedure definition list (and this module) 39 NULL_OP; end of modules in this input stream .SH "PMA Code" .ti SEG RLIT SYML ENT TREEPRINT,L1_ Make 'treeprint' available outside this module LINK EXT PRINTF L3_ EQU * IP PRINTF Use 'printf', defined outside this module PROC PROC L65535_ EQU * Beginning of 'treeprint' ARGT Transfer arguments from caller EAL L1_ Set up stack frame owner pointer for debugging STL SB%+18 LDA ='4000 STA% SB% LDL SB%+'24 If the argument... BLEQ L65534_ ...is nonzero... LDX ='1 we first get the pointer in the 'left' field EAXB SB%+'24,*X by addressing the field with XB LDL XB%+'0 then loading the value of the pointer into L STL SB%+'27 then storing it in a temporary PCL L1_ call 'treeprint' recursively AP SB%+'27,*SL using the temporary to pass the value LINK DATA '245 This is the format string for 'printf'... DATA '264 ...value is "%4d\n\0" DATA '344 DATA '212 DATA '0 PROC PCL LB%+'400,* Here's the call to 'printf' AP LB%+'402,S passing the formatting string AP SB%+'24,*SL and the value field of the current tnode LDX ='3 Now we get the pointer in the 'right' field EAXB SB%+'24,*X pretty much as we did it before LDL XB%+'0 STL SB%+'27 PCL L1_ and call 'treeprint', AP SB%+'27,*SL passing it the pointer to the right subtree L65534_ EQU * PRTN return from 'treeprint' L1_ ECB L65535_,,SB%+'24,1,'31 DATA '11 DATA '172362 DATA '162745 DATA '170362 DATA '164756 DATA '172041 END .EV .fo //- # -//