Gen.java 29 KB

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