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 }