Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.44 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", "%rdi", 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("call", info.get(n.e.expType).allMethods.get(n.i.s).classname + "$" + n.i.s);
  437.  
  438.  
  439. dealign("%r14");
  440.  
  441. pop("%rdi");
  442. }
  443.  
  444. // int i;
  445. public void visit(IntegerLiteral n) {
  446. if(n.i == 0){
  447. genbin("xorq", "%rax", "%rax");
  448. }
  449. else{
  450. genbin("movq", "$" + n.i, "%rax");
  451. }
  452. }
  453.  
  454. public void visit(True n) {
  455. genbin("movq", "$1", "%rax");
  456.  
  457. }
  458.  
  459. public void visit(False n) {
  460. genbin("movq", "$0", "%rax");
  461. }
  462.  
  463. // String s;
  464. public void visit(IdentifierExp n) {
  465. genbin("movq", getParamLocalOffset(n.s), "%rax");
  466. }
  467.  
  468. public void visit(This n) {
  469. genbin("movq", "%rdi", "%rax");
  470. }
  471.  
  472. // Exp e;
  473. public void visit(NewArray n) {
  474. push("%rdi");
  475. n.e.accept(this);
  476.  
  477. //Allocation 8 bytes for length and 8*length bytes
  478. <<<<<<< HEAD
  479.  
  480. push("%rdx");
  481. push("%rax");
  482.  
  483. genbin("addq", "$1", "%rdi");
  484. genbin("imulq", "$8", "%rdi");
  485.  
  486. genbin("movq", "%rax", "%rdi");
  487.  
  488. align("%rax");
  489. genbin("call", "mjcalloc");
  490. dealign("%r14");
  491. =======
  492.  
  493. push("%rdx");
  494. push("%rax");
  495.  
  496. genbin("addq", "$1", "%rdi");
  497. genbin("imulq", "$8", "%rdi");
  498.  
  499. genbin("movq", "%rax", "%rdi");
  500. genbin("call", "mjcalloc");
  501. >>>>>>> 448d8422558ba182b5dfbfea370272c71a5edc2f
  502.  
  503. pop("%rdx");
  504.  
  505. genbin("movq", "%rdx", "0(%rax)");
  506.  
  507. genbin("addq", "$1", "%rdx");
  508. genbin("imulq", "$8", "%rdx");
  509.  
  510. String _arr_ = "arr" + labelnum("arr");
  511. String _done_ = "done" + labelnum("done");
  512.  
  513. push("%rcx");
  514.  
  515.  
  516. //%rax = pointer to array
  517. //%rdx = array length
  518. //%rcx = current index
  519. genbin("movq", "$8", "%rcx");
  520.  
  521. //i < 8 + arr.length * 8
  522. genLabel(_arr_);
  523. genbin("cmpq", "%rcx", "%rdx");
  524.  
  525. genbin("je", _done_);
  526. genbin("movq", "$0", "(%rcx, %rax)");
  527. genbin("addq", "$8", "%rcx");
  528. genbin("jmp", _arr_);
  529.  
  530. genLabel(_done_);
  531.  
  532. pop("%rcx");
  533. pop("%rdx");
  534. pop("%rdi");
  535. }
  536.  
  537. // Identifier i;
  538. public void visit(NewObject n) {
  539. align("%rax");
  540. genbin("call", n.i.s + "$" + n.i.s);
  541. dealign("%r14");
  542. }
  543.  
  544. // Exp e;
  545. public void visit(Not n) {
  546. n.e.accept(this);
  547. push("%rdx");
  548. push("%rax");
  549.  
  550. genbin("movq", "$1", "%rax");
  551. pop("%rdx");
  552.  
  553. genbin("subq", "%rdx", "%rax");
  554. pop("%rdx");
  555. }
  556.  
  557. // String s;
  558. public void visit(Identifier n) {
  559.  
  560. }
  561.  
  562. // Exp e;
  563. public void visit(Display n) {
  564. }
  565.  
  566.  
  567. public void gen(String s){
  568. System.out.println(s);
  569. }
  570.  
  571. public void genbin(String op, String src, String dst){
  572. gen("\t" + op + "\t" + src + "," + dst);
  573. }
  574.  
  575. public void genbin(String op, String r){
  576. gen("\t" + op + "\t" + r);
  577. }
  578.  
  579. public void push(String s){
  580. memory += 8;
  581. genbin("pushq", s);
  582. }
  583.  
  584. public void pop(String s){
  585. memory -= 8;
  586. genbin("popq", s);
  587. }
  588.  
  589. public void align(String s){
  590. if(memory % 16 != 0) {
  591. push(s);
  592. aligned = true;
  593. }
  594. }
  595.  
  596.  
  597. public void dealign(String s){
  598. if(aligned) {
  599. pop(s);
  600. aligned = false;
  601. }
  602. }
  603.  
  604. public void genLabel(String L){
  605. gen(L + ":");
  606. }
  607.  
  608. public String getParamLocalOffset(String s) {
  609. //parameters
  610. List<ParameterTuple> methodArgs = info.get(currentClass).methods.get(currentMethod).argsOrder;
  611. for (int i = 0; i < methodArgs.size(); i++) {
  612. if (s.equals(methodArgs.get(i).name)) {
  613. return "-" + ((i + 2) * 8) + "(%rbp)";
  614. }
  615. }
  616. //local declarations
  617. List<ParameterTuple> varsOrder = info.get(currentClass).methods.get(currentMethod).varsOrder;
  618. int methodOffset = 8 * (methodArgs.size() + 1);
  619. for (int i = 0; i < varsOrder.size(); i++) {
  620. if (s.equals(varsOrder.get(i).name)) {
  621. return "-" + (methodOffset + (i + 1) * 8) + "(%rbp)";
  622. }
  623. }
  624. //class
  625. genbin("movq", "-8(%rbp)", "%r15");
  626.  
  627. if (info.get(currentClass).fieldOffset.containsKey(s)) {
  628. return info.get(currentClass).fieldOffset.get(s) + "(%r15)";
  629. } else {
  630. Integer offset = null;
  631. String tempClass = currentClass;
  632. while (offset == null) {
  633. tempClass = info.get(currentClass).parent;
  634. offset = info.get(tempClass).fieldOffset.get(s);
  635. }
  636. return offset + "(%r15)";
  637. }
  638. }
  639.  
  640. public int labelnum(String s){
  641. if (!labels.containsKey(s)) {
  642. labels.put(s, 1);
  643. } else {
  644. labels.put(s, labels.get(s) + 1);
  645. }
  646. return labels.get(s);
  647. }
  648. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement