12
|
1 /*
|
|
2 Very Simple Code Generator for Intel x86
|
|
3 $Id$
|
|
4 */
|
|
5
|
18
|
6 #include "s-compile.h"
|
12
|
7
|
|
8 int label = 0;
|
|
9 char *comments = "#####";
|
|
10 static
|
|
11 char *intro[] = {
|
|
12 " .cstring\n",
|
|
13 "LC0:\n",
|
|
14 " .ascii \"%d\\n\\0\"\n"
|
|
15 " .text\n",
|
|
16 ".globl _print\n",
|
|
17 "_print:\n",
|
|
18 "LFB2:\n",
|
|
19 " pushq %rbp\n",
|
|
20 "LCFI0:\n",
|
|
21 " movq %rsp, %rbp\n",
|
|
22 "LCFI1:\n",
|
|
23 " subq $16, %rsp\n",
|
|
24 "LCFI2:\n",
|
|
25 " movl %edi, -4(%rbp)\n",
|
|
26 " movl -4(%rbp), %esi\n",
|
|
27 " leaq LC0(%rip), %rdi\n",
|
|
28 " movl $0, %eax\n",
|
|
29 " call _printf\n",
|
|
30 " leave\n",
|
|
31 " ret\n",
|
|
32 "LFE2:\n",
|
|
33 ".globl _main\n",
|
|
34 "_main:\n",
|
|
35 "LFB3:\n",
|
|
36 " pushq %rbp\n",
|
|
37 "LCFI3:\n",
|
|
38 " movq %rsp, %rbp\n",
|
|
39 "LCFI4:\n",
|
|
40 " subq $16, %rsp\n",
|
|
41 "LCFI5:\n",
|
|
42 "\n",
|
|
43 "\n",
|
|
44 NULL
|
|
45 };
|
|
46
|
|
47 static
|
|
48 char *ending[] = {
|
|
49 " movq %rax, %rdi\n",
|
|
50 " call _print\n",
|
18
|
51 " movq $0,%rax\n",
|
12
|
52 " leave\n",
|
|
53 " ret\n",
|
|
54 "LFE3:\n",
|
|
55 ".comm _v,96,5\n",
|
|
56 " .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n",
|
|
57 "EH_frame1:\n",
|
|
58 " .set L$set$0,LECIE1-LSCIE1\n",
|
|
59 " .long L$set$0\n",
|
|
60 "LSCIE1:\n",
|
|
61 " .long 0x0\n",
|
|
62 " .byte 0x1\n",
|
|
63 " .ascii \"zR\\0\"\n",
|
|
64 " .byte 0x1\n",
|
|
65 " .byte 0x78\n",
|
|
66 " .byte 0x10\n",
|
|
67 " .byte 0x1\n",
|
|
68 " .byte 0x10\n",
|
|
69 " .byte 0xc\n",
|
|
70 " .byte 0x7\n",
|
|
71 " .byte 0x8\n",
|
|
72 " .byte 0x90\n",
|
|
73 " .byte 0x1\n",
|
|
74 " .align 3\n",
|
|
75 "LECIE1:\n",
|
|
76 " .globl _print.eh\n",
|
|
77 "_print.eh:\n",
|
|
78 "LSFDE1:\n",
|
|
79 " .set L$set$1,LEFDE1-LASFDE1\n",
|
|
80 " .long L$set$1\n",
|
|
81 "LASFDE1:\n",
|
|
82 " .long LASFDE1-EH_frame1\n",
|
|
83 " .quad LFB2-.\n",
|
|
84 " .set L$set$2,LFE2-LFB2\n",
|
|
85 " .quad L$set$2\n",
|
|
86 " .byte 0x0\n",
|
|
87 " .byte 0x4\n",
|
|
88 " .set L$set$3,LCFI0-LFB2\n",
|
|
89 " .long L$set$3\n",
|
|
90 " .byte 0xe\n",
|
|
91 " .byte 0x10\n",
|
|
92 " .byte 0x86\n",
|
|
93 " .byte 0x2\n",
|
|
94 " .byte 0x4\n",
|
|
95 " .set L$set$4,LCFI1-LCFI0\n",
|
|
96 " .long L$set$4\n",
|
|
97 " .byte 0xd\n",
|
|
98 " .byte 0x6\n",
|
|
99 " .align 3\n",
|
|
100 "LEFDE1:\n",
|
|
101 " .globl _main.eh\n",
|
|
102 "_main.eh:\n",
|
|
103 "LSFDE3:\n",
|
|
104 " .set L$set$5,LEFDE3-LASFDE3\n",
|
|
105 " .long L$set$5\n",
|
|
106 "LASFDE3:\n",
|
|
107 " .long LASFDE3-EH_frame1\n",
|
|
108 " .quad LFB3-.\n",
|
|
109 " .set L$set$6,LFE3-LFB3\n",
|
|
110 " .quad L$set$6\n",
|
|
111 " .byte 0x0\n",
|
|
112 " .byte 0x4\n",
|
|
113 " .set L$set$7,LCFI3-LFB3\n",
|
|
114 " .long L$set$7\n",
|
|
115 " .byte 0xe\n",
|
|
116 " .byte 0x10\n",
|
|
117 " .byte 0x86\n",
|
|
118 " .byte 0x2\n",
|
|
119 " .byte 0x4\n",
|
|
120 " .set L$set$8,LCFI4-LCFI3\n",
|
|
121 " .long L$set$8\n",
|
|
122 " .byte 0xd\n",
|
|
123 " .byte 0x6\n",
|
|
124 " .align 3\n",
|
|
125 "LEFDE3:\n",
|
|
126 " .subsections_via_symbols\n",
|
|
127 NULL
|
|
128 };
|
|
129
|
|
130 void
|
|
131 emit_push()
|
|
132 {
|
|
133 printf("\tpushq %%rax\n");
|
|
134 }
|
|
135
|
|
136 void
|
|
137 emit_compare()
|
|
138 {
|
|
139 printf("\tcmpq %%rax,(%%rsp)\n");
|
|
140 printf("\t%s %%al\n","setg");
|
|
141 printf("\tmovzbq %%al,%%rax\n");
|
|
142 printf("\taddq $8,%%rsp\n");
|
|
143 }
|
|
144
|
|
145 void
|
|
146 emit_store( int d )
|
|
147 {
|
|
148 printf("\tmovq _v@GOTPCREL(%%rip), %%rcx\n");
|
|
149 printf("\tmovq %%rax, %d(%%rcx)\n" ,d*8);
|
|
150 }
|
|
151
|
|
152 void
|
|
153 emit_load(int d)
|
|
154 {
|
|
155 printf("\tmovq _v@GOTPCREL(%%rip), %%rcx\n");
|
|
156 printf("\tmovq %d(%%rcx),%%rax\n" ,d*8);
|
|
157 }
|
|
158
|
|
159
|
|
160 static
|
|
161 char *opcode[] = {
|
|
162 "",
|
|
163 "subq",
|
|
164 "addq",
|
|
165 "imulq",
|
|
166 "idivq",
|
|
167 "",
|
|
168 "",
|
|
169 "",
|
|
170 "",
|
|
171 "subq",
|
|
172 "idivq",
|
|
173 };
|
|
174
|
|
175 void
|
|
176 emit_calc(enum opcode op)
|
|
177 {
|
20
|
178 if(op==O_DIV ) {
|
|
179 printf("\tmovq %%rax,%%rbx\n");
|
|
180 printf("\tpopq %%rax\n");
|
|
181 printf("\tcltd\n");
|
|
182 printf("\tidivq %%rbx\n");
|
|
183 } else if( op==O_DIV_R ) {
|
|
184 printf("\tpopq %%rbx\n");
|
|
185 printf("\tcltd\n");
|
|
186 printf("\tidivq %%rbx\n");
|
12
|
187 } else if(op==O_SUB) {
|
20
|
188 printf("\tpopq %%rbx\n");
|
|
189 printf("\t%s %%rbx,%%rax\n",opcode[op]);
|
|
190 printf("\tnegq %%rax\n");
|
12
|
191 } else {
|
20
|
192 printf("\tpopq %%rbx\n");
|
|
193 printf("\t%s %%rbx,%%rax\n",opcode[op]);
|
12
|
194 }
|
|
195 }
|
|
196
|
|
197 void
|
|
198 emit_value(d)
|
|
199 int d;
|
|
200 {
|
|
201 printf("\tmovq $%d,%%rax\n",d);
|
|
202 }
|
|
203
|
|
204 void
|
|
205 emit_comment()
|
|
206 {
|
|
207 if (before < ptr) {
|
|
208 putchar('#'); putchar('#'); putchar(' ');
|
|
209 while (before < ptr) {
|
|
210 if(*before && *before!='\n') {
|
|
211 putchar(*before);
|
|
212 }
|
|
213 before++;
|
|
214 }
|
|
215 putchar('\n');
|
|
216 }
|
|
217 }
|
|
218
|
|
219 void
|
|
220 emit_print()
|
|
221 {
|
|
222 printf("\tmovq %%rax, %%rdi\n");
|
|
223 printf("\tcall _print\n");
|
|
224 }
|
|
225
|
|
226
|
|
227 void
|
|
228 emit_intro()
|
|
229 {
|
|
230 char **iptr;
|
|
231 for(iptr=intro;*iptr;iptr++) {
|
|
232 printf("%s",*iptr);
|
|
233 }
|
|
234 }
|
|
235
|
|
236 void
|
|
237 emit_ending()
|
|
238 {
|
|
239 char **iptr;
|
|
240 for(iptr=ending;*iptr;iptr++) {
|
|
241 printf("%s",*iptr);
|
|
242 }
|
|
243 }
|
|
244
|
|
245 /* end */
|