94f6e620f7626c1a1407d65dad5858bed318bd60
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
1 package IR.Flat;
2 import IR.Tree.FlagExpressionNode;
3 import IR.Tree.DNFFlag;
4 import IR.Tree.DNFFlagAtom;
5 import IR.*;
6 import java.util.*;
7 import java.io.*;
8
9 public class BuildCode {
10     State state;
11     Hashtable temptovar;
12     Hashtable paramstable;
13     Hashtable tempstable;
14     Hashtable fieldorder;
15     Hashtable flagorder;
16     int tag=0;
17     String localsprefix="___locals___";
18     String paramsprefix="___params___";
19     public static boolean GENERATEPRECISEGC=false;
20     public static String PREFIX="";
21     public static String arraytype="ArrayObject";
22     Virtual virtualcalls;
23     TypeUtil typeutil;
24     private int maxtaskparams=0;
25     ClassDescriptor[] cdarray;
26     TypeDescriptor[] arraytable;
27
28     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
29         state=st;
30         this.temptovar=temptovar;
31         paramstable=new Hashtable();    
32         tempstable=new Hashtable();
33         fieldorder=new Hashtable();
34         flagorder=new Hashtable();
35         this.typeutil=typeutil;
36         virtualcalls=new Virtual(state);
37     }
38
39     /** The buildCode method outputs C code for all the methods.  The Flat
40      * versions of the methods must already be generated and stored in
41      * the State object. */
42
43     public void buildCode() {
44         /* Create output streams to write to */
45         PrintWriter outclassdefs=null;
46         PrintWriter outstructs=null;
47         PrintWriter outmethodheader=null;
48         PrintWriter outmethod=null;
49         PrintWriter outvirtual=null;
50         PrintWriter outtask=null;
51         PrintWriter outtaskdefs=null;
52
53         try {
54             OutputStream str=new FileOutputStream(PREFIX+"structdefs.h");
55             outstructs=new java.io.PrintWriter(str, true);
56             str=new FileOutputStream(PREFIX+"methodheaders.h");
57             outmethodheader=new java.io.PrintWriter(str, true);
58             str=new FileOutputStream(PREFIX+"classdefs.h");
59             outclassdefs=new java.io.PrintWriter(str, true);
60             str=new FileOutputStream(PREFIX+"methods.c");
61             outmethod=new java.io.PrintWriter(str, true);
62             str=new FileOutputStream(PREFIX+"virtualtable.h");
63             outvirtual=new java.io.PrintWriter(str, true);
64             if (state.TASK) {
65                 str=new FileOutputStream(PREFIX+"task.h");
66                 outtask=new java.io.PrintWriter(str, true);
67                 str=new FileOutputStream(PREFIX+"taskdefs.c");
68                 outtaskdefs=new java.io.PrintWriter(str, true);
69             }
70         } catch (Exception e) {
71             e.printStackTrace();
72             System.exit(-1);
73         }
74
75         /* Build the virtual dispatch tables */
76
77         buildVirtualTables(outvirtual);
78
79         /* Output includes */
80         outstructs.println("#include \"classdefs.h\"");
81         outmethodheader.println("#include \"structdefs.h\"");
82
83         /* Output types for short array and string */
84         outstructs.println("#define STRINGARRAYTYPE "+
85                            (state.getArrayNumber(
86                                                  (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
87
88         outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
89         outstructs.println("#define CHARARRAYTYPE "+
90                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
91         outstructs.println("#define NUMCLASSES "+state.numClasses());
92         if (state.TASK)
93             outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
94
95         // Output the C class declarations
96         // These could mutually reference each other
97         outclassdefs.println("struct "+arraytype+";");
98
99         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
100         while(it.hasNext()) {
101             ClassDescriptor cn=(ClassDescriptor)it.next();
102             outclassdefs.println("struct "+cn.getSafeSymbol()+";");
103         }
104         outclassdefs.println("");
105         {
106             //Print out definition for array type
107             outclassdefs.println("struct "+arraytype+" {");
108             outclassdefs.println("  int type;");
109             printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
110             outclassdefs.println("  int ___length___;");
111             outclassdefs.println("};\n");
112
113             if (state.TASK) {
114             //Print out definitions for task types
115                 outtask.println("struct parameterdescriptor {");
116                 outtask.println("int type;");
117                 outtask.println("int numberterms;");
118                 outtask.println("int *intarray;");
119                 outtask.println("void * queue;");
120                 outtask.println("};");
121
122                 outtask.println("struct taskdescriptor {");
123                 outtask.println("void * taskptr;");
124                 outtask.println("int numParameters;");
125                 outtask.println("struct parameterdescriptor **descriptorarray;");
126                 outtask.println("};");
127                 outtask.println("extern struct taskdescriptor * taskarray[];");
128                 outtask.println("extern numtasks;");
129             }
130         }
131
132         // Output function prototypes and structures for parameters
133         it=state.getClassSymbolTable().getDescriptorsIterator();
134         while(it.hasNext()) {
135             ClassDescriptor cn=(ClassDescriptor)it.next();
136             generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
137         }
138
139
140         if (state.TASK) {
141             /* Map flags to integers */
142             it=state.getClassSymbolTable().getDescriptorsIterator();
143             while(it.hasNext()) {
144                 ClassDescriptor cn=(ClassDescriptor)it.next();
145                 mapFlags(cn);
146             }
147             /* Generate Tasks */
148             generateTaskStructs(outstructs, outmethodheader);
149         }
150
151         outmethodheader.close();
152
153         /* Build the actual methods */
154         outmethod.println("#include \"methodheaders.h\"");
155         outmethod.println("#include \"virtualtable.h\"");
156         outmethod.println("#include <runtime.h>");
157         outclassdefs.println("extern int classsize[];");
158         outclassdefs.println("extern int * pointerarray[];");
159
160         //Store the sizes of classes & array elements
161         generateSizeArray(outmethod);
162         
163         //Store the layout of classes
164         generateLayoutStructs(outmethod);
165
166         /* Generate code for methods */
167         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
168         while(classit.hasNext()) {
169             ClassDescriptor cn=(ClassDescriptor)classit.next();
170             Iterator methodit=cn.getMethods();
171             while(methodit.hasNext()) {
172                 /* Classify parameters */
173                 MethodDescriptor md=(MethodDescriptor)methodit.next();
174                 FlatMethod fm=state.getMethodFlat(md);
175                 if (!md.getModifiers().isNative())
176                     generateFlatMethod(fm,outmethod);
177             }
178         }
179
180         if (state.TASK) {
181             /* Compile task based program */
182             outtaskdefs.println("#include \"task.h\"");
183             outtaskdefs.println("#include \"methodheaders.h\"");
184             Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
185             while(taskit.hasNext()) {
186                 TaskDescriptor td=(TaskDescriptor)taskit.next();
187                 FlatMethod fm=state.getMethodFlat(td);
188                 generateFlatMethod(fm, outmethod);
189                 generateTaskDescriptor(outtaskdefs, td);
190             }
191
192             taskit=state.getTaskSymbolTable().getDescriptorsIterator();
193             outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
194             boolean first=true;
195             while(taskit.hasNext()) {
196                 TaskDescriptor td=(TaskDescriptor)taskit.next();
197                 if (first)
198                     first=false;
199                 else
200                     outtaskdefs.println(",");
201                 outtaskdefs.print("&task_"+td.getSafeSymbol());
202             }
203             outtaskdefs.println("};");
204             outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
205
206         } else if (state.main!=null) {
207             /* Generate main method */
208             outmethod.println("int main(int argc, const char *argv[]) {");
209             ClassDescriptor cd=typeutil.getClass(state.main);
210             Set mainset=cd.getMethodTable().getSet("main");
211             for(Iterator mainit=mainset.iterator();mainit.hasNext();) {
212                 MethodDescriptor md=(MethodDescriptor)mainit.next();
213                 if (md.numParameters()!=0)
214                     continue;
215                 if (!md.getModifiers().isStatic())
216                     throw new Error("Error: Non static main");
217                 outmethod.println("   "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"();");
218                 break;
219             }
220             outmethod.println("}");
221         }
222         if (state.TASK)
223             outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
224         outstructs.close();
225         outmethod.close();
226     }
227
228     private int maxcount=0;
229
230     /** This method outputs TaskDescriptor information */
231     void generateTaskDescriptor(PrintWriter output, TaskDescriptor task) {
232         for (int i=0;i<task.numParameters();i++) {
233             VarDescriptor param_var=task.getParameter(i);
234             TypeDescriptor param_type=task.getParamType(i);
235             FlagExpressionNode param_flag=task.getFlag(param_var);
236             DNFFlag dflag=param_flag.getDNF();
237             
238             Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
239                         
240             output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
241             for(int j=0;j<dflag.size();j++) {
242                 if (j!=0)
243                     output.println(",");
244                 Vector term=dflag.get(j);
245                 int andmask=0;
246                 int checkmask=0;
247                 for(int k=0;k<term.size();k++) {
248                     DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
249                     FlagDescriptor fd=dfa.getFlag();
250                     boolean negated=dfa.getNegated();
251                     int flagid=1<<((Integer)flags.get(fd)).intValue();
252                     andmask|=flagid;
253                     if (!negated)
254                         checkmask|=flagid;
255                 }
256                 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
257             }
258             output.println("};");
259
260             output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
261             output.println("/* type */"+param_type.getClassDesc().getId()+",");
262             output.println("/* number of DNF terms */"+dflag.size()+",");
263             output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
264             output.println("0");
265             output.println("};");
266         }
267
268
269         output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
270         for (int i=0;i<task.numParameters();i++) {
271             if (i!=0)
272                 output.println(",");
273             output.print("&parameter_"+i+"_"+task.getSafeSymbol());
274         }
275         output.println("};");
276
277         output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
278         output.println("&"+task.getSafeSymbol()+",");
279         output.println("/* number of parameters */" +task.numParameters() + ",");
280         output.println("parameterdescriptors_"+task.getSafeSymbol());
281         output.println("};");
282     }
283
284
285     /** The buildVirtualTables method outputs the virtual dispatch
286      * tables for methods. */
287
288     private void buildVirtualTables(PrintWriter outvirtual) {
289         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
290         while(classit.hasNext()) {
291             ClassDescriptor cd=(ClassDescriptor)classit.next();
292             if (virtualcalls.getMethodCount(cd)>maxcount)
293                 maxcount=virtualcalls.getMethodCount(cd);
294         }
295         MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
296
297         /* Fill in virtual table */
298         classit=state.getClassSymbolTable().getDescriptorsIterator();
299         while(classit.hasNext()) {
300             ClassDescriptor cd=(ClassDescriptor)classit.next();
301             fillinRow(cd, virtualtable, cd.getId());
302         }
303
304         ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
305         Iterator arrayit=state.getArrayIterator();
306         while(arrayit.hasNext()) {
307             TypeDescriptor td=(TypeDescriptor)arrayit.next();
308             int id=state.getArrayNumber(td);
309             fillinRow(objectcd, virtualtable, id+state.numClasses());
310         }
311         
312         outvirtual.print("void * virtualtable[]={");
313         boolean needcomma=false;
314         for(int i=0;i<state.numClasses()+state.numArrays();i++) {
315             for(int j=0;j<maxcount;j++) {
316                 if (needcomma)
317                     outvirtual.print(", ");
318                 if (virtualtable[i][j]!=null) {
319                     MethodDescriptor md=virtualtable[i][j];
320                     outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
321                 } else {
322                     outvirtual.print("0");
323                 }
324                 needcomma=true;
325             }
326             outvirtual.println("");
327         }
328         outvirtual.println("};");
329         outvirtual.close();
330     }
331
332     private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
333         /* Get inherited methods */
334         if (cd.getSuperDesc()!=null)
335             fillinRow(cd.getSuperDesc(), virtualtable, rownum);
336         /* Override them with our methods */
337         for(Iterator it=cd.getMethods();it.hasNext();) {
338             MethodDescriptor md=(MethodDescriptor)it.next();
339             if (md.isStatic()||md.getReturnType()==null)
340                 continue;
341             int methodnum=virtualcalls.getMethodNumber(md);
342             virtualtable[rownum][methodnum]=md;
343         }
344     }
345
346     /** Generate array that contains the sizes of class objects.  The
347      * object allocation functions in the runtime use this
348      * information. */
349
350     private void generateSizeArray(PrintWriter outclassdefs) {
351         outclassdefs.print("int classsize[]={");
352         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
353         cdarray=new ClassDescriptor[state.numClasses()];
354         while(it.hasNext()) {
355             ClassDescriptor cd=(ClassDescriptor)it.next();
356             cdarray[cd.getId()]=cd;
357         }
358         boolean needcomma=false;
359         for(int i=0;i<state.numClasses();i++) {
360             if (needcomma)
361                 outclassdefs.print(", ");
362             outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");            
363             needcomma=true;
364         }
365
366         arraytable=new TypeDescriptor[state.numArrays()];
367
368         Iterator arrayit=state.getArrayIterator();
369         while(arrayit.hasNext()) {
370             TypeDescriptor td=(TypeDescriptor)arrayit.next();
371             int id=state.getArrayNumber(td);
372             arraytable[id]=td;
373         }
374         
375         for(int i=0;i<state.numArrays();i++) {
376             if (needcomma)
377                 outclassdefs.print(", ");
378             TypeDescriptor tdelement=arraytable[i].dereference();
379             if (tdelement.isArray()||tdelement.isClass())
380                 outclassdefs.print("sizeof(void *)");
381             else
382                 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
383             needcomma=true;
384         }
385
386         outclassdefs.println("};");
387     }
388
389     /** Constructs params and temp objects for each method or task.
390      * These objects tell the compiler which temps need to be
391      * allocated.  */
392
393     private void generateTempStructs(FlatMethod fm) {
394         MethodDescriptor md=fm.getMethod();
395         TaskDescriptor task=fm.getTask();
396
397         ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
398         if (md!=null)
399             paramstable.put(md, objectparams);
400         else
401             paramstable.put(task, objectparams);
402
403         for(int i=0;i<fm.numParameters();i++) {
404             TempDescriptor temp=fm.getParameter(i);
405             TypeDescriptor type=temp.getType();
406             if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
407                 objectparams.addPtr(temp);
408             else
409                 objectparams.addPrim(temp);
410         }
411
412         TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
413         if (md!=null)
414             tempstable.put(md, objecttemps);
415         else
416             tempstable.put(task, objecttemps);
417
418         for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
419             FlatNode fn=(FlatNode)nodeit.next();
420             TempDescriptor[] writes=fn.writesTemps();
421             for(int i=0;i<writes.length;i++) {
422                 TempDescriptor temp=writes[i];
423                 TypeDescriptor type=temp.getType();
424                 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
425                     objecttemps.addPtr(temp);
426                 else
427                     objecttemps.addPrim(temp);
428             }
429         }
430     }
431     
432     private void generateLayoutStructs(PrintWriter output) {
433         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
434         while(it.hasNext()) {
435             ClassDescriptor cn=(ClassDescriptor)it.next();
436             output.println("int "+cn.getSafeSymbol()+"_pointers[]={");
437             Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
438             int count=0;
439             while(allit.hasNext()) {
440                 FieldDescriptor fd=(FieldDescriptor)allit.next();
441                 TypeDescriptor type=fd.getType();
442                 if (type.isPtr()||type.isArray())
443                     count++;
444             }
445             output.print(count);
446             allit=cn.getFieldTable().getAllDescriptorsIterator();
447             while(allit.hasNext()) {
448                 FieldDescriptor fd=(FieldDescriptor)allit.next();
449                 TypeDescriptor type=fd.getType();
450                 if (type.isPtr()||type.isArray()) {
451                     output.println(",");
452                     output.print("((int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
453                 }
454             }
455             output.println("};");
456         }
457         output.println("int * pointerarray[]={");
458         boolean needcomma=false;
459         for(int i=0;i<state.numClasses();i++) {
460             ClassDescriptor cn=cdarray[i];
461             if (needcomma)
462                 output.println(",");
463             needcomma=true;
464             output.print(cn.getSafeSymbol()+"_pointers");
465         }
466
467         for(int i=0;i<state.numArrays();i++) {
468             if (needcomma)
469                 output.println(",");
470             TypeDescriptor tdelement=arraytable[i].dereference();
471             if (tdelement.isArray()||tdelement.isClass())
472                 output.print("((int *)1)");
473             else
474                 output.print("0");
475             needcomma=true;
476         }
477         
478         output.println("};");
479     }
480
481     /* Force consistent field ordering between inherited classes. */
482
483     private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
484         ClassDescriptor sp=cn.getSuperDesc();
485         if (sp!=null)
486             printClassStruct(sp, classdefout);
487         
488         if (!fieldorder.containsKey(cn)) {
489             Vector fields=new Vector();
490             fieldorder.put(cn,fields);
491             Iterator fieldit=cn.getFields();
492             while(fieldit.hasNext()) {
493                 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
494                 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
495                     fields.add(fd);
496             }
497         }
498         Vector fields=(Vector)fieldorder.get(cn);
499
500         for(int i=0;i<fields.size();i++) {
501             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
502             if (fd.getType().isClass()||fd.getType().isArray())
503                 classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
504             else 
505                 classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
506         }
507     }
508
509
510     /* Map flags to integers consistently between inherited
511      * classes. */
512
513     private void mapFlags(ClassDescriptor cn) {
514         ClassDescriptor sp=cn.getSuperDesc();
515         if (sp!=null)
516             mapFlags(sp);
517         int max=0;
518         if (!flagorder.containsKey(cn)) {
519             Hashtable flags=new Hashtable();
520             flagorder.put(cn,flags);
521             if (sp!=null) {
522                 Hashtable superflags=(Hashtable)flagorder.get(sp);
523                 Iterator superflagit=superflags.keySet().iterator();
524                 while(superflagit.hasNext()) {
525                     FlagDescriptor fd=(FlagDescriptor)superflagit.next();
526                     Integer number=(Integer)superflags.get(fd);
527                     flags.put(fd, number);
528                     if ((number.intValue()+1)>max)
529                         max=number.intValue()+1;
530                 }
531             }
532             
533             Iterator flagit=cn.getFlags();
534             while(flagit.hasNext()) {
535                 FlagDescriptor fd=(FlagDescriptor)flagit.next();
536                 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
537                     flags.put(fd, new Integer(max++));
538             }
539         }
540     }
541
542
543     /** This function outputs (1) structures that parameters are
544      * passed in (when PRECISE GC is enabled) and (2) function
545      * prototypes for the methods */
546
547     private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
548         /* Output class structure */
549         classdefout.println("struct "+cn.getSafeSymbol()+" {");
550         classdefout.println("  int type;");
551         if (cn.hasFlags()) {
552             classdefout.println("  int flag;");
553             classdefout.println("  void * flagptr;");
554         }
555         printClassStruct(cn, classdefout);
556         classdefout.println("};\n");
557
558         /* Cycle through methods */
559         Iterator methodit=cn.getMethods();
560         while(methodit.hasNext()) {
561             /* Classify parameters */
562             MethodDescriptor md=(MethodDescriptor)methodit.next();
563             FlatMethod fm=state.getMethodFlat(md);
564             generateTempStructs(fm);
565
566             ParamsObject objectparams=(ParamsObject) paramstable.get(md);
567             TempObject objecttemps=(TempObject) tempstable.get(md);
568
569             /* Output parameter structure */
570             if (GENERATEPRECISEGC) {
571                 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
572                 output.println("  int type;");
573                 output.println("  void * next;");
574                 for(int i=0;i<objectparams.numPointers();i++) {
575                     TempDescriptor temp=objectparams.getPointer(i);
576                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
577                 }
578                 output.println("};\n");
579             }
580
581             /* Output temp structure */
582             if (GENERATEPRECISEGC) {
583                 output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
584                 output.println("  int type;");
585                 output.println("  void * next;");
586                 for(int i=0;i<objecttemps.numPointers();i++) {
587                     TempDescriptor temp=objecttemps.getPointer(i);
588                     if (temp.getType().isNull())
589                         output.println("  void * "+temp.getSafeSymbol()+";");
590                     else
591                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
592                 }
593                 output.println("};\n");
594             }
595             
596             /* Output method declaration */
597             if (md.getReturnType()!=null) {
598                 if (md.getReturnType().isClass()||md.getReturnType().isArray())
599                     headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
600                 else
601                     headersout.print(md.getReturnType().getSafeSymbol()+" ");
602             } else 
603                 //catch the constructor case
604                 headersout.print("void ");
605             headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
606             
607             boolean printcomma=false;
608             if (GENERATEPRECISEGC) {
609                 headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
610                 printcomma=true;
611             }
612
613             //output parameter list
614             for(int i=0;i<objectparams.numPrimitives();i++) {
615                 TempDescriptor temp=objectparams.getPrimitive(i);
616                 if (printcomma)
617                     headersout.print(", ");
618                 printcomma=true;
619                 if (temp.getType().isClass()||temp.getType().isArray())
620                     headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
621                 else
622                     headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
623             }
624             headersout.println(");\n");
625         }
626     }
627
628
629     /** This function outputs (1) structures that parameters are
630      * passed in (when PRECISE GC is enabled) and (2) function
631      * prototypes for the tasks */
632
633     private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
634         /* Cycle through tasks */
635         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
636
637         while(taskit.hasNext()) {
638             /* Classify parameters */
639             TaskDescriptor task=(TaskDescriptor)taskit.next();
640             FlatMethod fm=state.getMethodFlat(task);
641             generateTempStructs(fm);
642
643             ParamsObject objectparams=(ParamsObject) paramstable.get(task);
644             TempObject objecttemps=(TempObject) tempstable.get(task);
645
646             /* Output parameter structure */
647             if (GENERATEPRECISEGC) {
648                 output.println("struct "+task.getSafeSymbol()+"_params {");
649
650                 output.println("  int type;");
651                 output.println("  void * next;");
652                 for(int i=0;i<objectparams.numPointers();i++) {
653                     TempDescriptor temp=objectparams.getPointer(i);
654                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
655                 }
656                 output.println("};\n");
657                 if (objectparams.numPointers()>maxtaskparams)
658                     maxtaskparams=objectparams.numPointers();
659             }
660
661             /* Output temp structure */
662             if (GENERATEPRECISEGC) {
663                 output.println("struct "+task.getSafeSymbol()+"_locals {");
664                 output.println("  int type;");
665                 output.println("  void * next;");
666                 for(int i=0;i<objecttemps.numPointers();i++) {
667                     TempDescriptor temp=objecttemps.getPointer(i);
668                     if (temp.getType().isNull())
669                         output.println("  void * "+temp.getSafeSymbol()+";");
670                     else
671                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
672                 }
673                 output.println("};\n");
674             }
675             
676             /* Output task declaration */
677             headersout.print("void " + task.getSafeSymbol()+"(");
678             
679             boolean printcomma=false;
680             if (GENERATEPRECISEGC) {
681                 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
682             } else
683                 headersout.print("void * parameterarray[]");
684             headersout.println(");\n");
685         }
686     }
687
688     /** Generate code for flatmethod fm. */
689
690     private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
691         MethodDescriptor md=fm.getMethod();
692         TaskDescriptor task=fm.getTask();
693
694         ClassDescriptor cn=md!=null?md.getClassDesc():null;
695
696         ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
697
698         generateHeader(md!=null?md:task,output);
699
700         /* Print code */
701         
702         if (GENERATEPRECISEGC) {
703             if (md!=null)
704                 output.println("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+";");
705             else
706                 output.println("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+";");
707         }
708         TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
709         for(int i=0;i<objecttemp.numPrimitives();i++) {
710             TempDescriptor td=objecttemp.getPrimitive(i);
711             TypeDescriptor type=td.getType();
712             if (type.isNull())
713                 output.println("   void * "+td.getSafeSymbol()+";");
714             else if (type.isClass()||type.isArray())
715                 output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
716             else
717                 output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
718         }
719         
720
721         /* Generate labels first */
722         HashSet tovisit=new HashSet();
723         HashSet visited=new HashSet();
724         int labelindex=0;
725         Hashtable nodetolabel=new Hashtable();
726         tovisit.add(fm.methodEntryNode());
727         FlatNode current_node=null;
728
729         //Assign labels 1st
730         //Node needs a label if it is
731         while(!tovisit.isEmpty()) {
732             FlatNode fn=(FlatNode)tovisit.iterator().next();
733             tovisit.remove(fn);
734             visited.add(fn);
735             for(int i=0;i<fn.numNext();i++) {
736                 FlatNode nn=fn.getNext(i);
737                 if(i>0) {
738                     //1) Edge >1 of node
739                     nodetolabel.put(nn,new Integer(labelindex++));
740                 }
741                 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
742                     tovisit.add(nn);
743                 } else {
744                     //2) Join point
745                     nodetolabel.put(nn,new Integer(labelindex++));
746                 }
747             }
748         }
749
750         //Do the actual code generation
751         tovisit=new HashSet();
752         visited=new HashSet();
753         tovisit.add(fm.methodEntryNode());
754         while(current_node!=null||!tovisit.isEmpty()) {
755             if (current_node==null) {
756                 current_node=(FlatNode)tovisit.iterator().next();
757                 tovisit.remove(current_node);
758             }
759             visited.add(current_node);
760             if (nodetolabel.containsKey(current_node))
761                 output.println("L"+nodetolabel.get(current_node)+":");
762             if (current_node.numNext()==0) {
763                 output.print("   ");
764                 generateFlatNode(fm, current_node, output);
765                 if (current_node.kind()!=FKind.FlatReturnNode) {
766                     output.println("   return;");
767                 }
768                 current_node=null;
769             } else if(current_node.numNext()==1) {
770                 output.print("   ");
771                 generateFlatNode(fm, current_node, output);
772                 FlatNode nextnode=current_node.getNext(0);
773                 if (visited.contains(nextnode)) {
774                     output.println("goto L"+nodetolabel.get(nextnode)+";");
775                     current_node=null;
776                 } else
777                     current_node=nextnode;
778             } else if (current_node.numNext()==2) {
779                 /* Branch */
780                 output.print("   ");
781                 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
782                 if (!visited.contains(current_node.getNext(1)))
783                     tovisit.add(current_node.getNext(1));
784                 if (visited.contains(current_node.getNext(0))) {
785                     output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
786                     current_node=null;
787                 } else
788                     current_node=current_node.getNext(0);
789             } else throw new Error();
790         }
791         output.println("}\n\n");
792     }
793
794     /** Generate text string that corresponds to the Temp td. */
795     private String generateTemp(FlatMethod fm, TempDescriptor td) {
796         MethodDescriptor md=fm.getMethod();
797         TaskDescriptor task=fm.getTask();
798         TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task);
799         if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
800             return td.getSafeSymbol();
801         }
802
803         if (objecttemps.isLocalPtr(td)) {
804             return localsprefix+"."+td.getSafeSymbol();
805         }
806
807         if (objecttemps.isParamPtr(td)) {
808             return paramsprefix+"->"+td.getSafeSymbol();
809         }
810         throw new Error();
811     }
812
813     private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
814         switch(fn.kind()) {
815         case FKind.FlatCall:
816             generateFlatCall(fm, (FlatCall) fn,output);
817             return;
818         case FKind.FlatFieldNode:
819             generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
820             return;
821         case FKind.FlatElementNode:
822             generateFlatElementNode(fm, (FlatElementNode) fn,output);
823             return;
824         case FKind.FlatSetElementNode:
825             generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
826             return;
827         case FKind.FlatSetFieldNode:
828             generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
829             return;
830         case FKind.FlatNew:
831             generateFlatNew(fm, (FlatNew) fn,output);
832             return;
833         case FKind.FlatOpNode:
834             generateFlatOpNode(fm, (FlatOpNode) fn,output);
835             return;
836         case FKind.FlatCastNode:
837             generateFlatCastNode(fm, (FlatCastNode) fn,output);
838             return;
839         case FKind.FlatLiteralNode:
840             generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
841             return;
842         case FKind.FlatReturnNode:
843             generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
844             return;
845         case FKind.FlatNop:
846             output.println("/* nop */");
847             return;
848         case FKind.FlatFlagActionNode:
849             generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
850             return;
851         }
852         throw new Error();
853
854     }
855
856     private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
857         MethodDescriptor md=fc.getMethod();
858         ParamsObject objectparams=(ParamsObject) paramstable.get(md);
859         ClassDescriptor cn=md.getClassDesc();
860         output.println("{");
861         if (GENERATEPRECISEGC) {
862             output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
863             
864             output.print(objectparams.getUID());
865             output.print(", & "+localsprefix);
866             if (fc.getThis()!=null) {
867                 output.print(", ");
868                 output.print(generateTemp(fm,fc.getThis()));
869             }
870             for(int i=0;i<fc.numArgs();i++) {
871                 VarDescriptor var=md.getParameter(i);
872                 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
873                 if (objectparams.isParamPtr(paramtemp)) {
874                     TempDescriptor targ=fc.getArg(i);
875                     output.print(", ");
876                     output.print(generateTemp(fm, targ));
877                 }
878             }
879             output.println("};");
880         }
881         output.print("       ");
882
883
884         if (fc.getReturnTemp()!=null)
885             output.print(generateTemp(fm,fc.getReturnTemp())+"=");
886         if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
887             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
888         } else {
889             
890             output.print("((");
891             if (md.getReturnType().isClass()||md.getReturnType().isArray())
892                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
893             else
894                 output.print(md.getReturnType().getSafeSymbol()+" ");
895             output.print("(*)(");
896
897             boolean printcomma=false;
898             if (GENERATEPRECISEGC) {
899                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
900                 printcomma=true;
901             } 
902
903
904             for(int i=0;i<objectparams.numPrimitives();i++) {
905                 TempDescriptor temp=objectparams.getPrimitive(i);
906                 if (printcomma)
907                     output.print(", ");
908                 printcomma=true;
909                 if (temp.getType().isClass()||temp.getType().isArray())
910                     output.print("struct " + temp.getType().getSafeSymbol()+" * ");
911                 else
912                     output.print(temp.getType().getSafeSymbol());
913             }
914
915             output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
916         }
917
918         output.print("(");
919         boolean needcomma=false;
920         if (GENERATEPRECISEGC) {
921             output.print("&__parameterlist__");
922             needcomma=true;
923         } else {
924             if (fc.getThis()!=null) {
925                 output.print(generateTemp(fm,fc.getThis()));
926                 needcomma=true;
927             }
928         }
929         for(int i=0;i<fc.numArgs();i++) {
930             VarDescriptor var=md.getParameter(i);
931             TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
932             if (objectparams.isParamPrim(paramtemp)) {
933                 TempDescriptor targ=fc.getArg(i);
934                 if (needcomma)
935                     output.print(", ");
936                 output.print(generateTemp(fm, targ));
937                 needcomma=true;
938             }
939         }
940         output.println(");");
941         output.println("   }");
942     }
943
944     private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
945         Set subclasses=typeutil.getSubClasses(thiscd);
946         if (subclasses==null)
947             return true;
948         for(Iterator classit=subclasses.iterator();classit.hasNext();) {
949             ClassDescriptor cd=(ClassDescriptor)classit.next();
950             Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
951             for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
952                 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
953                 if (md.matches(matchmd))
954                     return false;
955             }
956         }
957         return true;
958     }
959
960     private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
961         output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
962     }
963
964     private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
965         if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
966             throw new Error("Can't set array length");
967         output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
968     }
969
970     private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
971         TypeDescriptor elementtype=fen.getSrc().getType().dereference();
972         String type="";
973
974         if (elementtype.isArray()||elementtype.isClass())
975             type="void *";
976         else 
977             type=elementtype.getSafeSymbol()+" ";
978
979         if (fen.needsBoundsCheck()) {
980             output.println("if ("+generateTemp(fm, fen.getIndex())+"< 0 || "+generateTemp(fm, fen.getIndex())+" >= "+generateTemp(fm,fen.getSrc()) + "->___length___)");
981             output.println("failedboundschk();");
982         }
983
984         output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
985     }
986
987     private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
988         //TODO: need dynamic check to make sure this assignment is actually legal
989         //Because Object[] could actually be something more specific...ie. Integer[]
990
991         TypeDescriptor elementtype=fsen.getDst().getType().dereference();
992         String type="";
993
994         if (elementtype.isArray()||elementtype.isClass())
995             type="void *";
996         else 
997             type=elementtype.getSafeSymbol()+" ";
998
999         if (fsen.needsBoundsCheck()) {
1000             output.println("if ("+generateTemp(fm, fsen.getIndex())+"< 0 || "+generateTemp(fm, fsen.getIndex())+" >= "+generateTemp(fm,fsen.getDst()) + "->___length___)");
1001             output.println("failedboundschk();");
1002         }
1003
1004         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
1005     }
1006
1007     private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
1008         if (fn.getType().isArray()) {
1009             int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1010             output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1011         } else
1012             output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1013     }
1014
1015     private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
1016
1017         if (fon.getRight()!=null)
1018             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
1019         else if (fon.getOp().getOp()==Operation.ASSIGN)
1020             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1021         else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1022             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1023         else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1024             output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
1025         else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1026             output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
1027         else
1028             output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
1029     }
1030
1031     private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
1032         /* TODO: Do type check here */
1033         output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
1034     }
1035
1036     private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
1037         if (fln.getValue()==null)
1038             output.println(generateTemp(fm, fln.getDst())+"=0;");
1039         else if (fln.getType().getSymbol().equals(TypeUtil.StringClass))
1040             output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1041         else if (fln.getType().isBoolean()) {
1042             if (((Boolean)fln.getValue()).booleanValue())
1043                 output.println(generateTemp(fm, fln.getDst())+"=1;");
1044             else
1045                 output.println(generateTemp(fm, fln.getDst())+"=0;");
1046         } else if (fln.getType().isChar()) {
1047             output.println(generateTemp(fm, fln.getDst())+"='"+fln.getValue()+"';");
1048         } else
1049             output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
1050     }
1051
1052     private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
1053         if (frn.getReturnTemp()!=null)
1054             output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1055         else
1056             output.println("return;");
1057     }
1058
1059     private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
1060         output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
1061     }
1062
1063     private void generateHeader(Descriptor des, PrintWriter output) {
1064         /* Print header */
1065         ParamsObject objectparams=(ParamsObject)paramstable.get(des);
1066         MethodDescriptor md=null;
1067         TaskDescriptor task=null;
1068         if (des instanceof MethodDescriptor)
1069             md=(MethodDescriptor) des;
1070         else
1071             task=(TaskDescriptor) des;
1072
1073         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1074         
1075         if (md!=null&&md.getReturnType()!=null) {
1076             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1077                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1078             else
1079                 output.print(md.getReturnType().getSafeSymbol()+" ");
1080         } else 
1081             //catch the constructor case
1082             output.print("void ");
1083         if (md!=null)
1084             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1085         else
1086             output.print(task.getSafeSymbol()+"(");
1087         
1088         boolean printcomma=false;
1089         if (GENERATEPRECISEGC) {
1090             if (md!=null)
1091                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1092             else
1093                 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1094             printcomma=true;
1095         } 
1096
1097         if (md!=null) {
1098             for(int i=0;i<objectparams.numPrimitives();i++) {
1099                 TempDescriptor temp=objectparams.getPrimitive(i);
1100                 if (printcomma)
1101                     output.print(", ");
1102                 printcomma=true;
1103                 if (temp.getType().isClass()||temp.getType().isArray())
1104                     output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1105                 else
1106                     output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1107             }
1108             output.println(") {");
1109         } else if (!GENERATEPRECISEGC) {
1110             output.println("void * parameterarray[]) {");
1111             for(int i=0;i<objectparams.numPrimitives();i++) {
1112                 TempDescriptor temp=objectparams.getPrimitive(i);
1113                 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1114             }
1115             if (objectparams.numPrimitives()>maxtaskparams)
1116                 maxtaskparams=objectparams.numPrimitives();
1117         } else output.println(" {");
1118     }
1119
1120     public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
1121         output.println("/* FlatFlagActionNode */");
1122         Hashtable flagandtable=new Hashtable();
1123         Hashtable flagortable=new Hashtable();
1124
1125
1126         Iterator flagsit=ffan.getTempFlagPairs();
1127         while(flagsit.hasNext()) {
1128             TempFlagPair tfp=(TempFlagPair)flagsit.next();
1129             TempDescriptor temp=tfp.getTemp();
1130             Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1131             FlagDescriptor flag=tfp.getFlag();
1132             int flagid=1<<((Integer)flagtable.get(flag)).intValue();
1133             boolean flagstatus=ffan.getFlagChange(tfp);
1134             if (flagstatus) {
1135                 int mask=0;
1136                 if (flagortable.containsKey(temp)) {
1137                     mask=((Integer)flagortable.get(temp)).intValue();
1138                 }
1139                 mask|=flagid;
1140                 flagortable.put(temp,new Integer(mask));
1141             } else {
1142                 int mask=0xFFFFFFFF;
1143                 if (flagandtable.containsKey(temp)) {
1144                     mask=((Integer)flagandtable.get(temp)).intValue();
1145                 }
1146                 mask&=(0xFFFFFFFF^flagid);
1147                 flagandtable.put(temp,new Integer(mask));
1148             }
1149         }
1150         Iterator orit=flagortable.keySet().iterator();
1151         while(orit.hasNext()) {
1152             TempDescriptor temp=(TempDescriptor)orit.next();
1153             int ormask=((Integer)flagortable.get(temp)).intValue();
1154             int andmask=0xFFFFFFF;
1155             if (flagandtable.containsKey(temp))
1156                 andmask=((Integer)flagandtable.get(temp)).intValue();
1157             output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1158         }
1159         Iterator andit=flagandtable.keySet().iterator();
1160         while(andit.hasNext()) {
1161             TempDescriptor temp=(TempDescriptor)andit.next();
1162             int andmask=((Integer)flagandtable.get(temp)).intValue();
1163             if (!flagortable.containsKey(temp))
1164                 output.println("flagorand("+generateTemp(fm, temp)+", 0, 0x"+Integer.toHexString(andmask)+");");
1165         }
1166     }
1167 }