Advertisement
Guest User

Untitled

a guest
May 24th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.42 KB | None | 0 0
  1. package AST.Visitor;
  2.  
  3. import java.util.*;
  4.  
  5. import AST.*;
  6.  
  7. public class CodeGenVisitor implements Visitor {
  8. public int memory;
  9. public Map<String, ClassTable> info;
  10. public String currentClass;
  11. public String currentMethod;
  12. public String[] args = {"%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"};
  13.  
  14. public Map<String, Integer> labels = new HashMap<>();
  15. public boolean aligned = false;
  16.  
  17.  
  18. public CodeGenVisitor(){
  19.  
  20. }
  21.  
  22. public CodeGenVisitor(Map<String, ClassTable> info){
  23. this.info = info;
  24. this.memory = 0;
  25. }
  26.  
  27.  
  28. // MainClass m;
  29. // ClassDeclList cl;
  30. public void visit(Program n) {
  31. gen("\t.text");
  32. gen("\t.globl asm_main");
  33. n.m.accept(this);
  34.  
  35. for(int i = 0; i < n.cl.size(); i++){
  36. n.cl.get(i).accept(this);
  37. }
  38. }
  39.  
  40. // Identifier i1,i2;
  41. // Statement s;
  42. public void visit(MainClass n) {
  43. currentClass = n.i1.s;
  44. currentMethod = null;
  45.  
  46. genLabel("asm_main");
  47.  
  48. //Prologue
  49. //Allocate stack frame
  50. push("%rbp");
  51. genbin("movq", "%rsp","%rbp");
  52.  
  53. n.s.accept(this);
  54.  
  55. //Epilogue
  56. genbin("movq","%rbp", "%rsp");
  57. pop("%rbp");
  58. gen("\tret");
  59.  
  60. System.out.println();
  61. gen("\t.data");
  62. gen(n.i1.s + "$$:\t.quad\t0");
  63.  
  64. }
  65.  
  66. // Identifier i;
  67. // VarDeclList vl;
  68. // MethodDeclList ml;f
  69. public void visit(ClassDeclSimple n) {
  70. currentClass = n.i.s;
  71. currentMethod = null;
  72.  
  73. //Constructor
  74. genLabel(n.i.s + "$" + n.i.s);
  75.  
  76. push("%rbp");
  77. genbin("movq", "%rsp","%rbp");
  78.  
  79. push("%rdi");
  80.  
  81. genbin("movq", "$" + (8 + (info.get(n.i.s).fields.size() * 8)), "%rdi");
  82.  
  83. align("%rax");
  84. genbin("call", "mjcalloc");
  85. dealign("%r14");
  86.  
  87. pop("%rdi");
  88. genbin("leaq", n.i.s + "$$", "%rdx");
  89. genbin("movq", "%rdx", "0(%rax)");
  90. for (int i = 0; i < n.vl.size(); i++) {
  91. info.get(currentClass).fieldOffset.put(n.vl.get(i).i.s, (i + 1) * (-8));
  92. }
  93.  
  94. for(int i = 8; i < (8 + info.get(n.i.s).fields.size() * 8); i += 8){
  95. genbin("movq", "$0", i + "(%rax)");
  96. }
  97.  
  98. genbin("movq", "%rbp", "%rsp");
  99. pop("%rbp");
  100. gen("\tret");
  101. gen("");
  102.  
  103. for(int i = 0; i < n.ml.size(); i++){
  104. currentMethod = n.ml.get(i).i.s;
  105. n.ml.get(i).accept(this);
  106. }
  107.  
  108. gen("\t.data");
  109. gen(n.i.s + "$$:\t.quad\t0");
  110. gen( "\t\t.quad\t" + currentClass + "$" + currentClass);
  111. for(int i = 0; i < n.ml.size(); i++){
  112. gen( "\t\t.quad\t" + currentClass + "$" + n.ml.get(i).i.s);
  113. }
  114. }
  115.  
  116. // Identifier i;
  117. // Identifier j;
  118. // VarDeclList vl;
  119. // MethodDeclList ml;
  120. public void visit(ClassDeclExtends n) {
  121. currentClass = n.i.s;
  122. currentMethod = null;
  123. genLabel(n.i.s + "$" + n.i.s);
  124.  
  125. push("%rbp");
  126. genbin("movq", "%rsp","%rbp");
  127.  
  128. push("%rdi");
  129.  
  130. genbin("movq", "$" + (8 + (info.get(n.i.s).totalFields * 8)), "%rdi");
  131.  
  132. align("%rax");
  133. genbin("call", "mjcalloc");
  134. dealign("%r14");
  135.  
  136.  
  137. pop("%rdi");
  138. genbin("leaq", n.i.s + "$$", "%rdx");
  139. genbin("movq", "%rdx", "0(%rax)");
  140.  
  141. int fieldsBefore = info.get(info.get(currentClass).parent).totalFields;
  142. for (int i = 0; i < n.vl.size(); i++) {
  143. info.get(currentClass).fieldOffset.put(n.vl.get(i).i.s, (i + 1 + fieldsBefore) * (-8));
  144. }
  145.  
  146. for(int i = 8; i < (8 + info.get(n.i.s).totalFields * 8); i += 8){
  147. genbin("movq", "$0", i + "(%rax)");
  148. }
  149.  
  150. genbin("movq", "%rbp", "%rsp");
  151. pop("%rbp");
  152. gen("\tret");
  153. gen("");
  154.  
  155. for(int i = 0; i < n.ml.size(); i++){
  156. currentMethod = n.ml.get(i).i.s;
  157. n.ml.get(i).accept(this);
  158. }
  159.  
  160. gen("\t.data");
  161. gen(n.i.s + "$$:\t.quad\t0");
  162. gen( "\t\t.quad\t" + currentClass + "$" + currentClass);
  163.  
  164. Map<String, MethodTable> allMethods = info.get(currentClass).allMethods;
  165. for (String s : allMethods.keySet()) {
  166. gen("\t\t.quad\t" + allMethods.get(s).classname + "$" + allMethods.get(s).name);
  167. }
  168. }
  169.  
  170. // Type t;
  171. // Identifier i;
  172. public void visit(VarDecl n) {
  173. }
  174.  
  175. // Type t;
  176. // Identifier i;
  177. // FormalList fl;
  178. // VarDeclList vl;
  179. // StatementList sl;
  180. // Exp e;
  181. public void visit(MethodDecl n) {
  182. currentMethod = n.i.s;
  183. genLabel(currentClass + "$" + n.i.s);
  184.  
  185. push("%rbp");
  186. genbin("movq", "%rsp","%rbp");
  187.  
  188. if (n.fl.size() == 0) {
  189. push("%rdi");
  190. } else {
  191. for (int i = 0; i <= n.fl.size(); i++) {
  192. if (i == 0) {
  193. push("%rdi");
  194. } else {
  195. push(args[i]);
  196. }
  197. }
  198. }
  199. for (int i = 0; i < n.vl.size(); i++) {
  200. push("$0");
  201. }
  202.  
  203. for(int i = 0; i < n.sl.size(); i++){
  204. n.sl.get(i).accept(this);
  205. }
  206.  
  207. n.e.accept(this);
  208. for (int i = n.vl.size() - 1; i >= 0; i--) {
  209. pop("%rsi");
  210. }
  211. if (n.fl.size() == 0) {
  212. pop("%rdi");
  213. } else {
  214. for (int i = n.fl.size(); i >= 0; i--) {
  215. if (i == 0) {
  216. pop("%rdi");
  217. }
  218. pop(args[i]);
  219. }
  220. }
  221.  
  222. genbin("movq","%rbp", "%rsp");
  223. pop("%rbp");
  224. gen("\tret");
  225. }
  226.  
  227. // Type t;
  228. // Identifier i;
  229. public void visit(Formal n) {
  230. }
  231.  
  232. public void visit(IntArrayType n) {
  233. }
  234.  
  235. public void visit(BooleanType n) {
  236. }
  237.  
  238. public void visit(IntegerType n) {
  239. }
  240.  
  241. // String s;
  242. public void visit(IdentifierType n) {
  243.  
  244. }
  245.  
  246. // StatementList sl;
  247. public void visit(Block n) {
  248. for(int i = 0; i < n.sl.size(); i++){
  249. n.sl.get(i).accept(this);
  250. }
  251. }
  252.  
  253. // Exp e;
  254. // StatementList s1,s2;
  255. public void visit(If n) {
  256. String _else_ = "else" + labelnum("else");
  257. String _done_ = "done" + labelnum("done");
  258.  
  259. n.e.accept(this);
  260. genbin("cmpq", "$0", "%rax");
  261. genbin("je", _else_);
  262. n.s1.get(0).accept(this);
  263. genbin("jmp", _done_);
  264. genLabel(_else_);
  265. n.s2.get(0).accept(this);
  266. genLabel(_done_);
  267. }
  268.  
  269. // Exp e;
  270. // StatementList sl;
  271. public void visit(While n) {
  272. String _test_ = "test" + labelnum("test");
  273. String _done_ = "done" + labelnum("done");
  274.  
  275. genLabel(_test_);
  276.  
  277. n.e.accept(this);
  278. genbin("cmpq", "$0", "%rax");
  279. genbin("je", _done_);
  280. n.sl.get(0).accept(this);
  281. genbin("jmp", _test_);
  282. genLabel(_done_);
  283. }
  284.  
  285. // Exp e;
  286. public void visit(Print n) {
  287. n.e.accept(this);
  288. push("%rdi");
  289. genbin("movq", "%rax", "%rdi");
  290.  
  291. align("%rax");
  292. genbin("call", "put");
  293. dealign("%r14");
  294. pop("%rdi");
  295. }
  296.  
  297. // Identifier i;
  298. // Exp e;
  299. public void visit(Assign n) {
  300. n.e.accept(this);
  301. genbin("movq", "%rax", getParamLocalOffset(n.i.s));
  302. }
  303.  
  304. // Identifier i;
  305. // Exp e1,e2;
  306. public void visit(ArrayAssign n) {
  307. n.e1.accept(this); //index
  308. push("%rax");
  309.  
  310. n.e2.accept(this); //value
  311. pop("%rdx");
  312.  
  313. //Array pointer in %rax
  314.  
  315. genbin("movq", getParamLocalOffset(n.i.s), "%rcx");
  316. genbin("addq", "$1", "%rdx");
  317.  
  318. genbin("movq", "%rax", "(%rcx, %rdx, 8)");
  319.  
  320. }
  321.  
  322. // Exp e1,e2;
  323. public void visit(And n) {
  324. String _and_ = "and" + labelnum("and");
  325. String _done_ = "done" + labelnum("done");
  326.  
  327. n.e1.accept(this);
  328. genbin("cmpq", "$0", "%rax");
  329. genbin("je", _and_);
  330.  
  331. n.e2.accept(this);
  332. genbin("cmpq", "$0", "%rax");
  333. genbin("je", _and_);
  334.  
  335. genbin("movq", "$1", "%rax");
  336. genbin("jmp", _done_);
  337.  
  338. genLabel(_and_);
  339. genbin("movq", "$0", "%rax");
  340.  
  341. genLabel(_done_);
  342.  
  343. }
  344.  
  345. // Exp e1,e2;
  346. public void visit(LessThan n) {
  347. String _lt_ = "lt" + labelnum("lt");
  348. String _done_ = "done" + labelnum("done");
  349.  
  350. n.e1.accept(this);
  351. push("%rax");
  352. n.e2.accept(this);
  353. pop("%rdx");
  354. genbin("cmpq", "%rax", "%rdx");
  355. genbin("jl", _lt_);
  356. genbin("movq", "$0", "%rax");
  357. genbin("jmp", _done_);
  358. genLabel(_lt_);
  359. genbin("movq", "$1", "%rax");
  360. genbin("jmp", _done_);
  361. genLabel(_done_);
  362. }
  363.  
  364. // Exp e1,e2;
  365. public void visit(Plus n) {
  366. n.e1.accept(this);
  367. push("%rax");
  368. n.e2.accept(this);
  369. pop("%rdx");
  370. genbin("addq", "%rdx", "%rax");
  371. }
  372.  
  373. // Exp e1,e2;
  374. public void visit(Minus n) {
  375. n.e2.accept(this);
  376. push("%rax");
  377. n.e1.accept(this);
  378. pop("%rdx");
  379.  
  380. genbin("subq", "%rdx", "%rax");
  381.  
  382. }
  383.  
  384. // Exp e1,e2;
  385. public void visit(Times n) {
  386. n.e1.accept(this);
  387. push("%rax");
  388. n.e2.accept(this);
  389. pop("%rdx");
  390. genbin("imulq", "%rdx", "%rax");
  391. }
  392.  
  393. // Exp e1,e2;
  394. public void visit(ArrayLookup n) {
  395. n.e1.accept(this);
  396. push("%rax");
  397. n.e2.accept(this);
  398. pop("%rdx");
  399.  
  400. genbin("movq", "8(%rdx, %rax, 8)", "%rax");
  401. }
  402.  
  403. // Exp e;
  404. public void visit(ArrayLength n) {
  405. n.e.accept(this);
  406. genbin("movq", "0(%rax)", "%rax");
  407. }
  408.  
  409. // Exp e;
  410. // Identifier i;
  411. // ExpList el;
  412. public void visit(Call n) {
  413.  
  414. push("%rdi");
  415.  
  416. genbin("movq", "%rdi", "%rbx");
  417. n.e.accept(this);
  418.  
  419. if(!(n.e instanceof This)) {
  420. genbin("movq", "%rax", "%rdi");
  421. }
  422.  
  423. for (int i = 1; i <= n.el.size(); i++) {
  424. n.el.get(i - 1).accept(this);
  425. if (n.el.get(i - 1) instanceof This) {
  426. genbin("movq", "%rbx", args[i]);
  427. } else {
  428. genbin("movq", "%rax", args[i]);
  429. }
  430. }
  431.  
  432. if((memory + 8 * n.el.size()) % 16 != 0){
  433. align("%rax");
  434. }
  435.  
  436. genbin("movq", "(%rdi)", "%rax");
  437.  
  438. int offset = 1;
  439. for (String s : info.get(n.e.expType).allMethods.keySet()) {
  440. if (s.equals(n.i.s)) {
  441. break;
  442. }
  443. offset++;
  444. }
  445.  
  446. genbin("leaq", 8 + (offset * 8) + "(%rax)", "%rax");
  447. genbin("call", "*(%rax)");
  448.  
  449. dealign("%r14");
  450.  
  451. pop("%rdi");
  452. }
  453.  
  454. // int i;
  455. public void visit(IntegerLiteral n) {
  456. if(n.i == 0){
  457. genbin("xorq", "%rax", "%rax");
  458. }
  459. else{
  460. genbin("movq", "$" + n.i, "%rax");
  461. }
  462. }
  463.  
  464. public void visit(True n) {
  465. genbin("movq", "$1", "%rax");
  466.  
  467. }
  468.  
  469. public void visit(False n) {
  470. genbin("movq", "$0", "%rax");
  471. }
  472.  
  473. // String s;
  474. public void visit(IdentifierExp n) {
  475. genbin("movq", getParamLocalOffset(n.s), "%rax");
  476. }
  477.  
  478. public void visit(This n) {
  479. genbin("movq", "%rdi", "%rax");
  480. }
  481.  
  482. // Exp e;
  483. public void visit(NewArray n) {
  484. push("%rdi");
  485. n.e.accept(this);
  486.  
  487. //Allocation 8 bytes for length and 8*length bytes
  488.  
  489. push("%rdx");
  490. push("%rax");
  491.  
  492. genbin("addq", "$1", "%rdi");
  493. genbin("imulq", "$8", "%rdi");
  494.  
  495. genbin("movq", "%rax", "%rdi");
  496.  
  497. align("%rax");
  498. genbin("call", "mjcalloc");
  499. dealign("%r14");
  500.  
  501. pop("%rdx");
  502.  
  503. genbin("movq", "%rdx", "0(%rax)");
  504.  
  505. genbin("addq", "$1", "%rdx");
  506. genbin("imulq", "$8", "%rdx");
  507.  
  508. String _arr_ = "arr" + labelnum("arr");
  509. String _done_ = "done" + labelnum("done");
  510.  
  511. push("%rcx");
  512.  
  513.  
  514. //%rax = pointer to array
  515. //%rdx = array length
  516. //%rcx = current index
  517. genbin("movq", "$8", "%rcx");
  518.  
  519. //i < 8 + arr.length * 8
  520. genLabel(_arr_);
  521. genbin("cmpq", "%rcx", "%rdx");
  522.  
  523. genbin("je", _done_);
  524. genbin("movq", "$0", "(%rcx, %rax)");
  525. genbin("addq", "$8", "%rcx");
  526. genbin("jmp", _arr_);
  527.  
  528. genLabel(_done_);
  529.  
  530. pop("%rcx");
  531. pop("%rdx");
  532. pop("%rdi");
  533. }
  534.  
  535. // Identifier i;
  536. public void visit(NewObject n) {
  537. align("%rax");
  538. genbin("call", n.i.s + "$" + n.i.s);
  539. dealign("%r14");
  540. }
  541.  
  542. // Exp e;
  543. public void visit(Not n) {
  544. n.e.accept(this);
  545. push("%rdx");
  546. push("%rax");
  547.  
  548. genbin("movq", "$1", "%rax");
  549. pop("%rdx");
  550.  
  551. genbin("subq", "%rdx", "%rax");
  552. pop("%rdx");
  553. }
  554.  
  555. // String s;
  556. public void visit(Identifier n) {
  557.  
  558. }
  559.  
  560. // Exp e;
  561. public void visit(Display n) {
  562. }
  563.  
  564.  
  565. public void gen(String s){
  566. System.out.println(s);
  567. }
  568.  
  569. public void genbin(String op, String src, String dst){
  570. gen("\t" + op + "\t" + src + "," + dst);
  571. }
  572.  
  573. public void genbin(String op, String r){
  574. gen("\t" + op + "\t" + r);
  575. }
  576.  
  577. public void push(String s){
  578. memory += 8;
  579. genbin("pushq", s);
  580. }
  581.  
  582. public void pop(String s){
  583. memory -= 8;
  584. genbin("popq", s);
  585. }
  586.  
  587. public void align(String s){
  588. if(memory % 16 != 0) {
  589. push(s);
  590. aligned = true;
  591. }
  592. }
  593.  
  594.  
  595. public void dealign(String s){
  596. if(aligned) {
  597. pop(s);
  598. aligned = false;
  599. }
  600. }
  601.  
  602. public void genLabel(String L){
  603. gen(L + ":");
  604. }
  605.  
  606. public String getParamLocalOffset(String s) {
  607. //parameters
  608. List<ParameterTuple> methodArgs = info.get(currentClass).methods.get(currentMethod).argsOrder;
  609. for (int i = 0; i < methodArgs.size(); i++) {
  610. if (s.equals(methodArgs.get(i).name)) {
  611. return "-" + ((i + 2) * 8) + "(%rbp)";
  612. }
  613. }
  614. //local declarations
  615. List<ParameterTuple> varsOrder = info.get(currentClass).methods.get(currentMethod).varsOrder;
  616. int methodOffset = 8 * (methodArgs.size() + 1);
  617. for (int i = 0; i < varsOrder.size(); i++) {
  618. if (s.equals(varsOrder.get(i).name)) {
  619. return "-" + (methodOffset + (i + 1) * 8) + "(%rbp)";
  620. }
  621. }
  622. //class
  623. genbin("movq", "-8(%rbp)", "%r15");
  624.  
  625. if (info.get(currentClass).fieldOffset.containsKey(s)) {
  626. return info.get(currentClass).fieldOffset.get(s) + "(%r15)";
  627. } else {
  628. Integer offset = null;
  629. String tempClass = currentClass;
  630. while (offset == null) {
  631. tempClass = info.get(currentClass).parent;
  632. offset = info.get(tempClass).fieldOffset.get(s);
  633. }
  634. return offset + "(%r15)";
  635. }
  636. }
  637.  
  638. public int labelnum(String s){
  639. if (!labels.containsKey(s)) {
  640. labels.put(s, 1);
  641. } else {
  642. labels.put(s, labels.get(s) + 1);
  643. }
  644. return labels.get(s);
  645. }
  646. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement