Gen.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  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 target.mips;
  7. import API.Instruction;
  8. import API.Utils;
  9. import IntermediaryCode.Block;
  10. import IntermediaryCode.Code;
  11. import IntermediaryCode.DataFrame;
  12. import IntermediaryCode.OcorrenceFinderProcessor;
  13. import ast.Node;
  14. import compiler.IvannosysTargetArch;
  15. import java.io.IOException;
  16. import java.util.ArrayList;
  17. import java.util.HashMap;
  18. import java.util.LinkedHashMap;
  19. import java.util.LinkedList;
  20. import java.util.Map;
  21. import java.util.logging.Level;
  22. import java.util.logging.Logger;
  23. /**
  24. * MipS tranSlation
  25. *
  26. * @author EUGENIO CARVALHO
  27. */
  28. public class Gen extends API.Gen {
  29. protected HashMap<String, String> AddressCalculated = new HashMap<>();
  30. // protected AllocatorMipsProcessor allocation = new AllocatorMipsProcessor();
  31. protected HashMap<String, String> comments = new HashMap<String, String>() {
  32. {
  33. put("beq", "branch if equals");
  34. put("bne", "branch if not equals");
  35. put("blez", "branch if register <= 0");
  36. put("bltz", "branch if register < 0");
  37. put("bgez", "branch if register >= 0");
  38. put("bgtz", "branch if register > 0");
  39. }
  40. };
  41. private ArrayList<String> returnRegisters;
  42. private HashMap<String, Boolean> ctrlDataUpdate = new HashMap<>();
  43. private int WORD_INC = 4;
  44. public Gen() {
  45. super("MIPS");
  46. Init();
  47. }
  48. public void CopyData(LinkedHashMap<String, Node> dst, LinkedHashMap<String, Node> src) throws Exception {
  49. Node value;
  50. // for (Map.Entry<String, Node> x : data.values().entrySet()) {
  51. // v = x.getValue();
  52. // ctrlDataUpdate.put(v.G("id"), Boolean.TRUE);
  53. // v.S("size", v.getInt("size") * WORD_INC);
  54. // }
  55. for (Map.Entry<String, Node> x : src.entrySet()) {
  56. value = x.getValue().copy();
  57. value.S("size", value.getInt("size") * WORD_INC);
  58. // System.out.println("Copy:[" + x.getKey() + "][" + value.G("id") + "]" + value.G("size") + "\n" + value);
  59. dst.put(x.getKey(), value);
  60. }
  61. // for (Map.Entry<String, Node> x : src.entrySet()) {
  62. // System.out.println("size:" + x.getKey() + x.getValue());
  63. // }
  64. }
  65. public IvannosysTargetArch SetTAC(Code tac) {
  66. try {
  67. // System.out.println(">>>>>>>>>>>>>>> Set tac");
  68. this.tac = tac;
  69. CopyData(target.GData().values(), tac.GData().values());
  70. } catch (Exception ex) {
  71. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  72. }
  73. return this;
  74. }
  75. public void Init() {
  76. BeforeTranslateBlock("live.var", new OcorrenceFinderProcessor());
  77. BeforeTranslateBlock("register.alloc", new AllocatorMipsProcessor());
  78. AfterTranslateBlock("otimization.1", new OtimizationMips());
  79. AfterTranslate("update.address", new UpdateAddressProcessor());
  80. getTarget()
  81. .Template(new TemplateMips())
  82. .Formats(new HashMap<String, String>() {
  83. {
  84. String base = "{[HEX(global.position,_addressLen,' ')]': '}{[INSTDEC()]}{[T(1)]}{[inst]}' '",
  85. end = "{[T(1)]}{'.'[tac.position]'.'}{'--'[comment]}";
  86. put("S", base + end);
  87. put("label", "' '{[HEX(global.reference.position,8,0)]}{[INSTDEC()]}{' <'[label]'>:'");
  88. // TemplateMips para instrucoes do tipo J
  89. put("J", base + "{[rs]}{[L(label,'hex')]}" + end);
  90. // TemplateMips para instrucoes do tipo R
  91. put("R0", base + "{[rd]','}{[rs]','}{[rt]}" + end);
  92. put("R1", base + "{[rs]','}{[rt]}" + end);
  93. put("R2", base + "{[rs]}" + end);
  94. put("R3", base + "{[rt]','}{[rs]}" + end);
  95. put("R4", base + "{[rd]','}{[rt]','}{[sa]} " + end);
  96. put("R5", base + "{[rd]}" + end);
  97. // TemplateMips para instrucoes do tipo I
  98. put("I0", base + "{[rt]','}{[rs]','}{[L(label,'hex')]|[offset]|[rd]}" + end); //[rs:sp,rt:7,rd:sp]
  99. // SW,LW
  100. put("I1", base + "{[rt]','}{[OFFSET(offset,rs)]}" + end);
  101. // Templates avulsos
  102. put("PSEUDO", base);
  103. }
  104. });
  105. }
  106. @Override
  107. public void TranslateLabel(Instruction inst) {
  108. Add(new Instruction()
  109. .S("type", "label")
  110. .S("format", "norender")
  111. // .S("format", "label")
  112. .S("tac.position", inst.G("block.position"))
  113. .S("label", inst.G("label")));
  114. getTarget().RegisterLabelAddress(inst.G("label"));
  115. }
  116. @Override
  117. public void TranslateCopy(Instruction inst) throws Exception {
  118. //Se o valor deve ser armazenado em memoria
  119. String regDst = inst.G("reg.dst");
  120. if (inst.eq("reg.dst.store", "true")) {
  121. // System.out.println("::" + inst);
  122. inst.S("reg.p1", regDst);
  123. String dst = inst.G("dst");
  124. LoadParam(inst, "p1");
  125. // StoreWord(inst.G("reg.p1"),
  126. StoreWord(regDst,
  127. GlobalOrFrameRegister(dst),
  128. getTarget().Block().Data().Offset(dst))
  129. .S("tac.position", inst.G("block.position"))
  130. .S("comment", "store content of " + inst.G("reg.p1") + " in " + dst);
  131. } else {
  132. Copy(inst, regDst)
  133. .S("tac.position", inst.G("block.position"))
  134. .S("comment", "copy " + inst.G("dst") + " ← " + inst.G("p1"));
  135. }
  136. }
  137. @Override
  138. public void TranslateAssign(Instruction inst) throws Exception {
  139. String instruction = Mips.InstructionByOperator(inst);
  140. String rd = inst.G("reg.dst"),
  141. dst = inst.G("dst");
  142. Instruction ninst = new Instruction(instruction).S("tac.position", inst.G("block.position"));
  143. switch (Mips.Codops.get(instruction).G("type")) {
  144. //addi, addiu, slti, sltiu
  145. case "I":
  146. ninst.S("rt", rd);
  147. // System.out.println("Assign:" + inst);
  148. if (inst.eq("p2value", "true")) {
  149. LoadParam(inst, "p1");
  150. ninst.S("offset", inst.G("p2"))
  151. .S("rs", inst.G("reg.p1"));
  152. } else {
  153. LoadParam(inst, "p2");
  154. ninst.S("offset", inst.G("p1"))
  155. .S("rs", inst.G("reg.p2"));
  156. }
  157. break;
  158. // mult, divu, sgtu ,sltu
  159. // sra, srl, sll
  160. case "R":
  161. // System.out.println("SLL:" + inst);
  162. LoadParam(inst);
  163. //
  164. if (ninst.in("inst", "sll,srl,sra".split(","))) {
  165. rd = inst.G("reg.dst");
  166. ninst.S("sa", inst.G("p2"))
  167. .S("rt", inst.G("reg.p1"));
  168. } else {
  169. ninst.S("rs", inst.G("reg.p1"))
  170. .S("rt", inst.G("reg.p2"));
  171. }
  172. ninst.S("rd", rd);
  173. // System.out.println("inst["+rd+"]" + inst + ":" + ninst);
  174. break;
  175. }
  176. Add(ninst);
  177. // Verifica se a expr possui overflow
  178. String overflow = Mips.Instruction(instruction).G("overflow");
  179. if (!overflow.equals("")) {
  180. Add(new Instruction("R", overflow)
  181. .S("rd", rd)
  182. .S("tac.position", inst.G("block.position"))
  183. );
  184. }
  185. // Gravar na memoria?
  186. // System.out.println("ASSIGN:" + inst);
  187. StoreResult(inst, rd, dst);
  188. }
  189. @Override
  190. public void TranslateJump(Instruction inst) {
  191. Add(new Instruction("J", "j")
  192. .copy("label", inst)
  193. .S("comment", inst.getText())
  194. .S("tac.position", inst.G("block.position"))
  195. );
  196. }
  197. @Override
  198. public void TranslateCall(Instruction inst) throws Exception {
  199. // allocation.registers.ResetArgs();
  200. // Before load params
  201. // Copy(inst, returnRegisters.remove(2))
  202. // .S("tac.position", inst.G("block.position"))
  203. // .S("comment", "push param");
  204. // System.out.println("Call" + inst);
  205. ResetReturnArgs();
  206. try {
  207. Instruction retur;
  208. LinkedList<Instruction> intructions = getTac().Block().Instructions();
  209. int base = intructions.indexOf(inst);
  210. for (int i = inst.getInt("nump"); i > 0; i--) {
  211. retur = intructions.get(base - i);
  212. Copy(retur, returnRegisters.remove(2))
  213. .S("tac.position", retur.G("global.position"))
  214. .S("comment", "push param");
  215. }
  216. } catch (Exception ex) {
  217. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  218. }
  219. Add(new Instruction("J", "jal")
  220. .S("label", inst.G("funcname"))
  221. .S("comment", "jump to <" + inst.G("funcname") + ">")
  222. .S("tac.position", inst.G("block.position"))
  223. );
  224. // After store results
  225. // Restaura o array de registradores de retorno para fazer o pop dos returns
  226. ResetReturnArgs();
  227. }
  228. @Override
  229. public void TranslatePushReturn(Instruction inst) {
  230. // Tratado no metodo 'TranslateReturn'
  231. }
  232. @Override
  233. public void TranslateReturn(Instruction inst) {
  234. // Restaura o array de registradores de retorno
  235. ResetReturnArgs();
  236. try {
  237. Instruction retur;
  238. LinkedList<Instruction> intructions = getTac().Block().Instructions();
  239. int base = intructions.indexOf(inst);
  240. for (int i = inst.getInt("p1"); i > 0; i--) {
  241. retur = intructions.get(base - i);
  242. // System.out.println("Return:" + retur);
  243. Copy(retur, returnRegisters.remove(0))
  244. .S("tac.position", retur.G("global.position"))
  245. .S("comment", "push return");
  246. }
  247. } catch (Exception ex) {
  248. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  249. }
  250. }
  251. /**
  252. * Criar uma inStrucao que copia o valor ou conteudo do regiStrador para o
  253. * regiStrador 'r'
  254. *
  255. * @param inst
  256. * @param push
  257. * @param rt
  258. */
  259. protected Instruction Copy(Instruction inst, String rt) {
  260. Instruction c;
  261. if (inst.eq("p1value", "true")) {
  262. // andi Rt,Rs,immediate | Rt <-- [Rs] + ([I15]16 || [I15..0]);
  263. c = Copy(rt, Registers.R_ZERO, inst.G("p1"));
  264. } else {
  265. // addu Rd,Rs,Rt | Rd <-- [Rs] + [Rt];
  266. LoadParam(inst, "p1");
  267. c = CopyReg(inst.G("reg.p1"), rt);
  268. }
  269. // System.out.println("COPY::" + c);
  270. return c.S("tac.position", inst.G("block.position"));
  271. }
  272. @Override
  273. public void TranslatePushParam(Instruction inst) {
  274. // Tratado no metodo 'TranslateCall'
  275. }
  276. @Override
  277. public void TranslatePopReturn(Instruction inst) {
  278. String p1 = inst.G("p1");
  279. StoreWord(returnRegisters.remove(0),
  280. GlobalOrFrameRegister(p1),
  281. getTarget().Block().Data().Offset(p1));
  282. }
  283. @Override
  284. public void TranslatePopParam(Instruction inst) {
  285. // todo - resetar args
  286. // System.out.println("PopParam:" + inst);
  287. String p1 = inst.G("p1");
  288. // O indice é 2 por conta dos dois primeiros registradores {v0, v1}
  289. int offset = getTarget().Block().Data().Offset(p1);
  290. StoreWord(returnRegisters.remove(2),
  291. GlobalOrFrameRegister(p1),
  292. offset)
  293. .S("tac.position", inst.G("block.position"))
  294. .S("comment", "pop param");
  295. // System.out.println("POPpARAM:" + inst);
  296. LoadWord(inst.G("reg.p1"), Registers.R_FP, offset);
  297. }
  298. @Override
  299. public void TranslateBranch(Instruction inst) throws Exception {
  300. String instruction = Mips.InstructionByOperator(inst);
  301. LoadParam(inst);
  302. String rs = inst.G("reg.p1");
  303. String rt = inst.G("reg.p2");
  304. Instruction I = new Instruction("I", instruction)
  305. .S("label", inst.G("funcname"));
  306. switch (instruction) {
  307. case "beq": // == {[inst]}' ' {[rt]},{[rs]},{immediate}
  308. case "bne": // !=
  309. I.S("rs", rs).S("rt", rt);
  310. break;
  311. case "blez": // <= 0{[inst]}' ' {[rs]},{immediate}
  312. case "bltz": // < 0
  313. case "bgez": // >= 0
  314. case "bgtz": // > 0
  315. Add(new Instruction("R", "subu")// Rd <-- [Rs] - [Rt];
  316. .S("rs", rs)
  317. .S("rt", rt)
  318. .S("rd", Registers.R_V0)
  319. .S("tac.position", inst.G("block.position"))
  320. .S("comment", "")
  321. );
  322. I.S("rs", Registers.R_V0);
  323. break;
  324. }
  325. Add(I).S("label", inst.G("label"))
  326. .S("tac.position", inst.G("block.position"))
  327. .S("comment", comments.get(instruction));
  328. // System.out.println("Translate branch:" + I);
  329. }
  330. @Override
  331. public void Prolog(String id) throws Exception {
  332. DataFrame data = getTarget().Block().Data();
  333. // Copia os dados para block target
  334. //Updata size in 4 bytes
  335. CopyData(
  336. data.values(),
  337. getTac().Block().Data().values()
  338. );
  339. // Adiciona o label
  340. Add(new Instruction()
  341. .S("type", "label")
  342. .S("format", "label")
  343. .S("label", id)
  344. );
  345. // Aloca o espaco da pilha
  346. Instruction alloc = Copy(Registers.R_SP, Registers.R_SP, "-" + data.Size())
  347. .S("comment", "p| push stack frame");
  348. if (!getTarget().Block().getName().equals("main")) {
  349. // Restaura o fp
  350. // Restaura o ra
  351. boolean call = getTac().Block().HasCall();
  352. int newvars = 0;
  353. for (String reg : new String[]{Registers.R_FP, Registers.R_RA}) {
  354. if (call) {
  355. data.Add(reg, new Node().S("type", "int").set("size", 1 * WORD_INC));
  356. newvars--;
  357. StoreWord(reg, Registers.R_SP, data.Offset(reg))
  358. .S("comment", "p| backup " + reg);
  359. }
  360. }
  361. alloc.somar("offset", newvars);
  362. }
  363. // Copia o sp para o fp
  364. CopyReg(Registers.R_SP, Registers.R_FP).Prepend("comment", "p|");
  365. ResetReturnArgs();
  366. }
  367. /**
  368. * Encerra a chamada de uma funcao
  369. *
  370. * @param id
  371. * @throws Exception
  372. */
  373. @Override
  374. public void Epilog(String id) throws Exception {
  375. DataFrame data = getTarget().Block().Data();
  376. if (!getTarget().Block().getName().equals("main")) {
  377. // Restaura o fp
  378. // Restaura o ra
  379. boolean call = getTac().Block().HasCall();
  380. for (String reg : new String[]{Registers.R_FP, Registers.R_RA}) {
  381. if (call) {
  382. LoadWord(reg, Registers.R_SP, data.Offset(reg))
  383. .S("comment", "e| restore " + reg);
  384. }
  385. }
  386. // Desaloca a pilha
  387. Copy(Registers.R_SP, Registers.R_SP, data.Size())
  388. .S("comment", "e|pop stack frame");
  389. // if (getTac().Block().HasCall()) {
  390. Add(new Instruction("jr")
  391. .S("rs", Registers.R_RA)
  392. .S("comment", "e|return"));
  393. // }[]
  394. } else {
  395. Add(new Instruction("stop").S("txt", "11111111111111111111111111111111").S("comment", "end of programa"));
  396. }
  397. }
  398. @Override
  399. public void TranslateIndexedAssignment(Instruction inst) throws Exception {
  400. //Fase de leitura
  401. IndexedRead(inst);
  402. //Fase de atribuicao
  403. IndexedDest(inst);
  404. }
  405. protected void IndexedRead(Instruction inst) {
  406. // Se a fonte é indexada
  407. if (inst.eq("src_indexed", "true")) {
  408. int offset = getTarget().Block().Data().Offset(inst.G("p1"));
  409. String p1 = inst.G("p1"),
  410. rt = inst.G("reg.p1"),
  411. rs = GlobalOrFrameRegister(p1);
  412. // System.out.println("Indexed read:" + inst);
  413. if (!inst.isNumber("p1.indice")) {
  414. String rd = inst.G("reg.p1.indice");
  415. if (!AddressCalculated.containsKey(p1)) {
  416. Add(new Instruction("addu")
  417. .S("rd", rd)
  418. .S("rs", rs)
  419. .S("rt", rd))
  420. .S("tac.position", inst.G("block.position"));
  421. AddressCalculated.put(p1, rs);
  422. }
  423. rs = rd;
  424. }
  425. // Carrega o conteudo enderecado em rt para rt
  426. LoadWord(rt, rs, offset)
  427. .S("tac.position", inst.G("block.position"));
  428. } else {
  429. // Se não é indexada carrega o parametro normalmente
  430. LoadParam(inst);
  431. }
  432. }
  433. /**
  434. * FaSe de atribuicao
  435. *
  436. * @param inst
  437. */
  438. protected void IndexedDest(Instruction inst) {
  439. // System.out.println("Indexeds:" + inst);
  440. String regp1 = inst.G("reg.p1"),
  441. regdst = inst.G("reg.dst");
  442. // Valor atribuido é indexado
  443. // 1 - Verificar se deve ser armazenado ou copiado
  444. boolean dstIndexed = inst.eq("dst_indexed", "true");
  445. if (dstIndexed || inst.eq("reg.dst.store", "true")) { // deve ser armazenado
  446. String dst = inst.G("dst"),
  447. rs = GlobalOrFrameRegister(dst),
  448. comment;
  449. int offset = getTarget().Block().Data().Offset(dst);
  450. if (dstIndexed) {
  451. if (!inst.isNumber("dst.indice")) {
  452. // Offset agora deve ser 0 pois o registrador conterá o endereco completo
  453. // offset = 0;
  454. String rd = inst.G("reg.dst.indice");
  455. if (!AddressCalculated.containsKey(dst)) {
  456. Add(new Instruction("addu")
  457. .S("rd", rd)
  458. .S("rs", rs)
  459. .S("rt", rd)
  460. .S("tac.position", inst.G("block.position"))
  461. );
  462. AddressCalculated.put(dst, rs);
  463. }
  464. rs = rd;
  465. }
  466. comment = "store in loaded address";
  467. } else {
  468. comment = "store in " + dst;
  469. }
  470. // System.out.println("Inst:" + inst);
  471. StoreWord(regp1, rs, offset)
  472. .S("tac.position", inst.G("block.position"))
  473. .S("comment", comment);
  474. } else { // deve ser copiado
  475. CopyReg(regp1, regdst)
  476. .S("tac.position", inst.G("block.position"));
  477. }
  478. }
  479. /**
  480. * Verificar Se o valor da atribuição ja eSta em regiStrador. CaSo não
  481. * eSteja o valor é carregado e o valor retornado é o nome do regiStrador
  482. *
  483. * @param inst
  484. * @param param
  485. * @return
  486. */
  487. protected String LoadParam(Instruction inst) {
  488. return LoadParam(inst, "p1,p2");
  489. }
  490. protected String LoadParam(Instruction inst, String params) {
  491. return LoadParam(inst, params.split(","));
  492. }
  493. protected String LoadParam(Instruction inst, String[] params) {
  494. String pname;
  495. for (String param : params) {
  496. if (!inst.Has("reg." + param + ".load")) {
  497. continue;
  498. }
  499. Instruction Ninst = new Instruction();
  500. pname = inst.G(param);
  501. if (inst.eq(param + "value", "true")) {
  502. Ninst.S("inst", "addiu") // R[$rt] ← {(imm)[15:0], 0 × 16}
  503. .S("rs", Registers.R_ZERO)
  504. .S("rt", inst.G("reg." + param))
  505. .S("offset", pname);
  506. } else {
  507. Ninst.S("inst", "lw") // R[$rt] ← Mem4B(R[$rs] + SignExt16b(imm))
  508. .S("rt", inst.G("reg." + param))
  509. .S("rs", GlobalOrFrameRegister(pname))
  510. .S("comment", "load address stored in " + pname)
  511. .set("offset", getTarget().Block().Data().Offset(pname));
  512. }
  513. Add(Ninst.S("tac.position", inst.G("block.position")));
  514. // x.S("reg." + param, reg);
  515. }
  516. return null;
  517. }
  518. /**
  519. * Copia o valor do regiStrador Src para o dSt
  520. *
  521. * @param src
  522. * @param dst
  523. * @return
  524. */
  525. protected Instruction CopyReg(String src, String dst) {
  526. return Add(new Instruction("addu")
  527. .S("rs", Registers.R_ZERO)
  528. .S("rt", src)
  529. .S("rd", dst)
  530. .S("comment", "copy " + dst + " ← " + src));
  531. }
  532. protected Instruction Copy(String rt, String rs, int offset) {
  533. return Copy(rt, rs, "" + offset);
  534. }
  535. protected Instruction Copy(String rt, String rs, String offset) {
  536. return Add(new Instruction("addiu") // lw $rt, imm($rs)
  537. .S("rt", rt)
  538. .S("rs", rs)
  539. .S("offset", offset)
  540. .S("comment", "copy " + rs + " ← " + rt)
  541. );
  542. }
  543. protected Instruction StoreWord(String rt, String rs, int offset) {
  544. return StoreWord(rt, rs, "" + offset);
  545. }
  546. protected Instruction StoreWord(String rt, String rs, String offset) {
  547. return Add(new Instruction("sw").S("rt", rt).S("rs", rs).S("offset", offset));
  548. }
  549. protected Instruction LoadWord(String rt, String rs, int offset) {
  550. // System.out.println("LoadWord:" + rt + ":" + rs + ":" + "off:" + offset);
  551. return LoadWord(rt, rs, "" + offset);
  552. }
  553. protected Instruction LoadWord(String rt, String rs, String offset) {
  554. // System.out.println("LoadWord:" + rt + ":" + rs + ":" + "off:" + offset);
  555. return Add(new Instruction("lw") // lw $rt, imm($rs)
  556. .S("rt", rt)
  557. .S("rs", rs)
  558. .S("offset", offset)
  559. );
  560. }
  561. protected void Noop() {
  562. Add(new Instruction("sll")
  563. .S("rs", "zero")
  564. .S("rt", "0")
  565. .S("rd", "zero"));
  566. }
  567. @Override
  568. public IvannosysTargetArch Export() {
  569. Code Target = getTarget();
  570. System.out.println(Target.GData());
  571. String out = "", tmp;
  572. Integer index;
  573. for (Map.Entry<String, Block> x : Target.stmts.entrySet()) {
  574. System.out.println(x.getValue().Data());
  575. index = 0;
  576. for (Instruction instr : x.getValue().Instructions()) {
  577. // System.out.println("Export:" + instr);
  578. tmp = instr.G("inst.dec");
  579. if (tmp.equals("")) {
  580. continue;
  581. }
  582. out = out
  583. // .concat(Integer.toHexString(index))
  584. // .concat(":")
  585. // .concat(String.format("%X\n", tmp.trim()) + "\n");
  586. .concat(tmp + "\n");
  587. index++;
  588. }
  589. }
  590. // System.out.println("Export:" + out);
  591. // Grava resutlado no arquivo de memoria do simulador
  592. Utils.WriteFile("\\src\\tools\\mips\\memory\\mi.memory", out);
  593. try {
  594. new tools.mips.MipsProcessor(new tools.mips.MipsSettings() {
  595. {
  596. SetInstructionMemoryFile("\\src\\tools\\mips\\memory\\mi.memory");
  597. SetDataMemoryFile("\\src\\tools\\mips\\memory\\md.memory");
  598. }
  599. }).Run().Persist();
  600. } catch (IOException ex) {
  601. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  602. }
  603. throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  604. }
  605. @Override
  606. public void TranslateUnary(Instruction inst) throws Exception {
  607. // Carrega o valor se nao esta em registrador
  608. // System.out.println("Translate Unary:" + inst);
  609. switch (inst.G("op")) {
  610. case "-": // Retorna o valor negado 10 -> -10
  611. Add(new Instruction("subu")// Rd <-- [Rs] - [Rt];
  612. .S("rd", inst.G("reg.dst"))
  613. .S("rs", Registers.R_ZERO)
  614. .S("rt", inst.G("reg.p1"))
  615. .S("comment", "negation arith")
  616. .S("tac.position", inst.G("block.position"))
  617. );
  618. break;
  619. case "!": // XOR ( 0 1 -> 1) XOR( 1 1 -> 0)
  620. Add(new Instruction("xori") // Rt <-- [Rs] AND (016 || [I15..0]); ;
  621. .S("rt", inst.G("reg.dst"))
  622. .S("rs", inst.G("reg.p1"))
  623. .S("offset", "1")
  624. .S("comment", "negation bool")
  625. .S("tac.position", inst.G("block.position"))
  626. );
  627. break;
  628. // case "*": // Copia do conteudo do ponteiro
  629. //
  630. // case "&": // Copia do endereco da variavel
  631. // break;// case "*": // Copia do conteudo do ponteiro
  632. //
  633. // case "&": // Copia do endereco da variavel
  634. // break;// case "*": // Copia do conteudo do ponteiro
  635. //
  636. // case "&": // Copia do endereco da variavel
  637. // break;// case "*": // Copia do conteudo do ponteiro
  638. //
  639. // case "&": // Copia do endereco da variavel
  640. // break;// case "*": // Copia do conteudo do ponteiro
  641. //
  642. // case "&": // Copia do endereco da variavel
  643. // break;// case "*": // Copia do conteudo do ponteiro
  644. //
  645. // case "&": // Copia do endereco da variavel
  646. // break;// case "*": // Copia do conteudo do ponteiro
  647. //
  648. // case "&": // Copia do endereco da variavel
  649. // break;// case "*": // Copia do conteudo do ponteiro
  650. //
  651. // case "&": // Copia do endereco da variavel
  652. // break;
  653. }
  654. }
  655. /**
  656. * Traducao de intrucoeS do tipo
  657. *
  658. * - x = &a - copia do endereco de uma varaivel <br>
  659. * - x = *b - x recebe o conteudo da variavel referenciada por b<br>
  660. * - *x = y - conpia o conteudo de y para o endereco armazenado em x
  661. *
  662. * @param inst
  663. * @throws Exception
  664. */
  665. @Override
  666. public void TranslatePointerAssignment(Instruction inst) throws Exception {
  667. String p1 = inst.G("p1"),
  668. dst = inst.G("dst"),
  669. regdst = inst.G("reg.dst"),
  670. regp1 = inst.G("reg.p1");
  671. switch (inst.G("op")) {
  672. case "&": // Lendo o endereco de um ponteiro
  673. Copy(regp1,
  674. GlobalOrFrameRegister(p1),
  675. getTac().Block().Data().Offset(p1)
  676. )
  677. .S("tac.position", inst.G("block.position"))
  678. .S("comment", "copy address of " + p1);
  679. System.out.println("PointerAssi&:" + inst);
  680. // Se nao fez o store
  681. if (StoreResult(inst, regp1, dst) == null) {
  682. CopyReg(regp1, regdst);
  683. // .S("comment", "store content of " + regdst + " in " + dst);
  684. }
  685. break;
  686. case "*": // Lendo o conteudo de um ponteiro
  687. /**
  688. * Carrega o valor contido no ponteiro<br>
  689. * Utiliza o valor como endereço em um segundo load que carrega
  690. * o dado<br>
  691. * lw ${p1},12($fp)<br>
  692. * lw ${dst},0(${p1}) $s<br>
  693. */
  694. LoadWord(regp1,
  695. GlobalOrFrameRegister(p1),
  696. getTac().Block().Data().Offset(p1))
  697. .S("tac.position", inst.G("block.position"))
  698. .S("comment", "load address stored in " + p1);
  699. LoadWord(regdst,
  700. regp1,
  701. "0")
  702. .S("tac.position", inst.G("block.position"))
  703. .S("comment", "load content of address stored in " + regp1);
  704. /*Se for a ultima operacao de escrita nessa variavel salva em memoria*/
  705. Instruction store = StoreResult(inst, regdst, dst);
  706. if (store != null) {
  707. store.S("comment", "store content of " + regdst + " in " + dst);
  708. }
  709. break;
  710. default: // Atribuicao a um ponteiro
  711. LoadParam(inst);
  712. /**
  713. * Carrega o valor dentro do endereco do ponteiro <br>
  714. * lw ${p1},12(${fp|gp})<br>
  715. * lw ${dst},0(${p1}) $s<br>
  716. * conteudo da variavel referenciada
  717. */
  718. LoadWord(regdst,
  719. GlobalOrFrameRegister(dst),
  720. getTac().Block().Data().Offset(dst))
  721. .S("tac.position", inst.G("block.position"))
  722. .S("comment", "load address stored in " + dst);
  723. // Grava o valor do registrador na memoria
  724. StoreWord(regp1, regdst, "0")
  725. .S("tac.position", inst.G("block.position"))
  726. .S("comment", "store content of " + regp1 + " in *" + dst);
  727. }
  728. }
  729. @Override
  730. protected Instruction Add(Instruction inst) {
  731. try {
  732. if (!inst.eq("type", "label")) {
  733. getTarget().PositionInc();
  734. Instruction definiction = Mips.Instruction(inst.G("inst"));
  735. inst.Merge("sa,type,inst,codop,func,format", definiction);
  736. }
  737. } catch (Exception ex) {
  738. Logger.getLogger(Gen.class
  739. .getName()).log(Level.SEVERE, null, ex);
  740. }
  741. return super.Add(inst); //To change body of generated methods, choose Tools | Templates.
  742. }
  743. protected String GlobalOrFrameRegister(String var) {
  744. // System.out.println("GlobalOrFrameRegister:" + var);
  745. return var.contains("_G") ? Registers.R_GP : Registers.R_FP;
  746. }
  747. protected Instruction StoreResult(Instruction inst, String rd, String dst) {
  748. if (inst.eq("reg.dst.store", "true")) {
  749. return StoreWord(rd,
  750. GlobalOrFrameRegister(dst),
  751. getTarget().Block().Data().Offset(dst)
  752. ).S("tac.position", inst.G("block.position"));
  753. }
  754. return null;
  755. }
  756. private void ResetReturnArgs() {
  757. returnRegisters = new ArrayList<String>() {
  758. {
  759. add("v0");
  760. add("v1");
  761. add("a0");
  762. add("a1");
  763. add("a2");
  764. add("a3");
  765. }
  766. };
  767. }
  768. }