Skip to content
Snippets Groups Projects
Commit aa08469c authored by Deike, Benedikt's avatar Deike, Benedikt
Browse files

Upload New File

parent 836caec1
No related branches found
No related tags found
No related merge requests found
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Assembler {
private static List <JumpAddress> jumpAddressList;
private static BufferedWriter writer;
public static void main(String[] args) throws IOException {
File source = new File(args[0]);
Scanner scannerOne = new Scanner(source);
jumpAddressList = new ArrayList <JumpAddress> ();
int position = 0;
int address = 0;
// TODO : Don't allow the same label twice!
while(scannerOne.hasNextLine()) {
String noComment = scannerOne.nextLine().split("#")[0];
String line[] = noComment.trim().split("\\s+|,\\s+");
if(line[0].equals("")) {
continue;
} else if(line[0].matches("\\w+:$")) {
String labelName = line[0].substring(0, line[0].length() - 1);
jumpAddressList.add(position, new JumpAddress(labelName, address * 2));
position++;
} else {
address++;
}
}
writer = new BufferedWriter(new FileWriter(args[1], false));
Scanner scannerTwo = new Scanner(source);
address = 0;
while(scannerTwo.hasNextLine()) {
String noComment = scannerTwo.nextLine().split("#")[0];
// alternative regular expression: "[\\s,]+"
String line[] = noComment.trim().split("\\s+|,\\s+");
String mnemonic = line[0];
if(mnemonic.equals("")) { // empty line
continue;
} else if(mnemonic.matches("[A-Za-z]*:$")) { // line containing a label
continue;
} else { // line containing an instruction
switch(mnemonic) {
// -----------------------------------------------------
// -- ALU-Operations -----------------------------------
// -----------------------------------------------------
case "MOV":
writeALUOp("00100000", line[1], line[2]);
address++;
break;
case "ADDU":
writeALUOp("00100001", line[1], line[2]);
address++;
break;
case "ADDC":
writeALUOp("00100010", line[1], line[2]);
address++;
break;
case "SUBU":
writeALUOp("00100011", line[1], line[2]);
address++;
break;
case "AND":
writeALUOp("00100100", line[1], line[2]);
address++;
break;
case "OR":
writeALUOp("00100101", line[1], line[2]);
address++;
break;
case "XOR":
writeALUOp("00100110", line[1], line[2]);
address++;
break;
case "NOT":
writeALUOp("00100111", line[1], "0000");
address++;
break;
// -----------------------------------------------------
// -- Shift-Operations ---------------------------------
// -----------------------------------------------------
case "LSL":
writeShiftOp("00101000", line[1], line[2]);
address++;
break;
case "LSR":
writeShiftOp("00101001", line[1], line[2]);
address++;
break;
case "ASR":
writeShiftOp("00101010", line[1], line[2]);
address++;
break;
case "LSLC":
writeShiftOp("00101100", line[1], "0000");
address++;
break;
case "LSRC":
writeShiftOp("00101101", line[1], "0000");
address++;
break;
case "ASRC":
writeShiftOp("00101110", line[1], "0000");
address++;
break;
// -----------------------------------------------------
// -- Compare-Operations -------------------------------
// -----------------------------------------------------
case "CMPE":
writeCompOp("00110000", line[1], line[2]);
address++;
break;
case "CMPNE":
writeCompOp("00110001", line[1], line[2]);
address++;
break;
case "CMPGT":
writeCompOp("00110010", line[1], line[2]);
address++;
break;
case "CMPLT":
writeCompOp("00110011", line[1], line[2]);
address++;
break;
// -----------------------------------------------------
// -- Immediate-Operations -----------------------------
// -----------------------------------------------------
case "MOVI":
writeImmOp("00110100", line[1], line[2]);
address++;
break;
case "ADDI":
writeImmOp("00110101", line[1], line[2]);
address++;
break;
case "SUBI":
writeImmOp("00110110", line[1], line[2]);
address++;
break;
case "ANDI":
writeImmOp("00110111", line[1], line[2]);
address++;
break;
case "LSLI":
writeImmOp("00111000", line[1], line[2]);
address++;
break;
case "LSRI":
writeImmOp("00111001", line[1], line[2]);
address++;
break;
case "BSETI":
writeImmOp("00111010", line[1], line[2]);
address++;
break;
case "BCLRI":
writeImmOp("00111011", line[1], line[2]);
address++;
break;
// -----------------------------------------------------
// -- Memory-Operations --------------------------------
// -----------------------------------------------------
case "LDW":
writeMemOp("0100", line[1], line[2], line[3]);
address++;
break;
case "STW":
writeMemOp("0101", line[1], line[2], line[3]);
address++;
break;
// -----------------------------------------------------
// -- Control-Flow-Operations --------------------------
// -----------------------------------------------------
case "BR":
writeControlFlowOp("1000", line[1], address);
address++;
break;
case "JSR":
writeControlFlowOp("1001", line[1], address);
address++;
break;
case "BT":
writeControlFlowOp("1010", line[1], address);
address++;
break;
case "BF":
writeControlFlowOp("1011", line[1], address);
address++;
break;
case "JMP":
writeJMPOp("1100", line[1]);
address++;
break;
// -----------------------------------------------------
// -- Halt ---------------------------------------------
// -----------------------------------------------------
case "HALT":
writeHALTOp("1111");
address++;
break;
default:
// TODO: Throw exception, if no mnemonic matched!
}
}
}
writer.close();
scannerTwo.close();
scannerOne.close();
}
public static String regToBin(String register) {
String output;
switch(register) {
case "R0":
output = "0000";
break;
case "R1":
output = "0001";
break;
case "R2":
output = "0010";
break;
case "R3":
output = "0011";
break;
case "R4":
output = "0100";
break;
case "R5":
output = "0101";
break;
case "R6":
output = "0110";
break;
case "R7":
output = "0111";
break;
case "R8":
output = "1000";
break;
case "R9":
output = "1001";
break;
case "R10":
output = "1010";
break;
case "R11":
output = "1011";
break;
case "R12":
output = "1100";
break;
case "R13":
output = "1101";
break;
case "R14":
output = "1110";
break;
case "R15":
output = "1111";
break;
default:
// TODO: Throw exception, if no register matched!
output = "0000";
}
return output;
}
public static String hexToBin(String s) {
String hex = "";
if(s.startsWith("0x")) {
hex = s.substring(2, s.length());
}
if(s.startsWith("$")) {
hex = s.substring(1, s.length());
}
String bitstring = new BigInteger(hex, 16).toString(2);
StringBuffer extended = new StringBuffer(bitstring);
for(int i = bitstring.length(); i < 4; i++) {
extended.insert(0, "0");
}
return extended.toString();
}
public static void writeALUOp(String opCo, String rX, String rY) throws IOException {
writer.append(opCo);
writer.append(regToBin(rY));
writer.append(regToBin(rX));
writer.append("\n");
}
public static void writeShiftOp(String opCo, String rX, String rY) throws IOException {
writer.append(opCo);
writer.append(regToBin(rY));
writer.append(regToBin(rX));
writer.append("\n");
}
public static void writeCompOp(String opCo, String rX, String rY) throws IOException {
writer.append(opCo);
writer.append(regToBin(rY));
writer.append(regToBin(rX));
writer.append("\n");
}
public static void writeImmOp(String opCo, String rX, String imm) throws IOException {
writer.append(opCo);
writer.append(hexToBin(imm));
writer.append(regToBin(rX));
writer.append("\n");
}
public static void writeMemOp(String opCo, String rX, String rY, String offsetHex) throws IOException {
String offsetBin = hexToBin(offsetHex);
int offsetInt = Integer.parseInt(offsetBin, 2);
if((offsetInt % 2) == 1 ) {
// TODO: Throw exception, if invalid address is addressed!
}
if(offsetInt > 30) {
// TODO: Throw exception, if invalid address is addressed!
}
String offset = offsetBin.substring(0, offsetBin.length()-1);
StringBuffer extended = new StringBuffer(offset);
for(int i = offset.length(); i < 4; i++) {
extended.insert(0, "0");
}
String jumpAddressBinFixedLength = extended.toString();
writer.append(opCo);
writer.append(jumpAddressBinFixedLength);
writer.append(regToBin(rY));
writer.append(regToBin(rX));
writer.append("\n");
}
// TODO Throw exception, if label is not in jumpAddressList!
public static void writeControlFlowOp(String opCo, String label, int address) throws IOException {
// PC = PC + 2 + imm12
int byteAddress = 2 * (address + 1);
int labelAddress = 0;
for(int i = 0; i < jumpAddressList.size(); i++) {
if(jumpAddressList.get(i).getLabel().equals(label)) {
labelAddress = jumpAddressList.get(i).getAddress();
break;
}
}
int jumpAddressInt = labelAddress - byteAddress;
String jumpAddressBin = Integer.toBinaryString(jumpAddressInt);
String jumpAddressBinFixedLength;
if(jumpAddressInt < 0) {
jumpAddressBinFixedLength = jumpAddressBin.substring(jumpAddressBin.length()-12, jumpAddressBin.length());
} else {
StringBuffer extended = new StringBuffer(jumpAddressBin);
for(int i = jumpAddressBin.length(); i < 12; i++) {
extended.insert(0, "0");
}
jumpAddressBinFixedLength = extended.toString();
}
writer.append(opCo);
writer.append(jumpAddressBinFixedLength);
writer.append("\n");
}
public static void writeJMPOp(String opCo, String rX) throws IOException {
writer.append(opCo);
writer.append("00000000");
writer.append(regToBin(rX));
writer.append("\n");
}
public static void writeHALTOp(String opCo) throws IOException {
writer.append(opCo);
writer.append("000000000000");
writer.append("\n");
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment