Created
October 4, 2019 01:26
-
-
Save AugustNagro/792b162381304c0ebdaae5dddd85582d to your computer and use it in GitHub Desktop.
LEG V8 <=> BINARY... easy!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Map; | |
import java.util.Scanner; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import static java.lang.Integer.valueOf; | |
import static java.util.Map.entry; | |
public class Main { | |
// bit length = 10 | |
final Map<String, String> I_TYPE_INSTS = Map.ofEntries( | |
entry("addi", "1001000100"), | |
entry("andi", "1001001000"), | |
entry("subi", "11010000100"), | |
entry("subis", "1111000100"), | |
entry("andis", "1111001000"), | |
// reversed for decoding... | |
entry("1001000100", "addi"), | |
entry("1001001000", "andi"), | |
entry("1011000100", "addis"), | |
entry("11010000100", "subi"), | |
entry("1111000100", "subis"), | |
entry("1111001000", "andis") | |
); | |
// bit length = 11 | |
final Map<String, String> R_TYPE_INSTS = Map.ofEntries( | |
entry("add", "10001011000"), | |
entry("and", "10001010000"), | |
entry("sdiv", "10011010110"), | |
entry("mul", "10011011000"), | |
entry("orr", "10101010000"), | |
entry("adds", "10101011000"), | |
entry("addis", "1011000100"), | |
entry("sub", "11001011000"), | |
entry("lsr", "11010011010"), | |
entry("lsl", "11010011011"), | |
entry("ands", "11101010000"), | |
entry("subs", "11101011000"), | |
// reversed for decoding.. | |
entry("10001011000", "add"), | |
entry("10001010000", "and"), | |
entry("10011010110", "sdiv"), | |
entry("10011011000", "mul"), | |
entry("10101010000", "orr"), | |
entry("10101011000", "adds"), | |
entry("11001011000", "sub"), | |
entry("11010011010", "lsr"), | |
entry("11010011011", "lsl"), | |
entry("11101010000", "ands"), | |
entry("11101011000", "subs") | |
); | |
// bit length = 11 | |
final Map<String, String> D_TYPE_INSTS = Map.ofEntries( | |
entry("stur", "11111000000"), | |
entry("ldur", "11111000010"), | |
entry("sturb", "00111000000"), | |
entry("ldurb", "001110000010"), | |
entry("sturw", "10111000000"), | |
entry("ldursw", "10111000100"), | |
// reversed for decoding. | |
entry("11111000000", "stur"), | |
entry("11111000010", "ldur"), | |
entry("00111000000", "sturb"), | |
entry("001110000010", "ldurb"), | |
entry("10111000000", "sturw"), | |
entry("10111000100", "ldursw") | |
); | |
// bit length = 9 | |
final Map<String, String> IM_TYPE_INSTS = Map.ofEntries( | |
entry("movz", "110100101"), | |
entry("movk", "111100101"), | |
// reversed for decoding... | |
entry("110100101", "movz"), | |
entry("111100101", "movk") | |
); | |
final String ERR = "Could not match input"; | |
public static void main(String[] args) { | |
new Main().interpreter(); | |
} | |
void interpreter() { | |
Scanner scan = new Scanner(System.in); | |
while (scan.hasNextLine()) { | |
String line = sanitizeRegisters(scan.nextLine()); | |
String res = ERR; | |
int indexFirstSpace; | |
if ((indexFirstSpace = line.indexOf(' ')) != -1) { | |
// Encode Instruction | |
String inst = line.substring(0, indexFirstSpace); | |
String opCode; | |
if ((opCode = I_TYPE_INSTS.get(inst)) != null) res = encodeI(opCode, line); | |
else if ((opCode = R_TYPE_INSTS.get(inst)) != null) res = encodeR(opCode, line); | |
else if ((opCode = D_TYPE_INSTS.get(inst)) != null) res = encodeD(opCode, line); | |
else if ((opCode = IM_TYPE_INSTS.get(inst)) != null) res = encodeIM(opCode, line); | |
} else { | |
// decode inst | |
String opCode = line.substring(0, 11); | |
String inst; | |
if ((inst = R_TYPE_INSTS.get(opCode)) != null) res = decodeR(inst, line); | |
else if ((inst = D_TYPE_INSTS.get(opCode)) != null) res = decodeD(inst, line); | |
else if ((inst = I_TYPE_INSTS.get((opCode = line.substring(0, 10)))) != null) | |
res = decodeI(inst, line); | |
else if ((inst = IM_TYPE_INSTS.get((opCode = line.substring(0, 9)))) != null) | |
res = decodeIM(inst, line); | |
} | |
System.out.println(res); | |
System.out.println(); | |
} | |
} | |
final Pattern I_TYPE = | |
Pattern.compile("\\w+\\s+x(?<Rd>\\d+),\\s+x(?<Rn>\\d+),\\s+#(?<Im>\\w+)"); | |
String encodeI(String opBinary, String line) { | |
Matcher m = I_TYPE.matcher(line); | |
if (!m.find()) return ERR; | |
String Im = toBinary(m.group("Im"), 12); | |
String Rn = toBinary(m.group("Rn"), 5); | |
String Rd = toBinary(m.group("Rd"), 5); | |
return "OpCode:\t" + opBinary + | |
"\nIm:\t" + Im + | |
"\nRn:\t" + Rn + | |
"\nRd:\t" + Rd + | |
"\n\nFull Binary: " + opBinary + Im + Rn + Rd; | |
} | |
String decodeI(String inst, String line) { | |
int Im = valueOf(line.substring(10, 22), 2); | |
String Rn = reg(valueOf(line.substring(22, 27), 2)); | |
String Rd = reg(valueOf(line.substring(27), 2)); | |
return inst + " " + Rd + ", " + Rn + ", #" + Im + " (aka #0x" + Integer.toHexString(Im) + ")"; | |
} | |
final Pattern R_TYPE = | |
Pattern.compile("\\w+\\s+x(?<Rd>\\d+),\\s+x(?<Rn>\\d+),\\s+x(?<Rm>\\d+)"); | |
String encodeR(String opBinary, String line) { | |
Matcher m = R_TYPE.matcher(line); | |
if (!m.find()) return ERR; | |
String Rm = toBinary(m.group("Rm"), 5); | |
String shamt = "000000"; | |
String Rn = toBinary(m.group("Rn"), 5); | |
String Rd = toBinary(m.group("Rd"), 5); | |
return "OpCode:\t" + opBinary + | |
"\nRm:\t" + Rm + | |
"\nShamt:\t" + shamt + | |
"\nRn:\t" + Rn + | |
"\nRd:\t" + Rd + | |
"\n\nFull Binary: " + opBinary + Rm + shamt + Rn + Rd; | |
} | |
String decodeR(String inst, String line) { | |
String Rm = reg(valueOf(line.substring(11, 16), 2)); | |
String Rn = reg(valueOf(line.substring(22, 27), 2)); | |
String Rd = reg(valueOf(line.substring(27), 2)); | |
return inst + " " + Rd + ", " + Rn + ", " + Rm; | |
} | |
final Pattern D_TYPE = | |
Pattern.compile("\\w+\\s+x(?<Rt>\\d+),\\s+\\[x(?<Rn>\\d+),\\s+#(?<Im>\\w+)"); | |
String encodeD(String opBinary, String line) { | |
Matcher m = D_TYPE.matcher(line); | |
if (!m.find()) return ERR; | |
String Im = toBinary(m.group("Im"), 9); | |
String op = "00"; | |
String Rn = toBinary(m.group("Rn"), 5); | |
String Rt = toBinary(m.group("Rt"), 5); | |
return "OpCode:\t" + opBinary + | |
"\nIm:\t" + Im + | |
"\nop:\t" + op + | |
"\nRn:\t" + Rn + | |
"\nRt:\t" + Rt + | |
"\n\nFull Binary: " + opBinary + Im + op + Rn + Rt; | |
} | |
String decodeD(String inst, String line) { | |
int Im = valueOf(line.substring(11, 20), 2); | |
String Rn = reg(valueOf(line.substring(22, 27), 2)); | |
String Rt = reg(valueOf(line.substring(27), 2)); | |
return inst + " " + Rt + ", [" + Rn + ", #" + Im + " (aka 0x" + Integer.toHexString(Im) + ") ]"; | |
} | |
final Pattern IM_TYPE = | |
Pattern.compile("\\w+\\s+x(?<Rd>\\d+),\\s+#(?<Im>\\w+),\\s+lsl\\s+(?<shift>48|32|16|0)"); | |
String encodeIM(String opBinary, String line) { | |
Matcher m = IM_TYPE.matcher(line); | |
if (!m.find()) return ERR; | |
String Im = toBinary(m.group("Im"), 16); | |
String op = null; | |
switch (m.group("shift")) { | |
case "0": | |
op = "00"; | |
break; | |
case "16": | |
op = "01"; | |
break; | |
case "32": | |
op = "10"; | |
case "48": | |
op = "11"; | |
break; | |
} | |
String Rd = toBinary(m.group("Rd"), 5); | |
return "OpCode:\t" + opBinary + | |
"\nop:\t" + op + | |
"\nIm:\t" + Im + | |
"\nRd:\t" + Rd + | |
"\n\nFull Binary: " + opBinary + op + Im + Rd; | |
} | |
String decodeIM(String inst, String line) { | |
String op = null; | |
switch (line.substring(9, 11)) { | |
case "00": | |
op = "0"; | |
break; | |
case "01": | |
op = "16"; | |
break; | |
case "10": | |
op = "32"; | |
break; | |
case "11": | |
op = "64"; | |
break; | |
} | |
int Im = valueOf(line.substring(11, 27), 2); | |
String Rd = reg(valueOf(line.substring(27), 2)); | |
return inst + " " + Rd + ", #" + Im + " (aka 0x" + Integer.toHexString(Im) + "), LSL " + op; | |
} | |
/** | |
* Converts s to a padded binary number | |
*/ | |
String toBinary(String s, int size) { | |
int val; | |
try { | |
val = valueOf(s); | |
} catch (Exception e) { | |
// try hex value instead, ie 0xabc43 | |
val = valueOf(s.substring(2), 16); | |
} | |
s = Integer.toString(val, 2); | |
return "0".repeat(size - s.length()) + s; | |
} | |
String sanitizeRegisters(String line) { | |
return line.toLowerCase() | |
.replaceAll("sp", "x28") | |
.replaceAll("fp", "x29") | |
.replaceAll("lr", "x30") | |
.replaceAll("xzr", "x31"); | |
} | |
String reg(int num) { | |
switch (num) { | |
case 28: | |
return "sp"; | |
case 29: | |
return "fp"; | |
case 30: | |
return "lr"; | |
case 31: | |
return "xzr"; | |
default: | |
return "x" + num; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment