DEADSOFTWARE

bd1812c00d0d74309faee20c12301a3102675f42
[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 "../../oberon-internals.h"
12 #include "generator-jvm.h"
13 #include "generator-jvm-abi.h"
14 #include "generator-jvm-asm.h"
15 #include "generator-jvm-basic.h"
17 gen_proc_t *
18 jvm_create_proc(struct gen_class * class)
19 {
20 gen_proc_t * p = GC_MALLOC(sizeof *p);
21 memset(p, 0, sizeof *p);
23 struct gen_register_file * rf = GC_MALLOC(sizeof *rf);
24 memset(rf, 0, sizeof *rf);
26 struct gen_stack * stack = GC_MALLOC(sizeof *stack);
27 memset(rf, 0, sizeof *stack);
29 p -> rf = rf;
30 p -> stack = stack;
31 p -> class = class;
32 p -> label_id = 0;
34 return p;
35 }
37 void
38 jvm_generate_function_header(gen_proc_t * p, char * access, char * name, char * signature)
39 {
40 struct gen_class * class;
41 class = p -> class;
43 /* Делаем процедуру текущей в этом классе */
44 assert(class -> p == NULL);
45 class -> p = p;
47 fprintf(class -> fp, ".method %s %s%s\n", access, name, signature);
48 fprintf(class -> fp, " start:\n");
49 }
51 void
52 jvm_generate_function_end(gen_proc_t * p)
53 {
54 struct gen_class * class;
55 class = p -> class;
57 assert(class -> p);
58 class -> p = NULL;
60 int pointer = p -> stack -> pointer;
61 int max_pointer = p -> stack -> max_pointer;
62 int locals = p -> rf -> num_used;
63 int max_locals = p -> rf -> max_used;
65 fprintf(class -> fp, " .limit stack %i \t; current(%i)\n", max_pointer, pointer);
66 fprintf(class -> fp, " .limit locals %i \t; current(%i)\n", max_locals, locals);
67 fprintf(class -> fp, " end:\n");
68 fprintf(class -> fp, ".end method\n\n");
69 }
71 struct gen_class *
72 jvm_create_class(const char * dir, char * full_name)
73 {
74 struct gen_class * class = GC_MALLOC(sizeof *class);
75 memset(class, 0, sizeof *class);
77 char * fname = new_string("%s/%s.j", dir, full_name);
78 class -> full_name = new_string(full_name);
79 class -> fp = fopen(fname, "w");
80 class -> dir = new_string(dir);
82 if(class -> fp == NULL)
83 {
84 gen_error("unable to create file %s", fname);
85 }
87 return class;
88 }
90 void
91 jvm_destroy_class(struct gen_class * class)
92 {
93 assert(class -> p == NULL);
94 fclose(class -> fp);
95 }
97 void
98 jvm_stack_push(gen_proc_t * p, unsigned size)
99 {
100 p -> stack -> pointer += size;
101 if(p -> stack -> pointer > p -> stack -> max_pointer)
103 p -> stack -> max_pointer = p -> stack -> pointer;
107 void
108 jvm_stack_pop(gen_proc_t * p, unsigned size)
110 p -> stack -> pointer -= size;
112 if(p -> stack -> pointer < 0)
114 printf("WARING: stack pointer %i\n", p -> stack -> pointer);
118 void
119 jvm_generate(gen_proc_t * p, unsigned get, unsigned push, char * format, ...)
121 va_list ptr;
122 va_start(ptr, format);
124 jvm_stack_pop(p, get);
125 fprintf(p -> class -> fp, " ");
126 vfprintf(p -> class -> fp, format, ptr);
127 jvm_stack_push(p, push);
128 fprintf(p -> class -> fp, " \t ;>>>> %i -- %i : current_stack(%i)\n", get, push, p -> stack -> pointer);
130 va_end(ptr);
133 void
134 jvm_generate_comment(gen_proc_t * p, char * format, ...)
136 va_list ptr;
137 va_start(ptr, format);
139 fprintf(p -> class -> fp, " ;;;; ");
140 vfprintf(p -> class -> fp, format, ptr);
141 fprintf(p -> class -> fp, "\n");
143 va_end(ptr);
146 void
147 jvm_generate_push_int(gen_proc_t * p, int64_t i)
149 if(i == -1)
151 jvm_generate(p, 0, 1, "iconst_m1");
153 else if(i >= 0 && i <= 5)
155 jvm_generate(p, 0, 1, "iconst_%li", i);
157 else if(i >= -128 && i <= 127)
159 jvm_generate(p, 0, 1, "bipush %li", i);
161 else if(i >= -32768 && i <= 32767)
163 jvm_generate(p, 0, 1, "sipush %li", i);
165 else if(i >= -2147483648 && i <= 2147483647)
167 jvm_generate(p, 0, 1, "ldc %li", i);
169 else
171 jvm_generate(p, 0, 2, "ldc2_w %li", i);
175 void
176 jvm_generate_push_int_size(gen_proc_t * p, int64_t i, int size)
178 int pushed_cell = 1;
180 if(i == -1)
182 jvm_generate(p, 0, 1, "iconst_m1");
184 else if(i >= 0 && i <= 5)
186 jvm_generate(p, 0, 1, "iconst_%li", i);
188 else if(i >= -128 && i <= 127)
190 jvm_generate(p, 0, 1, "bipush %li", i);
192 else if(i >= -32768 && i <= 32767)
194 jvm_generate(p, 0, 1, "sipush %li", i);
196 else if(i >= -2147483648 && i <= 2147483647)
198 jvm_generate(p, 0, 1, "ldc %li", i);
200 else
202 pushed_cell = 2;
203 jvm_generate(p, 0, 2, "ldc2_w %li", i);
206 assert(size <= 8);
207 if(size > 4 && pushed_cell == 1)
209 jvm_generate(p, pushed_cell, 2, "i2l");
211 else if(size <= 4)
213 if(pushed_cell > 1)
215 jvm_generate(p, 2, 1, "l2i");
218 if(size == 2)
220 jvm_generate(p, 1, 1, "i2s");
222 else if(size == 1)
224 jvm_generate(p, 1, 1, "i2b");
229 void
230 jvm_generate_push_float(gen_proc_t * p, double f, int size)
232 if(size <= 4)
234 if(f == 0.0)
236 jvm_generate(p, 0, 1, "fconst_0");
238 if(f == 1.0)
240 jvm_generate(p, 0, 1, "fconst_1");
242 if(f == 2.0)
244 jvm_generate(p, 0, 1, "fconst_2");
246 else
248 jvm_generate(p, 0, 1, "ldc %lf", f);
251 else
253 if(f == 0.0)
255 jvm_generate(p, 0, 2, "dconst_0");
257 if(f == 1.0)
259 jvm_generate(p, 0, 2, "dconst_1");
261 else
263 jvm_generate(p, 0, 2, "ldc2_w %lf", f);
268 void
269 jvm_generate_push_string(gen_proc_t * p, char * str, int char_size)
271 assert(char_size == 1);
272 int len = strlen(str);
274 jvm_generate_push_int(p, len + 1);
275 jvm_generate(p, 1, 1, "newarray byte");
277 for(int i = 0; i < len; i++)
279 jvm_generate(p, 1, 2, "dup");
280 jvm_generate_push_int(p, i);
281 jvm_generate_push_int(p, str[i]);
282 jvm_generate(p, 3, 0, "bastore");
286 int
287 jvm_new_label_id(gen_proc_t * p)
289 int label_id = p -> label_id;
290 p -> label_id += 1;
291 return label_id;
294 void
295 jvm_generate_label(gen_proc_t * p, int label_id)
297 jvm_generate(p, 0, 0, "L%i:", label_id);