narray first check in
[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  
261                 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
262                         v = &interfaces[s][t];
263                         if (v->type >= 0) {
264                                 if (!saved) {
265                                         if (IS_FLT_DBL_TYPE(t)) {
266                                                 if (fltalloc >= 0) {
267                                                         v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
268                                                         v->regoff = interfaces[s][fltalloc].regoff;
269                                                         }
270                                                 else if (iftmpfltregcnt > 0) {
271                                                         iftmpfltregcnt--;
272                                                         v->regoff = tmpfltregs[iftmpfltregcnt];
273                                                         }
274                                                 else if (ifsavfltregcnt > 0) {
275                                                         ifsavfltregcnt--;
276                                                         v->regoff = savfltregs[ifsavfltregcnt];
277                                                         }
278                                                 else {
279                                                         v->flags |= INMEMORY;
280                                                         v->regoff = ifmemuse++;
281                                                         }
282                                                 fltalloc = t;
283                                                 }
284                                         else {
285                                                 if (intalloc >= 0) {
286                                                         v->flags |= interfaces[s][intalloc].flags & INMEMORY;
287                                                         v->regoff = interfaces[s][intalloc].regoff;
288                                                         }
289                                                 else if (iftmpintregcnt > 0) {
290                                                         iftmpintregcnt--;
291                                                         v->regoff = tmpintregs[iftmpintregcnt];
292                                                         }
293                                                 else if (ifsavintregcnt > 0) {
294                                                         ifsavintregcnt--;
295                                                         v->regoff = savintregs[ifsavintregcnt];
296                                                         }
297                                                 else {
298                                                         v->flags |= INMEMORY;
299                                                         v->regoff = ifmemuse++;
300                                                         }
301                                                 intalloc = t;
302                                                 }
303                                         }
304                                 else {
305                                         if (IS_FLT_DBL_TYPE(t)) {
306                                                 if (fltalloc >= 0) {
307                                                         v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
308                                                         v->regoff = interfaces[s][fltalloc].regoff;
309                                                         }
310                                                 else if (ifsavfltregcnt > 0) {
311                                                         ifsavfltregcnt--;
312                                                         v->regoff = savfltregs[ifsavfltregcnt];
313                                                         }
314                                                 else {
315                                                         v->flags |= INMEMORY;
316                                                         v->regoff = ifmemuse++;
317                                                         }
318                                                 fltalloc = t;
319                                                 }
320                                         else {
321                                                 if (intalloc >= 0) {
322                                                         v->flags |= interfaces[s][intalloc].flags & INMEMORY;
323                                                         v->regoff = interfaces[s][intalloc].regoff;
324                                                         }
325                                                 else if (ifsavintregcnt > 0) {
326                                                         ifsavintregcnt--;
327                                                         v->regoff = savintregs[ifsavintregcnt];
328                                                         }
329                                                 else {
330                                                         v->flags |= INMEMORY;
331                                                         v->regoff = ifmemuse++;
332                                                         }
333                                                 intalloc = t;
334                                                 }
335                                         }
336                                 } /* if (type >= 0) */
337                         }     /* for t */
338                 }         /* for s */
339
340         maxmemuse = ifmemuse;
341         maxtmpintreguse = iftmpintregcnt;
342         maxsavintreguse = ifsavintregcnt;
343         maxtmpfltreguse = iftmpfltregcnt;
344         maxsavfltreguse = ifsavfltregcnt;
345
346 }
347
348
349 /* function local_regalloc *****************************************************
350
351         allocates registers for all local variables
352         
353 *******************************************************************************/
354         
355 static void local_regalloc ()
356 {
357         int      s, t;
358         int      intalloc, fltalloc;
359         varinfo *v;
360         
361         if (isleafmethod) {
362                 int arg, doublewordarg;
363                 arg = 0;
364                 doublewordarg = 0;
365                 for (s = 0; s < maxlocals; s++) {
366                         intalloc = -1; fltalloc = -1;
367                         for (t = TYPE_INT; t <= TYPE_ADR; t++) {
368                                 v = &locals[s][t];
369                                 if (v->type >= 0) {
370                                         if (IS_FLT_DBL_TYPE(t)) {
371                                                 if (fltalloc >= 0) {
372                                                         v->flags = locals[s][fltalloc].flags;
373                                                         v->regoff = locals[s][fltalloc].regoff;
374                                                         }
375                                                 else if (!doublewordarg && (arg < mparamcount)
376                                                                         && (arg < fltreg_argnum)) {
377                                                         v->flags = 0;
378                                                         v->regoff = argfltregs[arg];
379                                                         }
380                                                 else if (maxtmpfltreguse > 0) {
381                                                         maxtmpfltreguse--;
382                                                         v->flags = 0;
383                                                         v->regoff = tmpfltregs[maxtmpfltreguse];
384                                                         }
385                                                 else if (maxsavfltreguse > 0) {
386                                                         maxsavfltreguse--;
387                                                         v->flags = 0;
388                                                         v->regoff = savfltregs[maxsavfltreguse];
389                                                         }
390                                                 else {
391                                                         v->flags = INMEMORY;
392                                                         v->regoff = maxmemuse++;
393                                                         }
394                                                 fltalloc = t;
395                                                 }
396                                         else {
397                                                 if (intalloc >= 0) {
398                                                         v->flags = locals[s][intalloc].flags;
399                                                         v->regoff = locals[s][intalloc].regoff;
400                                                         }
401                                                 else if (!doublewordarg && (arg < mparamcount)
402                                                                         && (arg < intreg_argnum)) {
403                                                         v->flags = 0;
404                                                         v->regoff = argintregs[arg];
405                                                         }
406                                                 else if (maxtmpintreguse > 0) {
407                                                         maxtmpintreguse--;
408                                                         v->flags = 0;
409                                                         v->regoff = tmpintregs[maxtmpintreguse];
410                                                         }
411                                                 else if (maxsavintreguse > 0) {
412                                                         maxsavintreguse--;
413                                                         v->flags = 0;
414                                                         v->regoff = savintregs[maxsavintreguse];
415                                                         }
416                                                 else {
417                                                         v->flags = INMEMORY;
418                                                         v->regoff = maxmemuse++;
419                                                         }
420                                                 intalloc = t;
421                                                 }
422                                         }
423                                 }
424                         if (arg < mparamcount) {
425                                 if (doublewordarg) {
426                                         doublewordarg = 0;
427                                         arg++;
428                                         }
429                                 else if (IS_2_WORD_TYPE(mparamtypes[arg]))
430                                         doublewordarg = 1;
431                                 else
432                                         arg++;
433                                 }
434                         }
435                 return;
436                 }
437         for (s = 0; s < maxlocals; s++) {
438                 intalloc = -1; fltalloc = -1;
439                 for (t=TYPE_INT; t<=TYPE_ADR; t++) {
440                         v = &locals[s][t];
441                         if (v->type >= 0) {
442                                 if (IS_FLT_DBL_TYPE(t)) {
443                                         if (fltalloc >= 0) {
444                                                 v->flags = locals[s][fltalloc].flags;
445                                                 v->regoff = locals[s][fltalloc].regoff;
446                                                 }
447                                         else if (maxsavfltreguse > 0) {
448                                                 maxsavfltreguse--;
449                                                 v->flags = 0;
450                                                 v->regoff = savfltregs[maxsavfltreguse];
451                                                 }
452                                         else {
453                                                 v->flags = INMEMORY;
454                                                 v->regoff = maxmemuse++;
455                                                 }
456                                         fltalloc = t;
457                                         }
458                                 else {
459                                         if (intalloc >= 0) {
460                                                 v->flags = locals[s][intalloc].flags;
461                                                 v->regoff = locals[s][intalloc].regoff;
462                                                 }
463                                         else if (maxsavintreguse > 0) {
464                                                 maxsavintreguse--;
465                                                 v->flags = 0;
466                                                 v->regoff = savintregs[maxsavintreguse];
467                                                 }
468                                         else {
469                                                 v->flags = INMEMORY;
470                                                 v->regoff = maxmemuse++;
471                                                 }
472                                         intalloc = t;
473                                         }
474                                 }
475                         }
476                 }
477 }
478
479
480 static void reg_init_temp()
481 {
482         freememtop = 0;
483         memuse = ifmemuse;
484
485         freetmpinttop = 0;
486         freesavinttop = 0;
487         freetmpflttop = 0;
488         freesavflttop = 0;
489         tmpintreguse = iftmpintregcnt;
490         savintreguse = ifsavintregcnt;
491         tmpfltreguse = iftmpfltregcnt;
492         savfltreguse = ifsavfltregcnt;
493 }
494
495
496 #define reg_new_temp(s) if(s->varkind==TEMPVAR)reg_new_temp_func(s)
497
498 static void reg_new_temp_func(stackptr s)
499 {
500 if (s->flags & SAVEDVAR) {
501         if (IS_FLT_DBL_TYPE(s->type)) {
502                 if (freesavflttop > 0) {
503                         freesavflttop--;
504                         s->regoff = freesavfltregs[freesavflttop];
505                         return;
506                         }
507                 else if (savfltreguse > 0) {
508                         savfltreguse--;
509                         if (savfltreguse < maxsavfltreguse)
510                                 maxsavfltreguse = savfltreguse;
511                         s->regoff = savfltregs[savfltreguse];
512                         return;
513                         }
514                 }
515         else {
516                 if (freesavinttop > 0) {
517                         freesavinttop--;
518                         s->regoff = freesavintregs[freesavinttop];
519                         return;
520                         }
521                 else if (savintreguse > 0) {
522                         savintreguse--;
523                         if (savintreguse < maxsavintreguse)
524                                 maxsavintreguse = savintreguse;
525                         s->regoff = savintregs[savintreguse];
526                         return;
527                         }
528                 }
529         }
530 else {
531         if (IS_FLT_DBL_TYPE(s->type)) {
532                 if (freetmpflttop > 0) {
533                         freetmpflttop--;
534                         s->regoff = freetmpfltregs[freetmpflttop];
535                         return;
536                         }
537                 else if (tmpfltreguse > 0) {
538                         tmpfltreguse--;
539                         if (tmpfltreguse < maxtmpfltreguse)
540                                 maxtmpfltreguse = tmpfltreguse;
541                         s->regoff = tmpfltregs[tmpfltreguse];
542                         return;
543                         }
544                 }
545         else {
546                 if (freetmpinttop > 0) {
547                         freetmpinttop--;
548                         s->regoff = freetmpintregs[freetmpinttop];
549                         return;
550                         }
551                 else if (tmpintreguse > 0) {
552                         tmpintreguse--;
553                         if (tmpintreguse < maxtmpintreguse)
554                                 maxtmpintreguse = tmpintreguse;
555                         s->regoff = tmpintregs[tmpintreguse];
556                         return;
557                         }
558                 }
559         }
560 if (freememtop > 0) {
561         freememtop--;
562         s->regoff = freemem[freememtop];
563         }
564 else {
565         s->regoff = memuse++;
566         if (memuse > maxmemuse)
567                 maxmemuse = memuse;
568         }
569 s->flags |= INMEMORY;
570 }
571
572
573 #define reg_free_temp(s) if(s->varkind==TEMPVAR)reg_free_temp_func(s)
574
575 static void reg_free_temp_func(stackptr s)
576 {
577 if (s->flags & INMEMORY)
578         freemem[freememtop++] = s->regoff;
579 else if (IS_FLT_DBL_TYPE(s->type)) {
580         if (s->flags & SAVEDVAR)
581                 freesavfltregs[freesavflttop++] = s->regoff;
582         else
583                 freetmpfltregs[freetmpflttop++] = s->regoff;
584         }
585 else
586         if (s->flags & SAVEDVAR)
587                 freesavintregs[freesavinttop++] = s->regoff;
588         else
589                 freetmpintregs[freetmpinttop++] = s->regoff;
590 }
591
592
593 static void allocate_scratch_registers()
594 {
595         int b_count;
596         int opcode, i, len;
597         stackptr    src, dst;
598         instruction *iptr = instr;
599         basicblock  *bptr;
600         
601         /* b_count = block_count; */
602
603         bptr = block;
604         while (bptr != NULL) {
605
606                 if (bptr->flags >= BBREACHED) {
607                         dst = bptr->instack;
608                         reg_init_temp();
609                         iptr = bptr->iinstr;
610                         len = bptr->icount;
611   
612                         while (--len >= 0)  {
613                                 src = dst;
614                                 dst = iptr->dst;
615                                 opcode = iptr->opc;
616
617                                 switch (opcode) {
618
619                                         /* pop 0 push 0 */
620
621                                         case ICMD_NOP:
622                                         case ICMD_ELSE_ICONST:
623                                         case ICMD_CHECKASIZE:
624                                         case ICMD_IINC:
625                                         case ICMD_JSR:
626                                         case ICMD_RET:
627                                         case ICMD_RETURN:
628                                         case ICMD_GOTO:
629                                                 break;
630
631                                         /* pop 0 push 1 const */
632                                         
633                                         case ICMD_ICONST:
634                                         case ICMD_LCONST:
635                                         case ICMD_FCONST:
636                                         case ICMD_DCONST:
637                                         case ICMD_ACONST:
638
639                                         /* pop 0 push 1 load */
640                                         
641                                         case ICMD_ILOAD:
642                                         case ICMD_LLOAD:
643                                         case ICMD_FLOAD:
644                                         case ICMD_DLOAD:
645                                         case ICMD_ALOAD:
646                                                 reg_new_temp(dst);
647                                                 break;
648
649                                         /* pop 2 push 1 */
650
651                                         case ICMD_IALOAD:
652                                         case ICMD_LALOAD:
653                                         case ICMD_FALOAD:
654                                         case ICMD_DALOAD:
655                                         case ICMD_AALOAD:
656
657                                         case ICMD_BALOAD:
658                                         case ICMD_CALOAD:
659                                         case ICMD_SALOAD:
660
661                                                 reg_free_temp(src);
662                                                 reg_free_temp(src->prev);
663                                                 reg_new_temp(dst);
664                                                 break;
665
666                                         /* pop 3 push 0 */
667
668                                         case ICMD_IASTORE:
669                                         case ICMD_LASTORE:
670                                         case ICMD_FASTORE:
671                                         case ICMD_DASTORE:
672                                         case ICMD_AASTORE:
673
674                                         case ICMD_BASTORE:
675                                         case ICMD_CASTORE:
676                                         case ICMD_SASTORE:
677
678                                                 reg_free_temp(src);
679                                                 reg_free_temp(src->prev);
680                                                 reg_free_temp(src->prev->prev);
681                                                 break;
682
683                                         /* pop 1 push 0 store */
684
685                                         case ICMD_ISTORE:
686                                         case ICMD_LSTORE:
687                                         case ICMD_FSTORE:
688                                         case ICMD_DSTORE:
689                                         case ICMD_ASTORE:
690
691                                         /* pop 1 push 0 */
692
693                                         case ICMD_POP:
694
695                                         case ICMD_IRETURN:
696                                         case ICMD_LRETURN:
697                                         case ICMD_FRETURN:
698                                         case ICMD_DRETURN:
699                                         case ICMD_ARETURN:
700
701                                         case ICMD_ATHROW:
702
703                                         case ICMD_PUTSTATIC:
704
705                                         /* pop 1 push 0 branch */
706
707                                         case ICMD_IFNULL:
708                                         case ICMD_IFNONNULL:
709
710                                         case ICMD_IFEQ:
711                                         case ICMD_IFNE:
712                                         case ICMD_IFLT:
713                                         case ICMD_IFGE:
714                                         case ICMD_IFGT:
715                                         case ICMD_IFLE:
716
717                                         case ICMD_IF_LEQ:
718                                         case ICMD_IF_LNE:
719                                         case ICMD_IF_LLT:
720                                         case ICMD_IF_LGE:
721                                         case ICMD_IF_LGT:
722                                         case ICMD_IF_LLE:
723
724                                         /* pop 1 push 0 table branch */
725
726                                         case ICMD_TABLESWITCH:
727                                         case ICMD_LOOKUPSWITCH:
728
729                                         case ICMD_NULLCHECKPOP:
730                                         case ICMD_MONITORENTER:
731                                         case ICMD_MONITOREXIT:
732                                                 reg_free_temp(src);
733                                                 break;
734
735                                         /* pop 2 push 0 branch */
736
737                                         case ICMD_IF_ICMPEQ:
738                                         case ICMD_IF_ICMPNE:
739                                         case ICMD_IF_ICMPLT:
740                                         case ICMD_IF_ICMPGE:
741                                         case ICMD_IF_ICMPGT:
742                                         case ICMD_IF_ICMPLE:
743
744                                         case ICMD_IF_LCMPEQ:
745                                         case ICMD_IF_LCMPNE:
746                                         case ICMD_IF_LCMPLT:
747                                         case ICMD_IF_LCMPGE:
748                                         case ICMD_IF_LCMPGT:
749                                         case ICMD_IF_LCMPLE:
750
751                                         case ICMD_IF_ACMPEQ:
752                                         case ICMD_IF_ACMPNE:
753
754                                         /* pop 2 push 0 */
755
756                                         case ICMD_POP2:
757
758                                         case ICMD_PUTFIELD:
759                                                 reg_free_temp(src);
760                                                 reg_free_temp(src->prev);
761                                                 break;
762
763                                         /* pop 0 push 1 dup */
764                                         
765                                         case ICMD_DUP:
766                                                 reg_new_temp(dst);
767                                                 break;
768
769                                         /* pop 0 push 2 dup */
770                                         
771                                         case ICMD_DUP2:
772                                                 reg_new_temp(dst->prev);
773                                                 reg_new_temp(dst);
774                                                 break;
775
776                                         /* pop 2 push 3 dup */
777                                         
778                                         case ICMD_DUP_X1:
779                                                 reg_new_temp(dst->prev->prev);
780                                                 reg_new_temp(dst->prev);
781                                                 reg_new_temp(dst);
782                                                 reg_free_temp(src);
783                                                 reg_free_temp(src->prev);
784                                                 break;
785
786                                         /* pop 3 push 4 dup */
787                                         
788                                         case ICMD_DUP_X2:
789                                                 reg_new_temp(dst->prev->prev->prev);
790                                                 reg_new_temp(dst->prev->prev);
791                                                 reg_new_temp(dst->prev);
792                                                 reg_new_temp(dst);
793                                                 reg_free_temp(src);
794                                                 reg_free_temp(src->prev);
795                                                 reg_free_temp(src->prev->prev);
796                                                 break;
797
798                                         /* pop 3 push 5 dup */
799                                         
800                                         case ICMD_DUP2_X1:
801                                                 reg_new_temp(dst->prev->prev->prev->prev);
802                                                 reg_new_temp(dst->prev->prev->prev);
803                                                 reg_new_temp(dst->prev->prev);
804                                                 reg_new_temp(dst->prev);
805                                                 reg_new_temp(dst);
806                                                 reg_free_temp(src);
807                                                 reg_free_temp(src->prev);
808                                                 reg_free_temp(src->prev->prev);
809                                                 break;
810
811                                         /* pop 4 push 6 dup */
812                                         
813                                         case ICMD_DUP2_X2:
814                                                 reg_new_temp(dst->prev->prev->prev->prev->prev);
815                                                 reg_new_temp(dst->prev->prev->prev->prev);
816                                                 reg_new_temp(dst->prev->prev->prev);
817                                                 reg_new_temp(dst->prev->prev);
818                                                 reg_new_temp(dst->prev);
819                                                 reg_new_temp(dst);
820                                                 reg_free_temp(src);
821                                                 reg_free_temp(src->prev);
822                                                 reg_free_temp(src->prev->prev);
823                                                 reg_free_temp(src->prev->prev->prev);
824                                                 break;
825
826                                         /* pop 2 push 2 swap */
827                                         
828                                         case ICMD_SWAP:
829                                                 reg_new_temp(dst->prev);
830                                                 reg_new_temp(dst);
831                                                 reg_free_temp(src);
832                                                 reg_free_temp(src->prev);
833                                                 break;
834
835                                         /* pop 2 push 1 */
836                                         
837                                         case ICMD_IADD:
838                                         case ICMD_ISUB:
839                                         case ICMD_IMUL:
840                                         case ICMD_IDIV:
841                                         case ICMD_IREM:
842
843                                         case ICMD_ISHL:
844                                         case ICMD_ISHR:
845                                         case ICMD_IUSHR:
846                                         case ICMD_IAND:
847                                         case ICMD_IOR:
848                                         case ICMD_IXOR:
849
850                                         case ICMD_LADD:
851                                         case ICMD_LSUB:
852                                         case ICMD_LMUL:
853                                         case ICMD_LDIV:
854                                         case ICMD_LREM:
855
856                                         case ICMD_LOR:
857                                         case ICMD_LAND:
858                                         case ICMD_LXOR:
859
860                                         case ICMD_LSHL:
861                                         case ICMD_LSHR:
862                                         case ICMD_LUSHR:
863
864                                         case ICMD_FADD:
865                                         case ICMD_FSUB:
866                                         case ICMD_FMUL:
867                                         case ICMD_FDIV:
868                                         case ICMD_FREM:
869
870                                         case ICMD_DADD:
871                                         case ICMD_DSUB:
872                                         case ICMD_DMUL:
873                                         case ICMD_DDIV:
874                                         case ICMD_DREM:
875
876                                         case ICMD_LCMP:
877                                         case ICMD_FCMPL:
878                                         case ICMD_FCMPG:
879                                         case ICMD_DCMPL:
880                                         case ICMD_DCMPG:
881                                                 reg_free_temp(src);
882                                                 reg_free_temp(src->prev);
883                                                 reg_new_temp(dst);
884                                                 break;
885
886                                         /* pop 1 push 1 */
887                                         
888                                         case ICMD_IADDCONST:
889                                         case ICMD_ISUBCONST:
890                                         case ICMD_IMULCONST:
891                                         case ICMD_IDIVPOW2:
892                                         case ICMD_IREMPOW2:
893                                         case ICMD_IREM0X10001:
894                                         case ICMD_IANDCONST:
895                                         case ICMD_IORCONST:
896                                         case ICMD_IXORCONST:
897                                         case ICMD_ISHLCONST:
898                                         case ICMD_ISHRCONST:
899                                         case ICMD_IUSHRCONST:
900
901                                         case ICMD_LADDCONST:
902                                         case ICMD_LSUBCONST:
903                                         case ICMD_LMULCONST:
904                                         case ICMD_LDIVPOW2:
905                                         case ICMD_LREMPOW2:
906                                         case ICMD_LREM0X10001:
907                                         case ICMD_LANDCONST:
908                                         case ICMD_LORCONST:
909                                         case ICMD_LXORCONST:
910                                         case ICMD_LSHLCONST:
911                                         case ICMD_LSHRCONST:
912                                         case ICMD_LUSHRCONST:
913
914                                         case ICMD_IFEQ_ICONST:
915                                         case ICMD_IFNE_ICONST:
916                                         case ICMD_IFLT_ICONST:
917                                         case ICMD_IFGE_ICONST:
918                                         case ICMD_IFGT_ICONST:
919                                         case ICMD_IFLE_ICONST:
920
921                                         case ICMD_INEG:
922                                         case ICMD_INT2BYTE:
923                                         case ICMD_INT2CHAR:
924                                         case ICMD_INT2SHORT:
925                                         case ICMD_LNEG:
926                                         case ICMD_FNEG:
927                                         case ICMD_DNEG:
928
929                                         case ICMD_I2L:
930                                         case ICMD_I2F:
931                                         case ICMD_I2D:
932                                         case ICMD_L2I:
933                                         case ICMD_L2F:
934                                         case ICMD_L2D:
935                                         case ICMD_F2I:
936                                         case ICMD_F2L:
937                                         case ICMD_F2D:
938                                         case ICMD_D2I:
939                                         case ICMD_D2L:
940                                         case ICMD_D2F:
941
942                                         case ICMD_CHECKCAST:
943
944                                         case ICMD_ARRAYLENGTH:
945                                         case ICMD_INSTANCEOF:
946
947                                         case ICMD_NEWARRAY:
948                                         case ICMD_ANEWARRAY:
949
950                                         case ICMD_GETFIELD:
951                                                 reg_free_temp(src);
952                                                 reg_new_temp(dst);
953                                                 break;
954
955                                         /* pop 0 push 1 */
956                                         
957                                         case ICMD_GETSTATIC:
958
959                                         case ICMD_NEW:
960
961                                                 reg_new_temp(dst);
962                                                 break;
963
964                                         /* pop many push any */
965                                         
966                                         case ICMD_INVOKEVIRTUAL:
967                                         case ICMD_INVOKESPECIAL:
968                                         case ICMD_INVOKESTATIC:
969                                         case ICMD_INVOKEINTERFACE:
970                                                 {
971                                                 i = iptr->op1;
972                                                 while (--i >= 0) {
973                                                         reg_free_temp(src);
974                                                         src = src->prev;
975                                                         }
976                                                 if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID)
977                                                         reg_new_temp(dst);
978                                                 break;
979                                                 }
980
981                                         case ICMD_BUILTIN3:
982                                                 reg_free_temp(src);
983                                                 src = src->prev;
984                                         case ICMD_BUILTIN2:
985                                                 reg_free_temp(src);
986                                                 src = src->prev;
987                                         case ICMD_BUILTIN1:
988                                                 reg_free_temp(src);
989                                                 src = src->prev;
990                                                 if (iptr->op1 != TYPE_VOID)
991                                                         reg_new_temp(dst);
992                                                 break;
993
994                                         case ICMD_MULTIANEWARRAY:
995                                                 i = iptr->op1;
996                                                 while (--i >= 0) {
997                                                         reg_free_temp(src);
998                                                         src = src->prev;
999                                                         }
1000                                                 reg_new_temp(dst);
1001                                                 break;
1002
1003                                         default:
1004                                                 printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
1005                                                 panic("Missing ICMD code during register allocation");
1006                                         } /* switch */
1007                                 iptr++;
1008                                 } /* while instructions */
1009                         } /* if */
1010                 bptr = bptr->next;
1011         } /* while blocks */
1012 }
1013
1014
1015 /*
1016  * These are local overrides for various environment variables in Emacs.
1017  * Please do not remove this and leave it at the end of the file, where
1018  * Emacs will automagically detect them.
1019  * ---------------------------------------------------------------------
1020  * Local variables:
1021  * mode: c
1022  * indent-tabs-mode: t
1023  * c-basic-offset: 4
1024  * tab-width: 4
1025  * End:
1026  */