BenchCookie  0.0.1
A simple, intuitive open source language.
x86_64_compiler.cpp
Go to the documentation of this file.
1 // allocate enough space for drew-sized strings.
2 #ifndef X86_64_COMPILER_SOURCE
3 #define X86_64_COMPILER_SOURCE
4 #define MAX_STRING_SIZE 100
5 void Command::doBSS(std::ostream & file)
6 {
7  file<<"\t.bss"<<std::endl<<std::endl;
8  for (int x = 0; x < m_string_vars.size(); ++x) {
9  file<<"\t.comm .IS"<<x<<", "<<MAX_STRING_SIZE<<", 32"<<std::endl;
10  }
11 
14  file<<"\t.comm .locals, 400, 64";
15  file<<std::endl;
16 }
17 
18 void Command::doData(std::ostream & file)
19 {
20  file<<"\t.section .rodata"<<std::endl<<std::endl;
21 
24  for (int x = 0; x < m_literals.size(); ++x) {
25  file<<"\t.S"<<x<<":\t\t.string \""<<m_literals[x]<<"\\0\""<<std::endl;
26  }
27 
28  file<<std::endl<<"\t.string_fmt:\t.string \"%s\\0\""<<std::endl;
29  file<<"\t.num_fmt:\t.string \"%d\\0\""<<std::endl;
30  file<<"\t.TRUE:\t\t.string \"true\\0\""<<std::endl;
31  file<<"\t.FALSE:\t\t.string \"false\\0\""<<std::endl;
32 
33  std::cout<<std::endl<<std::endl;;
34 
35  file<<std::endl<<"\t.section .data"<<std::endl;
38  for (int x = 0; x < m_int_vars.size() - m_int_declarations.size(); ++x) {
39  file<<".I"<<x<<":\t.fill 64"<<std::endl;
40  }
41 }
42 #define INTGR 67
43 #define STRNG 68
44 
45 void Command::evaluate_expression(std::ostream & file)
46 {
47  static ssize_t nszcount = 0;
48  static ssize_t divcount = 0;
49  static ssize_t exprdex = 0;
50 
51  unsigned int t1, t2;
52 
54  std::stack<math_expression> * expr = m_evaluations[exprdex++];
55  std::stack<unsigned short> arg_types;
56  ssize_t stack_depth = 0;
57 
58  std::stack<math_expression> eval;
59  for(; !expr->empty(); eval.push(expr->top()), expr->pop(), 1);
60  std::stack<math_expression> curr;
61 
62  for (; eval.size();) {
63  math_expression a = eval.top(); eval.pop();
64  Command::exp_type type = static_cast<Command::exp_type>(a.expr_type);
65  exp_type aExpType = static_cast<Command::exp_type>(a.expr_type);
66  if (aExpType == VAR) {
67  push_variable(a.pirate_name, arg_types, file);
68  stack_depth += 4;
69  continue;
70  } else if (aExpType == AN_INT) {
71  if (!eval.size()) file<<"\tmovq $"<<a.int_arg<<", %r9"<<std::endl;
72  else file<<"\tpushq $"<<a.int_arg<<std::endl;
73  stack_depth += 4;
74  arg_types.push(INTGR);
75  continue;
76  } else if (aExpType == LITERAL) {
77  arg_types.push(STRNG);
78  ssize_t idx = m_exp_literals.front();
79  m_exp_literals.pop();
80  file<<"\tpushq $.S"<<idx<<std::endl;
81  stack_depth += 4;
82  continue;
83  } else if (aExpType == PTRDEREF) {
84  file<<"\tpopq %r8"<<std::endl;
85  if (arg_types.top() == STRNG) {
86  file<<"\tmovq (%r8), %r8"<<std::endl;
87  } else file<<"\tmovq (%r8), %r8"<<std::endl;
88  file<<"\tpushq %r8"<<std::endl;
89  continue;
90  } else if (aExpType == LOGNOT) {
91  file<<"\tpopq %r8"<<std::endl;
92  file<<"\tmovq $1, %rax"<<std::endl;
93  file<<"\tcmpq $0, %r8"<<std::endl;
94  file<<"\tje NSZ"<<nszcount<<std::endl;
95  file<<"\tmovq $0, %rax"<<nszcount<<std::endl;
96  file<<"NSZ"<<nszcount<<":\tpushq %rax"<<std::endl;
97  ++nszcount;
98  continue;
99  }
100 
101  if (stack_depth >= 8) {
102  file<<"\tpopq %r8"<<std::endl;
103  file<<"\tpopq %r9"<<std::endl;
104  stack_depth -= 8;
105  } else continue;
106  switch (type) {
107  case ADD:
113  file<<"\taddq %r8, %r9"<<std::endl;
114  goto do_default;
115  case SUB:
116  file<<"\tsubq %r8, %r9"<<std::endl;
117  goto do_default;
118  case MUL:
119  file<<"\timul %r8, %r9"<<std::endl;
120  goto do_default;
121  case DIV:
122  /* @todo case divide by zero */
123  file<<"\txor %rax, %rax"<<std::endl;
124  file<<"\txor %rbx, %rbx"<<std::endl;
125  file<<"\tmovq $1, %rbx"<<std::endl;
126  file<<"\tcmpq $0, %r8"<<std::endl;
127  file<<"\tjge NLZ1"<<divcount<<std::endl;
128  file<<"\timul $-1, %rbx"<<std::endl;
129  file<<"\timul $-1, %r8"<<std::endl;
130  file<<"NLZ1"<<divcount<<":\tcmpq $0, %r9"<<std::endl;
131  file<<"\tjge NLZ2"<<divcount<<std::endl;
132  file<<"\timul $-1, %rbx"<<std::endl;
133  file<<"\timul $-1, %r9"<<std::endl;
134  file<<"NLZ2"<<divcount<<":"<<std::endl;
135  file<<"DIV"<<divcount<<":\tcmpq %r8, %r9"<<std::endl;
136  file<<"\tjl EDIV"<<divcount<<std::endl;
137  file<<"\tsubq %r8, %r9"<<std::endl;
138  file<<"\taddq $1, %rax"<<std::endl;
139  file<<"\tjmp DIV"<<divcount<<std::endl;
140  file<<"EDIV"<<divcount++<<":\timul %rbx, %rax"<<std::endl;
141  file<<"\tmovq %rax, %r9"<<std::endl;
142  goto do_default;
143  case MOD:
144  file<<"\tudiv %r0, %r2, %r1"<<std::endl;
145  file<<"\tmls %r2, %r1, %r0, %r2"<<std::endl;
146  goto do_default;
147  case GT:
148  t1 = arg_types.top(); arg_types.pop();
149  t2 = arg_types.top(); arg_types.pop();
150  if (t1 == STRNG && t2 == STRNG) {
151  file<<"\tmov %r8, %rdi"<<std::endl;
152  file<<"\tmov %r9, %rsi"<<std::endl;
153  file<<"\tcall strcmp"<<std::endl;
154  file<<"\tmovq $1, %r9"<<std::endl;
155  file<<"\tcmpq $0, %rax"<<std::endl;
156  file<<"\tjg NSZ"<<nszcount<<std::endl;
157  file<<"\tmovq $0, %r9"<<std::endl;
158  file<<"NSZ"<<nszcount<<":";
159  } else {
160  file<<"\tmovq $1, %rax"<<std::endl;
161  file<<"\tcmpq %r8, %r9"<<std::endl;
162  file<<"\tjg GT"<<nszcount<<std::endl;
163  file<<"\txor %rax, %rax"<<std::endl;
164  file<<"GT"<<nszcount<<":\tmovq %rax, %r9"<<std::endl;
165  }
166  nszcount++;
167  goto do_default;
168  case GEQ:
169  t1 = arg_types.top(); arg_types.pop();
170  t2 = arg_types.top(); arg_types.pop();
171  if (t1 == STRNG && t2 == STRNG) {
172  file<<"\tmov %r8, %rdi"<<std::endl;
173  file<<"\tmov %r9, %rsi"<<std::endl;
174  file<<"\tcall strcmp"<<std::endl;
175  file<<"\tmovq $1, %r9"<<std::endl;
176  file<<"\tcmpq $0, %rax"<<std::endl;
177  file<<"\tjge NSZ"<<nszcount<<std::endl;
178  file<<"\tmovq $0, %r9"<<std::endl;
179  file<<"NSZ"<<nszcount<<":"<<std::endl;
180  } else {
181  file<<"\tmovq $1, %rax"<<std::endl;
182  file<<"\tcmpq %r8, %r9"<<std::endl;
183  file<<"\tjge GEQ"<<nszcount<<std::endl;
184  file<<"\txor %rax, %rax"<<std::endl;
185  file<<"GEQ"<<nszcount<<":\tmovq %rax, %r9"<<std::endl;
186  }
187  nszcount++;
188  goto do_default;
189  case LT:
190  t1 = arg_types.top(); arg_types.pop();
191  t2 = arg_types.top(); arg_types.pop();
192  if (t1 == STRNG && t2 == STRNG) {
193  file<<"\tmov %r8, %rdi"<<std::endl;
194  file<<"\tmov %r9, %rsi"<<std::endl;
195  file<<"\tcall strcmp"<<std::endl;
196  file<<"\tmovq $1, %r9"<<std::endl;
197  file<<"\tcmpq $0, %rax"<<std::endl;
198  file<<"\tjl NSZ"<<nszcount<<std::endl;
199  file<<"\tmovq $0, %r9"<<std::endl;
200  file<<"NSZ"<<nszcount<<":"<<std::endl;
201  } else {
202  file<<"\tmovq $1, %rax"<<std::endl;
203  file<<"\tcmpq %r8, %r9"<<std::endl;
204  file<<"\tjl LT"<<nszcount<<std::endl;
205  file<<"\txor %rax, %rax"<<std::endl;
206  file<<"LT"<<nszcount<<":\tmovq %rax, %r9"<<std::endl;
207  }
208  nszcount++;
209  goto do_default;
210  case LEQ:
211  t1 = arg_types.top(); arg_types.pop();
212  t2 = arg_types.top(); arg_types.pop();
213  if (t1 == STRNG && t2 == STRNG) {
214  file<<"\tmov %r8, %rdi"<<std::endl;
215  file<<"\tmov %r9, %rsi"<<std::endl;
216  file<<"\tcall strcmp"<<std::endl;
217  file<<"\tmovq $1, %r9"<<std::endl;
218  file<<"\tcmpq $0, %rax"<<std::endl;
219  file<<"\tjle NSZ"<<nszcount<<std::endl;
220  file<<"\tmovq $0, %r9"<<std::endl;
221  file<<"NSZ"<<nszcount<<":"<<std::endl;
222  } else {
223  file<<"\tmovq $1, %rax"<<std::endl;
224  file<<"\tcmpq %r8, %r9"<<std::endl;
225  file<<"\tjle LE"<<nszcount<<std::endl;
226  file<<"\txor %rax, %rax"<<std::endl;
227  file<<"LE"<<nszcount<<":\tmovq %rax, %r9"<<std::endl;
228  }
229  nszcount++;
230  goto do_default;
231  case EQ:
232  t1 = arg_types.top(); arg_types.pop();
233  t2 = STRNG;// arg_types.top(); arg_types.pop();
234  if (t1 == STRNG && t2 == STRNG) {
235  file<<"\tmov %r8, %rdi"<<std::endl;
236  file<<"\tmov %r9, %rsi"<<std::endl;
237  file<<"\tcall strcmp"<<std::endl;
238  file<<"\tmovq $1, %r9"<<std::endl;
239  file<<"\tcmpq $0, %rax"<<std::endl;
240  file<<"\tje NSZ"<<nszcount<<std::endl;
241  file<<"\tmovq $0, %r9"<<std::endl;
242  file<<"NSZ"<<nszcount<<":"<<std::endl;
243  } else {
244  file<<"\tmovq $1, %rax"<<std::endl;
245  file<<"\tcmpq %r8, %r9"<<std::endl;
246  file<<"\tje EQ"<<nszcount<<std::endl;
247  file<<"\txor %rax, %rax"<<std::endl;
248  file<<"EQ"<<nszcount<<":\tmovq %rax, %r9"<<std::endl;
249  }
250  nszcount++;
251  goto do_default;
252  case NEQ:
253  t1 = arg_types.top(); arg_types.pop();
254  t2 = STRNG;// arg_types.top(); arg_types.pop();
255  if (t1 == STRNG && t2 == STRNG) {
256  file<<"\tmovq %r8, %rdi"<<std::endl;
257  file<<"\tmovq %r9, %rsi"<<std::endl;
258  file<<"\tcall strcmp"<<std::endl;
259  file<<"\tmovq $1, %r9"<<std::endl;
260  file<<"\tcmpq $0, %rax"<<std::endl;
261  file<<"\tjne NSZ"<<nszcount<<std::endl;
262  file<<"\tmovq $0, %r9"<<std::endl;
263  file<<"NSZ"<<nszcount<<":"<<std::endl;
264  } else {
265  file<<"\tmovq $1, %rax"<<std::endl;
266  file<<"\tcmpq %r8, %r9"<<std::endl;
267  file<<"\tjne NE"<<nszcount<<std::endl;
268  file<<"\txor %rax, %rax"<<std::endl;
269  file<<"NE"<<nszcount<<":\tmovq %rax, %r9"<<std::endl;
270  }
271  nszcount++;
272  goto do_default;
273  case LOGAND:
274  file<<"\timul %r8, %r9"<<std::endl;
275  file<<"\tmovq $1, %rax"<<std::endl;
276  file<<"\tcmpq $0, %r9"<<std::endl;
277  file<<"\tjne NSZ"<<nszcount<<std::endl;
278  file<<"\tmovq $0, %rax"<<std::endl;
279  file<<"NSZ"<<nszcount<<":\tmovq %rax, %r9"<<std::endl;
280  nszcount++;
281  goto do_default;
282  case LOGOR:
283  file<<"\taddq %r8, %r9"<<std::endl;
284  file<<"\tmovq %r9, %rbx"<<std::endl;
285  file<<"\tmovq $1, %r9"<<std::endl;
286  file<<"\tcmpq $0, %rbx"<<std::endl;
287  file<<"\tjne NSZ"<<nszcount<<std::endl;
288  file<<"\tmovq $0, %r9"<<std::endl;
289  file<<"NSZ"<<nszcount<<":"<<std::endl;
290  nszcount++;
291  goto do_default;
292  case LOGXOR:
293  file<<"\tmul %r3, %r1, %r2"<<std::endl;
294  file<<"\tadd %r4, %r1, %r2"<<std::endl;
295  file<<"\tmov %r1, $1"<<std::endl;
296  file<<"\tmov %r2, $1"<<std::endl;
297  file<<"\tcmp %r3, $0"<<std::endl;
298  file<<"\tbne NSZ"<<nszcount<<std::endl;
299  file<<"\tmov %r1, $0"<<std::endl;
300  file<<"NSZ"<<nszcount++<<": @ r1 <-- a && b"<<std::endl;
301  file<<"\tcmp %r4, $0"<<std::endl;
302  file<<"\tbne NSZ"<<nszcount<<std::endl;
303  file<<"\tmov %r2, $0";
304  file<<"NSZ"<<nszcount<<": @ r1 <-- a || b"<<std::endl;
305  file<<"\teor %r0, %r1, %r2"<<std::endl;
306  nszcount++;
307  goto do_default;
308  default:
309  std::cerr<<"Welp. You did it. You tried it."<<std::endl;
310  std::cerr<<"This is what happens. You get mad."<<std::endl;
311  std::cerr<<"Don't use things I didn't implement yet."<<std::endl;
312  exit(101);
313  do_default:
314  if (eval.size()) {
315  file<<"\tpushq %r9"<<std::endl;
316  stack_depth += 4;
317  }
318  // else ;
319  }
320  }
321 }
322 
323 void Command::push_variable(std::string var_name, std::stack<unsigned short> & vartype,
324  std::ostream & file)
325 {
326  std::string varname = var_name;
327  for (int x = 0; x < m_int_declarations.size(); ++x) {
328  if (m_int_declarations[x] == varname) {
329  file<<"\txor %r9, %r9"<<std::endl;
330  if (x) file<<"\taddq $"<<8*x<<", %r9"<<std::endl;
331  file<<"\taddq $.locals, %r9"<<std::endl;
332  file<<"\tpushq (%r9)"<<std::endl;
333  vartype.push(INTGR);
334  return;
335  }
336  }
337 
338  for (int x = 0; x < m_int_vars.size(); ++x) {
339  if (m_int_vars[x] == varname) {
340  file<<"\tpushq (.I"<<x<<")"<<std::endl;
341  vartype.push(INTGR);
342  return;
343  }
344  }
345 
346  for (int x = 0; x < m_string_vars.size(); ++x) {
347  if (m_string_vars[x] == varname) {
348  file<<"\tpushq $.IS"<<x<<std::endl;
349  vartype.push(STRNG);
350  return;
351  }
352  }
353 
354  std::cerr<<"Error: could not resolve variable \"";
355  std::cerr<<varname<<"\"."<<std::endl;
356  exit(6);
357 }
358 
359 void Command::doMain(std::ostream & file)
360 {
361  int y;
362  const size_t local_count = 0;// Idk, yo. Just... somewhere.
363  if (m_is_c_callable) file<<m_function_name<<":"<<std::endl;
364  else file<<"main:"<<std::endl;
365 
366  // file<<"\tldr %r9, =locals"<<std::endl;
367  file<<"\t/* Make space for locals */"<<std::endl;
372  for (int x = 0, intassdex = 0, stringdex = 0, exprdex = 0,
373  intdex = 0, pintdex = 0, pstringdex = 0, litdex = 0,
374  pbooldex = 0, sints = 0, ifndex = 0, forndex = 0, nszcount = 0;
375  x < m_execOrder.size(); ++x) {
376 
377  if (m_execOrder[x] == cmd_type::READ_STRING) {
378  file<<"\t/* Read input string */"<<std::endl;
379  file<<"\tmovl $.string_fmt, %edi"<<std::endl;
380  file<<"\tmovl $.IS"<<stringdex<<", %esi"<<std::endl;
381  file<<"\txor %rax, %rax"<<std::endl;
382  file<<"\tcall scanf"<<std::endl;
383  file<<std::endl;
384 
385  ++stringdex;
386  } else if (m_execOrder[x] == cmd_type::READ_LINE) {
390  file<<"\t/* Read line */"<<std::endl;
391  file<<"\tmovl $.IS"<<stringdex<<", %edi"<<std::endl;
392  file<<"\txor %rax, %rax"<<std::endl;
393  file<<"\tcall gets"<<std::endl;
394  file<<std::endl;
395 
396  ++stringdex;
397  } else if (m_execOrder[x] == cmd_type::DECL_INT) {
398  file<<"\tmovq $8, %rdi"<<std::endl;
399  file<<"\tmovq %rsp, %rsi"<<std::endl;
400  file<<"\txor %rax, %rax"<<std::endl;
401  file<<"\tcall malloc"<<std::endl;
402  file<<"\tmovq $.locals, %r9"<<std::endl;
403  file<<"\tmovq %rax, "<<sints * 8<<"(%r9)"<<std::endl;
404 
405  file<<std::endl;
406  m_int_vars.push_back(m_int_declarations[sints++]);
407  } else if (m_execOrder[x] == cmd_type::BEGIN_IF) {
408  // find the variable we depend on!
409  evaluate_expression(file);
410  file<<"IF"<<ifndex<<":\tcmpq $0, %r9"<<std::endl;
411  file<<"\tje END_IF"<<ifndex<<std::endl;
412  ++ifndex;
413  } else if (m_execOrder[x] == cmd_type::BEGIN_FOR) {
414  std::string var_name = m_for_deps[forndex];
415  for (y = 0; y < m_int_vars.size(); ++y) {
416  if (m_int_vars[y] == var_name) break;
417  } int z = 0;
418  for (; z < m_int_declarations.size(); ++z) {
419  if (m_int_declarations[z] == var_name) break;
420  } if (z < m_int_declarations.size()) {
421  file<<"FOR"<<forndex<<":";
422  file<<"\tmovq $.locals, %r8"<<std::endl;
423  if (8*z) file<<"\taddq $"<<8*z<<", %r8"<<std::endl;
424  file<<"\tmovq (%r8), %r8"<<std::endl;
425  } else if (y < m_int_vars.size()) {
426  file<<"FOR"<<forndex<<":";
427  file<<"\tmovq .I"<<y<<", %r8"<<std::endl;
428  } else {
429  std::cerr<<"Error: for-dependent variable "<<var_name;
430  std::cerr<<" not yet declared!"<<std::endl;
431  exit(7);
432  }
433 
434  file<<"\tcmpq $0, %r8"<<std::endl;
435  file<<"\tje END_FOR"<<forndex<<std::endl;
436  } else if (m_execOrder[x] == cmd_type::END_FOR) {
437  file<<"jmp FOR"<<forndex<<std::endl;
438  file<<"END_FOR"<<forndex++<<":"<<std::endl;
439  } else if (m_execOrder[x] == cmd_type::END_IF) {
440  file<<"END_IF"<<ifndex-1<<":"<<std::endl;
441  } else if (m_execOrder[x] == cmd_type::READ_INT) {
442  // file<<"\tldr %r0, =num_fmt"<<std::endl;
443  file<<"\tmovq $.num_fmt, %rdi"<<std::endl;
444  //file<<"\tldr %r1, =I"<<intdex<<std::endl;
445  file<<"\tmovq $.I"<<intdex<<", %rsi"<<std::endl;
446  file<<"\txor %rax, %rax"<<std::endl;
447  file<<"\tcall scanf"<<std::endl;
448  file<<std::endl;
449 
450  ++intdex;
451  } else if (m_execOrder[x] == cmd_type::NOPRINT) {
452  ++litdex;
453  } else if (m_execOrder[x] == cmd_type::PRINT) {
454  file<<"\tmovq $.S"<<litdex++<<", %rdi"<<std::endl;
455  file<<"\tmovq %rsp, %rsi"<<std::endl;
456  file<<"\txor %rax, %rax"<<std::endl;
457  file<<"\tcall printf"<<std::endl<<std::endl;
458  } else if (m_execOrder[x] == cmd_type::PRINT_STR) {
459  file<<"\tmovl $.string_fmt, %eax"<<std::endl;
460  for (y = 0; y < m_string_vars.size(); ++y) {
461  if (m_string_vars[y] == m_print_strings[pstringdex]) break;
462  } if (y == m_string_vars.size()) {
463  std::cerr<<"Error: variable "<<m_string_vars[y]<<" was not declared!"<<std::endl;
464  exit(3);
465  }
467  file<<"\tmovl $.IS"<<y<<", %esi"<<std::endl;
468  file<<"\tmovq %rax, %rdi"<<std::endl;
469  file<<"\txor %rax, %rax"<<std::endl;
470  file<<"\tcall printf"<<std::endl<<std::endl;
471  ++pstringdex;
472  } else if (m_execOrder[x] == cmd_type::PRINT_NUM) {
473  file<<"\tmovl $.num_fmt, %eax"<<std::endl;
474  for (y = 0; y < m_int_vars.size(); ++y) {
475  if (m_int_vars[y] == m_print_ints[pintdex]) break;
476  } if (y == m_int_vars.size()) {
477  std::cerr<<"Error: variable "<<m_int_vars[y]<<" was not declared!"<<std::endl;
478  exit(3);
479  } int z;
480  for (z = 0; z < m_int_declarations.size(); ++z) {
481  if (m_print_ints[pintdex] == m_int_declarations[z]) break;
482  } if (z != m_int_declarations.size()) {
483  file<<"\tmovq $.locals, %r10"<<std::endl;
484  if (8 * z) file<<"\taddq $"<<8 * z<<", %r10"<<std::endl;
485  file<<"\tmovq (%r10), %rbx"<<std::endl;
486  file<<"\tmovq %rbx, %rsi"<<std::endl;
487  file<<"\tmovq %rax, %rdi"<<std::endl;
488  file<<"\txor %rax, %rax"<<std::endl;
489  } else {
490  file<<"\tmovl .I"<<y<<", %esi"<<std::endl;
491  file<<"\tmovq %rax, %rdi"<<std::endl;
492  file<<"\txor %rax, %rax"<<std::endl;
493  } file<<"\tcall printf"<<std::endl;
494  ++pintdex;
495  } else if (m_execOrder[x] == cmd_type::PRINT_BOOL) {
496  for (y = 0; y < m_bool_vars.size(); ++y) {
497  if (m_bool_vars[y] == m_print_bools[pbooldex]) break;
498  } if (y == m_bool_vars.size()) {
499  std::cerr<<"Error: variable "<<m_bool_vars[y]<<" was not declared!"<<std::endl;
500  }
501  file<<"\tldr %r1, =B"<<y<<std::endl;
502  file<<"\tldr %r1, [%r1]"<<std::endl;
503  file<<"\tcmp %r1, $0"<<std::endl;
504  file<<"\tbne LIES"<<nszcount++<<std::endl;
505  file<<"\tldr %r0, =TRUE_STORY"<<std::endl;
506  file<<"\tb NOISTRUE"<<nszcount-1<<std::endl;
507  file<<"LIES"<<nszcount-1<<":"<<std::endl;
508  file<<"\tldr %r0, =FALSE"<<std::endl;
509  file<<"NOISTRUE"<<nszcount-1<<":"<<std::endl;
510  file<<"\tbl printf"<<std::endl;
511  ++pbooldex;
512  } else if (m_execOrder[x] == cmd_type::INTGETS) {
513  std::string int_gets = m_int_assigns[intassdex];
514  ssize_t offset;
515  for (y = 0; y < m_int_vars.size(); ++y) {
516  if (m_int_vars[y] == m_int_assigns[intassdex]) break;
517  } int z; bool on_stack = false; int * last_z = new int;
518  for (z = 0; z < m_int_declarations.size(); ++z) {
519  if (m_int_vars[y] == m_int_declarations[z]) { on_stack = true; break; }
520  } offset = (z != m_int_declarations.size()) ? 4 * z : y;
521  if (y == m_int_vars.size()) {
522  std::cerr<<"Error: variable "<<m_int_vars[y];
523  std::cerr<<" was not declared!"<<std::endl;
524  exit(3);
525  } *last_z = z;
526 
527  evaluate_expression(file);
528 
529  if (!on_stack) {
530  int x;
531  for (x = 0; x < m_int_vars.size(); ++x) {
532  if (m_int_vars[x] == int_gets) break;
533  } file<<"\tmovq %r9, .I"<<x<<std::endl;
534  } else {
535  file<<"\tmovq $.locals, %r10"<<std::endl;
536  if (*last_z) file<<"\taddq $"<<*last_z * 8<<", %r10"<<std::endl;
537  file<<"\tmovq %r9, (%r10)"<<std::endl;
538  delete last_z;
539  }
540  file<<std::endl; intassdex++;
541  }
542  }
543 }
544 
546 {
547  std::ofstream file;
548  file.open(m_filename);
549  if (!file.is_open()) {
550  std::cerr<<"Error: unable to open output file!";
551  exit(2);
552  }
553  file <<"/**"<<std::endl;
554  file <<" * "<<m_filename<<std::endl;
555  file <<" *"<<std::endl;
556  file <<" * Generated by Bench Cookie Compiler for x86_64!"<<std::endl;
557  file <<" * Bench Cookie is... Experimental. Don't be mad."<<std::endl;
558  file <<" */"<<std::endl;
559 
560  doBSS(file);
561 
562  file<<std::endl;
563 
564  doData(file);
565 
566  file<<std::endl<<std::endl;
567  file<<"\t.text"<<std::endl;
568  if (!m_is_c_callable) file<<"\t.globl main"<<std::endl;
569  if (m_is_c_callable) file<<"\t.globl "<<m_function_name<<std::endl;
570  doMain(file);
571 
579  file<<"\t/* Free local vars */"<<std::endl;
580  file<<"\tmovq $0, %rbx"<<std::endl;
581  file<<"\tmovq %rbx, %rcx"<<std::endl;
582  for (int x = 0; x < m_int_declarations.size(); ++x) {
583  file<<"\tmovq $.locals, %rax"<<std::endl;
584  if (8 * x) file<<"\taddq $"<<8 * x<<", %rax"<<std::endl;
585  file<<"\tcall free"<<std::endl<<std::endl;
586  }
587 
588  file<<"\t/* locals are free */"<<std::endl<<std::endl;
589 
590  file<<std::endl;
591  file<<"\tmovq $0, %rdi"<<std::endl;
592  file<<"\tmovq %rbp, %rsi"<<std::endl;
593  file<<"\txor %rax, %rax"<<std::endl;
594  file<<"\tcall fflush"<<std::endl;
601  if (!m_is_c_callable) {
602  file<<"\tnop"<<std::endl;
603  file<<"\tret"<<std::endl;
604  file.close();
605  } else {
606  if (m_current_returns.size() > 3) {
608  } else {
612  for (int x = 0; x < m_current_returns.size(); ++x) {
613  int y, z;
614  for (y = 0; y < m_int_vars.size(); ++y) {
615  if (m_int_vars[y] == m_current_returns[x]) break;
616  } if (y == m_int_vars.size()) {
617  std::cerr<<"Error: returned variable "<<m_current_returns[x]
618  <<" was not declared!"<<std::endl;
619  exit(9);
620  } for (z = 0; z < m_int_declarations.size(); ++z) {
621  if (m_int_declarations[z] == m_int_vars[y]) break;
622  } if (z != m_int_declarations.size()) {
623  file<<"\tmovq $.locals, %r8"<<std::endl;
624  if (z) file<<"\taddq $"<<4 * z<<", %r8"<<std::endl;
625  file<<"\tmovq (%r8), %r8"<<std::endl;
626  } else {
627  file<<"\tmovq .I"<<y<<", %r8"<<std::endl;
628  } char d = 'a';
629  file<<"\tmov %r"<<&(d)<<"x, %r6"<<std::endl;
630  ++d;
631  }
632  }
633  file<<"\tret"<<std::endl;
634  file<<"\tleave"<<std::endl;
635  }
636 }// allocate enough space for drew-sized strings.
637 #endif
#define INTGR
std::string pirate_name
Definition: command.h:45
void writeAssembly()
exp_type
Definition: command.h:65
#define STRNG
#define MAX_STRING_SIZE