.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 //- # -//
