summaryrefslogtreecommitdiff
path: root/submit/RegisterAllocator.java
diff options
context:
space:
mode:
Diffstat (limited to 'submit/RegisterAllocator.java')
-rw-r--r--submit/RegisterAllocator.java211
1 files changed, 119 insertions, 92 deletions
diff --git a/submit/RegisterAllocator.java b/submit/RegisterAllocator.java
index ce18b2b..161435d 100644
--- a/submit/RegisterAllocator.java
+++ b/submit/RegisterAllocator.java
@@ -15,112 +15,139 @@ import java.util.Set;
*/
public final class RegisterAllocator {
- // True if t is used
- private final boolean[] t = new boolean[10];
- private final boolean[] s = new boolean[8];
- private final Set<String> used = new HashSet<>();
+ // True if t is used
+ private final boolean[] t = new boolean[10];
+ private final boolean[] s = new boolean[8];
+ private final Set<String> used = new HashSet<>();
- public RegisterAllocator() {
- clearAll();
- }
+ public RegisterAllocator() { clearAll(); }
- public String getT() {
- for (int i = 0; i < t.length; ++i) {
- if (!t[i]) {
- t[i] = true;
- String str = "$t" + i;
- used.add(str);
- return str;
- }
- }
- return null;
+ public String getRegisterOrLoadIntoRegister(MIPSResult result,
+ StringBuilder code) {
+ if (result.getRegister() != null) {
+ return result.getRegister();
}
+ String reg = result.getAddress();
+ return this.loadIntoRegister(result, code, reg);
+ }
-// public String getS() {
-// for (int i = 0; i < s.length; ++i) {
-// if (!s[i]) {
-// s[i] = true;
-// String str = "$s" + i;
-// used.add(str);
-// return str;
-// }
-// }
-// return null;
-// }
-
- // Returns the number of bytes used to save the registers
- public int saveRestore(StringBuilder code, int baseOffset, boolean s_or_t, boolean save) {
- boolean[] r = s;
- String prefix = "$s";
- if (!s_or_t) {
- r = t;
- prefix = "$t";
- }
- String instruction = "sw";
- if (!save) {
- instruction = "lw";
- }
- int offset = 0;
- for (int i = 0; i < r.length; ++i) {
- if (r[i]) {
- offset -= 4;
- String str = prefix + i;
- code.append(instruction).append(" ").append(str).append(" ").append(offset-baseOffset).append("($sp)\n");
- }
- }
- return -offset;
- }
+ public String loadIntoRegister(MIPSResult result, StringBuilder code,
+ String register) {
+ return loadIntoRegisterWithOffset(result, code, register, 0);
+ }
+
+ public String loadIntoRegisterWithOffset(MIPSResult result,
+ StringBuilder code, String register,
+ int offset) {
+ code.append(
+ String.format("lw %s %d(%s)\n", register, offset, result.getAddress()));
-// public int saveS(StringBuilder code, int baseOffset) {
-// return saveRestore(code, baseOffset, true, true);
-// }
+ return register;
+ }
- public int saveT(StringBuilder code, int baseOffset) {
- return saveRestore(code, baseOffset, false, true);
+ public String getT() {
+ for (int i = 0; i < t.length; ++i) {
+ if (!t[i]) {
+ t[i] = true;
+ String str = "$t" + i;
+ used.add(str);
+ return str;
+ }
}
+ return null;
+ }
-// public int restoreS(StringBuilder code, int baseOffset) {
-// return saveRestore(code, baseOffset, true, false);
-// }
+ // public String getS() {
+ // for (int i = 0; i < s.length; ++i) {
+ // if (!s[i]) {
+ // s[i] = true;
+ // String str = "$s" + i;
+ // used.add(str);
+ // return str;
+ // }
+ // }
+ // return null;
+ // }
- public int restoreT(StringBuilder code, int baseOffset) {
- return saveRestore(code, baseOffset, false, false);
+ // Returns the number of bytes used to save the registers
+ public int saveRestore(StringBuilder code, int baseOffset, boolean s_or_t,
+ boolean save) {
+ boolean[] r = s;
+ String prefix = "$s";
+ if (!s_or_t) {
+ r = t;
+ prefix = "$t";
}
-
- public List<String> getUsed() {
- return new ArrayList<>(used);
+ String instruction = "sw";
+ if (!save) {
+ instruction = "lw";
}
-
- /**
- * Any time you call this method you should seriously consider adding a
- * corresponding clear() call.
- *
- * @return
- */
- public String getAny() {
-// String availS = getS();
-// if (availS != null) {
-// return availS;
-// }
- String t = getT();
- if (t == null) {
- throw new RuntimeException("Out of registers");
- }
- return t;
+ int offset = 0;
+ for (int i = 0; i < r.length; ++i) {
+ if (r[i]) {
+ offset -= 4;
+ String str = prefix + i;
+ code.append(instruction)
+ .append(" ")
+ .append(str)
+ .append(" ")
+ .append(offset - baseOffset)
+ .append("($sp)\n");
+ }
}
+ return -offset;
+ }
+
+ // public int saveS(StringBuilder code, int baseOffset) {
+ // return saveRestore(code, baseOffset, true, true);
+ // }
- public void clear(String reg) {
- if (reg.charAt(1) == 's') {
- s[Integer.parseInt(reg.substring(2))] = false;
- } else if (reg.charAt(1) == 't') {
- t[Integer.parseInt(reg.substring(2))] = false;
- } else {
- throw new RuntimeException("Unexpected register in clear");
- }
+ public int saveT(StringBuilder code, int baseOffset) {
+ return saveRestore(code, baseOffset, false, true);
+ }
+
+ // public int restoreS(StringBuilder code, int baseOffset) {
+ // return saveRestore(code, baseOffset, true, false);
+ // }
+
+ public int restoreT(StringBuilder code, int baseOffset) {
+ return saveRestore(code, baseOffset, false, false);
+ }
+
+ public List<String> getUsed() { return new ArrayList<>(used); }
+
+ /**
+ * Any time you call this method you should seriously consider adding a
+ * corresponding clear() call.
+ *
+ * @return
+ */
+ public String getAny() {
+ // String availS = getS();
+ // if (availS != null) {
+ // return availS;
+ // }
+ String t = getT();
+ if (t == null) {
+ throw new RuntimeException("Out of registers");
}
+ return t;
+ }
- public void clearAll() {
- Arrays.fill(t, false);
- Arrays.fill(s, false);
+ public void clear(String reg) {
+ if (reg == null)
+ return;
+ if (reg.charAt(1) == 's') {
+ s[Integer.parseInt(reg.substring(2))] = false;
+ } else if (reg.charAt(1) == 't') {
+ t[Integer.parseInt(reg.substring(2))] = false;
+ } else {
+ throw new RuntimeException("Unexpected register in clear");
}
+ }
+
+ public void clearAll() {
+ Arrays.fill(t, false);
+ Arrays.fill(s, false);
+ }
}