Gen.java 30 KB

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