#include <iostream> #include <iomanip> #include <fstream> #include <string> #include <sstream> #include "Assembler.h" using namespace std; Assembler::Assembler() { } int Assembler::assemble(fstream& in, fstream& out) { string line; string opcode; int rd, rs, addr, constant; int instruction; const int success = false; const int error = true; //const int debug = false; getline(in, line); while (!in.eof()) { if (line[0] == '!' or line == "") { // ignore comment or empty lines getline(in, line); continue; } istringstream str(line.c_str()); str >> opcode; if (opcode == "load") { str >> rd >> addr; if (rd < 0 || rd > 3) return error; if (addr < 0 || addr > 255) return error; instruction = 0; instruction = instruction | rd<<9 | addr; } else if (opcode == "loadi") { str >> rd >> constant; if (rd < 0 || rd > 3) return error; if (constant < -128 || constant > 127) return error; instruction = 0; instruction = instruction | rd<<9 | 1<<8 | (0xff & constant); } else if (opcode == "store") { str >> rd >> addr; if (rd < 0 || rd > 3) return error; if (addr < 0 || addr > 255) return error; instruction = 1; instruction = instruction<<11 | rd<<9 | 1<<8 | addr; } else if (opcode == "add") { str >> rd >> rs; if (rd < 0 || rd > 3) return error; if (rs < 0 || rs > 3) return error; instruction = 2; instruction = instruction<<11 | rd<<9 | rs<<6; } else if (opcode == "addi") { str >> rd >> constant; if (rd < 0 || rd > 3) return error; if (constant < -128 || constant > 127) return error; instruction = 2; instruction = instruction<<11 | rd<<9 | 1<<8 | (0xff & constant); } else if (opcode == "addc") { str >> rd >> rs; if (rd < 0 || rd > 3) return error; if (rs < 0 || rs > 3) return error; instruction = 3; instruction = instruction<<11 | rd<<9 | rs<<6; } else if (opcode == "addci") { str >> rd >> constant; if (rd < 0 || rd > 3) return error; if (constant < -128 || constant > 127) return error; instruction = 3; instruction = instruction<<11 | rd<<9 | 1<<8 | (0xff & constant); } else if (opcode == "sub") { str >> rd >> rs; if (rd < 0 || rd > 3) return error; if (rs < 0 || rs > 3) return error; instruction = 4; instruction = instruction<<11 | rd<<9 | rs<<6; } else if (opcode == "subi") { str >> rd >> constant; if (rd < 0 || rd > 3) return error; if (constant < -128 || constant > 127) return error; instruction = 4; instruction = instruction<<11 | rd<<9 | 1<<8 | (0xff & constant); } else if (opcode == "subc") { str >> rd >> rs; if (rd < 0 || rd > 3) return error; if (rs < 0 || rs > 3) return error; instruction = 5; instruction = instruction<<11 | rd<<9 | rs<<6; } else if (opcode == "subci") { str >> rd >> constant; if (rd < 0 || rd > 3) return error; if (constant < -128 || constant > 127) return error; instruction = 5; instruction = instruction<<11 | rd<<9 | 1<<8 | (0xff & constant); } else if (opcode == "and") { str >> rd >> rs; if (rd < 0 || rd > 3) return error; if (rs < 0 || rs > 3) return error; instruction = 6; instruction = instruction<<11 | rd<<9 | rs<<6; } else if (opcode == "andi") { str >> rd >> constant; if (rd < 0 || rd > 3) return error; if (constant < -128 || constant > 127) return error; instruction = 6; instruction = instruction<<11 | rd<<9 | 1<<8 | (0xff & constant); } else if (opcode == "xor") { str >> rd >> rs; if (rd < 0 || rd > 3) return error; if (rs < 0 || rs > 3) return error; instruction = 7; instruction = instruction<<11 | rd<<9 | rs<<6; } else if (opcode == "xori") { str >> rd >> constant; if (rd < 0 || rd > 3) return error; if (constant < -128 || constant > 127) return error; instruction = 7; instruction = instruction<<11 | rd<<9 | 1<<8 | (0xff & constant); } else if (opcode == "compl") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 8; instruction = instruction<<11 | rd<<9; } else if (opcode == "shl") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 9; instruction = instruction<<11 | rd<<9; } else if (opcode == "shla") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 10; instruction = instruction<<11 | rd<<9; } else if (opcode == "shr") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 11; instruction = instruction<<11 | rd<<9; } else if (opcode == "shra") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 12; instruction = instruction<<11 | rd<<9; } else if (opcode == "compr") { str >> rd >> rs; if (rd < 0 || rd > 3) return error; if (rs < 0 || rs > 3) return error; instruction = 13; instruction = instruction<<11 | rd<<9 | rs<<6; } else if (opcode == "compri") { str >> rd >> constant; if (rd < 0 || rd > 3) return error; if (constant < -128 || constant > 127) return error; instruction = 13; instruction = instruction<<11 | rd<<9 | 1<<8 | (0xff & constant); } else if (opcode == "getstat") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 14; instruction = instruction<<11 | rd<<9; } else if (opcode == "putstat") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 15; instruction = instruction<<11 | rd<<9; } else if (opcode == "jump") { str >> addr; if (addr < 0 || addr > 255) return error; instruction = 16; instruction = instruction<<11 | 1<<8 | addr; } else if (opcode == "jumpl") { str >> addr; if (addr < 0 || addr > 255) return error; instruction = 17; instruction = instruction<<11 | 1<<8 |addr; } else if (opcode == "jumpe") { str >> addr; if (addr < 0 || addr > 255) return error; instruction = 18; instruction = instruction<<11 | 1<<8 |addr; } else if (opcode == "jumpg") { str >> addr; if (addr < 0 || addr > 255) return error; instruction = 19; instruction = instruction<<11 | 1<<8 |addr; } else if (opcode == "call") { str >> addr; if (addr < 0 || addr > 255) return error; instruction = 20; instruction = instruction<<11 | 1<<8 |addr; } else if (opcode == "return") { instruction = 21; instruction = instruction<<11; } else if (opcode == "read") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 22; instruction = instruction<<11 | rd<<9; } else if (opcode == "write") { str >> rd; if (rd < 0 || rd > 3) return error; instruction = 23; instruction = instruction<<11 | rd<<9; } else if (opcode == "halt") { instruction = 24; instruction = instruction<<11; } else if (opcode == "noop") { instruction = 25; instruction = instruction<<11; } else return error; out << setfill('0') << setw(5) << instruction << endl; getline(in, line); } return success; } // assemble