doc: paulchen beispiele {code{a,b},gesamt} entpackt (jedes mal entpacken nervt langsa...
[uebersetzerbau-ss10.git] / aus_sammelwut / paulchen / ublu / ss08 / abgabe / gesamt / .svn / text-base / code_gen.c.svn-base
1 #include <stdio.h>
2 #include <string.h>
3 #include "code_gen.h"
4
5 int variables, call;
6 /* char *function_name; */
7 /* char *reg_return; */
8 extern char *saved_reg;
9
10 char *reg_names[]={"rax", "r10", "r11", "r9", "r8", "rcx", "rdx", "rsi", "rdi"};
11
12 void function_header(char *name, int vars, int has_call, int num_pars) {
13         int a;
14
15         variables = vars+(has_call ? num_pars : 0);
16         printf("# setting call to %i\n", has_call);
17         call = has_call;
18
19         printf("\t.globl %s\n\t.type %s, @function\n%s:\n", name, name, name);
20         printf("# %i %i %i %i\n",vars,has_call,num_pars,(has_call ? num_pars : 0));
21         if(vars+(has_call ? num_pars : 0)>0) {
22                 printf("\tpushq %%rbp\n\tmovq %%rsp, %%rbp\n\tsubq $%i, %%rsp\n", 8*(vars+num_pars));
23                 if(num_pars>0 && has_call) {
24                         for(a=0;a<num_pars;a++) {
25                                 printf("\tmovq %%%s, %i(%%rsp)\n",get_param_reg(a+1),8*(vars+num_pars-a-1));
26                         }
27                 }
28         }
29 }
30
31 void prepare_call(char *function, char *reg_return) {
32         int a;
33         /* TODO don't save all registers */
34         for(a=0;a<9;a++) {
35                 printf("\tpushq %%%s\n",reg_names[a]);
36         }
37 }
38
39 void do_call(char *function, char *reg_return) {
40         int a;
41         /* TODO don't restore all registers */
42         printf("\tcall %s\n", function);
43         move("rax",reg_return);
44         /* TODO return value? */
45         for(a=8;a>=0;a--) {
46                 if(strcmp(reg_return,reg_names[a])) {
47                         printf("\tpopq %%%s\n",reg_names[a]);
48                 }
49                 else {
50                         printf("\taddq $8, %%rsp\n");
51                 }
52         }
53 }
54
55 char *get_next_reg(char *name, int skip_reg) {
56         int index, a;
57         if(name==(char *)NULL) {
58                 index=0;
59         }
60         else {
61                 for(a=0;a<9;a++) {
62                         if(!strcmp(name,reg_names[a])) {
63                                 index=a+1;
64                                 break;
65                         }
66                 }
67         }
68         if(skip_reg) {
69                 index++;
70         }
71         if(index>8) {
72                 return saved_reg;
73         }
74         return reg_names[index];
75 }
76
77 char *get_next_param_reg(char *reg) {
78         int a=1;
79         while(1) {
80                 if(strcmp(get_param_reg(a),reg)==0) {
81                         return get_param_reg(a+1);
82                 }
83                 a++;
84         }
85 }
86
87 char *get_param_reg(long number) {
88         char *reg_names[]={"rdi", "rsi", "rdx", "rcx", "r8", "r9"};
89         return reg_names[number-1];
90 }
91
92 void ret(void) {
93         if(variables>0) {
94                 printf("\tleave\n");
95         }
96         printf("\tret\n");
97 }
98
99 void move(char *src, char *dst) {
100         if(strcmp(src,dst)) {
101                 printf("\tmovq %%%s, %%%s\n",src,dst);
102         }
103 }
104