DEADSOFTWARE

4aee145479330f49cb12751047bf244bc14b72a4
[dsw-obn.git] / src / backends / jvm / generator-jvm-asm.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <string.h>
7 #include <assert.h>
9 #include <gc.h>
11 #include "../../../include/oberon.h"
12 #include "../../oberon-internals.h"
13 #include "generator-jvm.h"
14 #include "generator-jvm-abi.h"
15 #include "generator-jvm-asm.h"
16 #include "generator-jvm-basic.h"
18 gen_proc_t *
19 jvm_create_proc(struct gen_class * class)
20 {
21 gen_proc_t * p = GC_MALLOC(sizeof *p);
22 memset(p, 0, sizeof *p);
24 struct gen_register_file * rf = GC_MALLOC(sizeof *rf);
25 memset(rf, 0, sizeof *rf);
27 struct gen_stack * stack = GC_MALLOC(sizeof *stack);
28 memset(rf, 0, sizeof *stack);
30 p -> rf = rf;
31 p -> stack = stack;
32 p -> class = class;
33 p -> label_id = 0;
35 return p;
36 }
38 void
39 jvm_generate_function_header(gen_proc_t * p, char * access, char * name, char * signature)
40 {
41 struct gen_class * class;
42 class = p -> class;
44 /* Делаем процедуру текущей в этом классе */
45 assert(class -> p == NULL);
46 class -> p = p;
48 fprintf(class -> fp, ".method %s %s%s\n", access, name, signature);
49 fprintf(class -> fp, " start:\n");
50 }
52 void
53 jvm_generate_function_end(gen_proc_t * p)
54 {
55 struct gen_class * class;
56 class = p -> class;
58 assert(class -> p);
59 class -> p = NULL;
61 int pointer = p -> stack -> pointer;
62 int max_pointer = p -> stack -> max_pointer;
63 int locals = p -> rf -> num_used;
64 int max_locals = p -> rf -> max_used;
66 fprintf(class -> fp, " .limit stack %i \t; current(%i)\n", max_pointer, pointer);
67 fprintf(class -> fp, " .limit locals %i \t; current(%i)\n", max_locals, locals);
68 fprintf(class -> fp, " end:\n");
69 fprintf(class -> fp, ".end method\n\n");
70 }
72 struct gen_class *
73 jvm_create_class(char * full_name)
74 {
75 struct gen_class * class = GC_MALLOC(sizeof *class);
76 memset(class, 0, sizeof *class);
78 char * fname = new_string("%s.j", full_name);
79 class -> full_name = new_string(full_name);
80 class -> fp = fopen(fname, "w");
81 assert(class -> fp);
83 return class;
84 }
86 void
87 jvm_destroy_class(struct gen_class * class)
88 {
89 assert(class -> p == NULL);
90 fclose(class -> fp);
91 }
93 void
94 jvm_stack_push(gen_proc_t * p, unsigned size)
95 {
96 p -> stack -> pointer += size;
97 if(p -> stack -> pointer > p -> stack -> max_pointer)
98 {
99 p -> stack -> max_pointer = p -> stack -> pointer;
103 void
104 jvm_stack_pop(gen_proc_t * p, unsigned size)
106 p -> stack -> pointer -= size;
108 if(p -> stack -> pointer < 0)
110 printf("WARING: stack pointer %i\n", p -> stack -> pointer);
114 void
115 jvm_generate(gen_proc_t * p, unsigned get, unsigned push, char * format, ...)
117 va_list ptr;
118 va_start(ptr, format);
120 jvm_stack_pop(p, get);
121 fprintf(p -> class -> fp, " ");
122 vfprintf(p -> class -> fp, format, ptr);
123 jvm_stack_push(p, push);
124 fprintf(p -> class -> fp, " \t ;>>>> %i -- %i : current_stack(%i)\n", get, push, p -> stack -> pointer);
126 va_end(ptr);
129 void
130 jvm_generate_comment(gen_proc_t * p, char * format, ...)
132 va_list ptr;
133 va_start(ptr, format);
135 fprintf(p -> class -> fp, " ;;;; ");
136 vfprintf(p -> class -> fp, format, ptr);
137 fprintf(p -> class -> fp, "\n");
139 va_end(ptr);
142 void
143 jvm_generate_push_int(gen_proc_t * p, int64_t i)
145 if(i == -1)
147 jvm_generate(p, 0, 1, "iconst_m1");
149 else if(i >= 0 && i <= 5)
151 jvm_generate(p, 0, 1, "iconst_%li", i);
153 else if(i >= -128 && i <= 127)
155 jvm_generate(p, 0, 1, "bipush %li", i);
157 else if(i >= -32768 && i <= 32767)
159 jvm_generate(p, 0, 1, "sipush %li", i);
161 else if(i >= -2147483648 && i <= 2147483647)
163 jvm_generate(p, 0, 1, "ldc %li", i);
165 else
167 jvm_generate(p, 0, 2, "ldc2_w %li", i);
171 void
172 jvm_generate_push_int_size(gen_proc_t * p, int64_t i, int size)
174 int pushed_cell = 1;
176 if(i == -1)
178 jvm_generate(p, 0, 1, "iconst_m1");
180 else if(i >= 0 && i <= 5)
182 jvm_generate(p, 0, 1, "iconst_%li", i);
184 else if(i >= -128 && i <= 127)
186 jvm_generate(p, 0, 1, "bipush %li", i);
188 else if(i >= -32768 && i <= 32767)
190 jvm_generate(p, 0, 1, "sipush %li", i);
192 else if(i >= -2147483648 && i <= 2147483647)
194 jvm_generate(p, 0, 1, "ldc %li", i);
196 else
198 pushed_cell = 2;
199 jvm_generate(p, 0, 2, "ldc2_w %li", i);
202 assert(size <= 8);
203 if(size > 4 && pushed_cell == 1)
205 jvm_generate(p, pushed_cell, 2, "i2l");
207 else if(size <= 4)
209 if(pushed_cell > 1)
211 jvm_generate(p, 2, 1, "l2i");
214 if(size == 2)
216 jvm_generate(p, 1, 1, "i2s");
218 else if(size == 1)
220 jvm_generate(p, 1, 1, "i2b");
225 void
226 jvm_generate_push_float(gen_proc_t * p, double f, int size)
228 if(size <= 4)
230 if(f == 0.0)
232 jvm_generate(p, 0, 1, "fconst_0");
234 if(f == 1.0)
236 jvm_generate(p, 0, 1, "fconst_1");
238 if(f == 2.0)
240 jvm_generate(p, 0, 1, "fconst_2");
242 else
244 jvm_generate(p, 0, 1, "ldc %lf", f);
247 else
249 if(f == 0.0)
251 jvm_generate(p, 0, 2, "dconst_0");
253 if(f == 1.0)
255 jvm_generate(p, 0, 2, "dconst_1");
257 else
259 jvm_generate(p, 0, 2, "ldc2_w %lf", f);
264 void
265 jvm_generate_push_string(gen_proc_t * p, char * str, int char_size)
267 assert(char_size == 1);
268 int len = strlen(str);
270 jvm_generate_push_int(p, len + 1);
271 jvm_generate(p, 1, 1, "newarray byte");
273 for(int i = 0; i < len; i++)
275 jvm_generate(p, 1, 2, "dup");
276 jvm_generate_push_int(p, i);
277 jvm_generate_push_int(p, str[i]);
278 jvm_generate(p, 3, 0, "bastore");
282 int
283 jvm_new_label_id(gen_proc_t * p)
285 int label_id = p -> label_id;
286 p -> label_id += 1;
287 return label_id;
290 void
291 jvm_generate_label(gen_proc_t * p, int label_id)
293 jvm_generate(p, 0, 0, "L%i:", label_id);