Translate.java 33 KB

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