* src/vm/jit/powerpc/codegen.c: Changed OUTVAR to INOUT.
[cacao.git] / src / vm / jit / allocator / simplereg.c
1 /* src/vm/jit/allocator/simplereg.c - register allocator
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28
29    Changes: Stefan Ring
30             Christian Thalinger
31             Christian Ullrich
32             Michael Starzinger
33             Edwin Steiner
34
35    $Id: simplereg.c 5633 2006-10-02 13:59:13Z edwin $
36
37 */
38
39
40 #include "config.h"
41 #include "vm/types.h"
42
43 #include <assert.h>
44
45 #include "arch.h"
46 #include "md-abi.h"
47
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "mm/memory.h"
51 #include "vm/method.h"
52 #include "vm/options.h"
53 #include "vm/resolve.h"
54 #include "vm/stringlocal.h"
55 #include "vm/jit/reg.h"
56 #include "vm/jit/allocator/simplereg.h"
57
58
59 /* function prototypes for this file ******************************************/
60
61 static void interface_regalloc(jitdata *jd);
62 static void local_regalloc(jitdata *jd);
63 static void new_allocate_scratch_registers(jitdata *jd);
64 static void allocate_scratch_registers(jitdata *jd);
65
66
67 /* regalloc ********************************************************************
68
69    Does a simple register allocation.
70         
71 *******************************************************************************/
72         
73 bool new_regalloc(jitdata *jd)
74 {
75         /* There is a problem with the use of unused float argument
76            registers in leafmethods for stackslots on c7 (2 * Dual Core
77            AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
78            benchmark is heaviliy increased. This could be prevented by
79            setting rd->argfltreguse to FLT_ARG_CNT before calling
80            allocate_scratch_registers and setting it back to the original
81            value before calling local_regalloc.  */
82
83         interface_regalloc(jd);
84         new_allocate_scratch_registers(jd);
85         local_regalloc(jd);
86
87         /* everthing's ok */
88
89         return true;
90 }
91
92 /* interface_regalloc **********************************************************
93
94    Allocates registers for all interface variables.
95         
96 *******************************************************************************/
97         
98 static void interface_regalloc(jitdata *jd)
99 {
100         methodinfo   *m;
101         codegendata  *cd;
102         registerdata *rd;
103
104         int     s, t, tt, saved;
105         int     intalloc, fltalloc; /* Remember allocated Register/Memory offset */
106                         /* in case more vars are packed into this interface slot */
107         int             intregsneeded = 0;
108         int             memneeded = 0;
109     /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
110         /* on HAS_4BYTE_STACKSLOT architectures */
111         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
112         int flags, regoff;
113
114         /* get required compiler data */
115
116         m  = jd->m;
117         cd = jd->cd;
118         rd = jd->rd;
119
120         /* rd->memuse was already set in stack.c to allocate stack space
121            for passing arguments to called methods. */
122
123 #if defined(__I386__)
124         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
125                 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
126                 if (rd->memuse < 1)
127                         rd->memuse = 1;
128         }
129 #endif
130
131         if (jd->isleafmethod) {
132                 /* Reserve argument register, which will be used for Locals acting */
133                 /* as Parameters */
134                 if (rd->argintreguse < m->parseddesc->argintreguse)
135                         rd->argintreguse = m->parseddesc->argintreguse;
136                 if (rd->argfltreguse < m->parseddesc->argfltreguse)
137                         rd->argfltreguse = m->parseddesc->argfltreguse;
138 #ifdef HAS_ADDRESS_REGISTER_FILE
139                 if (rd->argadrreguse < m->parseddesc->argadrreguse)
140                         rd->argadrreguse = m->parseddesc->argadrreguse;
141 #endif
142
143         }
144
145         for (s = 0; s < cd->maxstack; s++) {
146                 intalloc = -1; fltalloc = -1;
147
148                 saved = 0;
149
150                 for (tt = 0; tt <=4; tt++) {
151                         if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
152                                 saved |= t & SAVEDVAR;
153                         }
154                 }
155
156                 for (tt = 0; tt <= 4; tt++) {
157                         t = typeloop[tt];
158                         if (jd->interface_map[s * 5 + t].flags == UNUSED)
159                                 continue;
160
161                         flags = saved;
162                         regoff = -1; /* XXX for debugging */
163
164 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
165                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
166 #endif
167 #if defined(HAS_4BYTE_STACKSLOT)
168                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
169 #endif
170                                 if (!saved) {
171 #if defined(HAS_ADDRESS_REGISTER_FILE)
172                                         if (IS_ADR_TYPE(t)) {
173                                                 if (!jd->isleafmethod 
174                                                         &&(rd->argadrreguse < ADR_ARG_CNT)) {
175                                                         regoff = rd->argadrregs[rd->argadrreguse++];
176                                                 } else if (rd->tmpadrreguse > 0) {
177                                                                 regoff = rd->tmpadrregs[--rd->tmpadrreguse];
178                                                 } else if (rd->savadrreguse > 0) {
179                                                                 regoff = rd->savadrregs[--rd->savadrreguse];
180                                                 } else {
181                                                         flags |= INMEMORY;
182                                                         regoff = rd->memuse++;
183                                                 }                                               
184                                         } else /* !IS_ADR_TYPE */
185 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
186                                         {
187                                                 if (IS_FLT_DBL_TYPE(t)) {
188                                                         if (fltalloc >= 0) {
189                        /* Reuse memory slot(s)/register(s) for shared interface slots */
190                                                                 flags |= jd->interface_map[fltalloc].flags & INMEMORY;
191                                                                 regoff = jd->interface_map[fltalloc].regoff;
192                                                         } else if (rd->argfltreguse < FLT_ARG_CNT) {
193                                                                 regoff = rd->argfltregs[rd->argfltreguse++];
194                                                         } else if (rd->tmpfltreguse > 0) {
195                                                                 regoff = rd->tmpfltregs[--rd->tmpfltreguse];
196                                                         } else if (rd->savfltreguse > 0) {
197                                                                 regoff = rd->savfltregs[--rd->savfltreguse];
198                                                         } else {
199                                                                 flags |= INMEMORY;
200 #if defined(ALIGN_DOUBLES_IN_MEMORY)
201                                                                 /* Align doubles in Memory */
202                                                                 if ( (memneeded) && (rd->memuse & 1))
203                                                                         rd->memuse++;
204 #endif
205                                                                 regoff = rd->memuse;
206                                                                 rd->memuse += memneeded + 1;
207                                                         }
208                                                         fltalloc = s * 5 + t;
209                                                 } else { /* !IS_FLT_DBL_TYPE(t) */
210 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
211                                                         /*
212                                                          * for i386 put all longs in memory
213                                                          */
214                                                         if (IS_2_WORD_TYPE(t)) {
215                                                                 flags |= INMEMORY;
216 #if defined(ALIGN_LONGS_IN_MEMORY)
217                                                                 /* Align longs in Memory */
218                                                                 if (rd->memuse & 1)
219                                                                         rd->memuse++;
220 #endif
221                                                                 regoff = rd->memuse;
222                                                                 rd->memuse += memneeded + 1;
223                                                         } else
224 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
225                                                                 if (intalloc >= 0) {
226                        /* Reuse memory slot(s)/register(s) for shared interface slots */
227                                                                         flags |= jd->interface_map[intalloc].flags & INMEMORY;
228 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
229                                                                         if (!(flags & INMEMORY) 
230                                                                           && IS_2_WORD_TYPE(intalloc % 5))
231                                                                                 regoff = GET_LOW_REG(
232                                                                                         jd->interface_map[intalloc].regoff);
233                                                                         else
234 #endif
235                                                                                 regoff = 
236                                                                                     jd->interface_map[intalloc].regoff;
237                                                                 } else 
238                                                                         if (rd->argintreguse + intregsneeded 
239                                                                                 < INT_ARG_CNT) {
240 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
241                                                                                 if (intregsneeded) 
242                                                                                         regoff=PACK_REGS( 
243                                                                                   rd->argintregs[rd->argintreguse],
244                                                                                   rd->argintregs[rd->argintreguse + 1]);
245                                                                                 else
246 #endif
247                                                                                         regoff = 
248                                                                                            rd->argintregs[rd->argintreguse];
249                                                                                 rd->argintreguse += intregsneeded + 1;
250                                                                         }
251                                                                         else if (rd->tmpintreguse > intregsneeded) {
252                                                                                 rd->tmpintreguse -= intregsneeded + 1;
253 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
254                                                                                 if (intregsneeded) 
255                                                                                         regoff=PACK_REGS( 
256                                                                                   rd->tmpintregs[rd->tmpintreguse],
257                                                                                   rd->tmpintregs[rd->tmpintreguse + 1]);
258                                                                                 else
259 #endif
260                                                                                         regoff = 
261                                                                                            rd->tmpintregs[rd->tmpintreguse];
262                                                                         }
263                                                                         else if (rd->savintreguse > intregsneeded) {
264                                                                                 rd->savintreguse -= intregsneeded + 1;
265                                                                                 regoff = 
266                                                                                         rd->savintregs[rd->savintreguse];
267 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
268                                                                                 if (intregsneeded) 
269                                                                                         regoff=PACK_REGS( 
270                                                                                   rd->savintregs[rd->savintreguse],
271                                                                                   rd->savintregs[rd->savintreguse + 1]);
272                                                                                 else
273 #endif
274                                                                                         regoff = 
275                                                                                            rd->savintregs[rd->savintreguse];
276                                                                         }
277                                                                         else {
278                                                                                 flags |= INMEMORY;
279 #if defined(ALIGN_LONGS_IN_MEMORY)
280                                                                                 /* Align longs in Memory */
281                                                                                 if ( (memneeded) && (rd->memuse & 1))
282                                                                                         rd->memuse++;
283 #endif
284                                                                                 regoff = rd->memuse;
285                                                                                 rd->memuse += memneeded + 1;
286                                                                         }
287
288                                                         intalloc = s * 5 + t;
289                                                 } /* if (IS_FLT_DBL_TYPE(t)) */
290                                         } 
291                                 } else { /* (saved) */
292 /* now the same like above, but without a chance to take a temporary register */
293 #ifdef HAS_ADDRESS_REGISTER_FILE
294                                         if (IS_ADR_TYPE(t)) {
295                                                 if (rd->savadrreguse > 0) {
296                                                         regoff = rd->savadrregs[--rd->savadrreguse];
297                                                 }
298                                                 else {
299                                                         flags |= INMEMORY;
300                                                         regoff = rd->memuse++;
301                                                 }                                               
302                                         } else
303 #endif
304                                         {
305                                                 if (IS_FLT_DBL_TYPE(t)) {
306                                                         if (fltalloc >= 0) {
307                                                                 flags |= jd->interface_map[fltalloc].flags & INMEMORY;
308                                                                 regoff = jd->interface_map[fltalloc].regoff;
309                                                         } else
310                                                                 if (rd->savfltreguse > 0) {
311                                                                         regoff = 
312                                                                                 rd->savfltregs[--rd->savfltreguse];
313                                                                 }
314                                                                 else {
315                                                                         flags |= INMEMORY;
316 #if defined(ALIGN_DOUBLES_IN_MEMORY)
317                                                                         /* Align doubles in Memory */
318                                                                         if ( (memneeded) && (rd->memuse & 1))
319                                                                                 rd->memuse++;
320 #endif
321                                                                         regoff = rd->memuse;
322                                                                         rd->memuse += memneeded + 1;
323                                                                 }
324                                                         fltalloc = s * 5 + t;
325                                                 }
326                                                 else { /* IS_INT_LNG */
327 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
328                                                         /*
329                                                          * for i386 put all longs in memory
330                                                          */
331                                                         if (IS_2_WORD_TYPE(t)) {
332                                                                 flags |= INMEMORY;
333 #if defined(ALIGN_LONGS_IN_MEMORY)
334                                                                 /* Align longs in Memory */
335                                                                 if (rd->memuse & 1)
336                                                                         rd->memuse++;
337 #endif
338                                                                 regoff = rd->memuse;
339                                                                 rd->memuse += memneeded + 1;
340                                                         } else
341 #endif
342                                                         {
343                                                                 if (intalloc >= 0) {
344                                                                         flags |= jd->interface_map[intalloc].flags & INMEMORY;
345 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
346                                                                         if (!(flags & INMEMORY)
347                                                                           && IS_2_WORD_TYPE(intalloc % 5))
348                                                                                 regoff =
349                                                                                         GET_LOW_REG(
350                                                                                         jd->interface_map[intalloc].regoff);
351                                                                         else
352 #endif
353                                                                                 regoff =
354                                                                                     jd->interface_map[intalloc].regoff;
355                                                                 } else {
356                                                                         if (rd->savintreguse > intregsneeded) {
357                                                                                 rd->savintreguse -= intregsneeded + 1;
358 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
359                                                                                 if (intregsneeded) 
360                                                                                         regoff = PACK_REGS( 
361                                                                                   rd->savintregs[rd->savintreguse],
362                                                                                   rd->savintregs[rd->savintreguse + 1]);
363                                                                                 else
364 #endif
365                                                                                         regoff =
366                                                                                            rd->savintregs[rd->savintreguse];
367                                                                         } else {
368                                                                                 flags |= INMEMORY;
369 #if defined(ALIGN_LONGS_IN_MEMORY)
370                                                                         /* Align longs in Memory */
371                                                                         if ( (memneeded) && (rd->memuse & 1))
372                                                                                 rd->memuse++;
373 #endif
374                                                                                 regoff = rd->memuse;
375                                                                                 rd->memuse += memneeded + 1;
376                                                                         }
377                                                                 }
378                                                                 intalloc = s*5 + t;
379                                                         }
380                                                 } /* if (IS_FLT_DBL_TYPE(t) else */
381                                         } /* if (IS_ADR_TYPE(t)) else */
382                                 } /* if (saved) else */
383                         /* if (type >= 0) */
384
385                         assert(regoff >= 0);
386                         jd->interface_map[5*s + t].flags = flags | INOUT;
387                         jd->interface_map[5*s + t].regoff = regoff;
388                 } /* for t */
389         } /* for s */
390 }
391
392
393
394 /* local_regalloc **************************************************************
395
396    Allocates registers for all local variables.
397         
398 *******************************************************************************/
399         
400 static void local_regalloc(jitdata *jd)
401 {
402         methodinfo   *m;
403         codegendata  *cd;
404         registerdata *rd;
405
406         int     p, s, t, tt,lm;
407         int     intalloc, fltalloc;
408         varinfo *v;
409         int     intregsneeded = 0;
410         int     memneeded = 0;
411         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
412         int     fargcnt, iargcnt;
413 #ifdef HAS_ADDRESS_REGISTER_FILE
414         int     aargcnt;
415 #endif
416
417         /* get required compiler data */
418
419         m  = jd->m;
420         cd = jd->cd;
421         rd = jd->rd;
422
423         if (jd->isleafmethod) {
424                 methoddesc *md = m->parseddesc;
425
426                 iargcnt = rd->argintreguse;
427                 fargcnt = rd->argfltreguse;
428 #ifdef HAS_ADDRESS_REGISTER_FILE
429                 aargcnt = rd->argadrreguse;
430 #endif
431                 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
432                         intalloc = -1; fltalloc = -1;
433                         for (tt = 0; tt <= 4; tt++) {
434                                 t = typeloop[tt];
435                                 lm = jd->local_map[s * 5 + t];
436                                 if (lm == UNUSED)
437                                         continue;
438
439                                 v = VAR(lm);
440
441 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
442                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
443 #endif
444 #if defined(HAS_4BYTE_STACKSLOT)
445                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
446 #endif
447
448                                 /*
449                                  *  The order of
450                                  *
451                                  *  #ifdef HAS_ADDRESS_REGISTER_FILE
452                                  *  if (IS_ADR_TYPE) { 
453                                  *  ...
454                                  *  } else 
455                                  *  #endif
456                                  *  if (IS_FLT_DBL) {
457                                  *  ...
458                                  *  } else { / int & lng
459                                  *  ...
460                                  *  }
461                                  *
462                                  *  must not to be changed!
463                                  */
464
465 #ifdef HAS_ADDRESS_REGISTER_FILE
466                                 if (IS_ADR_TYPE(t)) {
467                                         if ((p < md->paramcount) && !md->params[p].inmemory) {
468                                                 v->flags = 0;
469                                                 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
470                                         }
471                                         else if (rd->tmpadrreguse > 0) {
472                                                 v->flags = 0;
473                                                 v->vv.regoff = rd->tmpadrregs[--rd->tmpadrreguse];
474                                         }
475                                         /* use unused argument registers as local registers */
476                                         else if ((p >= md->paramcount) &&
477                                                          (aargcnt < ADR_ARG_CNT)) {
478                                                 v->flags = 0;
479                                                 v->vv.regoff = rd->argadrregs[aargcnt++];
480                                         }
481                                         else if (rd->savadrreguse > 0) {
482                                                 v->flags = 0;
483                                                 v->vv.regoff = rd->savadrregs[--rd->savadrreguse];
484                                         }
485                                         else {
486                                                 v->flags |= INMEMORY;
487                                                 v->vv.regoff = rd->memuse++;
488                                         }                                               
489                                 } else {
490 #endif
491                                         if (IS_FLT_DBL_TYPE(t)) {
492                                                 if (fltalloc >= 0) {
493                                                         v->flags = VAR(fltalloc)->flags;
494                                                         v->vv.regoff = VAR(fltalloc)->vv.regoff;
495                                                 }
496 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
497                                                 /* We can only use float arguments as local variables,
498                                                  * if we do not pass them in integer registers. */
499                                                 else if ((p < md->paramcount) &&
500                                                                  !md->params[p].inmemory) {
501                                                         v->flags = 0;
502                                                         v->vv.regoff = rd->argfltregs[md->params[p].regoff];
503                                                 }
504 #endif
505                                                 else if (rd->tmpfltreguse > 0) {
506                                                         v->flags = 0;
507                                                         v->vv.regoff = rd->tmpfltregs[--rd->tmpfltreguse];
508                                                 }
509                                                 /* use unused argument registers as local registers */
510                                                 else if ((p >= md->paramcount) &&
511                                                                  (fargcnt < FLT_ARG_CNT)) {
512                                                         v->flags = 0;
513                                                         v->vv.regoff = rd->argfltregs[fargcnt];
514                                                         fargcnt++;
515                                                 }
516                                                 else if (rd->savfltreguse > 0) {
517                                                         v->flags = 0;
518                                                         v->vv.regoff = rd->savfltregs[--rd->savfltreguse];
519                                                 }
520                                                 else {
521                                                         v->flags = INMEMORY;
522 #if defined(ALIGN_DOUBLES_IN_MEMORY)
523                                                         /* Align doubles in Memory */
524                                                         if ( (memneeded) && (rd->memuse & 1))
525                                                                 rd->memuse++;
526 #endif
527                                                         v->vv.regoff = rd->memuse;
528                                                         rd->memuse += memneeded + 1;
529                                                 }
530                                                 fltalloc = jd->local_map[s * 5 + t];
531
532                                         } else {
533 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
534                                                 /*
535                                                  * for i386 put all longs in memory
536                                                  */
537                                                 if (IS_2_WORD_TYPE(t)) {
538                                                         v->flags = INMEMORY;
539 #if defined(ALIGN_LONGS_IN_MEMORY)
540                                                         /* Align longs in Memory */
541                                                         if (rd->memuse & 1)
542                                                                 rd->memuse++;
543 #endif
544                                                         v->vv.regoff = rd->memuse;
545                                                         rd->memuse += memneeded + 1;
546                                                 } else 
547 #endif
548                                                 {
549                                                         if (intalloc >= 0) {
550                                                                 v->flags = VAR(intalloc)->flags;
551 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
552                                                                 if (!(v->flags & INMEMORY)
553                                                                         && IS_2_WORD_TYPE(VAR(intalloc)->type))
554                                                                         v->vv.regoff = GET_LOW_REG(
555                                                                                                         VAR(intalloc)->vv.regoff);
556                                                                 else
557 #endif
558                                                                         v->vv.regoff = VAR(intalloc)->vv.regoff;
559                                                         }
560                                                         else if ((p < md->paramcount) && 
561                                                                          !md->params[p].inmemory) {
562                                                                 v->flags = 0;
563 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
564                                                                 if (IS_2_WORD_TYPE(t))
565                                                                         v->vv.regoff = PACK_REGS(
566                                                         rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
567                                                         rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
568                                                                         else
569 #endif
570                                                                                 v->vv.regoff =
571                                                                                rd->argintregs[md->params[p].regoff];
572                                                         }
573                                                         else if (rd->tmpintreguse > intregsneeded) {
574                                                                 rd->tmpintreguse -= intregsneeded + 1;
575                                                                 v->flags = 0;
576 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
577                                                                 if (intregsneeded) 
578                                                                         v->vv.regoff = PACK_REGS(
579                                                                             rd->tmpintregs[rd->tmpintreguse],
580                                                                                 rd->tmpintregs[rd->tmpintreguse + 1]);
581                                                                 else
582 #endif
583                                                                         v->vv.regoff = 
584                                                                                 rd->tmpintregs[rd->tmpintreguse];
585                                                         }
586                                                         /*
587                                                          * use unused argument registers as local registers
588                                                          */
589                                                         else if ((p >= m->parseddesc->paramcount) &&
590                                                                          (iargcnt + intregsneeded < INT_ARG_CNT)) {
591                                                                 v->flags = 0;
592 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
593                                                                 if (intregsneeded) 
594                                                                         v->vv.regoff=PACK_REGS( 
595                                                                                                    rd->argintregs[iargcnt],
596                                                                                                    rd->argintregs[iargcnt + 1]);
597                                                                 else
598 #endif
599                                                                 v->vv.regoff = rd->argintregs[iargcnt];
600                                                                 iargcnt += intregsneeded + 1;
601                                                         }
602                                                         else if (rd->savintreguse > intregsneeded) {
603                                                                 rd->savintreguse -= intregsneeded + 1;
604                                                                 v->flags = 0;
605 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
606                                                                 if (intregsneeded) 
607                                                                         v->vv.regoff = PACK_REGS(
608                                                                             rd->savintregs[rd->savintreguse],
609                                                                                 rd->savintregs[rd->savintreguse + 1]);
610                                                                 else
611 #endif
612                                                                         v->vv.regoff =rd->savintregs[rd->savintreguse];
613                                                         }
614                                                         else {
615                                                                 v->flags = INMEMORY;
616 #if defined(ALIGN_LONGS_IN_MEMORY)
617                                                                 /* Align longs in Memory */
618                                                                 if ( (memneeded) && (rd->memuse & 1))
619                                                                         rd->memuse++;
620 #endif
621                                                                 v->vv.regoff = rd->memuse;
622                                                                 rd->memuse += memneeded + 1;
623                                                         }
624                                                 }
625                                                 intalloc = jd->local_map[s * 5 + t];
626                                         }
627 #ifdef HAS_ADDRESS_REGISTER_FILE
628                                 }
629 #endif
630                         } /* for (tt=0;...) */
631
632                         /* If the current parameter is a 2-word type, the next local slot */
633                         /* is skipped.                                                    */
634
635                         if (p < md->paramcount)
636                                 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
637                                         s++;
638                 }
639                 return;
640         }
641
642         for (s = 0; s < cd->maxlocals; s++) {
643                 intalloc = -1; fltalloc = -1;
644                 for (tt=0; tt<=4; tt++) {
645                         t = typeloop[tt];
646
647                         lm = jd->local_map[s * 5 + t];
648                         if (lm == UNUSED)
649                                 continue;
650
651                         v = VAR(lm);
652
653 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
654                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
655 #endif
656 #if defined(HAS_4BYTE_STACKSLOT)
657                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
658 #endif
659 #ifdef HAS_ADDRESS_REGISTER_FILE
660                                 if ( IS_ADR_TYPE(t) ) {
661                                         if (rd->savadrreguse > 0) {
662                                                 v->flags = 0;
663                                                 v->vv.regoff = rd->savadrregs[--rd->savadrreguse];
664                                         }
665                                         else {
666                                                 v->flags = INMEMORY;
667                                                 v->vv.regoff = rd->memuse++;
668                                         }
669                                 } else {
670 #endif
671                                 if (IS_FLT_DBL_TYPE(t)) {
672                                         if (fltalloc >= 0) {
673                                                 v->flags = VAR(fltalloc)->flags;
674                                                 v->vv.regoff = VAR(fltalloc)->vv.regoff;
675                                         }
676                                         else if (rd->savfltreguse > 0) {
677                                                 v->flags = 0;
678                                                 v->vv.regoff = rd->savfltregs[--rd->savfltreguse];
679                                         }
680                                         else {
681                                                 v->flags = INMEMORY;
682 #if defined(ALIGN_DOUBLES_IN_MEMORY)
683                                                 /* Align doubles in Memory */
684                                                 if ( (memneeded) && (rd->memuse & 1))
685                                                         rd->memuse++;
686 #endif
687                                                 v->vv.regoff = rd->memuse;
688                                                 rd->memuse += memneeded + 1;
689                                         }
690                                         fltalloc = jd->local_map[s * 5 + t];
691                                 }
692                                 else {
693 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
694                                         /*
695                                          * for i386 put all longs in memory
696                                          */
697                                         if (IS_2_WORD_TYPE(t)) {
698                                                 v->flags = INMEMORY;
699 #if defined(ALIGN_LONGS_IN_MEMORY)
700                                                 /* Align longs in Memory */
701                                                 if (rd->memuse & 1)
702                                                         rd->memuse++;
703 #endif
704                                                 v->vv.regoff = rd->memuse;
705                                                 rd->memuse += memneeded + 1;
706                                         } else {
707 #endif
708                                                 if (intalloc >= 0) {
709                                                         v->flags = VAR(intalloc)->flags;
710 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
711                                                         if (!(v->flags & INMEMORY)
712                                                                 && IS_2_WORD_TYPE(VAR(intalloc)->type))
713                                                                 v->vv.regoff = GET_LOW_REG(
714                                                                                             VAR(intalloc)->vv.regoff);
715                                                         else
716 #endif
717                                                                 v->vv.regoff = VAR(intalloc)->vv.regoff;
718                                                 }
719                                                 else if (rd->savintreguse > intregsneeded) {
720                                                         rd->savintreguse -= intregsneeded+1;
721                                                         v->flags = 0;
722 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
723                                                                 if (intregsneeded) 
724                                                                         v->vv.regoff = PACK_REGS(
725                                                                                 rd->savintregs[rd->savintreguse],
726                                                                             rd->savintregs[rd->savintreguse + 1]);
727                                                                 else
728 #endif
729                                                                         v->vv.regoff =rd->savintregs[rd->savintreguse];
730                                                 }
731                                                 else {
732                                                         v->flags = INMEMORY;
733 #if defined(ALIGN_LONGS_IN_MEMORY)
734                                                         /* Align longs in Memory */
735                                                         if ( (memneeded) && (rd->memuse & 1))
736                                                                 rd->memuse++;
737 #endif
738                                                         v->vv.regoff = rd->memuse;
739                                                         rd->memuse += memneeded + 1;
740                                                 }
741 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
742                                         }
743 #endif
744                                         intalloc = jd->local_map[s * 5 + t];
745                                 }
746 #ifdef HAS_ADDRESS_REGISTER_FILE
747                                 }
748 #endif
749
750                 }
751         }
752 }
753
754
755 static void reg_init_temp(jitdata *jd, registerdata *rd)
756 {
757         rd->freememtop = 0;
758 #if defined(HAS_4BYTE_STACKSLOT)
759         rd->freememtop_2 = 0;
760 #endif
761
762         rd->freetmpinttop = 0;
763         rd->freesavinttop = 0;
764         rd->freetmpflttop = 0;
765         rd->freesavflttop = 0;
766 #ifdef HAS_ADDRESS_REGISTER_FILE
767         rd->freetmpadrtop = 0;
768         rd->freesavadrtop = 0;
769 #endif
770
771         rd->freearginttop = 0;
772         rd->freeargflttop = 0;
773 #ifdef HAS_ADDRESS_REGISTER_FILE
774         rd->freeargadrtop = 0;
775 #endif
776
777         rd->regcopycount = DMNEW(int, INT_REG_CNT + FLT_REG_CNT);
778         MZERO(rd->regcopycount, int, INT_REG_CNT + FLT_REG_CNT);
779
780         /* memcopycount is dynamically allocated when needed */
781
782         rd->memcopycount = NULL;
783         rd->memcopycountsize = 0;
784 }
785
786
787 #define reg_new_temp(jd,index)                                       \
788     if ( (index >= jd->localcount)                                   \
789          && (!(VAR(index)->flags & (INOUT | PREALLOC))) )            \
790         reg_new_temp_func(jd, index)
791
792 static void reg_new_temp_func(jitdata *jd, s4 index)
793 {
794         s4 intregsneeded;
795         s4 memneeded;
796         s4 tryagain;
797         registerdata *rd;
798         varinfo      *v;
799
800         rd = jd->rd;
801         v = VAR(index);
802
803         /* Try to allocate a saved register if there is no temporary one          */
804         /* available. This is what happens during the second run.                 */
805         tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
806
807 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
808         intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
809 #else
810         intregsneeded = 0;
811 #endif
812 #if defined(HAS_4BYTE_STACKSLOT)
813         memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
814 #else
815         memneeded = 0;
816 #endif
817
818         for(; tryagain; --tryagain) {
819                 if (tryagain == 1) {
820                         if (!(v->flags & SAVEDVAR))
821                                 v->flags |= SAVEDTMP;
822 #ifdef HAS_ADDRESS_REGISTER_FILE
823                         if (IS_ADR_TYPE(v->type)) {
824                                 if (rd->freesavadrtop > 0) {
825                                         v->vv.regoff = rd->freesavadrregs[--rd->freesavadrtop];
826                                         return;
827                                 } else if (rd->savadrreguse > 0) {
828                                         v->vv.regoff = rd->savadrregs[--rd->savadrreguse];
829                                         return;
830                                 }
831                         } else
832 #endif
833                         {
834                                 if (IS_FLT_DBL_TYPE(v->type)) {
835                                         if (rd->freesavflttop > 0) {
836                                                 v->vv.regoff = rd->freesavfltregs[--rd->freesavflttop];
837                                                 return;
838                                         } else if (rd->savfltreguse > 0) {
839                                                 v->vv.regoff = rd->savfltregs[--rd->savfltreguse];
840                                                 return;
841                                         }
842                                 } else {
843 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
844                                         /*
845                                          * for i386 put all longs in memory
846                                          */
847                                         if (!IS_2_WORD_TYPE(v->type))
848 #endif
849                                         {
850                                                 if (rd->freesavinttop > intregsneeded) {
851                                                         rd->freesavinttop -= intregsneeded + 1;
852 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
853                                                         if (intregsneeded)
854                                                                 v->vv.regoff = PACK_REGS(
855                                                                 rd->freesavintregs[rd->freesavinttop],
856                                                                         rd->freesavintregs[rd->freesavinttop + 1]);
857                                                 else
858 #endif
859                                                                 v->vv.regoff =
860                                                                         rd->freesavintregs[rd->freesavinttop];
861                                                         return;
862                                                 } else if (rd->savintreguse > intregsneeded) {
863                                                         rd->savintreguse -= intregsneeded + 1;
864 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
865                                                         if (intregsneeded)
866                                                                 v->vv.regoff = PACK_REGS(
867                                                                         rd->savintregs[rd->savintreguse],
868                                                                 rd->savintregs[rd->savintreguse + 1]);
869                                                         else
870 #endif
871                                                                 v->vv.regoff = rd->savintregs[rd->savintreguse];
872                                                         return;
873                                                 }
874                                         }
875                                 }
876                         }
877                 } else { /* tryagain == 2 */
878 #ifdef HAS_ADDRESS_REGISTER_FILE
879                         if (IS_ADR_TYPE(v->type)) {
880                                 if (rd->freetmpadrtop > 0) {
881                                         v->vv.regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
882                                         return;
883                                 } else if (rd->tmpadrreguse > 0) {
884                                         v->vv.regoff = rd->tmpadrregs[--rd->tmpadrreguse];
885                                         return;
886                                 }
887                         } else
888 #endif
889                         {
890                                 if (IS_FLT_DBL_TYPE(v->type)) {
891                                         if (rd->freeargflttop > 0) {
892                                                 v->vv.regoff = rd->freeargfltregs[--rd->freeargflttop];
893                                                 v->flags |= TMPARG;
894                                                 return;
895                                         } else if (rd->argfltreguse < FLT_ARG_CNT) {
896                                                 v->vv.regoff = rd->argfltregs[rd->argfltreguse++];
897                                                 v->flags |= TMPARG;
898                                                 return;
899                                         } else if (rd->freetmpflttop > 0) {
900                                                 v->vv.regoff = rd->freetmpfltregs[--rd->freetmpflttop];
901                                                 return;
902                                         } else if (rd->tmpfltreguse > 0) {
903                                                 v->vv.regoff = rd->tmpfltregs[--rd->tmpfltreguse];
904                                                 return;
905                                         }
906
907                                 } else {
908 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
909                                         /*
910                                          * for i386 put all longs in memory
911                                          */
912                                         if (!IS_2_WORD_TYPE(v->type))
913 #endif
914                                         {
915                                                 if (rd->freearginttop > intregsneeded) {
916                                                         rd->freearginttop -= intregsneeded + 1;
917                                                         v->flags |= TMPARG;
918 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
919                                                         if (intregsneeded) 
920                                                                 v->vv.regoff = PACK_REGS(
921                                                                         rd->freeargintregs[rd->freearginttop],
922                                                                 rd->freeargintregs[rd->freearginttop + 1]);
923                                                         else
924 #endif
925                                                                 v->vv.regoff =
926                                                                         rd->freeargintregs[rd->freearginttop];
927                                                         return;
928                                                 } else if (rd->argintreguse 
929                                                                    < INT_ARG_CNT - intregsneeded) {
930 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
931                                                         if (intregsneeded) 
932                                                                 v->vv.regoff = PACK_REGS(
933                                                                         rd->argintregs[rd->argintreguse],
934                                                                     rd->argintregs[rd->argintreguse + 1]);
935                                                         else
936 #endif
937                                                                 v->vv.regoff = rd->argintregs[rd->argintreguse];
938                                                         v->flags |= TMPARG;
939                                                         rd->argintreguse += intregsneeded + 1;
940                                                         return;
941                                                 } else if (rd->freetmpinttop > intregsneeded) {
942                                                         rd->freetmpinttop -= intregsneeded + 1;
943 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
944                                                         if (intregsneeded) 
945                                                                 v->vv.regoff = PACK_REGS(
946                                                                         rd->freetmpintregs[rd->freetmpinttop],
947                                                                     rd->freetmpintregs[rd->freetmpinttop + 1]);
948                                                         else
949 #endif
950                                                                 v->vv.regoff = rd->freetmpintregs[rd->freetmpinttop];
951                                                         return;
952                                                 } else if (rd->tmpintreguse > intregsneeded) {
953                                                         rd->tmpintreguse -= intregsneeded + 1;
954 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
955                                                         if (intregsneeded) 
956                                                                 v->vv.regoff = PACK_REGS(
957                                                                         rd->tmpintregs[rd->tmpintreguse],
958                                                                     rd->tmpintregs[rd->tmpintreguse + 1]);
959                                                         else
960 #endif
961                                                                 v->vv.regoff = rd->tmpintregs[rd->tmpintreguse];
962                                                         return;
963                                                 }
964                                         } /* if (!IS_2_WORD_TYPE(s->type)) */
965                                 } /* if (IS_FLT_DBL_TYPE(s->type)) */
966                         } /* if (IS_ADR_TYPE(s->type)) */
967                 } /* if (tryagain == 1) else */
968         } /* for(; tryagain; --tryagain) */
969
970 #if defined(HAS_4BYTE_STACKSLOT)
971         if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
972                 rd->freememtop_2--;
973                 v->vv.regoff = rd->freemem_2[rd->freememtop_2];
974         } else
975 #endif /*defined(HAS_4BYTE_STACKSLOT) */
976                 if ((memneeded == 0) && (rd->freememtop > 0)) {
977                         rd->freememtop--;;
978                         v->vv.regoff = rd->freemem[rd->freememtop];
979                 } else {
980 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
981                         /* align 2 Word Types */
982                         if ((memneeded) && ((rd->memuse & 1) == 1)) { 
983                                 /* Put patched memory slot on freemem */
984                                 rd->freemem[rd->freememtop++] = rd->memuse;
985                                 rd->memuse++;
986                         }
987 #endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
988                         v->vv.regoff = rd->memuse;
989                         rd->memuse += memneeded + 1;
990                 }
991         v->flags |= INMEMORY;
992 }
993
994
995 #define reg_free_temp(jd,index)                                      \
996     if ((index > jd->localcount)                                     \
997         && (!(VAR(index)->flags & (INOUT | PREALLOC))))              \
998         reg_free_temp_func(jd, index)
999
1000 /* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
1001 /* alive using this reg/memory location */
1002
1003 static void reg_free_temp_func(jitdata *jd, s4 index)
1004 {
1005         s4 intregsneeded;
1006         s4 memneeded;
1007         registerdata *rd;
1008         varinfo *v;
1009
1010         rd = jd->rd;
1011         v = VAR(index);
1012
1013         /* if this is a copy of another variable, just decrement the copy counter */
1014
1015         /* XXX split reg/mem variables on arm may need special handling here */
1016
1017         if (v->flags & INMEMORY) {
1018                 if (v->vv.regoff < rd->memcopycountsize && rd->memcopycount[v->vv.regoff]) {
1019                         rd->memcopycount[v->vv.regoff]--;
1020                         return;
1021                 }
1022         }
1023         else {
1024 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1025                 if (rd->regcopycount[GET_LOW_REG(v->vv.regoff)]) {
1026                         rd->regcopycount[GET_LOW_REG(v->vv.regoff)]--;
1027                         return;
1028                 }
1029 #else
1030                 if (rd->regcopycount[v->vv.regoff]) {
1031                         rd->regcopycount[v->vv.regoff]--;
1032                         return;
1033                 }
1034 #endif
1035         }
1036
1037 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1038         intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1039 #else
1040         intregsneeded = 0;
1041 #endif
1042
1043 #if defined(HAS_4BYTE_STACKSLOT)
1044         memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1045 #else
1046         memneeded = 0;
1047 #endif
1048
1049         if (v->flags & INMEMORY) {
1050 #if defined(HAS_4BYTE_STACKSLOT)
1051                 if (memneeded > 0) {
1052                         rd->freemem_2[rd->freememtop_2] = v->vv.regoff;
1053                         rd->freememtop_2++;
1054                 } else 
1055 #endif
1056                 {
1057                         rd->freemem[rd->freememtop] = v->vv.regoff;
1058                         rd->freememtop++;
1059                 }
1060
1061 #ifdef HAS_ADDRESS_REGISTER_FILE
1062         } else if (IS_ADR_TYPE(v->type)) {
1063                 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1064 /*                      v->flags &= ~SAVEDTMP; */
1065                         rd->freesavadrregs[rd->freesavadrtop++] = v->vv.regoff;
1066                 } else
1067                         rd->freetmpadrregs[rd->freetmpadrtop++] = v->vv.regoff;
1068 #endif
1069         } else if (IS_FLT_DBL_TYPE(v->type)) {
1070                 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1071 /*                      v->flags &= ~SAVEDTMP; */
1072                         rd->freesavfltregs[rd->freesavflttop++] = v->vv.regoff;
1073                 } else if (v->flags & TMPARG) {
1074 /*                      v->flags &= ~TMPARG; */
1075                         rd->freeargfltregs[rd->freeargflttop++] = v->vv.regoff;
1076                 } else
1077                         rd->freetmpfltregs[rd->freetmpflttop++] = v->vv.regoff;
1078         } else { /* IS_INT_LNG_TYPE */
1079                 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1080 /*                      v->flags &= ~SAVEDTMP; */
1081 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1082                         if (intregsneeded) {
1083                                 rd->freesavintregs[rd->freesavinttop] =
1084                                         GET_LOW_REG(v->vv.regoff);
1085                                 rd->freesavintregs[rd->freesavinttop + 1] =
1086                                         GET_HIGH_REG(v->vv.regoff);
1087                         } else
1088 #endif
1089                         rd->freesavintregs[rd->freesavinttop] = v->vv.regoff;
1090                         rd->freesavinttop += intregsneeded + 1;
1091
1092                 } else if (v->flags & TMPARG) {
1093 /*                      s->flags &= ~TMPARG; */
1094 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1095                         if (intregsneeded) {
1096                                 rd->freeargintregs[rd->freearginttop] =
1097                                         GET_LOW_REG(v->vv.regoff);
1098                                 rd->freeargintregs[rd->freearginttop + 1] =
1099                                         GET_HIGH_REG(v->vv.regoff);
1100                         } else 
1101 #endif
1102                         rd->freeargintregs[rd->freearginttop] = v->vv.regoff;
1103                         rd->freearginttop += intregsneeded + 1;
1104                 } else {
1105 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1106                         if (intregsneeded) {
1107                                 rd->freetmpintregs[rd->freetmpinttop] =
1108                                         GET_LOW_REG(v->vv.regoff);
1109                                 rd->freetmpintregs[rd->freetmpinttop + 1] =
1110                                         GET_HIGH_REG(v->vv.regoff);
1111                         } else
1112 #endif
1113                     rd->freetmpintregs[rd->freetmpinttop] = v->vv.regoff;
1114                         rd->freetmpinttop += intregsneeded + 1;
1115                 }
1116         }
1117 }
1118
1119
1120 static bool reg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1121 {
1122         varinfo *sv;
1123         varinfo *dv;
1124
1125         /* do not coalesce local variables here */
1126
1127         if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1128                 return false;
1129
1130         sv = VAR(srcindex);
1131         dv = VAR(dstindex);
1132
1133         /* do not coalesce in/out vars or preallocated variables here */
1134
1135         if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1136                 return false;
1137
1138         /* if the source is in memory, we can coalesce in any case */
1139
1140         if (sv->flags & INMEMORY) {
1141                 dv->flags |= INMEMORY;
1142                 dv->vv.regoff = sv->vv.regoff;
1143                 return true;
1144         }
1145
1146         /* we do not allocate a REG_TMP to a REG_SAV variable */
1147
1148         if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1149                 return false;
1150
1151         /* coalesce */
1152         dv->vv.regoff = sv->vv.regoff;
1153         dv->flags |= sv->flags & (SAVEDTMP | TMPARG);
1154
1155         return true;
1156 }
1157
1158
1159 /* allocate_scratch_registers **************************************************
1160
1161    Allocate temporary (non-interface, non-local) registers.
1162
1163 *******************************************************************************/
1164
1165 static void new_allocate_scratch_registers(jitdata *jd)
1166 {
1167         methodinfo         *m;
1168         registerdata       *rd;
1169         s4                  i;
1170         s4                  len;
1171         instruction        *iptr;
1172         basicblock         *bptr;
1173         builtintable_entry *bte;
1174         methoddesc         *md;
1175         s4                 *argp;
1176         varinfo            *v;
1177
1178         /* get required compiler data */
1179
1180         m  = jd->m;
1181         rd = jd->rd;
1182
1183         /* initialize temp registers */
1184
1185         reg_init_temp(jd, rd);
1186
1187         bptr = jd->new_basicblocks;
1188
1189         while (bptr != NULL) {
1190                 if (bptr->flags >= BBREACHED) {
1191
1192                         /* set allocation of invars */
1193
1194                         for (i=0; i<bptr->indepth; ++i) 
1195                         {
1196                                 v = VAR(bptr->invars[i]);
1197
1198                                 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1199                                 v->flags  = jd->interface_map[5*i + v->type].flags;
1200                         }
1201
1202                         /* set allocation of outvars */
1203
1204                         for (i=0; i<bptr->outdepth; ++i) 
1205                         {
1206                                 v = VAR(bptr->outvars[i]);
1207
1208                                 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1209                                 v->flags  = jd->interface_map[5*i + v->type].flags;
1210                         }
1211
1212                         /* iterate over ICMDS to allocate temporary variables */
1213
1214                         iptr = bptr->iinstr;
1215                         len = bptr->icount;
1216
1217                         while (--len >= 0)  {
1218                                 switch (iptr->opc) {
1219
1220                                         /* pop 0 push 0 */
1221
1222                                 case ICMD_JSR:
1223 #if !defined(NDEBUG)
1224                                         /* avoid problems with show_allocation */
1225                                         VAROP(iptr->dst)->vv.regoff = 0;
1226 #endif
1227                                 case ICMD_NOP:
1228                                 case ICMD_CHECKNULL:
1229                                 case ICMD_IINC:
1230                                 case ICMD_RET:
1231                                 case ICMD_RETURN:
1232                                 case ICMD_GOTO:
1233                                 case ICMD_PUTSTATICCONST:
1234                                 case ICMD_INLINE_START:
1235                                 case ICMD_INLINE_END:
1236                                 case ICMD_INLINE_GOTO:
1237                                         break;
1238
1239                                         /* pop 0 push 1 const */
1240                                         
1241                                 case ICMD_ICONST:
1242                                 case ICMD_LCONST:
1243                                 case ICMD_FCONST:
1244                                 case ICMD_DCONST:
1245                                 case ICMD_ACONST:
1246
1247                                         /* pop 0 push 1 load */
1248                                         
1249                                 case ICMD_ILOAD:
1250                                 case ICMD_LLOAD:
1251                                 case ICMD_FLOAD:
1252                                 case ICMD_DLOAD:
1253                                 case ICMD_ALOAD:
1254                                         reg_new_temp(jd, iptr->dst.varindex);
1255                                         break;
1256
1257                                         /* pop 2 push 1 */
1258
1259                                 case ICMD_IALOAD:
1260                                 case ICMD_LALOAD:
1261                                 case ICMD_FALOAD:
1262                                 case ICMD_DALOAD:
1263                                 case ICMD_AALOAD:
1264
1265                                 case ICMD_BALOAD:
1266                                 case ICMD_CALOAD:
1267                                 case ICMD_SALOAD:
1268                                         reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1269                                         reg_free_temp(jd, iptr->s1.varindex);
1270                                         reg_new_temp(jd, iptr->dst.varindex);
1271                                         break;
1272
1273                                         /* pop 3 push 0 */
1274
1275                                 case ICMD_IASTORE:
1276                                 case ICMD_LASTORE:
1277                                 case ICMD_FASTORE:
1278                                 case ICMD_DASTORE:
1279                                 case ICMD_AASTORE:
1280
1281                                 case ICMD_BASTORE:
1282                                 case ICMD_CASTORE:
1283                                 case ICMD_SASTORE:
1284                                         reg_free_temp(jd, iptr->sx.s23.s3.varindex);
1285                                         reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1286                                         reg_free_temp(jd, iptr->s1.varindex);
1287                                         break;
1288
1289                                         /* pop 1 push 0 store */
1290
1291                                 case ICMD_ISTORE:
1292                                 case ICMD_LSTORE:
1293                                 case ICMD_FSTORE:
1294                                 case ICMD_DSTORE:
1295                                 case ICMD_ASTORE:
1296
1297                                         /* pop 1 push 0 */
1298
1299                                 case ICMD_POP:
1300
1301                                 case ICMD_IRETURN:
1302                                 case ICMD_LRETURN:
1303                                 case ICMD_FRETURN:
1304                                 case ICMD_DRETURN:
1305                                 case ICMD_ARETURN:
1306
1307                                 case ICMD_ATHROW:
1308
1309                                 case ICMD_PUTSTATIC:
1310                                 case ICMD_PUTFIELDCONST:
1311
1312                                         /* pop 1 push 0 branch */
1313
1314                                 case ICMD_IFNULL:
1315                                 case ICMD_IFNONNULL:
1316
1317                                 case ICMD_IFEQ:
1318                                 case ICMD_IFNE:
1319                                 case ICMD_IFLT:
1320                                 case ICMD_IFGE:
1321                                 case ICMD_IFGT:
1322                                 case ICMD_IFLE:
1323
1324                                 case ICMD_IF_LEQ:
1325                                 case ICMD_IF_LNE:
1326                                 case ICMD_IF_LLT:
1327                                 case ICMD_IF_LGE:
1328                                 case ICMD_IF_LGT:
1329                                 case ICMD_IF_LLE:
1330
1331                                         /* pop 1 push 0 table branch */
1332
1333                                 case ICMD_TABLESWITCH:
1334                                 case ICMD_LOOKUPSWITCH:
1335
1336                                 case ICMD_MONITORENTER:
1337                                 case ICMD_MONITOREXIT:
1338                                         reg_free_temp(jd, iptr->s1.varindex);
1339                                         break;
1340
1341                                         /* pop 2 push 0 branch */
1342
1343                                 case ICMD_IF_ICMPEQ:
1344                                 case ICMD_IF_ICMPNE:
1345                                 case ICMD_IF_ICMPLT:
1346                                 case ICMD_IF_ICMPGE:
1347                                 case ICMD_IF_ICMPGT:
1348                                 case ICMD_IF_ICMPLE:
1349
1350                                 case ICMD_IF_LCMPEQ:
1351                                 case ICMD_IF_LCMPNE:
1352                                 case ICMD_IF_LCMPLT:
1353                                 case ICMD_IF_LCMPGE:
1354                                 case ICMD_IF_LCMPGT:
1355                                 case ICMD_IF_LCMPLE:
1356
1357                                 case ICMD_IF_FCMPEQ:
1358                                 case ICMD_IF_FCMPNE:
1359
1360                                 case ICMD_IF_FCMPL_LT:
1361                                 case ICMD_IF_FCMPL_GE:
1362                                 case ICMD_IF_FCMPL_GT:
1363                                 case ICMD_IF_FCMPL_LE:
1364
1365                                 case ICMD_IF_FCMPG_LT:
1366                                 case ICMD_IF_FCMPG_GE:
1367                                 case ICMD_IF_FCMPG_GT:
1368                                 case ICMD_IF_FCMPG_LE:
1369
1370                                 case ICMD_IF_DCMPEQ:
1371                                 case ICMD_IF_DCMPNE:
1372
1373                                 case ICMD_IF_DCMPL_LT:
1374                                 case ICMD_IF_DCMPL_GE:
1375                                 case ICMD_IF_DCMPL_GT:
1376                                 case ICMD_IF_DCMPL_LE:
1377
1378                                 case ICMD_IF_DCMPG_LT:
1379                                 case ICMD_IF_DCMPG_GE:
1380                                 case ICMD_IF_DCMPG_GT:
1381                                 case ICMD_IF_DCMPG_LE:
1382
1383                                 case ICMD_IF_ACMPEQ:
1384                                 case ICMD_IF_ACMPNE:
1385
1386                                         /* pop 2 push 0 */
1387
1388                                 case ICMD_POP2:
1389
1390                                 case ICMD_PUTFIELD:
1391
1392                                 case ICMD_IASTORECONST:
1393                                 case ICMD_LASTORECONST:
1394                                 case ICMD_AASTORECONST:
1395                                 case ICMD_BASTORECONST:
1396                                 case ICMD_CASTORECONST:
1397                                 case ICMD_SASTORECONST:
1398                                         reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1399                                         reg_free_temp(jd, iptr->s1.varindex);
1400                                         break;
1401
1402                                         /* pop 0 push 1 copy */
1403                                         
1404                                 case ICMD_COPY:
1405                                         /* src === dst->prev (identical Stackslot Element)     */
1406                                         /* src --> dst       (copied value, take same reg/mem) */
1407
1408                                         if (!reg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1409                                                 reg_new_temp(jd, iptr->dst.varindex);
1410                                         } else {
1411                                                 v = VAROP(iptr->dst);
1412
1413                                                 if (v->flags & INMEMORY) {
1414                                                         if (v->vv.regoff >= rd->memcopycountsize) {
1415                                                                 int newsize = (v->vv.regoff + 1) * 2;
1416                                                                 i = rd->memcopycountsize;
1417                                                                 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1418                                                                 MZERO(rd->memcopycount + i, int, newsize - i);
1419                                                                 rd->memcopycountsize = newsize;
1420                                                         }
1421                                                         rd->memcopycount[v->vv.regoff]++;
1422                                                 }
1423                                                 else {
1424                                                         /* XXX split reg/mem variables on arm may need special handling here */
1425
1426 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1427                                                         rd->regcopycount[GET_LOW_REG(v->vv.regoff)]++;
1428 #else
1429                                                         rd->regcopycount[v->vv.regoff]++;
1430 #endif
1431                                                 }
1432                                         }
1433                                         break;
1434
1435                                         /* pop 1 push 1 move */
1436
1437                                 case ICMD_MOVE:
1438                                         if (!reg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1439                                                 reg_new_temp(jd, iptr->dst.varindex);
1440                                                 reg_free_temp(jd, iptr->s1.varindex);
1441                                         }
1442                                         break;
1443
1444                                         /* pop 2 push 1 */
1445                                         
1446                                 case ICMD_IADD:
1447                                 case ICMD_ISUB:
1448                                 case ICMD_IMUL:
1449                                 case ICMD_IDIV:
1450                                 case ICMD_IREM:
1451
1452                                 case ICMD_ISHL:
1453                                 case ICMD_ISHR:
1454                                 case ICMD_IUSHR:
1455                                 case ICMD_IAND:
1456                                 case ICMD_IOR:
1457                                 case ICMD_IXOR:
1458
1459                                 case ICMD_LADD:
1460                                 case ICMD_LSUB:
1461                                 case ICMD_LMUL:
1462                                 case ICMD_LDIV:
1463                                 case ICMD_LREM:
1464
1465                                 case ICMD_LOR:
1466                                 case ICMD_LAND:
1467                                 case ICMD_LXOR:
1468
1469                                 case ICMD_LSHL:
1470                                 case ICMD_LSHR:
1471                                 case ICMD_LUSHR:
1472
1473                                 case ICMD_FADD:
1474                                 case ICMD_FSUB:
1475                                 case ICMD_FMUL:
1476                                 case ICMD_FDIV:
1477                                 case ICMD_FREM:
1478
1479                                 case ICMD_DADD:
1480                                 case ICMD_DSUB:
1481                                 case ICMD_DMUL:
1482                                 case ICMD_DDIV:
1483                                 case ICMD_DREM:
1484
1485                                 case ICMD_LCMP:
1486                                 case ICMD_FCMPL:
1487                                 case ICMD_FCMPG:
1488                                 case ICMD_DCMPL:
1489                                 case ICMD_DCMPG:
1490                                         reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1491                                         reg_free_temp(jd, iptr->s1.varindex);
1492                                         reg_new_temp(jd, iptr->dst.varindex);
1493                                         break;
1494
1495                                         /* pop 1 push 1 */
1496                                         
1497                                 case ICMD_IADDCONST:
1498                                 case ICMD_ISUBCONST:
1499                                 case ICMD_IMULCONST:
1500                                 case ICMD_IMULPOW2:
1501                                 case ICMD_IDIVPOW2:
1502                                 case ICMD_IREMPOW2:
1503                                 case ICMD_IANDCONST:
1504                                 case ICMD_IORCONST:
1505                                 case ICMD_IXORCONST:
1506                                 case ICMD_ISHLCONST:
1507                                 case ICMD_ISHRCONST:
1508                                 case ICMD_IUSHRCONST:
1509
1510                                 case ICMD_LADDCONST:
1511                                 case ICMD_LSUBCONST:
1512                                 case ICMD_LMULCONST:
1513                                 case ICMD_LMULPOW2:
1514                                 case ICMD_LDIVPOW2:
1515                                 case ICMD_LREMPOW2:
1516                                 case ICMD_LANDCONST:
1517                                 case ICMD_LORCONST:
1518                                 case ICMD_LXORCONST:
1519                                 case ICMD_LSHLCONST:
1520                                 case ICMD_LSHRCONST:
1521                                 case ICMD_LUSHRCONST:
1522
1523                                 case ICMD_INEG:
1524                                 case ICMD_INT2BYTE:
1525                                 case ICMD_INT2CHAR:
1526                                 case ICMD_INT2SHORT:
1527                                 case ICMD_LNEG:
1528                                 case ICMD_FNEG:
1529                                 case ICMD_DNEG:
1530
1531                                 case ICMD_I2L:
1532                                 case ICMD_I2F:
1533                                 case ICMD_I2D:
1534                                 case ICMD_L2I:
1535                                 case ICMD_L2F:
1536                                 case ICMD_L2D:
1537                                 case ICMD_F2I:
1538                                 case ICMD_F2L:
1539                                 case ICMD_F2D:
1540                                 case ICMD_D2I:
1541                                 case ICMD_D2L:
1542                                 case ICMD_D2F:
1543
1544                                 case ICMD_CHECKCAST:
1545
1546                                 case ICMD_ARRAYLENGTH:
1547                                 case ICMD_INSTANCEOF:
1548
1549                                 case ICMD_NEWARRAY:
1550                                 case ICMD_ANEWARRAY:
1551
1552                                 case ICMD_GETFIELD:
1553                                         reg_free_temp(jd, iptr->s1.varindex);
1554                                         reg_new_temp(jd, iptr->dst.varindex);
1555                                         break;
1556
1557                                         /* pop 0 push 1 */
1558                                         
1559                                 case ICMD_GETSTATIC:
1560
1561                                 case ICMD_NEW:
1562                                         reg_new_temp(jd, iptr->dst.varindex);
1563                                         break;
1564
1565                                         /* pop many push any */
1566                                         
1567                                 case ICMD_INVOKESTATIC:
1568                                 case ICMD_INVOKESPECIAL:
1569                                 case ICMD_INVOKEVIRTUAL:
1570                                 case ICMD_INVOKEINTERFACE:
1571                                         INSTRUCTION_GET_METHODDESC(iptr,md);
1572                                         i = md->paramcount;
1573                                         argp = iptr->sx.s23.s2.args;
1574                                         while (--i >= 0) {
1575                                                 reg_free_temp(jd, *argp);
1576                                                 argp++;
1577                                         }
1578                                         if (md->returntype.type != TYPE_VOID)
1579                                                 reg_new_temp(jd, iptr->dst.varindex);
1580                                         break;
1581
1582                                 case ICMD_BUILTIN:
1583                                         bte = iptr->sx.s23.s3.bte;
1584                                         md = bte->md;
1585                                         i = md->paramcount;
1586                                         argp = iptr->sx.s23.s2.args;
1587                                         while (--i >= 0) {
1588                                                 reg_free_temp(jd, *argp);
1589                                                 argp++;
1590                                         }
1591                                         if (md->returntype.type != TYPE_VOID)
1592                                                 reg_new_temp(jd, iptr->dst.varindex);
1593                                         break;
1594
1595                                 case ICMD_MULTIANEWARRAY:
1596                                         i = iptr->s1.argcount;
1597                                         argp = iptr->sx.s23.s2.args;
1598                                         while (--i >= 0) {
1599                                                 reg_free_temp(jd, *argp);
1600                                                 argp++;
1601                                         }
1602                                         reg_new_temp(jd, iptr->dst.varindex);
1603                                         break;
1604
1605                                 default:
1606                                         *exceptionptr =
1607                                                 new_internalerror("Unknown ICMD %d during register allocation",
1608                                                                                   iptr->opc);
1609                                         return;
1610                                 } /* switch */
1611                                 iptr++;
1612                         } /* while instructions */
1613                 } /* if */
1614                 bptr = bptr->next;
1615         } /* while blocks */
1616 }
1617
1618
1619 #if defined(ENABLE_STATISTICS)
1620 void reg_make_statistics(jitdata *jd)
1621 {
1622         methodinfo   *m;
1623         codegendata  *cd;
1624         registerdata *rd;
1625         int i,type;
1626         s4 len;
1627         stackptr    src, src_old;
1628         stackptr    dst;
1629         instruction *iptr;
1630         basicblock  *bptr;
1631         int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1632         bool in_register;
1633
1634         /* get required compiler data */
1635
1636         m  = jd->m;
1637         cd = jd->cd;
1638         rd = jd->rd;
1639
1640         in_register = true;
1641
1642         size_interface = 0;
1643
1644                 /* count how many local variables are held in memory or register */
1645                 for(i=0; i < cd->maxlocals; i++)
1646                         for (type=0; type <=4; type++)
1647                                 if (rd->locals[i][type].type != -1) { /* valid local */
1648                                         if (rd->locals[i][type].flags & INMEMORY) {
1649                                                 count_locals_spilled++;
1650                                                 in_register=false;
1651                                         }
1652                                         else
1653                                                 count_locals_register++;
1654                                 }
1655
1656                 /* count how many stack slots are held in memory or register */
1657
1658                 bptr = jd->new_basicblocks;
1659
1660                 while (bptr != NULL) {
1661                         if (bptr->flags >= BBREACHED) {
1662
1663 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1664                         if (!opt_lsra) {
1665 #endif  
1666                                 /* check for memory moves from interface to BB instack */
1667                                 dst = bptr->instack;
1668                                 len = bptr->indepth;
1669                                 
1670                                 if (len > size_interface) size_interface = len;
1671
1672                                 while (dst != NULL) {
1673                                         len--;
1674                                         if (dst->varkind != STACKVAR) {
1675                                                 if ( (dst->flags & INMEMORY) ||
1676                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) || 
1677                                                          ( (dst->flags & INMEMORY) && 
1678                                                            (rd->interfaces[len][dst->type].flags & INMEMORY) && 
1679                                                            (dst->vv.regoff != rd->interfaces[len][dst->type].regoff) ))
1680                                                 {
1681                                                         /* one in memory or both inmemory at different offsets */
1682                                                         count_mem_move_bb++;
1683                                                         in_register=false;
1684                                                 }
1685                                         }
1686
1687                                         dst = dst->prev;
1688                                 }
1689
1690                                 /* check for memory moves from BB outstack to interface */
1691                                 dst = bptr->outstack;
1692                                 len = bptr->outdepth;
1693                                 if (len > size_interface) size_interface = len;
1694
1695                                 while (dst) {
1696                                         len--;
1697                                         if (dst->varkind != STACKVAR) {
1698                                                 if ( (dst->flags & INMEMORY) || \
1699                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1700                                                          ( (dst->flags & INMEMORY) && \
1701                                                            (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1702                                                            (dst->vv.regoff != rd->interfaces[len][dst->type].regoff) ))
1703                                                 {
1704                                                         /* one in memory or both inmemory at different offsets */
1705                                                         count_mem_move_bb++;
1706                                                         in_register=false;
1707                                                 }
1708                                         }
1709
1710                                         dst = dst->prev;
1711                                 }
1712 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1713                         }
1714 #endif  
1715
1716
1717                                 dst = bptr->instack;
1718                                 iptr = bptr->iinstr;
1719                                 len = bptr->icount;
1720                                 src_old = NULL;
1721
1722                                 while (--len >= 0)  {
1723                                         src = dst;
1724                                         dst = iptr->dst.var;
1725
1726                                         if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1727                                                 switch (src->varkind) {
1728                                                 case TEMPVAR:
1729                                                 case STACKVAR:
1730                                                         if (!(src->flags & INMEMORY)) 
1731                                                                 count_ss_register++;
1732                                                         else {
1733                                                                 count_ss_spilled++;
1734                                                                 in_register=false;
1735                                                         }                               
1736                                                         break;
1737                                                         /*                                      case LOCALVAR: */
1738                                                         /*                                              if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1739                                                         /*                                                      count_ss_register++; */
1740                                                         /*                                              else */
1741                                                         /*                                                      count_ss_spilled++; */
1742                                                         /*                                              break; */
1743                                                 case ARGVAR:
1744                                                         if (!(src->flags & INMEMORY)) 
1745                                                                 count_argument_mem_ss++;
1746                                                         else
1747                                                                 count_argument_reg_ss++;
1748                                                         break;
1749
1750
1751                                                         /*                                              if (IS_FLT_DBL_TYPE(src->type)) { */
1752                                                         /*                                                      if (src->varnum < FLT_ARG_CNT) { */
1753                                                         /*                                                              count_ss_register++; */
1754                                                         /*                                                              break; */
1755                                                         /*                                                      } */
1756                                                         /*                                              } else { */
1757                                                         /* #if defined(__POWERPC__) */
1758                                                         /*                                                      if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1759                                                         /* #else */
1760                                                         /*                                                      if (src->varnum < INT_ARG_CNT) { */
1761                                                         /* #endif */
1762                                                         /*                                                              count_ss_register++; */
1763                                                         /*                                                              break; */
1764                                                         /*                                                      } */
1765                                                         /*                                              } */
1766                                                         /*                                              count_ss_spilled++; */
1767                                                         /*                                              break; */
1768                                                 }
1769                                         }
1770                                         src_old = src;
1771                                         
1772                                         iptr++;
1773                                 } /* while instructions */
1774                         } /* if */
1775
1776                         bptr = bptr->next;
1777                 } /* while blocks */
1778                 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1779                 if (in_register) count_method_in_register++;
1780                 if (in_register) {
1781                         printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
1782                 }
1783 }
1784 #endif /* defined(ENABLE_STATISTICS) */
1785
1786
1787 /*
1788  * These are local overrides for various environment variables in Emacs.
1789  * Please do not remove this and leave it at the end of the file, where
1790  * Emacs will automagically detect them.
1791  * ---------------------------------------------------------------------
1792  * Local variables:
1793  * mode: c
1794  * indent-tabs-mode: t
1795  * c-basic-offset: 4
1796  * tab-width: 4
1797  * End:
1798  * vim:noexpandtab:sw=4:ts=4:
1799  */