1 cananian 1.1.2.1  // CodeGen.java, created Wed Jul 28 18:19:29 1999 by pnkfelix
  2 cananian 1.1.2.1  // Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
  3 cananian 1.1.2.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1.2.1  package harpoon.Backend.Generic;
  5 cananian 1.1.2.1  
  6 cananian 1.1.2.2  import harpoon.ClassFile.HMethod;
  7 pnkfelix 1.1.2.10 import harpoon.ClassFile.HClass;
  8 cananian 1.1.2.1  import harpoon.IR.Assem.Instr;
  9 pnkfelix 1.1.2.17 import harpoon.IR.Assem.InstrFactory;
 10 pnkfelix 1.1.2.17 import harpoon.IR.Assem.InstrGroup;
 11 cananian 1.1.2.15 import harpoon.IR.Tree.TreeDerivation;
 12 cananian 1.1.2.15 import harpoon.IR.Tree.Exp;
 13 cananian 1.1.2.1  import harpoon.IR.Tree.Print;
 14 pnkfelix 1.1.2.10 import harpoon.Temp.Temp;
 15 pnkfelix 1.1.2.10 import harpoon.Analysis.Maps.Derivation;
 16 pnkfelix 1.1.2.6  
 17 pnkfelix 1.1.2.17 import java.util.ArrayList;
 18 pnkfelix 1.1.2.17 import java.util.Iterator;
 19 pnkfelix 1.1.2.17 
 20 cananian 1.1.2.1  /**
 21 cananian 1.1.2.1   * <code>Generic.CodeGen</code> is a general class for specific Backends to
 22 cananian 1.1.2.1   * extend.  Typically a Specfile for a specific backend will be
 23 cananian 1.1.2.1   * designed as an extension of this class.
 24 cananian 1.1.2.1   * 
 25 cananian 1.1.2.1   * @author  Felix S. Klock II <pnkfelix@mit.edu>
 26 cananian 1.4       * @version $Id: CodeGen.java,v 1.4 2002/04/10 03:02:43 cananian Exp $ */
 27 cananian 1.1.2.1  public abstract class CodeGen {
 28 cananian 1.1.2.1  
 29 cananian 1.1.2.1      private static boolean DEBUG = false;
 30 pnkfelix 1.1.2.3  
 31 pnkfelix 1.1.2.3      // Frame for instructions to access to get platform specific
 32 pnkfelix 1.1.2.3      // variables (Register Temps, etc)   
 33 pnkfelix 1.1.2.4      public final Frame frame;
 34 pnkfelix 1.1.2.9  
 35 pnkfelix 1.1.2.17     // last emitted instruction (to support endGroup(..) semantics)
 36 pnkfelix 1.1.2.17     private Instr lastEmitted; 
 37 pnkfelix 1.1.2.17     // list of InstrGroups that need to have entry Instr assigned 
 38 pnkfelix 1.1.2.17     private ArrayList groupsToBeStarted = new ArrayList();
 39 pnkfelix 1.1.2.17     private InstrGroup currentGroup = null;
 40 pnkfelix 1.1.2.17 
 41 pnkfelix 1.1.2.17     /** <code>InstrFactory</code> for <code>Instr</code>s currently
 42 pnkfelix 1.1.2.17         generated by <code>CodeGen#emit</code>.  (Assigned by
 43 pnkfelix 1.1.2.17         <code>CodeGen#genCode</code> and
 44 pnkfelix 1.1.2.17         <code>CodeGen#genData</code>). 
 45 pnkfelix 1.1.2.17     */
 46 pnkfelix 1.1.2.17     protected InstrFactory instrFactory;
 47 pnkfelix 1.1.2.17 
 48 cananian 1.1.2.1      /** Creates a <code>Generic.CodeGen</code>. */
 49 pnkfelix 1.1.2.3      public CodeGen(Frame frame) {
 50 pnkfelix 1.1.2.3          this.frame = frame;
 51 pnkfelix 1.1.2.9      }
 52 pnkfelix 1.1.2.17     protected InstrGroup startGroup(InstrGroup.Type type) { 
 53 pnkfelix 1.1.2.17         InstrGroup newGroup = type.makeGroup(currentGroup);
 54 pnkfelix 1.1.2.17         groupsToBeStarted.add(newGroup);
 55 pnkfelix 1.1.2.17         currentGroup = newGroup;
 56 pnkfelix 1.1.2.17         return newGroup;
 57 pnkfelix 1.1.2.17     }
 58 pnkfelix 1.1.2.17     protected void endGroup(InstrGroup g) { 
 59 pnkfelix 1.1.2.17         g.setExit(lastEmitted); 
 60 pnkfelix 1.1.2.17         currentGroup = g.getContainer();
 61 pnkfelix 1.1.2.12 
 62 pnkfelix 1.1.2.17         // only add groups after entry+exit have been assigned  
 63 pnkfelix 1.1.2.17         instrFactory.addGroup(g);
 64 pnkfelix 1.1.2.17     }
 65 pnkfelix 1.1.2.17     
 66 pnkfelix 1.1.2.9      /** Emits <code>i</code> as the next instruction in the
 67 pnkfelix 1.1.2.9          instruction stream.
 68 pnkfelix 1.1.2.9      */  
 69 pnkfelix 1.1.2.17     protected final Instr emit(Instr i) {
 70 pnkfelix 1.1.2.17         cgg_backendEmit(i);
 71 pnkfelix 1.1.2.17         i.setGroup(currentGroup);
 72 pnkfelix 1.1.2.17 
 73 pnkfelix 1.1.2.17         lastEmitted = i;
 74 pnkfelix 1.1.2.17         for(Iterator gs=groupsToBeStarted.iterator(); gs.hasNext();) {
 75 pnkfelix 1.1.2.17             ((InstrGroup)gs.next()).setEntry(i);
 76 pnkfelix 1.1.2.17         }
 77 pnkfelix 1.1.2.17         groupsToBeStarted.clear();
 78 pnkfelix 1.1.2.13 
 79 pnkfelix 1.1.2.17         return i;
 80 pnkfelix 1.1.2.17     }
 81 pnkfelix 1.1.2.17     /** Protected helper method guaranteed to be called by
 82 pnkfelix 1.1.2.17         emit(Instr).  Must be overridden by CGG specific extension.
 83 pnkfelix 1.1.2.17         (IE, there is a CodeGen extension where
 84 pnkfelix 1.1.2.17         <code>cgg_backendEmit(..)</code> is implemented for every
 85 pnkfelix 1.1.2.17         CodeGeneratorGenerator, such as <code>MaxMunchCG</code>).  
 86 pnkfelix 1.1.2.17     */
 87 pnkfelix 1.1.2.17     protected abstract Instr cgg_backendEmit(Instr i);
 88 pnkfelix 1.1.2.13     protected abstract void declare(Temp t, HClass clz);
 89 pnkfelix 1.1.2.13     protected abstract void declare(Temp t, Derivation.DList dl);
 90 cananian 1.1.2.15     // helper method for declarations.
 91 cananian 1.1.2.15     protected final void declare(Temp t, TreeDerivation td, Exp e) {
 92 cananian 1.1.2.15         if (td==null) return; // no derivation info.
 93 cananian 1.1.2.15         HClass hc = td.typeMap(e);
 94 cananian 1.1.2.15         if (hc!=null) declare(t, hc);
 95 cananian 1.1.2.15         else declare(t, td.derivation(e));
 96 cananian 1.1.2.15     }
 97 cananian 1.1.2.15 
 98 pnkfelix 1.1.2.11 
 99 cananian 1.1.2.2      /** Fixes up the procedure entry and exit code for a list of instrs, once
100 cananian 1.1.2.2       *  it is known how many registers and how much stack space is used.
101 pnkfelix 1.1.2.5       */ // FIXME: is there a more abstract way to specify these 
102 pnkfelix 1.1.2.6          // quantities?   FSK: I think we should deprecate this
103 cananian 1.1.2.2      public abstract Instr procFixup(HMethod hm, Instr instr, int stackspace,
104 cananian 1.1.2.2                                      java.util.Set usedRegisters);
105 pnkfelix 1.1.2.6  
106 pnkfelix 1.1.2.6      /** Fixes up the procedure entry and exit code for a list of instrs, once
107 pnkfelix 1.1.2.6       *  it is known how many registers and how much stack space is used.
108 pnkfelix 1.1.2.6       */ // FIXME: is there a more abstract way to specify these 
109 pnkfelix 1.1.2.6          // quantities?   FSK: This is what I think we should use instead
110 pnkfelix 1.1.2.14         public void procFixup(HMethod hm,
111 pnkfelix 1.1.2.6                            harpoon.Backend.Generic.Code code, 
112 pnkfelix 1.1.2.6                            int stackspace, 
113 pnkfelix 1.1.2.6                            java.util.Set usedRegisters) {
114 cananian 1.3.2.1          assert false : "abstract me and implement in subclasses";
115 pnkfelix 1.1.2.14         }
116 cananian 1.1.2.2  
117 cananian 1.1.2.1      /** Creates a <code>Instr</code> list from the
118 pnkfelix 1.1.2.12         <code>IR.Tree.Code</code> <code>tree</code>.  
119 pnkfelix 1.1.2.12         <BR> <B>effects:</B> Generates and returns a two element list,
120 pnkfelix 1.1.2.12         where the first element is the head of a <code>Instr</code>s
121 pnkfelix 1.1.2.12         to execute <code>tree</code>, and the second element is the
122 pnkfelix 1.1.2.12         <code>Derivation</code> for that list of instructions.
123 cananian 1.1.2.1          @return The head of a list of <code>Instr</code>s
124 cananian 1.1.2.1      */
125 pnkfelix 1.1.2.17     public final java.util.List genCode
126 pnkfelix 1.1.2.17         (harpoon.IR.Tree.Code tree,
127 pnkfelix 1.1.2.17          final harpoon.IR.Assem.InstrFactory inf) {
128 pnkfelix 1.1.2.17         instrFactory = inf;
129 pnkfelix 1.1.2.17         return cgg_genCode(tree, inf);
130 pnkfelix 1.1.2.17     }
131 pnkfelix 1.1.2.17     
132 pnkfelix 1.1.2.17     /** Creates a <code>Instr</code> list from the
133 pnkfelix 1.1.2.17         <code>IR.Tree.Code</code> <code>tree</code>.  
134 pnkfelix 1.1.2.17         <BR> <B>effects:</B> Generates and returns a two element list,
135 pnkfelix 1.1.2.17         where the first element is the head of a <code>Instr</code>s
136 pnkfelix 1.1.2.17         to execute <code>tree</code>, and the second element is the
137 pnkfelix 1.1.2.17         <code>Derivation</code> for that list of instructions.
138 pnkfelix 1.1.2.17         @return The head of a list of <code>Instr</code>s
139 pnkfelix 1.1.2.17     */
140 pnkfelix 1.1.2.17     public abstract java.util.List cgg_genCode(harpoon.IR.Tree.Code tree,
141 pnkfelix 1.1.2.3                                final harpoon.IR.Assem.InstrFactory inf); 
142 cananian 1.1.2.1  
143 pnkfelix 1.1.2.17     
144 cananian 1.1.2.1      /** Creates a <code>Instr</code> list from the
145 cananian 1.1.2.1          <code>IR.Tree.Data</code> <code>tree</code>. 
146 cananian 1.1.2.1          <BR> <B>effects:</B> Generates and returns a list of
147 cananian 1.1.2.1               <code>Instr</code>s representing the layout of
148 cananian 1.1.2.1               <code>tree</code>.
149 cananian 1.1.2.1          @return The head of a list of <code>Instr</code>s
150 cananian 1.1.2.1      */
151 pnkfelix 1.1.2.17     public final Instr genData
152 pnkfelix 1.1.2.17         (harpoon.IR.Tree.Data tree,
153 pnkfelix 1.1.2.17          final harpoon.IR.Assem.InstrFactory inf) {
154 pnkfelix 1.1.2.17         instrFactory = inf;
155 pnkfelix 1.1.2.17         return cgg_genData(tree, inf);
156 pnkfelix 1.1.2.17     }
157 pnkfelix 1.1.2.17 
158 pnkfelix 1.1.2.17     public abstract Instr cgg_genData
159 pnkfelix 1.1.2.17         (harpoon.IR.Tree.Data tree,
160 pnkfelix 1.1.2.17          final harpoon.IR.Assem.InstrFactory inf); 
161 cananian 1.1.2.1      
162 cananian 1.1.2.1      public void debug(String s) {
163 cananian 1.1.2.1          if (DEBUG) System.out.println(s);
164 cananian 1.1.2.1      }
165 cananian 1.1.2.1  
166 cananian 1.1.2.1      public String prettyPrint(harpoon.IR.Tree.Tree exp) {
167 cananian 1.1.2.1          return Print.print(exp);
168 cananian 1.1.2.1      }
169 cananian 1.1.2.1      
170 cananian 1.2      }