1 witchel  1.1.2.1 // InstrBuilder.java, created Fri Sep 10 23:37:52 1999 by pnkfelix
  2 witchel  1.1.2.1 // Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
  3 witchel  1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 witchel  1.1.2.1 package harpoon.Backend.MIPS;
  5 witchel  1.1.2.1 
  6 cananian 1.1.2.2 import harpoon.Backend.StrongARM.TwoWordTemp;
  7 witchel  1.1.2.1 import harpoon.IR.Assem.Instr;
  8 witchel  1.1.2.1 import harpoon.IR.Assem.InstrMEM;
  9 witchel  1.1.2.1 import harpoon.IR.Assem.InstrLABEL;
 10 witchel  1.1.2.1 import harpoon.Temp.Temp;
 11 witchel  1.1.2.1 import harpoon.Temp.Label;
 12 witchel  1.1.2.1 import harpoon.Util.Util;
 13 witchel  1.1.2.1 import harpoon.Util.ArrayIterator;
 14 witchel  1.1.2.1 
 15 witchel  1.1.2.1 import java.util.List;
 16 witchel  1.1.2.1 import java.util.Iterator;
 17 witchel  1.1.2.1 import java.util.Arrays;
 18 witchel  1.1.2.1 
 19 cananian 1.1.2.2 /** <code>MIPS.InstrBuilder</code> is an <code>Generic.InstrBuilder</code> for the
 20 cananian 1.1.2.2     MIPS architecture.
 21 witchel  1.1.2.1 
 22 witchel  1.1.2.1     @author  Felix S. Klock II <pnkfelix@mit.edu>
 23 cananian 1.1.2.2     @author  Emmett Witchel <witchel@mit.edu>
 24 cananian 1.4         @version $Id: InstrBuilder.java,v 1.4 2002/04/10 03:02:51 cananian Exp $
 25 witchel  1.1.2.1  */
 26 witchel  1.1.2.1 public class InstrBuilder extends harpoon.Backend.Generic.InstrBuilder {
 27 witchel  1.1.2.1 
 28 witchel  1.1.2.4    RegFileInfo rfInfo;
 29 witchel  1.1.2.3    private Frame frame;
 30 witchel  1.1.2.1 
 31 witchel  1.1.2.4    /* helper macro. */
 32 witchel  1.1.2.4    private final Temp SP() { 
 33 cananian 1.3.2.1       assert rfInfo.SP != null;
 34 witchel  1.1.2.4       return rfInfo.SP;
 35 witchel  1.1.2.4    }
 36 witchel  1.1.2.1     
 37 witchel  1.1.2.4    InstrBuilder(RegFileInfo rfInfo, Frame _frame) {
 38 witchel  1.1.2.4       super();
 39 witchel  1.1.2.4       this.rfInfo = rfInfo;
 40 witchel  1.1.2.4       frame = _frame;
 41 witchel  1.1.2.4    }
 42 witchel  1.1.2.4 
 43 witchel  1.1.2.4    public int getSize(Temp t) {
 44 witchel  1.1.2.4       if (t instanceof TwoWordTemp) {
 45 witchel  1.1.2.4          return 2; 
 46 witchel  1.1.2.4       } else {
 47 witchel  1.1.2.4          return 1;
 48 witchel  1.1.2.4       }
 49 witchel  1.1.2.4    }
 50 witchel  1.1.2.1 
 51 witchel  1.1.2.1    public List makeLoad(Temp r, int offset, Instr template) {
 52 witchel  1.1.2.3       StackInfo stack = ((CodeGen)frame.getCodeGen()).getStackInfo();
 53 witchel  1.1.2.3       offset = stack.localSaveOffset(offset);
 54 witchel  1.1.2.1       String[] strs = getLdrAssemStrs(r, offset);
 55 cananian 1.3.2.1       assert strs.length == 1 || strs.length == 2;
 56 witchel  1.1.2.1 
 57 witchel  1.1.2.1       if (strs.length == 2) {
 58 witchel  1.1.2.1          InstrMEM load1 = 
 59 witchel  1.1.2.1             new InstrMEM(template.getFactory(), template,
 60 witchel  1.1.2.1                          strs[0],
 61 witchel  1.1.2.1                          new Temp[]{ r },
 62 witchel  1.1.2.1                          new Temp[]{ SP()  });
 63 witchel  1.1.2.1          InstrMEM load2 = 
 64 witchel  1.1.2.1             new InstrMEM(template.getFactory(), template,
 65 witchel  1.1.2.1                          strs[1],
 66 witchel  1.1.2.1                          new Temp[]{ r },
 67 witchel  1.1.2.1                          new Temp[]{ SP()  });
 68 witchel  1.1.2.1          load2.layout(load1, null);
 69 witchel  1.1.2.1          return Arrays.asList(new InstrMEM[] { load1, load2 });
 70 witchel  1.1.2.1       } else {
 71 witchel  1.1.2.1          InstrMEM load = 
 72 witchel  1.1.2.1             new InstrMEM(template.getFactory(), template,
 73 witchel  1.1.2.1                          strs[0],
 74 witchel  1.1.2.1                          new Temp[]{ r },
 75 witchel  1.1.2.1                          new Temp[]{ SP()  });
 76 witchel  1.1.2.1          return Arrays.asList(new InstrMEM[] { load });
 77 witchel  1.1.2.1       }
 78 witchel  1.1.2.1    }
 79 witchel  1.1.2.1 
 80 witchel  1.1.2.4    private String[] getLdrAssemStrs(Temp r, int offset) {
 81 witchel  1.1.2.4       if (r instanceof TwoWordTemp) {
 82 witchel  1.1.2.4          return new String[] {
 83 witchel  1.1.2.4             "lw `d0h, ", + offset     + "(`s0)        # tmp restore (h)" ,
 84 witchel  1.1.2.4             "lw `d0l, ", + (offset+4) + "(`s0)        # tmp restore (l)" };
 85 witchel  1.1.2.4       } else {
 86 witchel  1.1.2.4          return new String[] { 
 87 witchel  1.1.2.4             "lw `d0, " + offset       + "(`s0)        # tmp restore" };
 88 witchel  1.1.2.4       }
 89 witchel  1.1.2.4    }
 90 witchel  1.1.2.4 
 91 witchel  1.1.2.4    private String[] getStrAssemStrs(Temp r, int offset) {
 92 witchel  1.1.2.4       if (r instanceof TwoWordTemp) {
 93 witchel  1.1.2.4          return new String[] {
 94 witchel  1.1.2.4             "sw `s0h, " + offset     + "(`s1)        # tmp save (h)", 
 95 witchel  1.1.2.4             "sw `s0l, " + (offset+4) + "(`s1)        # tmp save (l)" };
 96 witchel  1.1.2.4       } else {
 97 witchel  1.1.2.4          return new String[] { 
 98 witchel  1.1.2.4             "sw `s0, " + offset      + "(`s1)          # tmp save" };
 99 witchel  1.1.2.4       }
100 witchel  1.1.2.4    }
101 witchel  1.1.2.4 
102 witchel  1.1.2.4    public List makeStore(Temp r, int offset, Instr template) {
103 witchel  1.1.2.4       StackInfo stack = ((CodeGen)frame.getCodeGen()).getStackInfo();
104 witchel  1.1.2.4       offset = stack.localSaveOffset(offset);       
105 witchel  1.1.2.4       String[] strs = getStrAssemStrs(r, offset);
106 cananian 1.3.2.1       assert strs.length == 1 || 
107 cananian 1.3.2.1                   strs.length == 2;
108 witchel  1.1.2.1             
109 witchel  1.1.2.4       if (strs.length == 2) {
110 witchel  1.1.2.4          System.out.println("In makeStore, twoWord case");
111 witchel  1.1.2.4 
112 witchel  1.1.2.4          InstrMEM store1 = 
113 witchel  1.1.2.4             new InstrMEM(template.getFactory(), template,
114 witchel  1.1.2.4                          strs[0],
115 witchel  1.1.2.4                          new Temp[]{ },
116 witchel  1.1.2.4                          new Temp[]{ r , SP() });
117 witchel  1.1.2.4          InstrMEM store2 = 
118 witchel  1.1.2.4             new InstrMEM(template.getFactory(), template,
119 witchel  1.1.2.4                          strs[1],
120 witchel  1.1.2.4                          new Temp[]{ },
121 witchel  1.1.2.4                          new Temp[]{ r , SP() });
122 witchel  1.1.2.4          store2.layout(store1, null);
123 cananian 1.3.2.1          assert store1.getNext() == store2 : "store1.next == store2";
124 cananian 1.3.2.1          assert store2.getPrev() == store1 : "store2.prev == store1";
125 witchel  1.1.2.4          return Arrays.asList(new InstrMEM[]{ store1, store2 });
126 witchel  1.1.2.4       } else {
127 witchel  1.1.2.1 
128 witchel  1.1.2.4          InstrMEM store = 
129 witchel  1.1.2.4             new InstrMEM(template.getFactory(), template,
130 witchel  1.1.2.4                          strs[0],
131 witchel  1.1.2.4                          new Temp[]{ },
132 witchel  1.1.2.4                          new Temp[]{ r , SP() });
133 witchel  1.1.2.4          return Arrays.asList(new InstrMEM[] { store });
134 witchel  1.1.2.4       }
135 witchel  1.1.2.4    }
136 witchel  1.1.2.4 
137 witchel  1.1.2.4    public InstrLABEL makeLabel(Instr template) {
138 witchel  1.1.2.4       Label l = new Label();
139 witchel  1.1.2.4       InstrLABEL il = new InstrLABEL(template.getFactory(), 
140 witchel  1.1.2.4                                      template,
141 witchel  1.1.2.4                                      l.toString() + ":", l);
142 witchel  1.1.2.4       return il;
143 witchel  1.1.2.4    }
144 witchel  1.1.2.4 
145 witchel  1.1.2.4    /** Returns a new <code>InstrLABEL</code> for generating new
146 witchel  1.1.2.4        arbitrary code blocks to branch to.
147 witchel  1.1.2.4        @param template An <code>Instr</code> to base the generated
148 witchel  1.1.2.4        <code>InstrLABEL</code>.
149 witchel  1.1.2.4        <code>template</code> should be part of the
150 witchel  1.1.2.4        instruction stream that the returned
151 witchel  1.1.2.4        <code>InstrLABEL</code> is intended for. 
152 witchel  1.1.2.4    */
153 witchel  1.1.2.4    public InstrLABEL makeLabel(Label l, Instr template) {
154 witchel  1.1.2.4       InstrLABEL il = new InstrLABEL(template.getFactory(), 
155 witchel  1.1.2.4                                      template,
156 witchel  1.1.2.4                                      l.toString() + ":", l);
157 witchel  1.1.2.4       return il;
158 witchel  1.1.2.4    }
159 cananian 1.2     }