123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531 |
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package tools.mips;
- import API.Instruction;
- import API.Utils;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import target.mips.Mips;
- /**
- *
- * @author EUGENIO CARVALHO
- */
- public class MipsProcessor {
- public MipsSettings settings;
- public Memory MD;
- public Memory MI;
- public long PC = 0;
- public RegisterBank RBank;
- public HashMap<String, Instruction> instructions;
- public MipsProcessor(MipsSettings settings) throws IOException {
- this.settings = settings;
- MI = new Memory(settings.Get("mi"), 4096, false);
- MD = new Memory(settings.Get("md"), 4096, true);
- MD.AllAddress = true;
- RBank = new RegisterBank(32);
- InitInstructions();
- // InitInstructions2();
- }
- public MipsProcessor Persist() {
- MD.Save();
- return this;
- }
- public MipsProcessor Run() {
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- // Fetch
- // System.out.println("MI:" + MI);
- try {
- Instruction instruction;
- int i = 0;
- while (true) {
- long inst = MI.R(PC);
- instruction = Decode(inst);
- if (instruction.eq("inst", "stop")) {
- break;
- }
- System.out.println("Interation(" + (i++) + ")["
- + Integer.toHexString((int) PC) + "]"
- + instruction.G("inst"));
- Execute(instruction);
- System.out.println("Registradores(\n" + RBank
- + ")\b nextPC:" + Integer.toHexString((int) PC));
- br.readLine();
- // Decode
- // Exec
- // Persist
- } // return true;
- } catch (Exception ex) {
- Logger.getLogger(MipsProcessor.class.getName()).log(Level.SEVERE, null, ex);
- }
- return this;
- }
- public Instruction Decode(long instruction) {
- int val = (int) instruction;
- String bin = Utils.pad(32, Integer.toBinaryString(val));
- // System.out.println("Run:" + bin + ":" + bin.length());
- String codop = bin.substring(0, 6), key, func = "";
- if (codop.equals("000000")) {
- func = bin.substring(26);
- key = "@" + func;
- } else {
- key = codop;
- }
- // System.out.println(">>: "
- // // + "\n" + instruction
- // + "\n" + bin
- // // // + "\n" + val
- // // + "\nKey:" + key
- // + "\n" + instructions.get(key));
- if (!instructions.containsKey(key)) {
- System.out.println("Não encontrou a instrução " + key);
- return null;
- }
- Instruction i = instructions.get(key).copy();
- String rs = bin.substring(6, 11),
- rt = bin.substring(11, 16);
- switch (i.G("type")) {
- case "R":
- i.S("rs.bin", rs);
- i.S("rt.bin", rt);
- i.S("rd.bin", bin.substring(16, 21));
- i.S("shamt.bin", bin.substring(21, 26));
- i.S("funct.bin", func);
- i.S("rs", Long.parseLong(rs, 2));
- i.S("rt", Long.parseLong(rt, 2));
- i.S("rd", Long.parseLong(bin.substring(16, 21), 2));
- i.S("shamt", Long.parseLong(bin.substring(21, 26), 2));
- i.S("funct", func);
- break;
- case "I":
- i.S("rs.bin", rs);
- i.S("rt.bin", rt);
- i.S("imm.bin", bin.substring(16));
- i.S("rs", Long.parseLong(rs, 2));
- i.S("rt", Long.parseLong(rt, 2));
- i.S("imm", bin32ToDec(bin.substring(16)));
- // System.out.println("II:" + bin.substring(16)
- // + "\n:" + bin32ToDec(Utils.padPreserveSignal(32, bin.substring(16)))
- // + "\n:" + (Long.parseLong(Utils.padPreserveSignal(32, bin.substring(16)), 2) >> 0)
- // );
- // System.out.println("IIII:" + bin32ToDec(bin.substring(16)));
- break;
- case "J":
- i.S("addr.bin", bin.substring(6));
- i.S("imm", bin32ToDec(bin.substring(6)));
- // System.out.println("JJJJ:" + bin32ToDec(bin.substring(6)));
- }
- return i;
- }
- public static long bin32ToDec(String bin) {
- bin = Utils.padPreserveSignal(32, bin);
- // System.out.println("BIN32DEC:" + bin);
- if (bin.charAt(0) == '0') {
- return Long.parseLong(bin, 2);
- } else {
- long number = 0;
- for (int index = 0; index < 32; index++) {
- int b = bin.charAt(index) - '0';
- number = number << 1 | b;
- }
- return (int) number;
- }
- }
- public String IntToHexStr(Integer n) {
- return IntToHexStr(n) + "";
- }
- public Integer IntToHex(Integer n) {
- return Integer.valueOf(String.valueOf(n), 16);
- }
- protected void InitInstructions() {
- instructions = new HashMap<String, Instruction>();
- String key;
- for (Map.Entry<String, Instruction> entry : Mips.Codops.entrySet()) {
- // String string = entry.getKey();
- Instruction instruction = entry.getValue();
- key = instruction.G("codop");
- if (instruction.eq("codop", "000000")) {
- key = "@" + instruction.G("func");
- }
- // System.out.println("Add_Instruction: " + key + "\n");
- // System.out.println("===" + entry.getKey());
- instructions.put(key, instruction);
- };
- }
- private void Execute(Instruction inst) throws Exception {
- // System.out.println("Exec :" + inst);
- long rs = 0,
- rt = 0,
- imm = 0,
- rd = 0,
- shamt = 0;
- boolean hasImm = true;
- switch (inst.G("type")) {
- case "R":
- rd = inst.getInt("rd");
- shamt = inst.getInt("shamt");
- hasImm = false;
- case "I":
- rs = inst.getInt("rs");
- rt = inst.getInt("rt");
- case "J":
- if (hasImm) {
- // System.out.println("HAS_IMM:" + inst.G("imm"));
- imm = inst.getLong("imm");
- }
- }
- System.out.println(inst.G("inst") + " [rd:" + rd + "] [rs:" + rs + "] [rt:" + rt + "] [shamt:" + shamt + "] [imm:" + imm + "]");
- switch (inst.G("inst")) {
- // R
- case "add":
- case "addu":
- RBank.W(rd, RBank.R(rs) + RBank.R(rt));
- break;
- case "addi":
- case "addiu":
- // System.out.println("RBank.R(rs) + imm:" + RBank.R(rs) + ":" + imm);
- RBank.W(rt, RBank.R(rs) + imm);
- break;
- case "stop":
- break;
- case "and":
- case "andi":
- RBank.W(rd, RBank.R(rs) & RBank.R(rt));
- break;
- case "div":
- case "divu":
- RBank.W(RBank.REG_LO, RBank.R(rs) / RBank.R(rt));
- RBank.W(RBank.REG_HI, RBank.R(rs) % RBank.R(rt));
- break;
- case "jr":
- PC = RBank.R(rs);
- break;
- case "mfhi":
- RBank.W(rd, RBank.R(RBank.REG_HI));
- break;
- case "mflo":
- RBank.W(rd, RBank.R(RBank.REG_LO));
- break;
- case "mthi":
- RBank.W(RBank.R(RBank.REG_HI), RBank.R(rs));
- break;
- case "mtlo":
- RBank.W(RBank.R(RBank.REG_LO), RBank.R(rs));
- break;
- case "mult":
- case "multu":
- // verificar a questao do hi e lo
- RBank.W(RBank.R(RBank.REG_LO), RBank.R(rs) * RBank.R(rt));
- break;
- // case "nor":
- // RBank.W(rd, rs * rt);
- // break;
- case "or":
- RBank.W(rd, RBank.R(rs) | RBank.R(rt));
- break;
- case "sll":
- RBank.W(rd, RBank.R(rt) << shamt);
- break;
- case "slt":
- RBank.W(rd, (RBank.R(rs) < RBank.R(rt)) ? 1 : 0);
- break;
- case "sra":
- RBank.W(rd, RBank.R(rt) >> shamt);
- break;
- case "srl":
- RBank.W(rd, RBank.R(rt) >>> shamt);
- break;
- case "sub":
- case "subu":
- RBank.W(rd, RBank.R(rs) - RBank.R(rt));
- break;
- case "xor":
- RBank.W(rd, RBank.R(rs) ^ RBank.R(rt));
- break;
- // // I
- case "beq":
- if (RBank.R(rs) == RBank.R(rt)) {
- PC += imm << 2;
- return;
- }
- break;
- case "bgez":
- if (RBank.R(rs) >= RBank.R(rt)) {
- PC += imm << 2;
- return;
- }
- break;
- case "bgtz":
- if (RBank.R(rs) > 0) {
- PC += imm << 2;
- return;
- }
- break;
- case "blez":
- if (RBank.R(rs) <= 0) {
- PC += imm << 2;
- return;
- }
- break;
- case "bltz":
- if (RBank.R(rs) < 0) {
- PC += imm << 2;
- return;
- }
- break;
- case "bne":
- if (RBank.R(rs) != RBank.R(rt)) {
- PC += imm << 2;
- return;
- }
- break;
- // case "lb":
- // if (RBank.R(rs) != RBank.R(rt)) {
- // PC += imm << 2;
- // return;
- // }
- // case "lbu":
- // case "lh":
- // case "lhu":
- case "lui":
- RBank.W(rt, imm);
- break;
- case "lw":
- RBank.W(rt, MD.R(RBank.R(rs) + imm));
- System.out.printf("Load endereco '%d'\n", RBank.R(rs) + imm);
- break;
- // case "ori":
- // break;
- case "slti":
- // case "sltiu":
- case "sw":
- System.out.printf("Store '%d' no endereco '%d'\n", RBank.R(rt), RBank.R(rs) + imm);
- MD.W(RBank.R(rs) + imm, RBank.R(rt));
- break;
- // case "xori":
- // J
- case "jal":
- RBank.W(31, PC);
- case "j":
- PC = imm;
- return;
- default:
- throw new Exception("Instrução " + inst.G("inst") + " não definida!");
- }
- PC += 4;
- }
- }
- // protected void InitInstructions2() {
- // HashMap<String, Integer> x = new HashMap<String, Integer>();
- // //Constantes da instruções (Codop e Funct)
- // x.put("FUNCT_ADD", 32);
- // x.put("FUNCT_ADDU", 33);
- // x.put("FUNCT_SUB", 34);
- // x.put("FUNCT_SUBU", 35);
- // x.put("FUNCT_MULT", 24);
- // x.put("FUNCT_MULTU", 25);
- // x.put("FUNCT_AND", 36);
- // x.put("FUNCT_OR", 37);
- // x.put("FUNCT_XOR", 38);
- // x.put("FUNCT_NOR", 39);
- // x.put("FUNCT_DIV", 26);
- // x.put("FUNCT_DIVU", 27);
- // x.put("FUNCT_SLT", 42);
- //
- // x.put("FUNCT_SRL", 2);
- // x.put("FUNCT_SLL", 0);
- // x.put("FUNCT_SRA", 3);
- // x.put("FUNCT_SRLV", 6);
- // x.put("FUNCT_SLLV", 4);
- // x.put("FUNCT_SRAV", 7);
- //
- // x.put("FUNCT_MFHI", 16);
- // x.put("FUNCT_MFLO", 18);
- // x.put("FUNCT_JR", 8);
- //
- // x.put("FUNCT_NOP", 63);
- // x.put("NOP", 63);
- //
- ////Constante dos CODOPs
- // x.put("CODOP_ADDI", 8);
- // x.put("CODOP_ADDIU", 9);
- // x.put("CODOP_SLTI", 10);
- // x.put("CODOP_SLTIU", 11);
- // x.put("CODOP_ANDI", 12);
- // x.put("CODOP_ORI", 13);
- // x.put("CODOP_LUI", 15);
- //
- // x.put("CODOP_LB", 32);
- // x.put("CODOP_LH", 33);
- // x.put("CODOP_LW", 35);
- // x.put("CODOP_LBU", 36);
- // x.put("CODOP_LHU", 37);
- // x.put("CODOP_SB", 40);
- // x.put("CODOP_SH", 41);
- // x.put("CODOP_SW", 43);
- //
- // x.put("CODOP_BGEZ", 1);
- // x.put("CODOP_BEQ", 4);
- // x.put("CODOP_BNE", 5);
- // x.put("CODOP_BGTZ", 7);
- //
- // x.put("CODOP_JUMP", 2);
- // x.put("CODOP_JAL", 3);
- //
- // x.put("CODOP_STOP", 63);
- ////Constante das operações da ULA
- // x.put("SOMA", 1);
- // x.put("SUBTRACAO", 2);
- // x.put("MULTIPLICACAO", 3);
- // x.put("AND", 4);
- // x.put("OR", 5);
- // x.put("XOR", 6);
- // x.put("NOR", 7);
- // x.put("DIVISAO", 8);
- // x.put("SLT", 9);
- // x.put("SLTU", 10);
- // x.put("LUI", 11);
- //
- // x.put("SRL", 12); //Faz o shift usando o campo shamt
- // x.put("SLL", 13); //Faz o shift usando o campo shamt
- // x.put("SRA", 14); //Faz o shift usando o campo shamt
- //
- // x.put("SRLV", 15); //Faz o shift usando registrador
- // x.put("SLLV", 16); //Faz o shift usando registrador
- // x.put("SRAV", 17); //Faz o shift usando registrador
- // x.put("MOVE", 18);
- //
- // for (Map.Entry<String, Integer> entry : x.entrySet()) {
- // String string = entry.getKey();
- // System.out.println(string + ":" + Utils.pad(6, Integer.toBinaryString(entry.getValue())));
- // }
- // }
- //CODOP_JUMP:000010
- //CODOP_LBU:100100
- //NOP:111111
- //CODOP_STOP:111111
- //FUNCT_DIVU:011011
- //CODOP_LH:100001
- //MULTIPLICACAO:000011
- //SRLV:001111
- //NOR:000111
- //SLL:001101
- //FUNCT_SRA:000011
- //CODOP_ANDI:001100
- //AND:000100
- //FUNCT_SRL:000010
- //CODOP_ORI:001101
- //SRAV:010001
- //SLT:001001
- //SUBTRACAO:000010
- //CODOP_LW:100011
- //FUNCT_ADD:100000
- //SOMA:000001
- //FUNCT_MULTU:011001
- //CODOP_SLTI:001010
- //SLLV:010000
- //SLTU:001010
- //FUNCT_MULT:011000
- //CODOP_ADDIU:001001
- //LUI:001011
- //CODOP_SH:101001
- //XOR:000110
- //FUNCT_MFLO:010010
- //FUNCT_SRAV:000111
- //DIVISAO:001000
- //SRL:001100
- //SRA:001110
- //CODOP_SB:101000
- //CODOP_ADDI:001000
- //FUNCT_JR:001000
- //FUNCT_MFHI:010000
- //FUNCT_NOR:100111
- //FUNCT_NOP:111111
- //FUNCT_SUBU:100011
- //FUNCT_OR:100101
- //FUNCT_AND:100100
- //FUNCT_XOR:100110
- //FUNCT_DIV:011010
- //FUNCT_SRLV:000110
- //FUNCT_ADDU:100001
- //CODOP_LUI:001111
- //CODOP_BGEZ:000001
- //MOVE:010010
- //CODOP_SLTIU:001011
- //CODOP_JAL:000011
- //OR:000101
- //CODOP_SW:101011
- //FUNCT_SUB:100010
- //FUNCT_SLLV:000100
- //CODOP_LB:100000
- //CODOP_BNE:000101
- //FUNCT_SLL:000000
- //CODOP_LHU:100101
- //CODOP_BGTZ:000111
- //CODOP_BEQ:000100
- //FUNCT_SLT:101010
- /*
- 1652044928
- 1100010011110000011010010000000
- 1100010011110000011010010000000
- 011000 10011110000011010010000000
- 011000
- 596080229
- 00100011100001110111011001100101 - js
- 100011100001110111011001100101
-
- c
- 10010110000010000000001000101001
- */
- //1652044928 -> 01010010000001000100100100101000 ->
- //0: 0062783480 addiu sp,sp,-8
|