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