1 pnkfelix 1.1.2.1 // InstrBuilder.java, created Fri Sep 10 23:29:27 1999 by pnkfelix
  2 pnkfelix 1.1.2.1 // Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
  3 pnkfelix 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 pnkfelix 1.1.2.1 package harpoon.Backend.Generic;
  5 pnkfelix 1.1.2.1 
  6 pnkfelix 1.1.2.1 import harpoon.IR.Assem.Instr;
  7 pnkfelix 1.1.2.1 import harpoon.IR.Assem.InstrLABEL;
  8 pnkfelix 1.1.2.1 import harpoon.Temp.Temp;
  9 pnkfelix 1.1.2.5 import harpoon.Temp.Label;
 10 cananian 1.5     import net.cscott.jutil.ListFactory;
 11 pnkfelix 1.1.2.1 
 12 pnkfelix 1.1.2.1 import java.util.List;
 13 pnkfelix 1.1.2.1 import java.util.ArrayList;
 14 pnkfelix 1.1.2.1 
 15 pnkfelix 1.1.2.1 /** <code>InstrBuilder</code> defines an interface that general program
 16 pnkfelix 1.1.2.1     transformations can call to generate needed assembly code blocks for
 17 pnkfelix 1.1.2.1     arbitrary target architectures.  
 18 pnkfelix 1.1.2.1     <p>
 19 pnkfelix 1.1.2.1     Many of the <code>Instr</code> optimizations need to insert new
 20 pnkfelix 1.1.2.1     code to support the transformations that they make on the code.
 21 pnkfelix 1.1.2.1     This class provides a set of generic <code>Instr</code> creation
 22 pnkfelix 1.1.2.1     routines that each backend wil implement, to be used in creating
 23 pnkfelix 1.1.2.1     the support code.
 24 pnkfelix 1.1.2.1     
 25 pnkfelix 1.1.2.1     @see harpoon.Analysis.Instr
 26 pnkfelix 1.1.2.1     @author  Felix S. Klock II <pnkfelix@mit.edu>
 27 cananian 1.5         @version $Id: InstrBuilder.java,v 1.5 2004/02/08 01:57:30 cananian Exp $
 28 pnkfelix 1.1.2.1  */
 29 pnkfelix 1.1.2.1 public abstract class InstrBuilder {
 30 pnkfelix 1.1.2.1     
 31 pnkfelix 1.1.2.1     /** Creates a <code>InstrBuilder</code>. */
 32 pnkfelix 1.1.2.1     public InstrBuilder() {
 33 pnkfelix 1.1.2.1         
 34 pnkfelix 1.1.2.1     }
 35 pnkfelix 1.1.2.3 
 36 pnkfelix 1.1.2.1     /** Generates a new set of <code>Instr</code>s for memory traffic
 37 pnkfelix 1.1.2.1         from RAM to multiple registers in the register file.  This
 38 pnkfelix 1.1.2.1         method's default implementation simply calls
 39 pnkfelix 1.1.2.1         <code>makeLoad(Temp,int,Instr)</code> for each element of
 40 pnkfelix 1.1.2.1         <code>regs</code> and concatenates the returned
 41 pnkfelix 1.1.2.1         <code>List</code>s of <code>Instr</code>s, so architectures
 42 pnkfelix 1.1.2.1         with more efficient memory-to-multiple-register operations
 43 pnkfelix 1.1.2.1         should override this implementation with a better one.
 44 pnkfelix 1.1.2.1         @param <code>regs</code> The target register <code>Temp</code>s
 45 pnkfelix 1.1.2.1                to hold the values that will be loaded from
 46 pnkfelix 1.1.2.1                <code>startingOffset</code> in memory.
 47 pnkfelix 1.1.2.7         @param <code>startingOffset</code> The stack offset
 48 pnkfelix 1.1.2.7                (zero-indexed).  This is 
 49 pnkfelix 1.1.2.1                an ordinal number, it is NOT meant to be a multiple of
 50 pnkfelix 1.1.2.1                some byte size.  Note that this method will load values
 51 pnkfelix 1.1.2.1                starting at <code>startingOffset</code> and go up to
 52 pnkfelix 1.1.2.1                <code>startingOffset</code> +
 53 pnkfelix 1.1.2.1                <code>regs.size()-1</code> (with the first register in
 54 pnkfelix 1.1.2.1                <code>regs</code> corresponding to
 55 pnkfelix 1.1.2.1                <code>startingOffset</code> + 0, the second to
 56 pnkfelix 1.1.2.1                <code>startingOffset</code> + 1, and so on), so code
 57 pnkfelix 1.1.2.1                planning to reference the locations corresponding to
 58 pnkfelix 1.1.2.1                the sources for the data in the register file should 
 59 pnkfelix 1.1.2.1                account for any additional offsets.
 60 pnkfelix 1.1.2.1         @param <code>template</code> An <code>Instr</code> to derive
 61 pnkfelix 1.1.2.1                the generated <code>List</code> from.
 62 pnkfelix 1.1.2.1                <code>template</code> gives <code>this</code> the
 63 pnkfelix 1.1.2.1                ability to incorporate additional information into the
 64 pnkfelix 1.1.2.1                produced <code>List</code> of <code>Instr</code>s.
 65 pnkfelix 1.1.2.2         @see InstrBuilder#makeLoad(Temp, int, Instr)
 66 pnkfelix 1.1.2.2         @see InstrBuilder#getSize
 67 pnkfelix 1.1.2.1     */ 
 68 pnkfelix 1.1.2.1     public List makeLoad(List regs, int startingOffset, Instr template) { 
 69 pnkfelix 1.1.2.4         ArrayList list = new ArrayList();
 70 pnkfelix 1.1.2.4         Instr last=null, curr=null;
 71 pnkfelix 1.1.2.1         for (int i=0; i<regs.size(); i++) {
 72 pnkfelix 1.1.2.4             List cl = makeLoad((Temp)regs.get(i), startingOffset+i, template);
 73 pnkfelix 1.1.2.4             curr = (Instr) cl.get(0);
 74 pnkfelix 1.1.2.4             curr.layout(last, curr.getNext());
 75 pnkfelix 1.1.2.4             list.addAll(cl);
 76 pnkfelix 1.1.2.4             last = (Instr) cl.get(cl.size() - 1);
 77 pnkfelix 1.1.2.1         }
 78 pnkfelix 1.1.2.4         return list;
 79 pnkfelix 1.1.2.1     }
 80 pnkfelix 1.1.2.1 
 81 pnkfelix 1.1.2.1     /** Generates a new set of <code>Instr</code>s for memory traffic
 82 pnkfelix 1.1.2.1         from multiple registers in the register file to RAM.  This
 83 pnkfelix 1.1.2.1         method's default implementation simply calls
 84 pnkfelix 1.1.2.1         <code>makeStore(Temp,int,Instr)</code> for each element of
 85 pnkfelix 1.1.2.1         <code>regs</code> and concatenates the returned
 86 pnkfelix 1.1.2.1         <code>List</code>s of <code>Instr</code>s, so architectures
 87 pnkfelix 1.1.2.1         with more efficient multiple-register-to-memory operations
 88 pnkfelix 1.1.2.1         should override this implementation with a better one.
 89 pnkfelix 1.1.2.1         @param <code>regs</code> The register <code>Temp</code>s
 90 pnkfelix 1.1.2.1                holding the values that will be stored starting at
 91 pnkfelix 1.1.2.1                <code>startingOffset</code> in memory.
 92 pnkfelix 1.1.2.7         @param <code>startingOffset</code> The stack offset
 93 pnkfelix 1.1.2.7                (zero-indexed).  This is 
 94 pnkfelix 1.1.2.1                an ordinal number, it is NOT meant to be a multiple of
 95 pnkfelix 1.1.2.1                some byte size.  Note that this method will store values
 96 pnkfelix 1.1.2.1                starting at <code>startingOffset</code> and go up to
 97 pnkfelix 1.1.2.1                <code>startingOffset</code> +
 98 pnkfelix 1.1.2.1                <code>regs.size()-1</code> (with the first register in
 99 pnkfelix 1.1.2.1                <code>regs</code> corresponding to
100 pnkfelix 1.1.2.1                <code>startingOffset</code> + 0, the second to
101 pnkfelix 1.1.2.1                <code>startingOffset</code> + 1, and so on), so code
102 pnkfelix 1.1.2.1                planning to reference the locations corresponding to
103 pnkfelix 1.1.2.1                the targets for the data in the register file should
104 pnkfelix 1.1.2.1                account for any additional offsets. 
105 pnkfelix 1.1.2.1         @param <code>template</code> An <code>Instr</code> to derive
106 pnkfelix 1.1.2.1                the generated <code>List</code> from.
107 pnkfelix 1.1.2.1                <code>template</code> gives <code>this</code> the
108 pnkfelix 1.1.2.1                ability to incorporate additional information into the
109 pnkfelix 1.1.2.1                produced <code>List</code> of <code>Instr</code>s.
110 pnkfelix 1.1.2.2         @see InstrBuilder#makeStore(Temp, int, Instr)
111 pnkfelix 1.1.2.2         @see InstrBuilder#getSize
112 pnkfelix 1.1.2.1 
113 pnkfelix 1.1.2.1     */ 
114 pnkfelix 1.1.2.1     public List makeStore(List regs, int startingOffset, Instr template) { 
115 pnkfelix 1.1.2.4         ArrayList list = new ArrayList();
116 pnkfelix 1.1.2.4         Instr last=null, curr=null;
117 pnkfelix 1.1.2.1         for (int i=0; i<regs.size(); i++) {
118 pnkfelix 1.1.2.4             List cl = makeStore((Temp)regs.get(i), startingOffset+i, template);
119 pnkfelix 1.1.2.4             curr = (Instr) cl.get(0);
120 pnkfelix 1.1.2.4             Instr next = curr.getNext();
121 pnkfelix 1.1.2.4             curr.remove(); // FSK: being safe; removing before relayouting
122 pnkfelix 1.1.2.4             curr.layout(last, next);
123 pnkfelix 1.1.2.4             list.addAll(cl);
124 pnkfelix 1.1.2.4             last = (Instr) cl.get(cl.size() - 1);
125 pnkfelix 1.1.2.1         }
126 pnkfelix 1.1.2.4         
127 pnkfelix 1.1.2.4         // System.out.println("store: "+list);
128 pnkfelix 1.1.2.4         
129 pnkfelix 1.1.2.4         return list;
130 pnkfelix 1.1.2.1     }
131 pnkfelix 1.1.2.1 
132 pnkfelix 1.1.2.1     /** Generates a new set of <code>Instr</code>s for memory traffic
133 pnkfelix 1.1.2.1         from RAM to one register in the register file.
134 pnkfelix 1.1.2.1         @param <code>reg</code> The target register <code>Temp</code>
135 pnkfelix 1.1.2.1                to hold the value that will be loaded from
136 pnkfelix 1.1.2.1                <code>offset</code> in memory. 
137 pnkfelix 1.1.2.7         @param <code>offset</code> The stack offset (zero-indexed).
138 pnkfelix 1.1.2.7                This is an 
139 pnkfelix 1.1.2.1                ordinal number, it is NOT meant to be a multiple of
140 pnkfelix 1.1.2.1                some byte size.  This frame should perform the
141 pnkfelix 1.1.2.1                necessary magic to turn the number into an appropriate
142 pnkfelix 1.1.2.1                stack offset. 
143 pnkfelix 1.1.2.1         @param <code>template</code> An <code>Instr</code> to derive
144 pnkfelix 1.1.2.1                the generated <code>List</code> from.
145 pnkfelix 1.1.2.1                <code>template</code> gives <code>this</code> the
146 pnkfelix 1.1.2.1                ability to incorporate additional information into the
147 pnkfelix 1.1.2.1                produced <code>List</code> of <code>Instr</code>s.   
148 pnkfelix 1.1.2.2         @see InstrBuilder#getSize
149 pnkfelix 1.1.2.1     */ 
150 pnkfelix 1.1.2.1     protected abstract List makeLoad(Temp reg, int offset, Instr template);
151 pnkfelix 1.1.2.1 
152 pnkfelix 1.1.2.1     /** Generates a new set of <code>Instr</code>s for memory traffic
153 pnkfelix 1.1.2.1         from the register file to RAM. 
154 pnkfelix 1.1.2.1         @param <code>reg</code> The register <code>Temp</code> holding
155 pnkfelix 1.1.2.1                the value that will be stored at <code>offset</code> in
156 pnkfelix 1.1.2.1                memory. 
157 pnkfelix 1.1.2.7         @param <code>offset</code> The stack offset (zero-indexed).
158 pnkfelix 1.1.2.7                This is an 
159 pnkfelix 1.1.2.1                abstract number, it is NOT necessarily a multiple of
160 pnkfelix 1.1.2.1                some byte size.  This frame should perform the
161 pnkfelix 1.1.2.1                necessary magic to turn the number into an appropriate
162 pnkfelix 1.1.2.1                stack offset. 
163 pnkfelix 1.1.2.1         @param <code>template</code> An <code>Instr</code> to derive
164 pnkfelix 1.1.2.1                the generated <code>List</code> from
165 pnkfelix 1.1.2.1                <code>template</code> gives <code>this</code> the
166 pnkfelix 1.1.2.1                ability to incorporate additional information into the
167 pnkfelix 1.1.2.1                produced <code>List</code> of <code>Instr</code>s.   
168 pnkfelix 1.1.2.2         @see InstrBuilder#getSize
169 pnkfelix 1.1.2.1     */ 
170 pnkfelix 1.1.2.1     protected abstract List makeStore(Temp reg, int offset, Instr template);
171 pnkfelix 1.1.2.2 
172 pnkfelix 1.1.2.2     /** Returns the size of <code>temp</code> on the stack.
173 pnkfelix 1.1.2.2         <BR><B>effects:</B> Calculates the size that a value of the
174 pnkfelix 1.1.2.2             type of <code>temp</code> would have on the stack (in
175 pnkfelix 1.1.2.2             terms of the abstract number used for calculating stack
176 pnkfelix 1.1.2.2             offsets in <code>makeLoad()</code> and
177 pnkfelix 1.1.2.2             <code>makeStore()</code>).  
178 pnkfelix 1.1.2.2         <BR> When constructing loads and stores, the register allocator
179 pnkfelix 1.1.2.2             should ensure that live values do not overlap on the
180 pnkfelix 1.1.2.2             stack.  Thus, given two temps <code>t1</code> and
181 pnkfelix 1.1.2.3             <code>t2</code>, either 
182 pnkfelix 1.1.2.3             ( <code>offset(t2)</code> is greater than or equal to
183 pnkfelix 1.1.2.3             <code>offset(t1) + getSize(t1)</code> )
184 pnkfelix 1.1.2.3             OR
185 pnkfelix 1.1.2.3             ( <code>offset(t1)</code> is greater than or equal to
186 pnkfelix 1.1.2.3             <code>offset(t2) + getSize(t2)</code> ).
187 pnkfelix 1.1.2.3 
188 pnkfelix 1.1.2.2         <BR> The default implementation simply returns 1; subclasses
189 pnkfelix 1.1.2.2              should override this and check for double word temps, etc.
190 pnkfelix 1.1.2.2         @see InstrBuilder#makeLoad
191 pnkfelix 1.1.2.2         @see InstrBuilder#makeStore
192 pnkfelix 1.1.2.2     */
193 pnkfelix 1.1.2.2     public int getSize(Temp temp) {
194 pnkfelix 1.1.2.2         return 1;
195 pnkfelix 1.1.2.2     }
196 pnkfelix 1.1.2.1 
197 pnkfelix 1.1.2.1     /** Returns a new <code>InstrLABEL</code> for generating new
198 pnkfelix 1.1.2.1         arbitrary code blocks to branch to.
199 pnkfelix 1.1.2.1         @param template An <code>Instr</code> to base the generated
200 pnkfelix 1.1.2.1                         <code>InstrLABEL</code>.
201 pnkfelix 1.1.2.1                         <code>template</code> should be part of the
202 pnkfelix 1.1.2.1                         instruction stream that the returned
203 pnkfelix 1.1.2.1                         <code>InstrLABEL</code> is intended for. 
204 pnkfelix 1.1.2.1     */
205 pnkfelix 1.1.2.5     public InstrLABEL makeLabel(Label l, Instr template) {
206 cananian 1.3.2.1         assert false : "abstract method";
207 pnkfelix 1.1.2.5         return null;
208 pnkfelix 1.1.2.5     }
209 cananian 1.2     }