1f9445b2d0c61b870251a3a49f8fa62f73a4233a
[cacao.git] / jit / reg.c
1 /* jit/reg.c *******************************************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         The register-manager.
8
9         Authors:  Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
10
11         Last Change: 1998/11/09
12
13 *******************************************************************************/
14
15 static varinfo5 *locals;
16 static varinfo5 *interfaces;
17
18 static int intregsnum;              /* absolute number of integer registers   */
19 static int floatregsnum;            /* absolute number of float registers     */ 
20
21 static int intreg_ret;              /* register to return integer values      */
22 static int intreg_argnum;           /* number of integer argument registers   */
23
24 static int floatreg_ret;            /* register for return float values       */
25 static int fltreg_argnum;           /* number of float argument registers     */
26
27
28 static int *argintregs;             /* scratch integer registers              */
29 static int *tmpintregs = NULL;      /* scratch integer registers              */
30 static int *savintregs;             /* saved integer registers                */
31 static int *argfltregs;             /* scratch float registers                */
32 static int *tmpfltregs;             /* scratch float registers                */
33 static int *savfltregs;             /* saved float registers                  */
34 static int *freetmpintregs;         /* free scratch integer registers         */
35 static int *freesavintregs;         /* free saved integer registers           */
36 static int *freetmpfltregs;         /* free scratch float registers           */
37 static int *freesavfltregs;         /* free saved float registers             */
38
39 static int *freemem;                /* free scratch memory                    */
40 static int memuse;                  /* used memory count                      */
41 static int ifmemuse;                /* interface used memory count            */
42 static int maxmemuse;               /* maximal used memory count (spills)     */
43 static int freememtop;              /* free memory count                      */
44
45 static int tmpintregcnt;            /* scratch integer register count         */
46 static int savintregcnt;            /* saved integer register count           */
47 static int tmpfltregcnt;            /* scratch float register count           */
48 static int savfltregcnt;            /* saved float register count             */
49
50 static int iftmpintregcnt;          /* iface scratch integer register count   */
51 static int ifsavintregcnt;          /* iface saved integer register count     */
52 static int iftmpfltregcnt;          /* iface scratch float register count     */
53 static int ifsavfltregcnt;          /* iface saved float register count       */
54
55 static int tmpintreguse;            /* used scratch integer register count    */
56 static int savintreguse;            /* used saved integer register count      */
57 static int tmpfltreguse;            /* used scratch float register count      */
58 static int savfltreguse;            /* used saved float register count        */
59
60 static int maxtmpintreguse;         /* max used scratch int register count    */
61 static int maxsavintreguse;         /* max used saved int register count      */
62 static int maxtmpfltreguse;         /* max used scratch float register count  */
63 static int maxsavfltreguse;         /* max used saved float register count    */
64
65 static int freetmpinttop;           /* free scratch integer register count    */
66 static int freesavinttop;           /* free saved integer register count      */
67 static int freetmpflttop;           /* free scratch float register count      */
68 static int freesavflttop;           /* free saved float register count        */
69
70 static int savedregs_num;       /* total number of registers to be saved      */
71 static int arguments_num;       /* size of parameter field in the stackframe  */
72
73
74
75 /* function reg_init ***********************************************************
76
77         initialises the register-allocator
78         
79 *******************************************************************************/
80
81 static void reg_init()
82 {
83         int n;
84         
85         if (!tmpintregs) {
86
87                 if (TYPE_INT != 0 || TYPE_ADR != 4) 
88                         panic ("JAVA-Basictypes have been changed");
89
90                 intreg_argnum = 0;
91                 tmpintregcnt = 0;
92                 savintregcnt = 0;
93
94                 for (intregsnum = 0; nregdescint[intregsnum] != REG_END; intregsnum++) {
95                         switch (nregdescint[intregsnum]) {
96                                 case REG_SAV: savintregcnt++;
97                                               break;
98                                 case REG_TMP: tmpintregcnt++;
99                                               break;
100                                 case REG_ARG: intreg_argnum++;
101                                 }
102                         }
103
104                 argintregs = MNEW (int, intreg_argnum);
105                 tmpintregs = MNEW (int, tmpintregcnt);
106                 savintregs = MNEW (int, savintregcnt);
107                 freetmpintregs = MNEW (int, tmpintregcnt);
108                 freesavintregs = MNEW (int, savintregcnt);
109
110                 intreg_argnum = 0;
111                 tmpintreguse = 0;
112                 savintreguse = 0;
113
114                 for (n = 0; n < intregsnum; n++) {
115                         switch (nregdescint[n]) {
116                                 case REG_RET: intreg_ret = n; 
117                                               break;
118                                 case REG_SAV: savintregs[savintreguse++] = n;
119                                               break;
120                                 case REG_TMP: tmpintregs[tmpintreguse++] = n;
121                                               break;
122                                 case REG_ARG: argintregs[intreg_argnum++] = n;
123                                               break;
124                                 }
125                         }
126                                         
127                 
128                 fltreg_argnum = 0;
129                 tmpfltregcnt = 0;
130                 savfltregcnt = 0;
131
132                 for (floatregsnum = 0; nregdescfloat[floatregsnum] != REG_END; floatregsnum++) {
133                         switch (nregdescfloat[floatregsnum]) {
134                                 case REG_SAV: savfltregcnt++;
135                                               break;
136                                 case REG_TMP: tmpfltregcnt++;
137                                               break;
138                                 case REG_ARG: fltreg_argnum++;
139                                               break;
140                                 }
141                         }
142
143                 argfltregs = MNEW (int, fltreg_argnum);
144                 tmpfltregs = MNEW (int, tmpfltregcnt);
145                 savfltregs = MNEW (int, savfltregcnt);
146                 freetmpfltregs = MNEW (int, tmpfltregcnt);
147                 freesavfltregs = MNEW (int, savfltregcnt);
148
149                 fltreg_argnum = 0;
150                 tmpfltreguse = 0;
151                 savfltreguse = 0;
152
153                 for (n = 0; n < floatregsnum; n++) {
154                         switch (nregdescfloat[n]) {
155                                 case REG_RET: floatreg_ret = n; 
156                                               break;
157                                 case REG_SAV: savfltregs[savfltreguse++] = n;
158                                               break;
159                                 case REG_TMP: tmpfltregs[tmpfltreguse++] = n;
160                                               break;
161                                 case REG_ARG: argfltregs[fltreg_argnum++] = n;
162                                               break;
163                                 }
164                         }
165                                         
166                 }
167
168 }
169
170
171 /* function reg_close **********************************************************
172
173         releases all allocated space for registers
174
175 *******************************************************************************/
176
177 static void reg_close ()
178 {
179         if (argintregs) MFREE (argintregs, int, intreg_argnum);
180         if (argfltregs) MFREE (argfltregs, int, fltreg_argnum);
181         if (tmpintregs) MFREE (tmpintregs, int, tmpintregcnt);
182         if (savintregs) MFREE (savintregs, int, savintregcnt);
183         if (tmpfltregs) MFREE (tmpfltregs, int, tmpfltregcnt);
184         if (savfltregs) MFREE (savfltregs, int, savfltregcnt);
185
186         if (freetmpintregs) MFREE (freetmpintregs, int, tmpintregcnt);
187         if (freesavintregs) MFREE (freesavintregs, int, savintregcnt);
188         if (freetmpfltregs) MFREE (freetmpfltregs, int, tmpfltregcnt);
189         if (freesavfltregs) MFREE (freesavfltregs, int, savfltregcnt);
190 }
191
192
193 /* function local_init *********************************************************
194
195         initialises the local variable and interfaces table
196         
197 *******************************************************************************/
198
199 static void local_init()
200 {
201         int i;
202         varinfo5 *v;
203
204         freemem    = DMNEW(int, maxstack);
205         locals     = DMNEW(varinfo5, maxlocals);
206         interfaces = DMNEW(varinfo5, maxstack);
207
208         for (v = locals, i = maxlocals; i > 0; v++, i--) {
209                 v[0][TYPE_INT].type = -1;
210                 v[0][TYPE_LNG].type = -1;
211                 v[0][TYPE_FLT].type = -1;
212                 v[0][TYPE_DBL].type = -1;
213                 v[0][TYPE_ADR].type = -1;
214                 }
215
216         for (v = interfaces, i = maxstack; i > 0; v++, i--) {
217                 v[0][TYPE_INT].type = -1;
218                 v[0][TYPE_INT].flags = 0;
219                 v[0][TYPE_LNG].type = -1;
220                 v[0][TYPE_LNG].flags = 0;
221                 v[0][TYPE_FLT].type = -1;
222                 v[0][TYPE_FLT].flags = 0;
223                 v[0][TYPE_DBL].type = -1;
224                 v[0][TYPE_DBL].flags = 0;
225                 v[0][TYPE_ADR].type = -1;
226                 v[0][TYPE_ADR].flags = 0;
227                 }
228 }
229
230
231 /* function interface_regalloc *************************************************
232
233         allocates registers for all interface variables
234         
235 *******************************************************************************/
236         
237 static void interface_regalloc ()
238 {
239         int     s, t, saved;
240         int     intalloc, fltalloc;
241         varinfo *v;
242         
243         /* allocate stack space for passing arguments to called methods */
244
245         if (arguments_num > intreg_argnum)
246                 ifmemuse = arguments_num - intreg_argnum;
247         else
248                 ifmemuse = 0;
249
250         iftmpintregcnt = tmpintregcnt;
251         ifsavintregcnt = savintregcnt;
252         iftmpfltregcnt = tmpfltregcnt;
253         ifsavfltregcnt = savfltregcnt;
254
255         for (s = 0; s < maxstack; s++) {
256                 intalloc = -1; fltalloc = -1;
257                 saved = (interfaces[s][TYPE_INT].flags | interfaces[s][TYPE_LNG].flags |
258                          interfaces[s][TYPE_FLT].flags | interfaces[s][TYPE_DBL].flags |
259                          interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
260                 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
261                         v = &interfaces[s][t];
262                         if (v->type >= 0) {
263                                 if (!saved) {
264                                         if (IS_FLT_DBL_TYPE(t)) {
265                                                 if (fltalloc >= 0) {
266                                                         v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
267                                                         v->regoff = interfaces[s][fltalloc].regoff;
268                                                         }
269                                                 else if (iftmpfltregcnt > 0) {
270                                                         iftmpfltregcnt--;
271                                                         v->regoff = tmpfltregs[iftmpfltregcnt];
272                                                         }
273                                                 else if (ifsavfltregcnt > 0) {
274                                                         ifsavfltregcnt--;
275                                                         v->regoff = savfltregs[ifsavfltregcnt];
276                                                         }
277                                                 else {
278                                                         v->flags |= INMEMORY;
279                                                         v->regoff = ifmemuse++;
280                                                         }
281                                                 fltalloc = t;
282                                                 }
283                                         else {
284                                                 if (intalloc >= 0) {
285                                                         v->flags |= interfaces[s][intalloc].flags & INMEMORY;
286                                                         v->regoff = interfaces[s][intalloc].regoff;
287                                                         }
288                                                 else if (iftmpintregcnt > 0) {
289                                                         iftmpintregcnt--;
290                                                         v->regoff = tmpintregs[iftmpintregcnt];
291                                                         }
292                                                 else if (ifsavintregcnt > 0) {
293                                                         ifsavintregcnt--;
294                                                         v->regoff = savintregs[ifsavintregcnt];
295                                                         }
296                                                 else {
297                                                         v->flags |= INMEMORY;
298                                                         v->regoff = ifmemuse++;
299                                                         }
300                                                 intalloc = t;
301                                                 }
302                                         }
303                                 else {
304                                         if (IS_FLT_DBL_TYPE(t)) {
305                                                 if (fltalloc >= 0) {
306                                                         v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
307                                                         v->regoff = interfaces[s][fltalloc].regoff;
308                                                         }
309                                                 else if (ifsavfltregcnt > 0) {
310                                                         ifsavfltregcnt--;
311                                                         v->regoff = savfltregs[ifsavfltregcnt];
312                                                         }
313                                                 else {
314                                                         v->flags |= INMEMORY;
315                                                         v->regoff = ifmemuse++;
316                                                         }
317                                                 fltalloc = t;
318                                                 }
319                                         else {
320                                                 if (intalloc >= 0) {
321                                                         v->flags |= interfaces[s][intalloc].flags & INMEMORY;
322                                                         v->regoff = interfaces[s][intalloc].regoff;
323                                                         }
324                                                 else if (ifsavintregcnt > 0) {
325                                                         ifsavintregcnt--;
326                                                         v->regoff = savintregs[ifsavintregcnt];
327                                                         }
328                                                 else {
329                                                         v->flags |= INMEMORY;
330                                                         v->regoff = ifmemuse++;
331                                                         }
332                                                 intalloc = t;
333                                                 }
334                                         }
335                                 } /* if (type >= 0) */
336                         }     /* for t */
337                 }         /* for s */
338         maxmemuse = ifmemuse;
339         maxtmpintreguse = iftmpintregcnt;
340         maxsavintreguse = ifsavintregcnt;
341         maxtmpfltreguse = iftmpfltregcnt;
342         maxsavfltreguse = ifsavfltregcnt;
343 }
344
345
346 /* function local_regalloc *****************************************************
347
348         allocates registers for all local variables
349         
350 *******************************************************************************/
351         
352 static void local_regalloc ()
353 {
354         int      s, t;
355         int      intalloc, fltalloc;
356         varinfo *v;
357         
358         if (isleafmethod) {
359                 int arg, doublewordarg;
360                 arg = 0;
361                 doublewordarg = 0;
362                 for (s = 0; s < maxlocals; s++) {
363                         intalloc = -1; fltalloc = -1;
364                         for (t = TYPE_INT; t <= TYPE_ADR; t++) {
365                                 v = &locals[s][t];
366                                 if (v->type >= 0) {
367                                         if (IS_FLT_DBL_TYPE(t)) {
368                                                 if (fltalloc >= 0) {
369                                                         v->flags = locals[s][fltalloc].flags;
370                                                         v->regoff = locals[s][fltalloc].regoff;
371                                                         }
372                                                 else if (!doublewordarg && (arg < mparamcount)
373                                                                         && (arg < fltreg_argnum)) {
374                                                         v->flags = 0;
375                                                         v->regoff = argfltregs[arg];
376                                                         }
377                                                 else if (maxtmpfltreguse > 0) {
378                                                         maxtmpfltreguse--;
379                                                         v->flags = 0;
380                                                         v->regoff = tmpfltregs[maxtmpfltreguse];
381                                                         }
382                                                 else if (maxsavfltreguse > 0) {
383                                                         maxsavfltreguse--;
384                                                         v->flags = 0;
385                                                         v->regoff = savfltregs[maxsavfltreguse];
386                                                         }
387                                                 else {
388                                                         v->flags = INMEMORY;
389                                                         v->regoff = maxmemuse++;
390                                                         }
391                                                 fltalloc = t;
392                                                 }
393                                         else {
394                                                 if (intalloc >= 0) {
395                                                         v->flags = locals[s][intalloc].flags;
396                                                         v->regoff = locals[s][intalloc].regoff;
397                                                         }
398                                                 else if (!doublewordarg && (arg < mparamcount)
399                                                                         && (arg < intreg_argnum)) {
400                                                         v->flags = 0;
401                                                         v->regoff = argintregs[arg];
402                                                         }
403                                                 else if (maxtmpintreguse > 0) {
404                                                         maxtmpintreguse--;
405                                                         v->flags = 0;
406                                                         v->regoff = tmpintregs[maxtmpintreguse];
407                                                         }
408                                                 else if (maxsavintreguse > 0) {
409                                                         maxsavintreguse--;
410                                                         v->flags = 0;
411                                                         v->regoff = savintregs[maxsavintreguse];
412                                                         }
413                                                 else {
414                                                         v->flags = INMEMORY;
415                                                         v->regoff = maxmemuse++;
416                                                         }
417                                                 intalloc = t;
418                                                 }
419                                         }
420                                 }
421                         if (arg < mparamcount) {
422                                 if (doublewordarg) {
423                                         doublewordarg = 0;
424                                         arg++;
425                                         }
426                                 else if (IS_2_WORD_TYPE(mparamtypes[arg]))
427                                         doublewordarg = 1;
428                                 else
429                                         arg++;
430                                 }
431                         }
432                 return;
433                 }
434         for (s = 0; s < maxlocals; s++) {
435                 intalloc = -1; fltalloc = -1;
436                 for (t=TYPE_INT; t<=TYPE_ADR; t++) {
437                         v = &locals[s][t];
438                         if (v->type >= 0) {
439                                 if (IS_FLT_DBL_TYPE(t)) {
440                                         if (fltalloc >= 0) {
441                                                 v->flags = locals[s][fltalloc].flags;
442                                                 v->regoff = locals[s][fltalloc].regoff;
443                                                 }
444                                         else if (maxsavfltreguse > 0) {
445                                                 maxsavfltreguse--;
446                                                 v->flags = 0;
447                                                 v->regoff = savfltregs[maxsavfltreguse];
448                                                 }
449                                         else {
450                                                 v->flags = INMEMORY;
451                                                 v->regoff = maxmemuse++;
452                                                 }
453                                         fltalloc = t;
454                                         }
455                                 else {
456                                         if (intalloc >= 0) {
457                                                 v->flags = locals[s][intalloc].flags;
458                                                 v->regoff = locals[s][intalloc].regoff;
459                                                 }
460                                         else if (maxsavintreguse > 0) {
461                                                 maxsavintreguse--;
462                                                 v->flags = 0;
463                                                 v->regoff = savintregs[maxsavintreguse];
464                                                 }
465                                         else {
466                                                 v->flags = INMEMORY;
467                                                 v->regoff = maxmemuse++;
468                                                 }
469                                         intalloc = t;
470                                         }
471                                 }
472                         }
473                 }
474 }
475
476
477 static void reg_init_temp()
478 {
479         freememtop = 0;
480         memuse = ifmemuse;
481
482         freetmpinttop = 0;
483         freesavinttop = 0;
484         freetmpflttop = 0;
485         freesavflttop = 0;
486         tmpintreguse = iftmpintregcnt;
487         savintreguse = ifsavintregcnt;
488         tmpfltreguse = iftmpfltregcnt;
489         savfltreguse = ifsavfltregcnt;
490 }
491
492
493 #define reg_new_temp(s) if(s->varkind==TEMPVAR)reg_new_temp_func(s)
494
495 static void reg_new_temp_func(stackptr s)
496 {
497 if (s->flags & SAVEDVAR) {
498         if (IS_FLT_DBL_TYPE(s->type)) {
499                 if (freesavflttop > 0) {
500                         freesavflttop--;
501                         s->regoff = freesavfltregs[freesavflttop];
502                         return;
503                         }
504                 else if (savfltreguse > 0) {
505                         savfltreguse--;
506                         if (savfltreguse < maxsavfltreguse)
507                                 maxsavfltreguse = savfltreguse;
508                         s->regoff = savfltregs[savfltreguse];
509                         return;
510                         }
511                 }
512         else {
513                 if (freesavinttop > 0) {
514                         freesavinttop--;
515                         s->regoff = freesavintregs[freesavinttop];
516                         return;
517                         }
518                 else if (savintreguse > 0) {
519                         savintreguse--;
520                         if (savintreguse < maxsavintreguse)
521                                 maxsavintreguse = savintreguse;
522                         s->regoff = savintregs[savintreguse];
523                         return;
524                         }
525                 }
526         }
527 else {
528         if (IS_FLT_DBL_TYPE(s->type)) {
529                 if (freetmpflttop > 0) {
530                         freetmpflttop--;
531                         s->regoff = freetmpfltregs[freetmpflttop];
532                         return;
533                         }
534                 else if (tmpfltreguse > 0) {
535                         tmpfltreguse--;
536                         if (tmpfltreguse < maxtmpfltreguse)
537                                 maxtmpfltreguse = tmpfltreguse;
538                         s->regoff = tmpfltregs[tmpfltreguse];
539                         return;
540                         }
541                 }
542         else {
543                 if (freetmpinttop > 0) {
544                         freetmpinttop--;
545                         s->regoff = freetmpintregs[freetmpinttop];
546                         return;
547                         }
548                 else if (tmpintreguse > 0) {
549                         tmpintreguse--;
550                         if (tmpintreguse < maxtmpintreguse)
551                                 maxtmpintreguse = tmpintreguse;
552                         s->regoff = tmpintregs[tmpintreguse];
553                         return;
554                         }
555                 }
556         }
557 if (freememtop > 0) {
558         freememtop--;
559         s->regoff = freemem[freememtop];
560         }
561 else {
562         s->regoff = memuse++;
563         if (memuse > maxmemuse)
564                 maxmemuse = memuse;
565         }
566 s->flags |= INMEMORY;
567 }
568
569
570 #define reg_free_temp(s) if(s->varkind==TEMPVAR)reg_free_temp_func(s)
571
572 static void reg_free_temp_func(stackptr s)
573 {
574 if (s->flags & INMEMORY)
575         freemem[freememtop++] = s->regoff;
576 else if (IS_FLT_DBL_TYPE(s->type)) {
577         if (s->flags & SAVEDVAR)
578                 freesavfltregs[freesavflttop++] = s->regoff;
579         else
580                 freetmpfltregs[freetmpflttop++] = s->regoff;
581         }
582 else
583         if (s->flags & SAVEDVAR)
584                 freesavintregs[freesavinttop++] = s->regoff;
585         else
586                 freetmpintregs[freetmpinttop++] = s->regoff;
587 }
588
589
590 static void allocate_scratch_registers()
591 {
592         int b_count;
593         int opcode, i, len;
594         stackptr    src, dst;
595         instruction *iptr = instr;
596         basicblock  *bptr;
597         
598         b_count = block_count;
599         bptr = block;
600         while (--b_count >= 0) {
601                 if (bptr->flags >= BBREACHED) {
602                         dst = bptr->instack;
603                         reg_init_temp();
604                         iptr = bptr->iinstr;
605                         len = bptr->icount;
606                         while (--len >= 0)  {
607                                 src = dst;
608                                 dst = iptr->dst;
609                                 opcode = iptr->opc;
610                                 switch (opcode) {
611
612                                         /* pop 0 push 0 */
613
614                                         case ICMD_NOP:
615                                         case ICMD_ELSE_ICONST:
616                                         case ICMD_CHECKASIZE:
617                                         case ICMD_IINC:
618                                         case ICMD_JSR:
619                                         case ICMD_RET:
620                                         case ICMD_RETURN:
621                                         case ICMD_GOTO:
622                                                 break;
623
624                                         /* pop 0 push 1 const */
625                                         
626                                         case ICMD_ICONST:
627                                         case ICMD_LCONST:
628                                         case ICMD_FCONST:
629                                         case ICMD_DCONST:
630                                         case ICMD_ACONST:
631
632                                         /* pop 0 push 1 load */
633                                         
634                                         case ICMD_ILOAD:
635                                         case ICMD_LLOAD:
636                                         case ICMD_FLOAD:
637                                         case ICMD_DLOAD:
638                                         case ICMD_ALOAD:
639                                                 reg_new_temp(dst);
640                                                 break;
641
642                                         /* pop 2 push 1 */
643
644                                         case ICMD_IALOAD:
645                                         case ICMD_LALOAD:
646                                         case ICMD_FALOAD:
647                                         case ICMD_DALOAD:
648                                         case ICMD_AALOAD:
649
650                                         case ICMD_BALOAD:
651                                         case ICMD_CALOAD:
652                                         case ICMD_SALOAD:
653
654                                                 reg_free_temp(src);
655                                                 reg_free_temp(src->prev);
656                                                 reg_new_temp(dst);
657                                                 break;
658
659                                         /* pop 3 push 0 */
660
661                                         case ICMD_IASTORE:
662                                         case ICMD_LASTORE:
663                                         case ICMD_FASTORE:
664                                         case ICMD_DASTORE:
665                                         case ICMD_AASTORE:
666
667                                         case ICMD_BASTORE:
668                                         case ICMD_CASTORE:
669                                         case ICMD_SASTORE:
670
671                                                 reg_free_temp(src);
672                                                 reg_free_temp(src->prev);
673                                                 reg_free_temp(src->prev->prev);
674                                                 break;
675
676                                         /* pop 1 push 0 store */
677
678                                         case ICMD_ISTORE:
679                                         case ICMD_LSTORE:
680                                         case ICMD_FSTORE:
681                                         case ICMD_DSTORE:
682                                         case ICMD_ASTORE:
683
684                                         /* pop 1 push 0 */
685
686                                         case ICMD_POP:
687
688                                         case ICMD_IRETURN:
689                                         case ICMD_LRETURN:
690                                         case ICMD_FRETURN:
691                                         case ICMD_DRETURN:
692                                         case ICMD_ARETURN:
693
694                                         case ICMD_ATHROW:
695
696                                         case ICMD_PUTSTATIC:
697
698                                         /* pop 1 push 0 branch */
699
700                                         case ICMD_IFNULL:
701                                         case ICMD_IFNONNULL:
702
703                                         case ICMD_IFEQ:
704                                         case ICMD_IFNE:
705                                         case ICMD_IFLT:
706                                         case ICMD_IFGE:
707                                         case ICMD_IFGT:
708                                         case ICMD_IFLE:
709
710                                         case ICMD_IF_LEQ:
711                                         case ICMD_IF_LNE:
712                                         case ICMD_IF_LLT:
713                                         case ICMD_IF_LGE:
714                                         case ICMD_IF_LGT:
715                                         case ICMD_IF_LLE:
716
717                                         /* pop 1 push 0 table branch */
718
719                                         case ICMD_TABLESWITCH:
720                                         case ICMD_LOOKUPSWITCH:
721
722                                         case ICMD_NULLCHECKPOP:
723                                         case ICMD_MONITORENTER:
724                                         case ICMD_MONITOREXIT:
725                                                 reg_free_temp(src);
726                                                 break;
727
728                                         /* pop 2 push 0 branch */
729
730                                         case ICMD_IF_ICMPEQ:
731                                         case ICMD_IF_ICMPNE:
732                                         case ICMD_IF_ICMPLT:
733                                         case ICMD_IF_ICMPGE:
734                                         case ICMD_IF_ICMPGT:
735                                         case ICMD_IF_ICMPLE:
736
737                                         case ICMD_IF_LCMPEQ:
738                                         case ICMD_IF_LCMPNE:
739                                         case ICMD_IF_LCMPLT:
740                                         case ICMD_IF_LCMPGE:
741                                         case ICMD_IF_LCMPGT:
742                                         case ICMD_IF_LCMPLE:
743
744                                         case ICMD_IF_ACMPEQ:
745                                         case ICMD_IF_ACMPNE:
746
747                                         /* pop 2 push 0 */
748
749                                         case ICMD_POP2:
750
751                                         case ICMD_PUTFIELD:
752                                                 reg_free_temp(src);
753                                                 reg_free_temp(src->prev);
754                                                 break;
755
756                                         /* pop 0 push 1 dup */
757                                         
758                                         case ICMD_DUP:
759                                                 reg_new_temp(dst);
760                                                 break;
761
762                                         /* pop 0 push 2 dup */
763                                         
764                                         case ICMD_DUP2:
765                                                 reg_new_temp(dst->prev);
766                                                 reg_new_temp(dst);
767                                                 break;
768
769                                         /* pop 2 push 3 dup */
770                                         
771                                         case ICMD_DUP_X1:
772                                                 reg_new_temp(dst->prev->prev);
773                                                 reg_new_temp(dst->prev);
774                                                 reg_new_temp(dst);
775                                                 reg_free_temp(src);
776                                                 reg_free_temp(src->prev);
777                                                 break;
778
779                                         /* pop 3 push 4 dup */
780                                         
781                                         case ICMD_DUP_X2:
782                                                 reg_new_temp(dst->prev->prev->prev);
783                                                 reg_new_temp(dst->prev->prev);
784                                                 reg_new_temp(dst->prev);
785                                                 reg_new_temp(dst);
786                                                 reg_free_temp(src);
787                                                 reg_free_temp(src->prev);
788                                                 reg_free_temp(src->prev->prev);
789                                                 break;
790
791                                         /* pop 3 push 5 dup */
792                                         
793                                         case ICMD_DUP2_X1:
794                                                 reg_new_temp(dst->prev->prev->prev->prev);
795                                                 reg_new_temp(dst->prev->prev->prev);
796                                                 reg_new_temp(dst->prev->prev);
797                                                 reg_new_temp(dst->prev);
798                                                 reg_new_temp(dst);
799                                                 reg_free_temp(src);
800                                                 reg_free_temp(src->prev);
801                                                 reg_free_temp(src->prev->prev);
802                                                 break;
803
804                                         /* pop 4 push 6 dup */
805                                         
806                                         case ICMD_DUP2_X2:
807                                                 reg_new_temp(dst->prev->prev->prev->prev->prev);
808                                                 reg_new_temp(dst->prev->prev->prev->prev);
809                                                 reg_new_temp(dst->prev->prev->prev);
810                                                 reg_new_temp(dst->prev->prev);
811                                                 reg_new_temp(dst->prev);
812                                                 reg_new_temp(dst);
813                                                 reg_free_temp(src);
814                                                 reg_free_temp(src->prev);
815                                                 reg_free_temp(src->prev->prev);
816                                                 reg_free_temp(src->prev->prev->prev);
817                                                 break;
818
819                                         /* pop 2 push 2 swap */
820                                         
821                                         case ICMD_SWAP:
822                                                 reg_new_temp(dst->prev);
823                                                 reg_new_temp(dst);
824                                                 reg_free_temp(src);
825                                                 reg_free_temp(src->prev);
826                                                 break;
827
828                                         /* pop 2 push 1 */
829                                         
830                                         case ICMD_IADD:
831                                         case ICMD_ISUB:
832                                         case ICMD_IMUL:
833                                         case ICMD_IDIV:
834                                         case ICMD_IREM:
835
836                                         case ICMD_ISHL:
837                                         case ICMD_ISHR:
838                                         case ICMD_IUSHR:
839                                         case ICMD_IAND:
840                                         case ICMD_IOR:
841                                         case ICMD_IXOR:
842
843                                         case ICMD_LADD:
844                                         case ICMD_LSUB:
845                                         case ICMD_LMUL:
846                                         case ICMD_LDIV:
847                                         case ICMD_LREM:
848
849                                         case ICMD_LOR:
850                                         case ICMD_LAND:
851                                         case ICMD_LXOR:
852
853                                         case ICMD_LSHL:
854                                         case ICMD_LSHR:
855                                         case ICMD_LUSHR:
856
857                                         case ICMD_FADD:
858                                         case ICMD_FSUB:
859                                         case ICMD_FMUL:
860                                         case ICMD_FDIV:
861                                         case ICMD_FREM:
862
863                                         case ICMD_DADD:
864                                         case ICMD_DSUB:
865                                         case ICMD_DMUL:
866                                         case ICMD_DDIV:
867                                         case ICMD_DREM:
868
869                                         case ICMD_LCMP:
870                                         case ICMD_FCMPL:
871                                         case ICMD_FCMPG:
872                                         case ICMD_DCMPL:
873                                         case ICMD_DCMPG:
874                                                 reg_free_temp(src);
875                                                 reg_free_temp(src->prev);
876                                                 reg_new_temp(dst);
877                                                 break;
878
879                                         /* pop 1 push 1 */
880                                         
881                                         case ICMD_IADDCONST:
882                                         case ICMD_ISUBCONST:
883                                         case ICMD_IMULCONST:
884                                         case ICMD_IDIVPOW2:
885                                         case ICMD_IREMPOW2:
886                                         case ICMD_IREM0X10001:
887                                         case ICMD_IANDCONST:
888                                         case ICMD_IORCONST:
889                                         case ICMD_IXORCONST:
890                                         case ICMD_ISHLCONST:
891                                         case ICMD_ISHRCONST:
892                                         case ICMD_IUSHRCONST:
893
894                                         case ICMD_LADDCONST:
895                                         case ICMD_LSUBCONST:
896                                         case ICMD_LMULCONST:
897                                         case ICMD_LDIVPOW2:
898                                         case ICMD_LREMPOW2:
899                                         case ICMD_LREM0X10001:
900                                         case ICMD_LANDCONST:
901                                         case ICMD_LORCONST:
902                                         case ICMD_LXORCONST:
903                                         case ICMD_LSHLCONST:
904                                         case ICMD_LSHRCONST:
905                                         case ICMD_LUSHRCONST:
906
907                                         case ICMD_IFEQ_ICONST:
908                                         case ICMD_IFNE_ICONST:
909                                         case ICMD_IFLT_ICONST:
910                                         case ICMD_IFGE_ICONST:
911                                         case ICMD_IFGT_ICONST:
912                                         case ICMD_IFLE_ICONST:
913
914                                         case ICMD_INEG:
915                                         case ICMD_INT2BYTE:
916                                         case ICMD_INT2CHAR:
917                                         case ICMD_INT2SHORT:
918                                         case ICMD_LNEG:
919                                         case ICMD_FNEG:
920                                         case ICMD_DNEG:
921
922                                         case ICMD_I2L:
923                                         case ICMD_I2F:
924                                         case ICMD_I2D:
925                                         case ICMD_L2I:
926                                         case ICMD_L2F:
927                                         case ICMD_L2D:
928                                         case ICMD_F2I:
929                                         case ICMD_F2L:
930                                         case ICMD_F2D:
931                                         case ICMD_D2I:
932                                         case ICMD_D2L:
933                                         case ICMD_D2F:
934
935                                         case ICMD_CHECKCAST:
936
937                                         case ICMD_ARRAYLENGTH:
938                                         case ICMD_INSTANCEOF:
939
940                                         case ICMD_NEWARRAY:
941                                         case ICMD_ANEWARRAY:
942
943                                         case ICMD_GETFIELD:
944                                                 reg_free_temp(src);
945                                                 reg_new_temp(dst);
946                                                 break;
947
948                                         /* pop 0 push 1 */
949                                         
950                                         case ICMD_GETSTATIC:
951
952                                         case ICMD_NEW:
953
954                                                 reg_new_temp(dst);
955                                                 break;
956
957                                         /* pop many push any */
958                                         
959                                         case ICMD_INVOKEVIRTUAL:
960                                         case ICMD_INVOKESPECIAL:
961                                         case ICMD_INVOKESTATIC:
962                                         case ICMD_INVOKEINTERFACE:
963                                                 {
964                                                 i = iptr->op1;
965                                                 while (--i >= 0) {
966                                                         reg_free_temp(src);
967                                                         src = src->prev;
968                                                         }
969                                                 if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID)
970                                                         reg_new_temp(dst);
971                                                 break;
972                                                 }
973
974                                         case ICMD_BUILTIN3:
975                                                 reg_free_temp(src);
976                                                 src = src->prev;
977                                         case ICMD_BUILTIN2:
978                                                 reg_free_temp(src);
979                                                 src = src->prev;
980                                         case ICMD_BUILTIN1:
981                                                 reg_free_temp(src);
982                                                 src = src->prev;
983                                                 if (iptr->op1 != TYPE_VOID)
984                                                         reg_new_temp(dst);
985                                                 break;
986
987                                         case ICMD_MULTIANEWARRAY:
988                                                 i = iptr->op1;
989                                                 while (--i >= 0) {
990                                                         reg_free_temp(src);
991                                                         src = src->prev;
992                                                         }
993                                                 reg_new_temp(dst);
994                                                 break;
995
996                                         default:
997                                                 printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
998                                                 panic("Missing ICMD code during register allocation");
999                                         } /* switch */
1000                                 iptr++;
1001                                 } /* while instructions */
1002                         } /* if */
1003                 bptr++;
1004         } /* while blocks */
1005 }
1006
1007
1008 /*
1009  * These are local overrides for various environment variables in Emacs.
1010  * Please do not remove this and leave it at the end of the file, where
1011  * Emacs will automagically detect them.
1012  * ---------------------------------------------------------------------
1013  * Local variables:
1014  * mode: c
1015  * indent-tabs-mode: t
1016  * c-basic-offset: 4
1017  * tab-width: 4
1018  * End:
1019  */