Skip to content

Instantly share code, notes, and snippets.

@AugustNagro
Created October 4, 2019 01:26
Show Gist options
  • Save AugustNagro/792b162381304c0ebdaae5dddd85582d to your computer and use it in GitHub Desktop.
Save AugustNagro/792b162381304c0ebdaae5dddd85582d to your computer and use it in GitHub Desktop.
LEG V8 <=> BINARY... easy!
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