1 /***************************** comp/mcode.c ************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 This file is an include file for "compiler.c" . It contains (mostly)
8 architecture independent functions for writing instructions into the
9 code area and constants into the data area.
11 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
12 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
13 Changes: Micheal Gschwind EMAIL: cacao@complang.tuwien.ac.at
15 Last Change: 1998/08/10
18 All functions assume the following code area / data area layout:
22 | code area | code area grows to higher addresses
24 +-----------+ <-- start of procedure
26 | data area | data area grows to lower addresses
30 The functions first write into a temporary code/data area allocated by
31 "mcode_init". "mcode_finish" copies the code and data area into permanent
32 memory. All functions writing values into the data area return the offset
33 relative the begin of the code area (start of procedure).
35 *******************************************************************************/
37 #define MCODEINITSIZE (1<<15) /* 32 Kbyte code area initialization size */
38 #define DSEGINITSIZE (1<<12) /* 4 Kbyte data area initialization size */
40 static u1* mcodebase = NULL; /* base pointer of code area */
41 static s4* mcodeend = NULL; /* pointer to end of code area */
42 static int mcodesize; /* complete size of code area (bytes) */
44 static u1* dsegtop = NULL; /* pointer to top (end) of data area */
45 static int dsegsize; /* complete size of data area (bytes) */
46 static int dseglen; /* used size of data area (bytes) */
47 /* data area grows from top to bottom */
49 static jumpref *jumpreferences; /* list of jumptable target addresses */
50 static branchref *xboundrefs; /* list of bound check branches */
51 static branchref *xcheckarefs; /* list of array size check branches */
52 static branchref *xnullrefs; /* list of null check branches */
53 static branchref *xcastrefs; /* list of cast check branches */
55 static void mcode_init(); /* allocates code and data area */
56 static void mcode_close(); /* releases temporary storage */
57 static void mcode_finish(); /* makes code and data area permanent and */
58 /* updates branch references to code/data */
60 static s4 dseg_adds4(s4 value); /* adds an int to data area */
61 static s4 dseg_adds8(s8 value); /* adds an long to data area */
62 static s4 dseg_addfloat (float value); /* adds an float to data area */
63 static s4 dseg_adddouble(double value); /* adds an double to data area */
66 #define dseg_addaddress(value) dseg_adds8((s8)(value))
68 #define dseg_addaddress(value) dseg_adds4((s4)(value))
71 static void dseg_addtarget(basicblock *target);
72 static void mcode_addreference(basicblock *target, void *branchptr);
73 static void mcode_addxboundrefs(void *branchptr);
74 static void mcode_addxnullrefs(void *branchptr);
75 static void mcode_addxcastrefs(void *branchptr);
77 static void dseg_display(s4 *s4ptr);
79 /* mcode_init allocates and initialises code area, data area and references */
81 static void mcode_init()
84 mcodebase = MNEW (u1, MCODEINITSIZE);
85 mcodesize = MCODEINITSIZE;
89 dsegtop = MNEW (u1, DSEGINITSIZE);
90 dsegsize = DSEGINITSIZE;
96 jumpreferences = NULL;
103 /* mcode_close releases temporary code and data area */
105 static void mcode_close()
108 MFREE (mcodebase, u1, mcodesize);
112 MFREE (dsegtop - dsegsize, u1, dsegsize);
118 /* mcode_increase doubles code area */
120 static s4 *mcode_increase(u1 *codeptr)
124 len = codeptr - mcodebase;
125 mcodebase = MREALLOC(mcodebase, u1, mcodesize, mcodesize * 2);
127 mcodeend = (s4*) (mcodebase + mcodesize);
128 return (s4*) (mcodebase + len);
132 /* desg_increase doubles data area */
134 static void dseg_increase() {
135 u1 *newstorage = MNEW (u1, dsegsize * 2);
136 memcpy ( newstorage + dsegsize, dsegtop - dsegsize, dsegsize);
137 MFREE (dsegtop - dsegsize, u1, dsegsize);
138 dsegtop = newstorage;
144 static s4 dseg_adds4_increase(s4 value)
147 *((s4 *) (dsegtop - dseglen)) = value;
152 static s4 dseg_adds4(s4 value)
157 dataptr = (s4 *) (dsegtop - dseglen);
158 if (dseglen > dsegsize)
159 return dseg_adds4_increase(value);
165 static s4 dseg_adds8_increase(s8 value)
168 *((s8 *) (dsegtop - dseglen)) = value;
173 static s4 dseg_adds8(s8 value)
177 dseglen = ALIGN (dseglen + 8, 8);
178 dataptr = (s8 *) (dsegtop - dseglen);
179 if (dseglen > dsegsize)
180 return dseg_adds8_increase(value);
186 static s4 dseg_addfloat_increase(float value)
189 *((float *) (dsegtop - dseglen)) = value;
194 static s4 dseg_addfloat(float value)
199 dataptr = (float *) (dsegtop - dseglen);
200 if (dseglen > dsegsize)
201 return dseg_addfloat_increase(value);
207 static s4 dseg_adddouble_increase(double value)
210 *((double *) (dsegtop - dseglen)) = value;
215 static s4 dseg_adddouble(double value)
219 dseglen = ALIGN (dseglen + 8, 8);
220 dataptr = (double *) (dsegtop - dseglen);
221 if (dseglen > dsegsize)
222 return dseg_adddouble_increase(value);
228 static void dseg_addtarget(basicblock *target)
230 jumpref *jr = DNEW(jumpref);
232 jr->tablepos = dseg_addaddress(NULL);
234 jr->next = jumpreferences;
239 static void mcode_addreference(basicblock *target, void *branchptr)
241 s4 branchpos = (u1*) branchptr - mcodebase;
243 if (target->mpc >= 0) {
244 gen_resolvebranch((u1*) mcodebase + branchpos, branchpos, target->mpc);
247 branchref *br = DNEW(branchref);
249 br->branchpos = branchpos;
250 br->next = target->branchrefs;
251 target->branchrefs= br;
256 static void mcode_addxboundrefs(void *branchptr)
258 s4 branchpos = (u1*) branchptr - mcodebase;
260 branchref *br = DNEW(branchref);
262 br->branchpos = branchpos;
263 br->next = xboundrefs;
268 static void mcode_addxcheckarefs(void *branchptr)
270 s4 branchpos = (u1*) branchptr - mcodebase;
272 branchref *br = DNEW(branchref);
274 br->branchpos = branchpos;
275 br->next = xcheckarefs;
280 static void mcode_addxnullrefs(void *branchptr)
282 s4 branchpos = (u1*) branchptr - mcodebase;
284 branchref *br = DNEW(branchref);
286 br->branchpos = branchpos;
287 br->next = xnullrefs;
292 static void mcode_addxcastrefs(void *branchptr)
294 s4 branchpos = (u1*) branchptr - mcodebase;
296 branchref *br = DNEW(branchref);
298 br->branchpos = branchpos;
299 br->next = xcastrefs;
304 static void mcode_finish(int mcodelen)
309 count_code_len += mcodelen;
310 count_data_len += dseglen;
312 dseglen = ALIGN(dseglen, MAX_ALIGN);
314 method -> mcodelength = mcodelen + dseglen;
315 method -> mcode = CNEW(u1, mcodelen + dseglen);
317 memcpy ( method->mcode, dsegtop - dseglen, dseglen);
318 memcpy ( method->mcode + dseglen, mcodebase, mcodelen);
320 method -> entrypoint = epoint = (u1*) (method->mcode + dseglen);
322 /* jump table resolving */
326 *((void**) (epoint + jr->tablepos)) = epoint + jr->target->mpc;
332 static void dseg_display(s4 *s4ptr)
336 printf(" --- dump of datasegment\n");
337 for (i = dseglen; i > 0 ; i -= 4) {
338 printf("-%6x: %8x\n", i, (int)(*s4ptr++));
340 printf(" --- begin of data segment: %p\n", s4ptr);