summaryrefslogtreecommitdiff
path: root/Homework/cs5300/compiler/p5-compiler/submit/RegisterAllocator.java
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
committerElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
commit6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 (patch)
treeed97e39ec77c5231ffd2c394493e68d00ddac5a4 /Homework/cs5300/compiler/p5-compiler/submit/RegisterAllocator.java
downloadmisc-undergrad-6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6.tar.gz
misc-undergrad-6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6.zip
Diffstat (limited to 'Homework/cs5300/compiler/p5-compiler/submit/RegisterAllocator.java')
-rw-r--r--Homework/cs5300/compiler/p5-compiler/submit/RegisterAllocator.java151
1 files changed, 151 insertions, 0 deletions
diff --git a/Homework/cs5300/compiler/p5-compiler/submit/RegisterAllocator.java b/Homework/cs5300/compiler/p5-compiler/submit/RegisterAllocator.java
new file mode 100644
index 0000000..b0c9d03
--- /dev/null
+++ b/Homework/cs5300/compiler/p5-compiler/submit/RegisterAllocator.java
@@ -0,0 +1,151 @@
+/*
+ */
+package submit;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+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<>();
+
+ public RegisterAllocator() { clearAll(); }
+
+ 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 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()));
+
+ return register;
+ }
+
+ 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 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 int saveS(StringBuilder code, int baseOffset) {
+ // return saveRestore(code, baseOffset, true, true);
+ // }
+
+ 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 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 void clearAll() {
+ Arrays.fill(t, false);
+ Arrays.fill(s, false);
+ }
+}