MipsProcessor.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package tools.mips;
  7. import API.Instruction;
  8. import API.Utils;
  9. import java.io.BufferedReader;
  10. import java.io.IOException;
  11. import java.io.InputStreamReader;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. import java.util.logging.Level;
  15. import java.util.logging.Logger;
  16. import target.mips.Mips;
  17. /**
  18. *
  19. * @author EUGENIO CARVALHO
  20. */
  21. public class MipsProcessor {
  22. public MipsSettings settings;
  23. public Memory MD;
  24. public Memory MI;
  25. public long PC = 0;
  26. public RegisterBank RBank;
  27. public HashMap<String, Instruction> instructions;
  28. public MipsProcessor(MipsSettings settings) throws IOException {
  29. this.settings = settings;
  30. MI = new Memory(settings.Get("mi"), 4096, false);
  31. MD = new Memory(settings.Get("md"), 4096, true);
  32. MD.AllAddress = true;
  33. RBank = new RegisterBank(32);
  34. InitInstructions();
  35. // InitInstructions2();
  36. }
  37. public MipsProcessor Persist() {
  38. MD.Save();
  39. return this;
  40. }
  41. public MipsProcessor Run() {
  42. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  43. // Fetch
  44. // System.out.println("MI:" + MI);
  45. try {
  46. Instruction instruction;
  47. int i = 0;
  48. while (true) {
  49. long inst = MI.R(PC);
  50. instruction = Decode(inst);
  51. if (instruction.eq("inst", "stop")) {
  52. break;
  53. }
  54. System.out.println("Interation(" + (i++) + ")["
  55. + Integer.toHexString((int) PC) + "]"
  56. + instruction.G("inst"));
  57. Execute(instruction);
  58. System.out.println("Registradores(\n" + RBank
  59. + ")\b nextPC:" + Integer.toHexString((int) PC));
  60. br.readLine();
  61. // Decode
  62. // Exec
  63. // Persist
  64. } // return true;
  65. } catch (Exception ex) {
  66. Logger.getLogger(MipsProcessor.class.getName()).log(Level.SEVERE, null, ex);
  67. }
  68. return this;
  69. }
  70. public Instruction Decode(long instruction) {
  71. int val = (int) instruction;
  72. String bin = Utils.pad(32, Integer.toBinaryString(val));
  73. // System.out.println("Run:" + bin + ":" + bin.length());
  74. String codop = bin.substring(0, 6), key, func = "";
  75. if (codop.equals("000000")) {
  76. func = bin.substring(26);
  77. key = "@" + func;
  78. } else {
  79. key = codop;
  80. }
  81. // System.out.println(">>: "
  82. // // + "\n" + instruction
  83. // + "\n" + bin
  84. // // // + "\n" + val
  85. // // + "\nKey:" + key
  86. // + "\n" + instructions.get(key));
  87. if (!instructions.containsKey(key)) {
  88. System.out.println("Não encontrou a instrução " + key);
  89. return null;
  90. }
  91. Instruction i = instructions.get(key).copy();
  92. String rs = bin.substring(6, 11),
  93. rt = bin.substring(11, 16);
  94. switch (i.G("type")) {
  95. case "R":
  96. i.S("rs.bin", rs);
  97. i.S("rt.bin", rt);
  98. i.S("rd.bin", bin.substring(16, 21));
  99. i.S("shamt.bin", bin.substring(21, 26));
  100. i.S("funct.bin", func);
  101. i.S("rs", Long.parseLong(rs, 2));
  102. i.S("rt", Long.parseLong(rt, 2));
  103. i.S("rd", Long.parseLong(bin.substring(16, 21), 2));
  104. i.S("shamt", Long.parseLong(bin.substring(21, 26), 2));
  105. i.S("funct", func);
  106. break;
  107. case "I":
  108. i.S("rs.bin", rs);
  109. i.S("rt.bin", rt);
  110. i.S("imm.bin", bin.substring(16));
  111. i.S("rs", Long.parseLong(rs, 2));
  112. i.S("rt", Long.parseLong(rt, 2));
  113. i.S("imm", bin32ToDec(bin.substring(16)));
  114. // System.out.println("II:" + bin.substring(16)
  115. // + "\n:" + bin32ToDec(Utils.padPreserveSignal(32, bin.substring(16)))
  116. // + "\n:" + (Long.parseLong(Utils.padPreserveSignal(32, bin.substring(16)), 2) >> 0)
  117. // );
  118. // System.out.println("IIII:" + bin32ToDec(bin.substring(16)));
  119. break;
  120. case "J":
  121. i.S("addr.bin", bin.substring(6));
  122. i.S("imm", bin32ToDec(bin.substring(6)));
  123. // System.out.println("JJJJ:" + bin32ToDec(bin.substring(6)));
  124. }
  125. return i;
  126. }
  127. public static long bin32ToDec(String bin) {
  128. bin = Utils.padPreserveSignal(32, bin);
  129. // System.out.println("BIN32DEC:" + bin);
  130. if (bin.charAt(0) == '0') {
  131. return Long.parseLong(bin, 2);
  132. } else {
  133. long number = 0;
  134. for (int index = 0; index < 32; index++) {
  135. int b = bin.charAt(index) - '0';
  136. number = number << 1 | b;
  137. }
  138. return (int) number;
  139. }
  140. }
  141. public String IntToHexStr(Integer n) {
  142. return IntToHexStr(n) + "";
  143. }
  144. public Integer IntToHex(Integer n) {
  145. return Integer.valueOf(String.valueOf(n), 16);
  146. }
  147. protected void InitInstructions() {
  148. instructions = new HashMap<String, Instruction>();
  149. String key;
  150. for (Map.Entry<String, Instruction> entry : Mips.Codops.entrySet()) {
  151. // String string = entry.getKey();
  152. Instruction instruction = entry.getValue();
  153. key = instruction.G("codop");
  154. if (instruction.eq("codop", "000000")) {
  155. key = "@" + instruction.G("func");
  156. }
  157. // System.out.println("Add_Instruction: " + key + "\n");
  158. // System.out.println("===" + entry.getKey());
  159. instructions.put(key, instruction);
  160. };
  161. }
  162. private void Execute(Instruction inst) throws Exception {
  163. // System.out.println("Exec :" + inst);
  164. long rs = 0,
  165. rt = 0,
  166. imm = 0,
  167. rd = 0,
  168. shamt = 0;
  169. boolean hasImm = true;
  170. switch (inst.G("type")) {
  171. case "R":
  172. rd = inst.getInt("rd");
  173. shamt = inst.getInt("shamt");
  174. hasImm = false;
  175. case "I":
  176. rs = inst.getInt("rs");
  177. rt = inst.getInt("rt");
  178. case "J":
  179. if (hasImm) {
  180. // System.out.println("HAS_IMM:" + inst.G("imm"));
  181. imm = inst.getLong("imm");
  182. }
  183. }
  184. System.out.println(inst.G("inst") + " [rd:" + rd + "] [rs:" + rs + "] [rt:" + rt + "] [shamt:" + shamt + "] [imm:" + imm + "]");
  185. switch (inst.G("inst")) {
  186. // R
  187. case "add":
  188. case "addu":
  189. RBank.W(rd, RBank.R(rs) + RBank.R(rt));
  190. break;
  191. case "addi":
  192. case "addiu":
  193. // System.out.println("RBank.R(rs) + imm:" + RBank.R(rs) + ":" + imm);
  194. RBank.W(rt, RBank.R(rs) + imm);
  195. break;
  196. case "stop":
  197. break;
  198. case "and":
  199. case "andi":
  200. RBank.W(rd, RBank.R(rs) & RBank.R(rt));
  201. break;
  202. case "div":
  203. case "divu":
  204. RBank.W(RBank.REG_LO, RBank.R(rs) / RBank.R(rt));
  205. RBank.W(RBank.REG_HI, RBank.R(rs) % RBank.R(rt));
  206. break;
  207. case "jr":
  208. PC = RBank.R(rs);
  209. break;
  210. case "mfhi":
  211. RBank.W(rd, RBank.R(RBank.REG_HI));
  212. break;
  213. case "mflo":
  214. RBank.W(rd, RBank.R(RBank.REG_LO));
  215. break;
  216. case "mthi":
  217. RBank.W(RBank.R(RBank.REG_HI), RBank.R(rs));
  218. break;
  219. case "mtlo":
  220. RBank.W(RBank.R(RBank.REG_LO), RBank.R(rs));
  221. break;
  222. case "mult":
  223. case "multu":
  224. // verificar a questao do hi e lo
  225. RBank.W(RBank.R(RBank.REG_LO), RBank.R(rs) * RBank.R(rt));
  226. break;
  227. // case "nor":
  228. // RBank.W(rd, rs * rt);
  229. // break;
  230. case "or":
  231. RBank.W(rd, RBank.R(rs) | RBank.R(rt));
  232. break;
  233. case "sll":
  234. RBank.W(rd, RBank.R(rt) << shamt);
  235. break;
  236. case "slt":
  237. RBank.W(rd, (RBank.R(rs) < RBank.R(rt)) ? 1 : 0);
  238. break;
  239. case "sra":
  240. RBank.W(rd, RBank.R(rt) >> shamt);
  241. break;
  242. case "srl":
  243. RBank.W(rd, RBank.R(rt) >>> shamt);
  244. break;
  245. case "sub":
  246. case "subu":
  247. RBank.W(rd, RBank.R(rs) - RBank.R(rt));
  248. break;
  249. case "xor":
  250. RBank.W(rd, RBank.R(rs) ^ RBank.R(rt));
  251. break;
  252. // // I
  253. case "beq":
  254. if (RBank.R(rs) == RBank.R(rt)) {
  255. PC += imm << 2;
  256. return;
  257. }
  258. break;
  259. case "bgez":
  260. if (RBank.R(rs) >= RBank.R(rt)) {
  261. PC += imm << 2;
  262. return;
  263. }
  264. break;
  265. case "bgtz":
  266. if (RBank.R(rs) > 0) {
  267. PC += imm << 2;
  268. return;
  269. }
  270. break;
  271. case "blez":
  272. if (RBank.R(rs) <= 0) {
  273. PC += imm << 2;
  274. return;
  275. }
  276. break;
  277. case "bltz":
  278. if (RBank.R(rs) < 0) {
  279. PC += imm << 2;
  280. return;
  281. }
  282. break;
  283. case "bne":
  284. if (RBank.R(rs) != RBank.R(rt)) {
  285. PC += imm << 2;
  286. return;
  287. }
  288. break;
  289. // case "lb":
  290. // if (RBank.R(rs) != RBank.R(rt)) {
  291. // PC += imm << 2;
  292. // return;
  293. // }
  294. // case "lbu":
  295. // case "lh":
  296. // case "lhu":
  297. case "lui":
  298. RBank.W(rt, imm);
  299. break;
  300. case "lw":
  301. RBank.W(rt, MD.R(RBank.R(rs) + imm));
  302. System.out.printf("Load endereco '%d'\n", RBank.R(rs) + imm);
  303. break;
  304. // case "ori":
  305. // break;
  306. case "slti":
  307. // case "sltiu":
  308. case "sw":
  309. System.out.printf("Store '%d' no endereco '%d'\n", RBank.R(rt), RBank.R(rs) + imm);
  310. MD.W(RBank.R(rs) + imm, RBank.R(rt));
  311. break;
  312. // case "xori":
  313. // J
  314. case "jal":
  315. RBank.W(31, PC);
  316. case "j":
  317. PC = imm;
  318. return;
  319. default:
  320. throw new Exception("Instrução " + inst.G("inst") + " não definida!");
  321. }
  322. PC += 4;
  323. }
  324. }
  325. // protected void InitInstructions2() {
  326. // HashMap<String, Integer> x = new HashMap<String, Integer>();
  327. // //Constantes da instruções (Codop e Funct)
  328. // x.put("FUNCT_ADD", 32);
  329. // x.put("FUNCT_ADDU", 33);
  330. // x.put("FUNCT_SUB", 34);
  331. // x.put("FUNCT_SUBU", 35);
  332. // x.put("FUNCT_MULT", 24);
  333. // x.put("FUNCT_MULTU", 25);
  334. // x.put("FUNCT_AND", 36);
  335. // x.put("FUNCT_OR", 37);
  336. // x.put("FUNCT_XOR", 38);
  337. // x.put("FUNCT_NOR", 39);
  338. // x.put("FUNCT_DIV", 26);
  339. // x.put("FUNCT_DIVU", 27);
  340. // x.put("FUNCT_SLT", 42);
  341. //
  342. // x.put("FUNCT_SRL", 2);
  343. // x.put("FUNCT_SLL", 0);
  344. // x.put("FUNCT_SRA", 3);
  345. // x.put("FUNCT_SRLV", 6);
  346. // x.put("FUNCT_SLLV", 4);
  347. // x.put("FUNCT_SRAV", 7);
  348. //
  349. // x.put("FUNCT_MFHI", 16);
  350. // x.put("FUNCT_MFLO", 18);
  351. // x.put("FUNCT_JR", 8);
  352. //
  353. // x.put("FUNCT_NOP", 63);
  354. // x.put("NOP", 63);
  355. //
  356. ////Constante dos CODOPs
  357. // x.put("CODOP_ADDI", 8);
  358. // x.put("CODOP_ADDIU", 9);
  359. // x.put("CODOP_SLTI", 10);
  360. // x.put("CODOP_SLTIU", 11);
  361. // x.put("CODOP_ANDI", 12);
  362. // x.put("CODOP_ORI", 13);
  363. // x.put("CODOP_LUI", 15);
  364. //
  365. // x.put("CODOP_LB", 32);
  366. // x.put("CODOP_LH", 33);
  367. // x.put("CODOP_LW", 35);
  368. // x.put("CODOP_LBU", 36);
  369. // x.put("CODOP_LHU", 37);
  370. // x.put("CODOP_SB", 40);
  371. // x.put("CODOP_SH", 41);
  372. // x.put("CODOP_SW", 43);
  373. //
  374. // x.put("CODOP_BGEZ", 1);
  375. // x.put("CODOP_BEQ", 4);
  376. // x.put("CODOP_BNE", 5);
  377. // x.put("CODOP_BGTZ", 7);
  378. //
  379. // x.put("CODOP_JUMP", 2);
  380. // x.put("CODOP_JAL", 3);
  381. //
  382. // x.put("CODOP_STOP", 63);
  383. ////Constante das operações da ULA
  384. // x.put("SOMA", 1);
  385. // x.put("SUBTRACAO", 2);
  386. // x.put("MULTIPLICACAO", 3);
  387. // x.put("AND", 4);
  388. // x.put("OR", 5);
  389. // x.put("XOR", 6);
  390. // x.put("NOR", 7);
  391. // x.put("DIVISAO", 8);
  392. // x.put("SLT", 9);
  393. // x.put("SLTU", 10);
  394. // x.put("LUI", 11);
  395. //
  396. // x.put("SRL", 12); //Faz o shift usando o campo shamt
  397. // x.put("SLL", 13); //Faz o shift usando o campo shamt
  398. // x.put("SRA", 14); //Faz o shift usando o campo shamt
  399. //
  400. // x.put("SRLV", 15); //Faz o shift usando registrador
  401. // x.put("SLLV", 16); //Faz o shift usando registrador
  402. // x.put("SRAV", 17); //Faz o shift usando registrador
  403. // x.put("MOVE", 18);
  404. //
  405. // for (Map.Entry<String, Integer> entry : x.entrySet()) {
  406. // String string = entry.getKey();
  407. // System.out.println(string + ":" + Utils.pad(6, Integer.toBinaryString(entry.getValue())));
  408. // }
  409. // }
  410. //CODOP_JUMP:000010
  411. //CODOP_LBU:100100
  412. //NOP:111111
  413. //CODOP_STOP:111111
  414. //FUNCT_DIVU:011011
  415. //CODOP_LH:100001
  416. //MULTIPLICACAO:000011
  417. //SRLV:001111
  418. //NOR:000111
  419. //SLL:001101
  420. //FUNCT_SRA:000011
  421. //CODOP_ANDI:001100
  422. //AND:000100
  423. //FUNCT_SRL:000010
  424. //CODOP_ORI:001101
  425. //SRAV:010001
  426. //SLT:001001
  427. //SUBTRACAO:000010
  428. //CODOP_LW:100011
  429. //FUNCT_ADD:100000
  430. //SOMA:000001
  431. //FUNCT_MULTU:011001
  432. //CODOP_SLTI:001010
  433. //SLLV:010000
  434. //SLTU:001010
  435. //FUNCT_MULT:011000
  436. //CODOP_ADDIU:001001
  437. //LUI:001011
  438. //CODOP_SH:101001
  439. //XOR:000110
  440. //FUNCT_MFLO:010010
  441. //FUNCT_SRAV:000111
  442. //DIVISAO:001000
  443. //SRL:001100
  444. //SRA:001110
  445. //CODOP_SB:101000
  446. //CODOP_ADDI:001000
  447. //FUNCT_JR:001000
  448. //FUNCT_MFHI:010000
  449. //FUNCT_NOR:100111
  450. //FUNCT_NOP:111111
  451. //FUNCT_SUBU:100011
  452. //FUNCT_OR:100101
  453. //FUNCT_AND:100100
  454. //FUNCT_XOR:100110
  455. //FUNCT_DIV:011010
  456. //FUNCT_SRLV:000110
  457. //FUNCT_ADDU:100001
  458. //CODOP_LUI:001111
  459. //CODOP_BGEZ:000001
  460. //MOVE:010010
  461. //CODOP_SLTIU:001011
  462. //CODOP_JAL:000011
  463. //OR:000101
  464. //CODOP_SW:101011
  465. //FUNCT_SUB:100010
  466. //FUNCT_SLLV:000100
  467. //CODOP_LB:100000
  468. //CODOP_BNE:000101
  469. //FUNCT_SLL:000000
  470. //CODOP_LHU:100101
  471. //CODOP_BGTZ:000111
  472. //CODOP_BEQ:000100
  473. //FUNCT_SLT:101010
  474. /*
  475. 1652044928
  476. 1100010011110000011010010000000
  477. 1100010011110000011010010000000
  478. 011000 10011110000011010010000000
  479. 011000
  480. 596080229
  481. 00100011100001110111011001100101 - js
  482. 100011100001110111011001100101
  483. c
  484. 10010110000010000000001000101001
  485. */
  486. //1652044928 -> 01010010000001000100100100101000 ->
  487. //0: 0062783480 addiu sp,sp,-8