1 kkz      1.1.2.1  // DataGC.java, created Thu Jan 13 20:55:26 2000 by kkz
  2 cananian 1.1.2.15 // Copyright (C) 1999 Karen K. Zee <kkz@alum.mit.edu>
  3 kkz      1.1.2.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 kkz      1.1.2.1  package harpoon.Backend.Runtime1;
  5 kkz      1.1.2.1  
  6 kkz      1.1.2.3  import harpoon.Analysis.Maps.Derivation;
  7 kkz      1.1.2.1  import harpoon.Backend.Generic.Frame;
  8 kkz      1.1.2.1  import harpoon.Backend.Generic.GCInfo;
  9 kkz      1.1.2.6  import harpoon.Backend.Generic.GCInfo.DLoc;
 10 kkz      1.1.2.1  import harpoon.Backend.Generic.GCInfo.GCPoint;
 11 kkz      1.1.2.11 import harpoon.Backend.Generic.GCInfo.WrappedMachineRegLoc;
 12 kkz      1.1.2.11 import harpoon.Backend.Generic.GCInfo.WrappedStackOffsetLoc;
 13 kkz      1.1.2.3  import harpoon.Backend.Generic.RegFileInfo.CommonLoc;
 14 kkz      1.1.2.1  import harpoon.Backend.Generic.RegFileInfo.MachineRegLoc;
 15 kkz      1.1.2.2  import harpoon.Backend.Generic.RegFileInfo.StackOffsetLoc;
 16 kkz      1.1.2.10 import harpoon.Backend.Maps.BackendDerivation;
 17 kkz      1.1.2.1  import harpoon.Backend.Maps.NameMap;
 18 kkz      1.1.2.1  import harpoon.ClassFile.HClass;
 19 kkz      1.1.2.1  import harpoon.ClassFile.HDataElement;
 20 kkz      1.1.2.1  import harpoon.ClassFile.HMethod;
 21 kkz      1.1.2.1  import harpoon.IR.Tree.ALIGN;
 22 kkz      1.1.2.1  import harpoon.IR.Tree.CONST;
 23 kkz      1.1.2.1  import harpoon.IR.Tree.LABEL;
 24 kkz      1.1.2.1  import harpoon.IR.Tree.SEGMENT;
 25 kkz      1.1.2.1  import harpoon.IR.Tree.Stm;
 26 kkz      1.1.2.2  import harpoon.Temp.Label;
 27 kkz      1.1.2.1  import harpoon.Util.Util;
 28 kkz      1.1.2.1  
 29 kkz      1.1.2.1  import java.util.ArrayList;
 30 kkz      1.1.2.1  import java.util.Arrays;
 31 kkz      1.1.2.1  import java.util.List;
 32 kkz      1.1.2.2  import java.util.HashMap;
 33 kkz      1.1.2.2  import java.util.HashSet;
 34 kkz      1.1.2.1  import java.util.Iterator;
 35 kkz      1.1.2.1  import java.util.Map;
 36 kkz      1.1.2.1  import java.util.Set;
 37 kkz      1.1.2.1  import java.util.TreeSet;
 38 kkz      1.1.2.1  
 39 kkz      1.1.2.1  /**
 40 kkz      1.1.2.1   * <code>DataGC</code> outputs the tables needed by the garbage collector.
 41 kkz      1.1.2.1   * 
 42 cananian 1.1.2.15  * @author  Karen K. Zee <kkz@alum.mit.edu>
 43 cananian 1.6       * @version $Id: DataGC.java,v 1.6 2004/02/08 03:20:58 cananian Exp $
 44 kkz      1.1.2.1   */
 45 kkz      1.1.2.1  public class DataGC extends Data {
 46 kkz      1.1.2.3      final GCInfo m_gc;
 47 kkz      1.1.2.3      final NameMap m_nm;
 48 kkz      1.1.2.3      final TreeBuilder m_tb;
 49 kkz      1.1.2.6      final int numRegs;
 50 cananian 1.5          final boolean pointersAreLong;
 51 kkz      1.1.2.1      
 52 kkz      1.1.2.6      // number of bits in a 32-bit int
 53 kkz      1.1.2.6      final int INT_BITS = 32;
 54 kkz      1.1.2.6      // size of descriptor in bits
 55 kkz      1.1.2.9      final int DESC_BITS = 8;
 56 kkz      1.1.2.6  
 57 kkz      1.1.2.1      /** Creates a <code>DataGC</code>. */
 58 kkz      1.1.2.6      public DataGC(Frame f, HClass hc) {
 59 kkz      1.1.2.1          super("gc-data", hc, f);
 60 cananian 1.3.2.1          assert f.getGCInfo() != null;
 61 kkz      1.1.2.3          this.m_gc = f.getGCInfo();
 62 cananian 1.1.2.16         this.m_nm = f.getRuntime().getNameMap();
 63 cananian 1.1.2.16         this.m_tb = (TreeBuilder) f.getRuntime().getTreeBuilder();
 64 kkz      1.1.2.6          this.numRegs = f.getRegFileInfo().maxRegIndex();
 65 cananian 1.5              this.pointersAreLong = f.pointersAreLong();
 66 kkz      1.1.2.6          this.root = build();
 67 kkz      1.1.2.1      }
 68 kkz      1.1.2.6  
 69 kkz      1.1.2.6      private HDataElement build() {
 70 kkz      1.1.2.11         final List stmlist = new ArrayList();
 71 kkz      1.1.2.7          // handle only methods that we've had to generate
 72 kkz      1.1.2.7          // GCInfo for and do so in the order saved by GCInfo
 73 kkz      1.1.2.11         final List methods = m_gc.getOrderedMethods(hc);
 74 kkz      1.1.2.7          if (methods == null) return null;
 75 kkz      1.1.2.11         report(methods.toString());
 76 kkz      1.1.2.6          // switch to the GC segment
 77 kkz      1.1.2.1          stmlist.add(new SEGMENT(tf, null, SEGMENT.GC));
 78 kkz      1.1.2.6          // align on word-boundary
 79 cananian 1.5              stmlist.add(new ALIGN(tf, null, pointersAreLong ? 8 : 4));
 80 kkz      1.1.2.11         for (Iterator it=methods.iterator(); it.hasNext(); ) {
 81 kkz      1.1.2.11             Stm output = outputGCData((HMethod)it.next());
 82 kkz      1.1.2.11             if (output != null)
 83 kkz      1.1.2.11                 stmlist.add(output);
 84 kkz      1.1.2.11         }
 85 kkz      1.1.2.1          return (HDataElement) Stm.toStm(stmlist);
 86 kkz      1.1.2.1      }
 87 kkz      1.1.2.6  
 88 kkz      1.1.2.6      // requires: method for which GC points have been calculated
 89 kkz      1.1.2.6      // modifies: basetableMap
 90 kkz      1.1.2.6      // effects:  returns statements for outputting base table and
 91 kkz      1.1.2.6      //           puts numeric mapping of stackOffsetLocs into the
 92 kkz      1.1.2.6      //           basetableMap
 93 kkz      1.1.2.6      private Stm outputBaseTable(HMethod hm) {
 94 kkz      1.1.2.6          // get ordered list of GC points for this method
 95 kkz      1.1.2.3          List gcps = m_gc.gcPoints(hm);
 96 kkz      1.1.2.6          // make sure the list is non-null
 97 cananian 1.3.2.1          assert gcps != null;
 98 kkz      1.1.2.6          // first create base table for stack locations
 99 kkz      1.1.2.6          Set basetableSet = new HashSet();
100 kkz      1.1.2.11         // take union of live WrappedStackOffsetLocs for all GC points
101 kkz      1.1.2.6          for(Iterator it = gcps.iterator(); it.hasNext(); )
102 kkz      1.1.2.6              basetableSet.addAll(((GCPoint)it.next()).liveStackOffsetLocs());
103 kkz      1.1.2.6          // make statements
104 kkz      1.1.2.6          List stmlist = new ArrayList(basetableSet.size()+2);
105 kkz      1.1.2.6          // label base table location
106 kkz      1.1.2.6          stmlist.add(new LABEL(tf, null, m_nm.label(hm, "gc_bt"), true));
107 kkz      1.1.2.6          // number of entries in base table (int)
108 kkz      1.1.2.6          stmlist.add(_DATUM(new CONST(tf, null, basetableSet.size())));
109 kkz      1.1.2.6          report("Size of base table = " + basetableSet.size());
110 kkz      1.1.2.6          // clear basetableMap
111 kkz      1.1.2.11         basetableMap = new HashMap(); int i = 0;
112 kkz      1.1.2.11         for(Iterator btIt = basetableSet.iterator();
113 kkz      1.1.2.11             btIt.hasNext(); ) {
114 kkz      1.1.2.11             // put new entries into basetableMap
115 kkz      1.1.2.11             WrappedStackOffsetLoc wsol = (WrappedStackOffsetLoc)btIt.next();
116 kkz      1.1.2.6              // output stackOffset (int)
117 kkz      1.1.2.11             stmlist.add(_DATUM(new CONST(tf, null, wsol.stackOffset())));
118 kkz      1.1.2.11             report("Base table entry: " + wsol.stackOffset());
119 kkz      1.1.2.11             basetableMap.put(wsol, new Integer(i++));
120 kkz      1.1.2.2          }
121 kkz      1.1.2.6          return Stm.toStm(stmlist);
122 kkz      1.1.2.6      }
123 kkz      1.1.2.6      private Map basetableMap;
124 kkz      1.1.2.6  
125 kkz      1.1.2.6      private Stm outputGCData(HMethod hm) {
126 kkz      1.1.2.11         // get ordered list of GC points for this method
127 kkz      1.1.2.11         final List gcps = m_gc.gcPoints(hm);
128 kkz      1.1.2.11         if (gcps.isEmpty()) return null;
129 kkz      1.1.2.11         final List stmlist = new ArrayList();
130 kkz      1.1.2.6          // make base table for method
131 kkz      1.1.2.6          stmlist.add(outputBaseTable(hm));
132 kkz      1.1.2.11         GCPoint prev = null; int i = 0;
133 kkz      1.1.2.6          // make entry for each GC point
134 cananian 1.6              for(Object gcpO : gcps) {
135 cananian 1.6                  GCPoint gcp = (GCPoint) gcpO;
136 kkz      1.1.2.6              // add index entry to GC_INDEX segment
137 kkz      1.1.2.6              stmlist.add(new SEGMENT(tf, null, SEGMENT.GC_INDEX));
138 kkz      1.1.2.6              // location of GC point
139 kkz      1.1.2.11             stmlist.add(_DATUM(gcp.label()));
140 kkz      1.1.2.6              // location of GC data
141 kkz      1.1.2.6              stmlist.add(_DATUM(m_nm.label(hm, "gcp_index_"+i)));
142 kkz      1.1.2.6              // location of GC base table
143 kkz      1.1.2.11             // stmlist.add(_DATUM(m_nm.label(hm, "gc_bt")));
144 kkz      1.1.2.6              // add data entry to GC segment
145 kkz      1.1.2.6              stmlist.add(new SEGMENT(tf, null, SEGMENT.GC));
146 kkz      1.1.2.6              // align on word boundary
147 cananian 1.5                  stmlist.add(new ALIGN(tf, null, pointersAreLong ? 8 : 4));
148 kkz      1.1.2.6              // label GC data
149 kkz      1.1.2.6              stmlist.add(new LABEL(tf, null, m_nm.label(hm, "gcp_index_"+i), 
150 kkz      1.1.2.6                                    true));
151 kkz      1.1.2.6              // output actual data
152 kkz      1.1.2.11             stmlist.add(outputGCPoint(gcp, prev));
153 kkz      1.1.2.11             // setup for next
154 kkz      1.1.2.11             prev = gcp; i++;
155 kkz      1.1.2.2          }
156 kkz      1.1.2.11         //System.out.println(i+" GC points in "+hm);
157 kkz      1.1.2.6          return Stm.toStm(stmlist);
158 kkz      1.1.2.6      }
159 kkz      1.1.2.6  
160 kkz      1.1.2.11     // octal
161 kkz      1.1.2.11     final int NO_LIVE_REGISTERS              =   01;
162 kkz      1.1.2.11     final int NO_CHANGE_IN_REGISTERS         =   02;
163 kkz      1.1.2.11     final int NO_LIVE_STACK_LOCATIONS        =   04;
164 kkz      1.1.2.11     final int NO_CHANGE_IN_STACK_LOCATIONS   =  010;
165 kkz      1.1.2.11     final int NO_LIVE_DERIVED_POINTERS       =  020;
166 kkz      1.1.2.11     final int NO_CHANGE_IN_DERIVED_POINTERS  =  040;
167 kkz      1.1.2.11     final int NO_LIVE_CALLEE_SAVED_REGISTERS = 0100;
168 kkz      1.1.2.11     final int NO_CHANGE_IN_CALLEE_SAVED_REGISTERS = 0200;
169 kkz      1.1.2.11     final int DESCRIPTOR_SIZE                =    8; // in bits
170 kkz      1.1.2.6      // requires: current and previous GC point
171 kkz      1.1.2.6      // modifies: nil
172 kkz      1.1.2.6      // effects:  returns statements for outputting data relevant
173 kkz      1.1.2.6      //           to current GC point
174 kkz      1.1.2.6      private Stm outputGCPoint(GCPoint curr, GCPoint prev) {
175 kkz      1.1.2.6          // output format: bits 31-26 -- descriptor
176 kkz      1.1.2.6          int output = 0;
177 kkz      1.1.2.11         boolean outputRegisters = true;
178 kkz      1.1.2.11         final Set registers = curr.liveMachineRegLocs();
179 kkz      1.1.2.11         if (registers.isEmpty()) {
180 kkz      1.1.2.11             output |= NO_LIVE_REGISTERS; outputRegisters = false;
181 kkz      1.1.2.6          } else if (prev != null && 
182 kkz      1.1.2.11                    registers.equals(prev.liveMachineRegLocs())) {
183 kkz      1.1.2.11             output |= NO_CHANGE_IN_REGISTERS; outputRegisters = false;
184 kkz      1.1.2.2          }
185 kkz      1.1.2.6          boolean needStack = true;
186 kkz      1.1.2.6          Set stack = curr.liveStackOffsetLocs();
187 kkz      1.1.2.6          if (stack.isEmpty()) {
188 kkz      1.1.2.11             output |= NO_LIVE_STACK_LOCATIONS;
189 kkz      1.1.2.6              needStack = false;
190 kkz      1.1.2.6          } else if (prev != null &&
191 kkz      1.1.2.6                     stack.equals(prev.liveStackOffsetLocs())) {
192 kkz      1.1.2.11             output |= NO_CHANGE_IN_STACK_LOCATIONS;
193 kkz      1.1.2.1                  needStack = false;
194 kkz      1.1.2.1              }   
195 kkz      1.1.2.6          boolean needDerivs = true;
196 kkz      1.1.2.8          Map regDerivs = curr.regDerivations();
197 kkz      1.1.2.8          Map stackDerivs = curr.stackDerivations();
198 kkz      1.1.2.8          if (regDerivs.isEmpty() && stackDerivs.isEmpty()) {
199 kkz      1.1.2.11             output |= NO_LIVE_DERIVED_POINTERS;
200 kkz      1.1.2.6              needDerivs = false;
201 kkz      1.1.2.6          } else if (prev != null && 
202 kkz      1.1.2.8                     regDerivs.equals(prev.regDerivations()) &&
203 kkz      1.1.2.8                     stackDerivs.equals(prev.stackDerivations())) {
204 kkz      1.1.2.11             output |= NO_CHANGE_IN_DERIVED_POINTERS;
205 kkz      1.1.2.6              needDerivs = false;
206 kkz      1.1.2.6          }
207 kkz      1.1.2.9          // handle callee-saved registers
208 kkz      1.1.2.9          boolean needCSaved = true;
209 kkz      1.1.2.10         Map cSaved = curr.calleeSaved();
210 kkz      1.1.2.10         if (cSaved.isEmpty()) {
211 kkz      1.1.2.11             output |= NO_LIVE_CALLEE_SAVED_REGISTERS;
212 kkz      1.1.2.9              needCSaved = false;
213 kkz      1.1.2.10         } else if (prev != null && cSaved.equals(prev.calleeSaved())) {
214 kkz      1.1.2.11             output |= NO_CHANGE_IN_CALLEE_SAVED_REGISTERS;
215 kkz      1.1.2.9              needCSaved = false;
216 kkz      1.1.2.9          }
217 kkz      1.1.2.6          List stmlist = new ArrayList();
218 kkz      1.1.2.11         if (!outputRegisters && !needStack)
219 kkz      1.1.2.6              // output descriptor (int)
220 kkz      1.1.2.6              stmlist.add(_DATUM(new CONST(tf, null, output)));
221 kkz      1.1.2.6          else
222 kkz      1.1.2.6              // handle both registers and stack together to save bits
223 kkz      1.1.2.11             stmlist.add(outputRS(outputRegisters, needStack, 
224 kkz      1.1.2.11                                  registers, stack, output));
225 kkz      1.1.2.6          if (needDerivs)
226 kkz      1.1.2.8              stmlist.add(outputDerivs(regDerivs, stackDerivs));
227 kkz      1.1.2.9          if (needCSaved)
228 kkz      1.1.2.9              stmlist.add(outputCSaved(cSaved));
229 kkz      1.1.2.1          return Stm.toStm(stmlist);
230 kkz      1.1.2.11     } // outputGCPoint
231 kkz      1.1.2.6  
232 kkz      1.1.2.10     // requires: descriptor set in output
233 kkz      1.1.2.6      // modifies: nil
234 kkz      1.1.2.10     // effects: returns statements that output descriptor
235 kkz      1.1.2.6      //          plus register data (if needed) and stack data
236 kkz      1.1.2.6      //          (if needed)
237 kkz      1.1.2.6      private Stm outputRS(boolean needRegs, boolean needStack,
238 kkz      1.1.2.6                           Set regs, Set stack, int output)
239 kkz      1.1.2.6      {
240 kkz      1.1.2.10         // number of bits needed to store the descriptor,
241 kkz      1.1.2.6          // the register bitmap and the stack bitmap
242 kkz      1.1.2.11         final int bits = DESCRIPTOR_SIZE + 
243 kkz      1.1.2.13             (needRegs?numRegs:0) + (needStack?basetableMap.size():0);
244 kkz      1.1.2.6          // number of 32-bit integers needed to encode the data 
245 kkz      1.1.2.6          final int numInts = (bits + INT_BITS - 1) / INT_BITS;
246 kkz      1.1.2.6          int[] data = new int[numInts];
247 kkz      1.1.2.10         // remember the descriptor
248 kkz      1.1.2.11         int offset = DESCRIPTOR_SIZE;
249 kkz      1.1.2.10         // get descriptor from output
250 kkz      1.1.2.6          data[0] = output;
251 kkz      1.1.2.6          // do registers first
252 kkz      1.1.2.6          if (needRegs) {
253 kkz      1.1.2.6              for(Iterator it=regs.iterator(); it.hasNext(); ) {
254 kkz      1.1.2.12                 int regIndex = ((WrappedMachineRegLoc)it.next()).regIndex();
255 cananian 1.3.2.1                  assert regIndex < numRegs;
256 kkz      1.1.2.6                  int i = (regIndex+offset) / INT_BITS;
257 kkz      1.1.2.6                  int j = (regIndex+offset) % INT_BITS;
258 cananian 1.3.2.1                  assert i < numInts;
259 kkz      1.1.2.6                  data[i] |= 1 << (INT_BITS - j - 1);
260 kkz      1.1.2.6              }
261 kkz      1.1.2.6              offset += numRegs;
262 kkz      1.1.2.1          }
263 kkz      1.1.2.6          if (needStack) {
264 kkz      1.1.2.6              for(Iterator it=stack.iterator(); it.hasNext(); ) {
265 kkz      1.1.2.6                  int index = ((Integer)basetableMap.get(it.next())).intValue();
266 kkz      1.1.2.6                  int i = (index+offset) / INT_BITS;
267 kkz      1.1.2.6                  int j = (index+offset) % INT_BITS;
268 cananian 1.3.2.1                  assert i < numInts;
269 kkz      1.1.2.6                  data[i] |= 1 << (INT_BITS - j - 1);
270 kkz      1.1.2.6              }
271 kkz      1.1.2.1          }
272 kkz      1.1.2.6          // output accumulated data
273 kkz      1.1.2.2          List stmlist = new ArrayList();
274 kkz      1.1.2.6          for(int k=0; k < numInts; k++)
275 kkz      1.1.2.2              stmlist.add(_DATUM(new CONST(tf, null, data[k])));
276 kkz      1.1.2.3          return Stm.toStm(stmlist);
277 kkz      1.1.2.3      }
278 kkz      1.1.2.6  
279 kkz      1.1.2.6      // effects: returns statements that output the derivation data
280 kkz      1.1.2.8      private Stm outputDerivs(Map regDerivs, Map stackDerivs) {
281 kkz      1.1.2.3          List stmlist = new ArrayList();
282 kkz      1.1.2.8          // number of derived pointers in registers
283 kkz      1.1.2.8          stmlist.add(_DATUM(new CONST(tf, null, regDerivs.size())));
284 kkz      1.1.2.8          // number of derived pointers in stack
285 kkz      1.1.2.8          stmlist.add(_DATUM(new CONST(tf, null, stackDerivs.size())));
286 kkz      1.1.2.8          // handle derived pointers in registers
287 cananian 1.6              for(Object keyO : regDerivs.keySet()) {
288 cananian 1.6                  WrappedMachineRegLoc key = (WrappedMachineRegLoc) keyO;
289 kkz      1.1.2.8              // location of derived pointer (int)
290 kkz      1.1.2.8              stmlist.add(_DATUM(new CONST(tf, null, key.regIndex()))); 
291 kkz      1.1.2.8              // derivation information
292 kkz      1.1.2.8              stmlist.add(outputDLoc((GCInfo.DLoc)regDerivs.get(key)));
293 kkz      1.1.2.8          }
294 kkz      1.1.2.8          // handle derived pointers in stack
295 cananian 1.6              for (Object keyO : stackDerivs.keySet()) {
296 cananian 1.6                  WrappedStackOffsetLoc key = (WrappedStackOffsetLoc) keyO;
297 kkz      1.1.2.8              // location of derived pointer (int)
298 kkz      1.1.2.8              stmlist.add(_DATUM(new CONST(tf, null, key.stackOffset())));
299 kkz      1.1.2.8              // derivation information
300 kkz      1.1.2.8              stmlist.add(outputDLoc((GCInfo.DLoc)stackDerivs.get(key)));
301 kkz      1.1.2.8          }
302 kkz      1.1.2.8          return Stm.toStm(stmlist);
303 kkz      1.1.2.8      }
304 kkz      1.1.2.8      private Stm outputDLoc(GCInfo.DLoc dl) {
305 kkz      1.1.2.8          List stmlist = new ArrayList();
306 kkz      1.1.2.8          // number of base pointers total
307 kkz      1.1.2.8          stmlist.add(_DATUM(new CONST(tf, null, (dl.stackLocs.length + 
308 kkz      1.1.2.8                                                  dl.regLocs.length))));
309 kkz      1.1.2.8          // register bits are laid out in (data, sign) pairs
310 kkz      1.1.2.8          {
311 kkz      1.1.2.8              final int numInts = (2 * numRegs + INT_BITS - 1) / INT_BITS;
312 kkz      1.1.2.8              int[] data = new int[numInts];
313 kkz      1.1.2.8              for(int index=0; index < dl.regLocs.length; index++) {
314 kkz      1.1.2.8                  int regIndex = dl.regLocs[index].regIndex();
315 kkz      1.1.2.8                  int i = (2 * regIndex) / INT_BITS;
316 kkz      1.1.2.8                  int j = (2 * regIndex) % INT_BITS;
317 kkz      1.1.2.8                  data[i] |= 1 << (INT_BITS - j - 1);
318 kkz      1.1.2.8                  data[i] |= 
319 kkz      1.1.2.8                      (dl.regSigns[index] ? 0 : 1) << (INT_BITS - j - 2);
320 kkz      1.1.2.3              }
321 kkz      1.1.2.8              for(int k=0; k < numInts; k++)
322 kkz      1.1.2.8                  stmlist.add(_DATUM(new CONST(tf, null, data[k])));
323 kkz      1.1.2.8          }
324 kkz      1.1.2.8          // only output if we have non-zero entries
325 kkz      1.1.2.8          if (dl.stackLocs.length != 0) {
326 kkz      1.1.2.8              final int numInts = (dl.stackLocs.length+INT_BITS-1)/INT_BITS;
327 kkz      1.1.2.8              int[] sign = new int[numInts];
328 kkz      1.1.2.8              for(int index=0; index < dl.stackLocs.length; index++) {
329 kkz      1.1.2.8                  int stackOffset = dl.stackLocs[index].stackOffset();
330 kkz      1.1.2.8                  stmlist.add(_DATUM(new CONST(tf, null, stackOffset)));
331 kkz      1.1.2.8                  int i = index / INT_BITS;
332 kkz      1.1.2.8                  int j = index % INT_BITS;
333 kkz      1.1.2.8                  sign[i] |= 
334 kkz      1.1.2.8                      (dl.stackSigns[index] ? 0 : 1) << (INT_BITS - j - 1);
335 kkz      1.1.2.3              }
336 kkz      1.1.2.8              for(int k=0; k < numInts; k++)
337 kkz      1.1.2.8                  stmlist.add(_DATUM(new CONST(tf, null, sign[k])));
338 kkz      1.1.2.2          }
339 kkz      1.1.2.2          return Stm.toStm(stmlist);
340 kkz      1.1.2.9      }
341 kkz      1.1.2.9      // output information about callee-saved registers
342 kkz      1.1.2.10     private Stm outputCSaved(Map cSaved) {
343 kkz      1.1.2.9          // calculate how many 32-bit ints we need to encode bit field
344 kkz      1.1.2.9          final int numInts = (2 * numRegs + INT_BITS - 1) / INT_BITS;
345 kkz      1.1.2.9          int[] bitfield = new int[numInts];
346 kkz      1.1.2.10         int[] locations = new int[cSaved.size()];
347 kkz      1.1.2.9          // output a bit field indicating which entries have data
348 kkz      1.1.2.10         //   00, 10 - no data
349 kkz      1.1.2.10         //       01 - register
350 kkz      1.1.2.10         //       11 - stack
351 cananian 1.6              for(Object keyO : cSaved.keySet()) {
352 cananian 1.6                  BackendDerivation.Register key = (BackendDerivation.Register) keyO;
353 kkz      1.1.2.10             CommonLoc location = (CommonLoc)cSaved.get(key);
354 kkz      1.1.2.10             // make sure we have a valid register index
355 cananian 1.3.2.1              assert key.regIndex() < numRegs;
356 kkz      1.1.2.10             int i = (2 * key.regIndex()) / INT_BITS;
357 kkz      1.1.2.10             int j = (2 * key.regIndex()) % INT_BITS;
358 kkz      1.1.2.10             // set the bit for data/no data
359 kkz      1.1.2.10             bitfield[i] |= 1 << (INT_BITS - j - 2);
360 kkz      1.1.2.10             switch(location.kind()) {
361 kkz      1.1.2.10             case StackOffsetLoc.KIND:
362 kkz      1.1.2.10                 // set the bit for stack/register
363 kkz      1.1.2.10                 bitfield[i] |= 1 << (INT_BITS - j - 1);
364 kkz      1.1.2.10                 locations[key.regIndex()] = 
365 kkz      1.1.2.10                     ((StackOffsetLoc)location).stackOffset(); break;
366 kkz      1.1.2.10             case MachineRegLoc.KIND:
367 kkz      1.1.2.10                 locations[key.regIndex()] =
368 kkz      1.1.2.10                     ((MachineRegLoc)location).regIndex(); break;
369 kkz      1.1.2.10             default:
370 cananian 1.3.2.1                  assert false;
371 kkz      1.1.2.10             }
372 kkz      1.1.2.9          }
373 kkz      1.1.2.10         List stmlist = new ArrayList();
374 kkz      1.1.2.9          // dump out bitfield
375 kkz      1.1.2.10         for(int k = 0; k < bitfield.length; k++)
376 kkz      1.1.2.9              stmlist.add(_DATUM(new CONST(tf, null, bitfield[k])));
377 kkz      1.1.2.10         // dump out register and stack locations
378 kkz      1.1.2.10         for(int k = 0; k < locations.length; k++)
379 kkz      1.1.2.10             stmlist.add(_DATUM(new CONST(tf, null, locations[k])));
380 kkz      1.1.2.9          return Stm.toStm(stmlist);
381 kkz      1.1.2.1      }
382 kkz      1.1.2.11     final private boolean DEBUG = false;
383 kkz      1.1.2.6      // convenient debugging utility
384 kkz      1.1.2.3      private void report(String str) {
385 kkz      1.1.2.3          if (DEBUG) System.out.println(str);
386 kkz      1.1.2.1      }
387 kkz      1.1.2.1  }
388 kkz      1.1.2.1  
389 kkz      1.1.2.1  
390 kkz      1.1.2.1  
391 kkz      1.1.2.1  
392 kkz      1.1.2.1  
393 kkz      1.1.2.1  
394 kkz      1.1.2.1  
395 kkz      1.1.2.1  
396 kkz      1.1.2.1  
397 kkz      1.1.2.1  
398 kkz      1.1.2.1  
399 cananian 1.2