diff options
author | Lizzy Hunt <elizabeth.hunt@simponic.xyz> | 2023-04-10 09:17:11 -0600 |
---|---|---|
committer | Lizzy Hunt <elizabeth.hunt@simponic.xyz> | 2023-04-10 09:17:11 -0600 |
commit | 5f28f80c4e25a56cd444914c2f0b3da5e7fdb088 (patch) | |
tree | 600ad8b1ec5aad5155baf8c0352281054a8e6366 /submit/RegisterAllocator.java | |
download | cminus-5f28f80c4e25a56cd444914c2f0b3da5e7fdb088.tar.gz cminus-5f28f80c4e25a56cd444914c2f0b3da5e7fdb088.zip |
Initial commit - building
Diffstat (limited to 'submit/RegisterAllocator.java')
-rw-r--r-- | submit/RegisterAllocator.java | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/submit/RegisterAllocator.java b/submit/RegisterAllocator.java new file mode 100644 index 0000000..ce18b2b --- /dev/null +++ b/submit/RegisterAllocator.java @@ -0,0 +1,126 @@ +/* + */ +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 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); + } +} |