Gen.java 32 KB

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