Gen.java 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045
  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 target.mips;
  7. import API.Utils;
  8. import IntermediaryCode.BaseBlockProcessor;
  9. import ast.Node;
  10. import common.Block;
  11. import common.Code;
  12. import common.DataFrame;
  13. import common.Instruction;
  14. import common.IvannosysTargetArch;
  15. import java.util.ArrayList;
  16. import java.util.HashMap;
  17. import java.util.LinkedHashMap;
  18. import java.util.LinkedList;
  19. import java.util.Map;
  20. import java.util.logging.Level;
  21. import java.util.logging.Logger;
  22. /**
  23. * MipS tranSlation
  24. *
  25. * @author EUGENIO CARVALHO
  26. */
  27. public class Gen extends API.TargetGen {
  28. protected HashMap<String, String> AddressCalculated = new HashMap<>();
  29. // protected AllocatorMipsProcessor allocation = new AllocatorMipsProcessor();
  30. protected HashMap<String, String> formatMips = new HashMap<String, String>() {
  31. {
  32. String base = "{[HEX(global.position,_addressLen,' ')]': '}{[INSTDEC()]}{[T(1)]}{[inst]}' '",
  33. // String base = "{[HEX(global.position,_addressLen,' ')]': '}{[INSTHEX()]}{[T(1)]}{[inst]}' '",
  34. end = "{[T(1)]}{'.'[tac.position]'.'}{'--'[comment]}";
  35. put("S", base + end);
  36. put("label", "' '{[HEX(global.reference.position,8,0)]}{[INSTDEC()]}{' <'[label]'>:'");
  37. // TemplateMips para instrucoes do tipo J
  38. put("J", base + "{[rs]}{[L(label,'hex')]}" + end);
  39. // TemplateMips para instrucoes do tipo R
  40. put("R0", base + "{[rd]','}{[rs]','}{[rt]}" + end);
  41. put("R1", base + "{[rs]','}{[rt]}" + end);
  42. put("R2", base + "{[rs]}" + end);
  43. put("R3", base + "{[rt]','}{[rs]}" + end);
  44. put("R4", base + "{[rd]','}{[rt]','}{[sa]} " + end);
  45. put("R5", base + "{[rd]}" + end);
  46. // TemplateMips para instrucoes do tipo I
  47. put("I0", base + "{[rt]','}{[rs]','}{[L(label,'hex')]|[offset]|[rd]}" + end); //[rs:sp,rt:7,rd:sp]
  48. // SW,LW
  49. put("I1", base + "{[rt]','}{[OFFSET(offset,rs)]}" + end);
  50. // Templates avulsos
  51. put("PSEUDO", base);
  52. }
  53. };
  54. protected HashMap<String, String> comments = new HashMap<String, String>() {
  55. {
  56. put("beq", "branch if equals");
  57. put("bne", "branch if not equals");
  58. put("blez", "branch if register <= 0");
  59. put("bltz", "branch if register < 0");
  60. put("bgez", "branch if register >= 0");
  61. put("bgtz", "branch if register > 0");
  62. }
  63. };
  64. protected ArrayList<String> returnRegisters;
  65. protected HashMap<String, Boolean> ctrlDataUpdate = new HashMap<>();
  66. protected Integer WORD_INC = 4;
  67. public Gen() {
  68. super("MIPS");
  69. }
  70. public void Init() {
  71. BaseBlockProcessor ocorrences = new BaseBlockProcessor();
  72. // Rotinas executadas no codigo intermediario de um bloco antes de ser traduzido.
  73. getIR()
  74. .BeforeTranslateBlock("basic.blocks", ocorrences)
  75. .BeforeTranslateBlock("remove.load.store", new LoadStoreProcessor(ocorrences))
  76. .BeforeTranslateBlock("register.alloc", new AllocatorMipsProcessor(ocorrences));
  77. getTarget()
  78. // Rotina a ser executada em um bloco do codigo alvo depois de ser traduzido.
  79. .AfterTranslateBlock("oti.1", new OtimizationMips())
  80. // Otimizacao - Reducao do registro de ativacao de uma chamada
  81. // .AfterTranslateBlock("oti.1", new OTMinActivationRegister(ocorrences))
  82. // Rotina a ser executada em todo o codigo alvo apos ser traduzido.
  83. .AfterTranslate("update.address", new UpdateAddressProcessor())
  84. // Tefinicao da classe de renderizacao de templates
  85. .Template(new TemplateMips())
  86. // Templa das instrucoes mips
  87. .Formats(formatMips);
  88. }
  89. @Override
  90. public void TranslateLabel(Instruction inst) {
  91. Add(new Instruction()
  92. .S("type", "label")
  93. .S("format", "norender")
  94. .S("tac.position", inst.G("block.position"))
  95. .S("label", inst.G("label")));
  96. getTarget().RegisterLabelAddress(inst.G("label"));
  97. }
  98. @Override
  99. public void TranslateCopy(Instruction inst) throws Exception {
  100. //Se o valor deve ser armazenado em memoria
  101. // String regDst = inst.G("reg.dst");
  102. System.out.println("COPY:::::::::::" + inst);
  103. // if (inst.eq("reg.dst.store", "true")) {
  104. //
  105. //// System.out.println("::" + inst);
  106. // inst.S("reg.p1", regDst);
  107. // String dst = inst.G("dst");
  108. // LoadParam(inst, "p1");
  109. //// StoreWord(inst.G("reg.p1"),
  110. // StoreWord(regDst,
  111. // GlobalOrFrameRegister(dst),
  112. // getTarget().Block().Data().Offset(dst))
  113. // .S("tac.position", inst.G("block.position"))
  114. // .S("comment", "store content of " + inst.G("reg.p1") + " in " + dst);
  115. // } else {
  116. Copy(inst, inst.G("reg.dst"))
  117. .S("tac.position", inst.G("block.position"))
  118. .S("comment", "copy " + inst.G("dst") + " ← " + inst.G("p1"));
  119. // }
  120. }
  121. @Override
  122. public void TranslateAssign(Instruction inst) throws Exception {
  123. String instruction = Mips.InstructionByOperator(inst);
  124. String rd = inst.G("reg.dst"),
  125. dst = inst.G("dst");
  126. Instruction ninst = new Instruction(instruction).S("tac.position", inst.G("block.position"));
  127. switch (Mips.Codops.get(instruction).G("type")) {
  128. //addi, addiu, slti, sltiu
  129. case "I":
  130. ninst.S("rt", rd);
  131. // System.out.println("Assign:" + inst);
  132. if (inst.eq("p2value", "true")) {
  133. LoadParam(inst, "p1");
  134. ninst.S("offset", inst.G("p2"))
  135. .S("rs", inst.G("reg.p1"));
  136. } else {
  137. LoadParam(inst, "p2");
  138. ninst.S("offset", inst.G("p1"))
  139. .S("rs", inst.G("reg.p2"));
  140. }
  141. break;
  142. // mult, divu, sgtu ,sltu
  143. // sra, srl, sll
  144. case "R":
  145. // System.out.println("Translate assign:" + inst + "-" + Mips.Codops.get(instruction).G("type"));
  146. // System.out.println("SLL:" + inst);
  147. LoadParam(inst);
  148. //
  149. if (ninst.in("inst", "sll,srl,sra".split(","))) {
  150. rd = inst.G("reg.dst");
  151. ninst.S("sa", inst.G("p2"))
  152. .S("rt", inst.G("reg.p1"));
  153. } else {
  154. ninst.S("rs", inst.G("reg.p1"))
  155. .S("rt", inst.G("reg.p2"));
  156. }
  157. ninst.S("rd", rd);
  158. // System.out.println("inst["+rd+"]" + inst + ":" + ninst);
  159. break;
  160. }
  161. Add(ninst);
  162. // Verifica se a expr possui overflow
  163. String overflow = Mips.Instruction(instruction).G("overflow");
  164. if (!overflow.equals("")) {
  165. Add(new Instruction("R", overflow)
  166. .S("rd", rd)
  167. .S("tac.position", inst.G("block.position"))
  168. );
  169. }
  170. // Gravar na memoria?
  171. // System.out.println("ASSIGN:" + inst);
  172. StoreResult(inst, rd, dst);
  173. }
  174. @Override
  175. public void TranslateJump(Instruction inst) {
  176. Add(new Instruction("J", "j")
  177. .copy("label", inst)
  178. .S("comment", inst.getText())
  179. .S("tac.position", inst.G("block.position"))
  180. );
  181. Noop();
  182. }
  183. @Override
  184. public void TranslateCall(Instruction inst) throws Exception {
  185. // allocation.registers.ResetArgs();
  186. // Before load params
  187. // Copy(inst, returnRegisters.remove(2))
  188. // .S("IR.position", inst.G("block.position"))
  189. // .S("comment", "push param");
  190. // System.out.println("Call" + inst);
  191. ResetReturnArgs();
  192. try {
  193. Instruction retur;
  194. LinkedList<Instruction> intructions = getIR().Block().Instructions();
  195. int base = intructions.indexOf(inst);
  196. for (int i = inst.getInt("nump"); i > 0; i--) {
  197. retur = intructions.get(base - i);
  198. Copy(retur, returnRegisters.remove(2))
  199. .S("tac.position", retur.G("global.position"))
  200. .S("comment", "push param");
  201. }
  202. } catch (Exception ex) {
  203. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  204. }
  205. Add(new Instruction("J", "jal")
  206. .S("label", inst.G("funcname"))
  207. .S("comment", "jump to <" + inst.G("funcname") + ">")
  208. .S("tac.position", inst.G("block.position"))
  209. );
  210. // After store results
  211. // Restaura o array de registradores de retorno para fazer o pop dos returns
  212. ResetReturnArgs();
  213. }
  214. @Override
  215. public void TranslatePushReturn(Instruction inst) {
  216. // Tratado no metodo 'TranslateReturn'
  217. }
  218. @Override
  219. public void TranslateReturn(Instruction inst) {
  220. // Restaura o array de registradores de retorno
  221. ResetReturnArgs();
  222. try {
  223. Instruction retur;
  224. LinkedList<Instruction> intructions = getIR().Block().Instructions();
  225. int base = intructions.indexOf(inst);
  226. for (int i = inst.getInt("p1"); i > 0; i--) {
  227. retur = intructions.get(base - i);
  228. // System.out.println("Return:" + retur);
  229. Copy(retur, returnRegisters.remove(0))
  230. .S("tac.position", retur.G("global.position"))
  231. .S("comment", "push return");
  232. }
  233. } catch (Exception ex) {
  234. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  235. }
  236. }
  237. @Override
  238. public void TranslatePushParam(Instruction inst) {
  239. // Tratado no metodo 'TranslateCall'
  240. }
  241. @Override
  242. public void TranslatePopReturn(Instruction inst) {
  243. try {
  244. String p1 = inst.G("p1"), reg = returnRegisters.remove(0);
  245. // Se for uma variavel temporaria
  246. if (p1.contains("_T")) {
  247. CopyReg(reg, inst.G("reg.p1"));
  248. } else {
  249. StoreWord(reg,
  250. GlobalOrFrameRegister(p1),
  251. getTarget().Block().Data().Offset(p1));
  252. }
  253. System.out.println("Translate pop return" + inst);
  254. } catch (Exception ex) {
  255. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  256. }
  257. }
  258. @Override
  259. public void TranslatePopParam(Instruction inst) {
  260. try {
  261. // todo - resetar args
  262. // System.out.println("PopParam:" + inst);
  263. String p1 = inst.G("p1");
  264. // O indice é 2 por conta dos dois primeiros registradores {v0, v1}
  265. // System.out.println("PopParams:" + inst);
  266. int offset = getTarget().Block().Data().Offset(p1);
  267. StoreWord(returnRegisters.remove(2),
  268. GlobalOrFrameRegister(p1),
  269. offset)
  270. .S("tac.position", inst.G("block.position"))
  271. .S("comment", "pop param");
  272. // System.out.println("POPpARAM:" + inst);
  273. // LoadWord(inst.G("reg.p1"), Registers.R_FP, offset);
  274. } catch (Exception ex) {
  275. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  276. }
  277. }
  278. @Override
  279. public void TranslateBranch(Instruction inst) throws Exception {
  280. String instruction = Mips.InstructionByOperator(inst);
  281. LoadParam(inst);
  282. String rs = inst.G("reg.p1");
  283. String rt = inst.G("reg.p2");
  284. Instruction I = new Instruction("I", instruction)
  285. .S("label", inst.G("funcname"));
  286. switch (instruction) {
  287. case "beq": // == {[inst]}' ' {[rt]},{[rs]},{immediate}
  288. case "bne": // !=
  289. I.S("rs", rs).S("rt", rt);
  290. break;
  291. case "blez": // <= 0{[inst]}' ' {[rs]},{immediate}
  292. case "bltz": // < 0
  293. case "bgez": // >= 0
  294. case "bgtz": // > 0
  295. Add(new Instruction("R", "subu")// Rd <-- [Rs] - [Rt];
  296. .S("rs", rs)
  297. .S("rt", rt)
  298. .S("rd", Registers.R_V0)
  299. .S("tac.position", inst.G("block.position"))
  300. .S("comment", "")
  301. );
  302. I.S("rs", Registers.R_V0);
  303. break;
  304. }
  305. Add(I).S("label", inst.G("label"))
  306. .S("tac.position", inst.G("block.position"))
  307. .S("comment", comments.get(instruction));
  308. // Noop();
  309. // System.out.println("Translate branch:" + I);
  310. }
  311. @Override
  312. public void Prolog(String id) throws Exception {
  313. DataFrame data = getTarget().Block().Data();
  314. // Copia os dados para block target
  315. //Updata size in 4 bytes
  316. CopyData(
  317. // data.values(),
  318. // getIR().Block().Data().values()
  319. data,
  320. getIR().Block().Data()
  321. );
  322. // Adiciona o label
  323. Add(new Instruction()
  324. .S("type", "label")
  325. .S("format", "label")
  326. .S("label", id)
  327. );
  328. // Aloca o espaco da pilha
  329. Instruction alloc = Copy(Registers.R_SP, Registers.R_SP, "-" + data.Size())
  330. .S("comment", "p| push stack frame");
  331. if (!getTarget().Block().getName().equals("main")) {
  332. // Restaura o fp
  333. // Restaura o ra
  334. // boolean call = getIR().Block().HasCall();
  335. if (getIR().Block().HasCall()) {
  336. int newvars = 0;
  337. for (String reg : new String[]{Registers.R_FP, Registers.R_RA}) {
  338. data.Add(reg, new Node()
  339. .S("type", "int")
  340. .S("size", 1 * WORD_INC),
  341. 1);
  342. newvars -= WORD_INC;
  343. StoreWord(reg, Registers.R_SP, data.Offset(reg))
  344. .S("comment", "p| backup " + reg);
  345. }
  346. alloc.somar("offset", newvars);
  347. }
  348. // System.out.println("PROLOG:(" + newvars + ")" + alloc);
  349. }
  350. // System.out.println("Activation Registry:()\n" + data);
  351. if (alloc.getInt("offset", 0) != 0) {
  352. // Copia o sp para o fp
  353. CopyReg(Registers.R_SP, Registers.R_FP).Prepend("comment", "p|");
  354. ResetReturnArgs();
  355. } else {
  356. getTarget().Block().Remove(alloc);
  357. }
  358. }
  359. /**
  360. * Encerra a chamada de uma funcao
  361. *
  362. * @param id
  363. * @throws Exception
  364. */
  365. @Override
  366. public void Epilog(String id) throws Exception {
  367. DataFrame data = getTarget().Block().Data();
  368. if (!getTarget().Block().getName().equals("main")) {
  369. // Restaura o fp
  370. // Restaura o ra
  371. boolean call = getIR().Block().HasCall();
  372. for (String reg : new String[]{Registers.R_FP, Registers.R_RA}) {
  373. if (call) {
  374. LoadWord(reg, Registers.R_SP, data.Offset(reg)).S("comment", "e| restore " + reg);
  375. }
  376. }
  377. // Desaloca a pilha
  378. Copy(Registers.R_SP, Registers.R_SP, data.Size())
  379. .S("comment", "e|pop stack frame");
  380. CopyReg(Registers.R_SP, Registers.R_FP)
  381. .S("comment", "e|pop stack frame");
  382. // if (getIR().Block().HasCall()) {
  383. Add(new Instruction("jr")
  384. .S("rs", Registers.R_RA)
  385. .S("comment", "e|return"));
  386. // }[]
  387. } else {
  388. Add(new Instruction("stop").S("txt", "11111111111111111111111111111111").S("comment", "end of programa"));
  389. }
  390. }
  391. @Override
  392. public void TranslateIndexedAssignment(Instruction inst) throws Exception {
  393. //Fase de leitura
  394. IndexedRead(inst);
  395. //Fase de atribuicao
  396. IndexedDest(inst);
  397. }
  398. @Override
  399. public void TranslateUnary(Instruction inst) throws Exception {
  400. // Carrega o valor se nao esta em registrador
  401. // System.out.println("Translate Unary:" + inst);
  402. switch (inst.G("op")) {
  403. case "-": // Retorna o valor negado 10 -> -10
  404. Add(new Instruction("subu")// Rd <-- [Rs] - [Rt];
  405. .S("rd", inst.G("reg.dst"))
  406. .S("rs", Registers.R_ZERO)
  407. .S("rt", inst.G("reg.p1"))
  408. .S("comment", "negation arith")
  409. .S("tac.position", inst.G("block.position"))
  410. );
  411. break;
  412. case "!": // XOR ( 0 1 -> 1) XOR( 1 1 -> 0)
  413. Add(new Instruction("xori") // Rt <-- [Rs] AND (016 || [I15..0]); ;
  414. .S("rt", inst.G("reg.dst"))
  415. .S("rs", inst.G("reg.p1"))
  416. .S("offset", "1")
  417. .S("comment", "negation bool")
  418. .S("tac.position", inst.G("block.position"))
  419. );
  420. break;
  421. // case "*": // Copia do conteudo do ponteiro
  422. //
  423. // case "&": // Copia do endereco da variavel
  424. // break;// case "*": // Copia do conteudo do ponteiro
  425. //
  426. // case "&": // Copia do endereco da variavel
  427. // break;// case "*": // Copia do conteudo do ponteiro
  428. //
  429. // case "&": // Copia do endereco da variavel
  430. // break;// case "*": // Copia do conteudo do ponteiro
  431. //
  432. // case "&": // Copia do endereco da variavel
  433. // break;// case "*": // Copia do conteudo do ponteiro
  434. //
  435. // case "&": // Copia do endereco da variavel
  436. // break;// case "*": // Copia do conteudo do ponteiro
  437. //
  438. // case "&": // Copia do endereco da variavel
  439. // break;// case "*": // Copia do conteudo do ponteiro
  440. //
  441. // case "&": // Copia do endereco da variavel
  442. // break;// case "*": // Copia do conteudo do ponteiro
  443. //
  444. // case "&": // Copia do endereco da variavel
  445. // break;
  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. GlobalOrFrameRegister(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. GlobalOrFrameRegister(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. GlobalOrFrameRegister(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. @Override
  523. public IvannosysTargetArch Export() {
  524. Code Target = getTarget();
  525. System.out.println(Target.GData());
  526. String out = "", tmp;
  527. Integer index;
  528. for (Map.Entry<String, Block> x : Target.stmts.entrySet()) {
  529. System.out.println(x.getValue().Data());
  530. index = 0;
  531. for (Instruction instr : x.getValue().Instructions()) {
  532. // System.out.println("Export:" + instr);
  533. tmp = instr.G("inst.dec");
  534. if (tmp.equals("")) {
  535. continue;
  536. }
  537. out = out
  538. // .concat(Integer.toHexString(index))
  539. // .concat(":")
  540. // .concat(String.format("%X\n", tmp.trim()) + "\n");
  541. .concat(tmp + "\n");
  542. index++;
  543. }
  544. }
  545. // System.out.println("Export:" + out);
  546. // Grava resutlado no arquivo de memoria do simulador
  547. Utils.WriteFile("\\src\\tools\\mips\\memory\\mi.memory", out);
  548. try {
  549. new tools.mips.MipsProcessor(new tools.mips.MipsSettings() {
  550. {
  551. debugmode = true;
  552. // stepByStep = true;
  553. SetInstructionMemoryFile("\\src\\tools\\mips\\memory\\mi.memory");
  554. SetDataMemoryFile("\\src\\tools\\mips\\memory\\md.memory");
  555. }
  556. })
  557. .SetBreak("6c")
  558. .Run()
  559. .Persist();
  560. } catch (Exception ex) {
  561. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  562. }
  563. throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  564. }
  565. // public void CopyData(LinkedHashMap<String, Node> dst, LinkedHashMap<String, Node> src) throws Exception {
  566. public void CopyData(DataFrame dst, DataFrame src) throws Exception {
  567. Node value;
  568. LinkedHashMap<String, Node> svalues = src.values(),
  569. dvalues = dst.values();
  570. for (Map.Entry<String, Node> x : svalues.entrySet()) {
  571. value = x.getValue().copy();
  572. value.S("size", value.getInt("size") * WORD_INC);
  573. // System.out.println("Copy:[" + x.getKey() + "][" + value.G("id") + "]" + value.G("size") + "\n" + value);
  574. // dvalues.put(x.getKey(), value);
  575. dst.Set(x.getKey(), value);
  576. }
  577. }
  578. public IvannosysTargetArch SetTAC(Code tac) {
  579. try {
  580. this.IR = tac;
  581. Init();
  582. getTarget().AfterTranslateBlock("copy.dep", new CopyDeps(tac));
  583. // CopyData(target.GData().values(), IR.GData().values());
  584. CopyData(
  585. target.GData(),
  586. tac.GData()
  587. );
  588. } catch (Exception ex) {
  589. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  590. }
  591. return this;
  592. }
  593. /**
  594. * Criar uma inStrucao que copia o valor ou conteudo do regiStrador para o
  595. * regiStrador 'r'
  596. *
  597. * @param inst
  598. * @param push
  599. * @param rt
  600. */
  601. protected Instruction Copy(Instruction inst, String rt) {
  602. Instruction c;
  603. if (inst.eq("p1value", "true")) {
  604. // andi Rt,Rs,immediate | Rt <-- [Rs] + ([I15]16 || [I15..0]);
  605. c = Copy(rt, Registers.R_ZERO, inst.G("p1"));
  606. } else {
  607. // addu Rd,Rs,Rt | Rd <-- [Rs] + [Rt];
  608. LoadParam(inst, "p1");
  609. c = CopyReg(inst.G("reg.p1"), rt);
  610. }
  611. // System.out.println("COPY::" + c);
  612. return c.S("tac.position", inst.G("block.position"));
  613. }
  614. protected void IndexedRead(Instruction inst) {
  615. // Se a fonte é indexada
  616. if (inst.eq("src_indexed", "true")) {
  617. try {
  618. int offset = getTarget().Block().Data().Offset(inst.G("p1"));
  619. String p1 = inst.G("p1"),
  620. rt = inst.G("reg.p1"),
  621. rs = GlobalOrFrameRegister(p1);
  622. // System.out.println("Indexed read:" + inst);
  623. if (!inst.isNumber("p1.indice")) {
  624. String rd = inst.G("reg.p1.indice");
  625. if (!AddressCalculated.containsKey(p1)) {
  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. AddressCalculated.put(p1, rs);
  632. }
  633. rs = rd;
  634. } // Carrega o conteudo enderecado em rt para rt
  635. LoadWord(rt, rs, offset).S("tac.position", inst.G("block.position"));
  636. } catch (Exception ex) {
  637. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  638. }
  639. } else {
  640. // Se não é indexada carrega o parametro normalmente
  641. LoadParam(inst);
  642. }
  643. }
  644. /**
  645. * FaSe de atribuicao
  646. *
  647. * @param inst
  648. */
  649. protected void IndexedDest(Instruction inst) {
  650. // System.out.println("Indexeds:" + inst);
  651. String regp1 = inst.G("reg.p1"),
  652. regdst = inst.G("reg.dst");
  653. // Valor atribuido é indexado
  654. // 1 - Verificar se deve ser armazenado ou copiado
  655. boolean dstIndexed = inst.eq("dst_indexed", "true");
  656. if (dstIndexed || inst.eq("reg.dst.store", "true")) {
  657. try {
  658. // deve ser armazenado
  659. String dst = inst.G("dst"),
  660. rs = GlobalOrFrameRegister(dst),
  661. comment;
  662. int offset = getTarget().Block().Data().Offset(dst);
  663. if (dstIndexed) {
  664. if (!inst.isNumber("dst.indice")) {
  665. // Offset agora deve ser 0 pois o registrador conterá o endereco completo
  666. // offset = 0;
  667. String rd = inst.G("reg.dst.indice");
  668. if (!AddressCalculated.containsKey(dst)) {
  669. Add(new Instruction("addu")
  670. .S("rd", rd)
  671. .S("rs", rs)
  672. .S("rt", rd)
  673. .S("tac.position", inst.G("block.position"))
  674. );
  675. AddressCalculated.put(dst, rs);
  676. }
  677. rs = rd;
  678. }
  679. comment = "store in loaded address";
  680. } else {
  681. comment = "store in " + dst;
  682. }// System.out.println("Inst:" + inst);
  683. StoreWord(regp1, rs, offset)
  684. .S("tac.position", inst.G("block.position"))
  685. .S("comment", comment);
  686. } catch (Exception ex) {
  687. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  688. }
  689. } else { // deve ser copiado
  690. CopyReg(regp1, regdst)
  691. .S("tac.position", inst.G("block.position"));
  692. }
  693. }
  694. /**
  695. * Verificar Se o valor da atribuição ja eSta em regiStrador. CaSo não
  696. * eSteja o valor é carregado e o valor retornado é o nome do regiStrador
  697. *
  698. * @param inst
  699. * @param param
  700. * @return
  701. */
  702. protected String LoadParam(Instruction inst) {
  703. return LoadParam(inst, "p1,p2");
  704. }
  705. protected String LoadParam(Instruction inst, String params) {
  706. return LoadParam(inst, params.split(","));
  707. }
  708. protected String LoadParam(Instruction inst, String[] params) {
  709. String pname;
  710. for (String param : params) {
  711. if (!inst.Has("reg." + param + ".load")) {
  712. continue;
  713. }
  714. Instruction Ninst = new Instruction();
  715. pname = inst.G(param);
  716. if (inst.eq(param + "value", "true")) {
  717. // System.out.println("pname:" + pname);
  718. if (pname.equals("0")) {
  719. inst.S("reg." + param, Registers.R_ZERO);
  720. continue;
  721. }
  722. Ninst.S("inst", "addiu") // R[$rt] ← {(imm)[15:0], 0 × 16}
  723. .S("rs", Registers.R_ZERO)
  724. .S("rt", inst.G("reg." + param))
  725. .S("offset", pname);
  726. } else {
  727. try {
  728. Ninst.S("inst", "lw") // R[$rt] ← Mem4B(R[$rs] + SignExt16b(imm))
  729. .S("rt", inst.G("reg." + param))
  730. .S("rs", GlobalOrFrameRegister(pname))
  731. .S("comment", "load address stored in " + pname)
  732. .set("offset", getTarget().Block().Data().Offset(pname));
  733. } catch (Exception ex) {
  734. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  735. }
  736. }
  737. Add(Ninst.S("tac.position", inst.G("block.position")));
  738. // x.S("reg." + param, reg);
  739. }
  740. return null;
  741. }
  742. /**
  743. * Copia o valor do regiStrador Src para o dSt
  744. *
  745. * @param src
  746. * @param dst
  747. * @return
  748. */
  749. protected Instruction CopyReg(String src, String dst) {
  750. return Add(new Instruction("addu")
  751. .S("rs", Registers.R_ZERO)
  752. .S("rt", src)
  753. .S("rd", dst)
  754. .S("comment", "copy " + dst + " ← " + src));
  755. }
  756. protected Instruction Copy(String rt, String rs, int offset) {
  757. return Copy(rt, rs, "" + offset);
  758. }
  759. protected Instruction Copy(String rt, String rs, String offset) {
  760. return Add(new Instruction("addiu") // lw $rt, imm($rs)
  761. .S("rt", rt)
  762. .S("rs", rs)
  763. .S("offset", offset)
  764. .S("comment", "copy " + rs + " ← " + rt)
  765. );
  766. }
  767. protected Instruction StoreWord(String rt, String rs, int offset) {
  768. return StoreWord(rt, rs, "" + offset);
  769. }
  770. protected Instruction StoreWord(String rt, String rs, String offset) {
  771. return Add(new Instruction("sw")
  772. .S("rt", rt)
  773. .S("rs", rs)
  774. .S("offset", offset));
  775. }
  776. protected Instruction LoadWord(String rt, String rs, int offset) {
  777. return LoadWord(rt, rs, "" + offset);
  778. }
  779. protected Instruction LoadWord(String rt, String rs, String offset) {
  780. return Add(new Instruction("lw") // lw $rt, imm($rs)
  781. .S("rt", rt)
  782. .S("rs", rs)
  783. .S("offset", offset));
  784. }
  785. protected Instruction Noop() {
  786. return new Instruction("sll")
  787. .S("rs", "zero")
  788. .S("rt", "zero")
  789. .S("rd", "zero");
  790. }
  791. protected Instruction AddNoop() {
  792. return Add(Noop());
  793. }
  794. @Override
  795. protected Instruction Add(Instruction inst) {
  796. try {
  797. if (!inst.eq("type", "label")) {
  798. getTarget().PositionInc();
  799. Instruction definiction = Mips.Instruction(inst.G("inst"));
  800. inst.Merge("sa,type,inst,codop,func,format", definiction);
  801. }
  802. } catch (Exception ex) {
  803. Logger.getLogger(Gen.class
  804. .getName()).log(Level.SEVERE, null, ex);
  805. }
  806. return super.Add(inst); //To change body of generated methods, choose Tools | Templates.
  807. }
  808. protected String GlobalOrFrameRegister(String var) {
  809. // System.out.println("GlobalOrFrameRegister:" + var);
  810. return var.contains("_G") ? Registers.R_GP : Registers.R_FP;
  811. }
  812. protected Instruction StoreResult(Instruction inst, String rd, String dst) {
  813. if (inst.eq("reg.dst.store", "true")) {
  814. try {
  815. return StoreWord(rd,
  816. GlobalOrFrameRegister(dst),
  817. getTarget().Block().Data().Offset(dst)
  818. ).S("tac.position", inst.G("block.position"));
  819. } catch (Exception ex) {
  820. Logger.getLogger(Gen.class.getName()).log(Level.SEVERE, null, ex);
  821. }
  822. }
  823. return null;
  824. }
  825. private void ResetReturnArgs() {
  826. returnRegisters = new ArrayList<String>() {
  827. {
  828. add("v0");
  829. add("v1");
  830. add("a0");
  831. add("a1");
  832. add("a2");
  833. add("a3");
  834. }
  835. };
  836. }
  837. @Override
  838. public void TranslateLoad(Instruction inst) throws Exception {
  839. // System.out.println("TranslateLoad:" + inst);
  840. String addr = inst.G("p1");
  841. // System.out.println("Load " + addr + " on block ");
  842. LoadWord(
  843. inst.G("reg.p1"),
  844. GlobalOrFrameRegister(addr),
  845. getTarget().Block().Data().Offset(addr)
  846. );
  847. }
  848. @Override
  849. public void TranslateStore(Instruction inst) throws Exception {
  850. String addr = inst.G("p1");
  851. // System.out.println("Store " + addr + " on block ");
  852. StoreWord(
  853. inst.G("reg.p1"),
  854. GlobalOrFrameRegister(addr),
  855. getTarget().Block().Data().Offset(addr)
  856. );
  857. }
  858. }
  859. // 00000000 <main>:
  860. // 0: 0666763252 addiu sp,sp,-12 --p| push stack frame
  861. // 4: 0001962017 addu fp,zero,sp --p|copy fp ← sp
  862. // 8: 0605028352 addiu s0,zero,0 .0.--copy _V1 ← 0
  863. // c: 2949644288 sw s0,fp,0
  864. //10: 0605093890 addiu s1,zero,2 .2.--copy _V2 ← 2
  865. //14: 2949709828 sw s1,fp,4
  866. //18: 0605159424 addiu s2,zero,0 .4.--copy _V3 ← 0
  867. //1c: 2949775368 sw s2,fp,8
  868. //20: 0134217750 j 58 <main+0x58> .6.
  869. //24: 2412969988 lw s3,fp,4
  870. //28: 0001253409 addu a0,zero,s3 .8.--push param
  871. //2c: 0201326621 jal 74 <bitCount+0x0> .9.--jump to <bitCount>
  872. //30: 0000153633 addu t3,zero,v0 --copy t3 ← v0
  873. //34: 2413035520 lw s4,fp,0
  874. //38: 0042704929 addu s4,s4,t3 .12.
  875. //3c: 2949906432 sw s4,fp,0
  876. //40: 2413101060 lw s5,fp,4
  877. //44: 0649396225 addiu s5,s5,1 .15.
  878. //48: 2949971972 sw s5,fp,4
  879. //4c: 2413166600 lw s6,fp,8
  880. //50: 0651558913 addiu s6,s6,1 .18.
  881. //54: 2950037512 sw s6,fp,8
  882. //58: 2413232136 lw s7,fp,8
  883. //5c: 0604897282 addiu t6,zero,2 .21.
  884. //60: 0049156131 subu v0,s7,t6 .21.
  885. //64: 0071368687 bltz v0,24 <main+0x24> .21.--branch if register < 0
  886. //68: 2412773376 lw s0,fp,0
  887. //6c: 0001052705 addu v0,zero,s0 .23.--push return
  888. //70: 4294967295 stop --end of programa
  889. // 00000074 <bitCount>:
  890. //74: 0666763256 addiu sp,sp,-8 --p| push stack frame
  891. //78: 0001962017 addu fp,zero,sp --p|copy fp ← sp
  892. //7c: 2948857856 sw a0,fp,0 .0.--pop param
  893. //80: 0605093888 addiu s1,zero,0 .1.--copy _V5 ← 0
  894. //84: 2949709828 sw s1,fp,4
  895. //88: 2412773376 lw s0,fp,0
  896. //8c: 0033558563 subu v0,s0,zero .4.
  897. //90: 0406847500 blez v0,c4 <bitCount+0x50> .4.--branch if register <= 0
  898. //94: 2412904452 lw s2,fp,4
  899. //98: 0642908161 addiu s2,s2,1 .6.
  900. //9c: 2949775364 sw s2,fp,4
  901. //a0: 2412969984 lw s3,fp,0
  902. //a4: 0604700673 addiu t3,zero,1 .9.
  903. //a8: 0040591395 subu t4,s3,t3 .9.
  904. //ac: 2412969984 lw s3,fp,0
  905. //b0: 0040671268 and s3,s3,t4 .11.
  906. //b4: 2949840896 sw s3,fp,0
  907. //b8: 2412969984 lw s3,fp,0
  908. //bc: 0308281345 beq zero,s3,c4 <bitCount+0x50> .14.--branch if equals
  909. //c0: 0134217765 j 94 <bitCount+0x20> .15.
  910. //c4: 2413035524 lw s4,fp,4
  911. //c8: 0001314849 addu v0,zero,s4 .42.--push return
  912. //cc: 0666697736 addiu sp,sp,8 --e|pop stack frame
  913. //d0: 0065011720 jr ra --e|return