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 }