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 */
54 static void mcode_init(); /* allocates code and data area */
55 static void mcode_close(); /* releases temporary storage */
56 static void mcode_finish(); /* makes code and data area permanent and */
57 /* updates branch references to code/data */
59 static s4 dseg_adds4(s4 value); /* adds an int to data area */
60 static s4 dseg_adds8(s8 value); /* adds an long to data area */
61 static s4 dseg_addfloat (float value); /* adds an float to data area */
62 static s4 dseg_adddouble(double value); /* adds an double to data area */
65 #define dseg_addaddress(value) dseg_adds8((s8)(value))
67 #define dseg_addaddress(value) dseg_adds4((s4)(value))
70 static void dseg_addtarget(basicblock *target);
71 static void mcode_addreference(basicblock *target, void *branchptr);
72 static void mcode_addxboundrefs(void *branchptr);
73 static void mcode_addxnullrefs(void *branchptr);
75 static void dseg_display(s4 *s4ptr);
77 /* mcode_init allocates and initialises code area, data area and references */
79 static void mcode_init()
82 mcodebase = MNEW (u1, MCODEINITSIZE);
83 mcodesize = MCODEINITSIZE;
87 dsegtop = MNEW (u1, DSEGINITSIZE);
88 dsegsize = DSEGINITSIZE;
94 jumpreferences = NULL;
100 /* mcode_close releases temporary code and data area */
102 static void mcode_close()
105 MFREE (mcodebase, u1, mcodesize);
109 MFREE (dsegtop - dsegsize, u1, dsegsize);
115 /* mcode_increase doubles code area */
117 static s4 *mcode_increase(u1 *codeptr)
121 len = codeptr - mcodebase;
122 mcodebase = MREALLOC(mcodebase, u1, mcodesize, mcodesize * 2);
124 mcodeend = (s4*) (mcodebase + mcodesize);
125 return (s4*) (mcodebase + len);
129 /* desg_increase doubles data area */
131 static void dseg_increase() {
132 u1 *newstorage = MNEW (u1, dsegsize * 2);
133 memcpy ( newstorage + dsegsize, dsegtop - dsegsize, dsegsize);
134 MFREE (dsegtop - dsegsize, u1, dsegsize);
135 dsegtop = newstorage;
141 static s4 dseg_adds4_increase(s4 value)
144 *((s4 *) (dsegtop - dseglen)) = value;
149 static s4 dseg_adds4(s4 value)
154 dataptr = (s4 *) (dsegtop - dseglen);
155 if (dseglen > dsegsize)
156 return dseg_adds4_increase(value);
162 static s4 dseg_adds8_increase(s8 value)
165 *((s8 *) (dsegtop - dseglen)) = value;
170 static s4 dseg_adds8(s8 value)
174 dseglen = ALIGN (dseglen + 8, 8);
175 dataptr = (s8 *) (dsegtop - dseglen);
176 if (dseglen > dsegsize)
177 return dseg_adds8_increase(value);
183 static s4 dseg_addfloat_increase(float value)
186 *((float *) (dsegtop - dseglen)) = value;
191 static s4 dseg_addfloat(float value)
196 dataptr = (float *) (dsegtop - dseglen);
197 if (dseglen > dsegsize)
198 return dseg_addfloat_increase(value);
204 static s4 dseg_adddouble_increase(double value)
207 *((double *) (dsegtop - dseglen)) = value;
212 static s4 dseg_adddouble(double value)
216 dseglen = ALIGN (dseglen + 8, 8);
217 dataptr = (double *) (dsegtop - dseglen);
218 if (dseglen > dsegsize)
219 return dseg_adddouble_increase(value);
225 static void dseg_addtarget(basicblock *target)
227 jumpref *jr = DNEW(jumpref);
229 jr->tablepos = dseg_addaddress(NULL);
231 jr->next = jumpreferences;
236 static void mcode_addreference(basicblock *target, void *branchptr)
238 s4 branchpos = (u1*) branchptr - mcodebase;
240 if (target->mpc >= 0) {
241 gen_resolvebranch((u1*) mcodebase + branchpos, branchpos, target->mpc);
244 branchref *br = DNEW(branchref);
246 br->branchpos = branchpos;
247 br->next = target->branchrefs;
248 target->branchrefs= br;
253 static void mcode_addxboundrefs(void *branchptr)
255 s4 branchpos = (u1*) branchptr - mcodebase;
257 branchref *br = DNEW(branchref);
259 br->branchpos = branchpos;
260 br->next = xboundrefs;
265 static void mcode_addxcheckarefs(void *branchptr)
267 s4 branchpos = (u1*) branchptr - mcodebase;
269 branchref *br = DNEW(branchref);
271 br->branchpos = branchpos;
272 br->next = xcheckarefs;
277 static void mcode_addxnullrefs(void *branchptr)
279 s4 branchpos = (u1*) branchptr - mcodebase;
281 branchref *br = DNEW(branchref);
283 br->branchpos = branchpos;
284 br->next = xnullrefs;
289 static void mcode_finish(int mcodelen)
294 count_code_len += mcodelen;
295 count_data_len += dseglen;
297 dseglen = ALIGN(dseglen, MAX_ALIGN);
299 method -> mcodelength = mcodelen + dseglen;
300 method -> mcode = CNEW(u1, mcodelen + dseglen);
302 memcpy ( method->mcode, dsegtop - dseglen, dseglen);
303 memcpy ( method->mcode + dseglen, mcodebase, mcodelen);
305 method -> entrypoint = epoint = (u1*) (method->mcode + dseglen);
307 /* jump table resolving */
311 *((void**) (epoint + jr->tablepos)) = epoint + jr->target->mpc;
315 #ifdef CACHE_FLUSH_BLOCK
316 synchronize_caches(method->mcode, (mcodelen>>2));
322 static void dseg_display(s4 *s4ptr)
326 printf(" --- dump of datasegment\n");
327 for (i = dseglen; i > 0 ; i -= 4) {
328 printf("-%6x: %8x\n", i, (int)(*s4ptr++));
330 printf(" --- begin of data segment: %p\n", s4ptr);