Translate.java 30 KB

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