Gen.java 32 KB

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