Translate.java 28 KB

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