From 5f28f80c4e25a56cd444914c2f0b3da5e7fdb088 Mon Sep 17 00:00:00 2001 From: Lizzy Hunt Date: Mon, 10 Apr 2023 09:17:11 -0600 Subject: Initial commit - building --- submit/RegisterAllocator.java | 126 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 submit/RegisterAllocator.java (limited to 'submit/RegisterAllocator.java') 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 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 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); + } +} -- cgit v1.2.3-70-g09d2