1 /* src/vm/jit/reg.inc - register allocator
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
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
32 $Id: reg.inc 2620 2005-06-09 07:28:50Z christian $
38 #include "mm/memory.h"
39 #include "vm/method.h"
40 #include "vm/resolve.h"
41 #include "vm/jit/reg.h"
44 /* function prototypes for this file */
46 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
47 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
48 static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
51 /* reg_init ********************************************************************
55 *******************************************************************************/
63 /* reg_setup *******************************************************************
67 *******************************************************************************/
69 void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
74 /* setup the integer register table */
75 rd->intreg_argnum = 0;
79 for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
80 switch (nregdescint[rd->intregsnum]) {
93 rd->argintregs = DMNEW(s4, rd->intreg_argnum);
94 rd->tmpintregs = DMNEW(s4, rd->tmpintregcnt);
95 rd->savintregs = DMNEW(s4, rd->savintregcnt);
96 rd->freeargintregs = DMNEW(s4, rd->intreg_argnum);
97 rd->freetmpintregs = DMNEW(s4, rd->tmpintregcnt);
98 rd->freesavintregs = DMNEW(s4, rd->savintregcnt);
99 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
100 rd->secondregs = DMNEW(s4, rd->intregsnum);
103 rd->intreg_argnum = 0;
104 rd->argintreguse = 0;
105 rd->tmpintreguse = 0;
106 rd->savintreguse = 0;
108 for (i = 0; i < rd->intregsnum; i++) {
109 switch (nregdescint[i]) {
114 rd->savintregs[rd->savintreguse++] = i;
117 rd->tmpintregs[rd->tmpintreguse++] = i;
120 rd->argintregs[rd->intreg_argnum++] = i;
126 #if defined(__X86_64__)
128 * on x86_64 the argument registers are not in ascending order
129 * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
131 i = rd->argintregs[3];
132 rd->argintregs[3] = rd->argintregs[0];
133 rd->argintregs[0] = i;
135 i = rd->argintregs[2];
136 rd->argintregs[2] = rd->argintregs[1];
137 rd->argintregs[1] = i;
140 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
141 for (i = 1; i < rd->intreg_argnum; i++)
142 rd->secondregs[rd->argintregs[i - 1]] = rd->argintregs[i];
143 for (i = 1; i < rd->tmpintregcnt; i++)
144 rd->secondregs[rd->tmpintregs[i - 1]] = rd->tmpintregs[i];
145 for (i = 1; i < rd->savintregcnt; i++)
146 rd->secondregs[rd->savintregs[i - 1]] = rd->savintregs[i];
148 rd->secondregs[REG_ITMP1] = REG_ITMP2;
149 rd->secondregs[REG_ITMP3] = REG_ITMP2;
150 rd->secondregs[REG_RESULT] = REG_RESULT + 1;
151 rd->secondregs[rd->argintregs[rd->intreg_argnum - 1]] = REG_ITMP3;
154 #ifdef HAS_ADDRESS_REGISTER_FILE
155 /* setup the address register table */
156 rd->adrreg_argnum = 0;
157 rd->tmpadrregcnt = 0;
158 rd->savadrregcnt = 0;
160 for (rd->adrregsnum = 0; nregdescadr[rd->adrregsnum] != REG_END; rd->adrregsnum++) {
161 switch (nregdescadr[rd->adrregsnum]) {
174 rd->argadrregs = DMNEW(s4, rd->adrreg_argnum);
175 rd->tmpadrregs = DMNEW(s4, rd->tmpadrregcnt);
176 rd->savadrregs = DMNEW(s4, rd->savadrregcnt);
177 rd->freeargadrregs = DMNEW(s4, rd->adrreg_argnum);
178 rd->freetmpadrregs = DMNEW(s4, rd->tmpadrregcnt);
179 rd->freesavadrregs = DMNEW(s4, rd->savadrregcnt);
181 rd->adrreg_argnum = 0;
182 rd->argadrreguse = 0;
183 rd->tmpadrreguse = 0;
184 rd->savadrreguse = 0;
186 for (i = 0; i < rd->adrregsnum; i++) {
187 switch (nregdescadr[i]) {
192 rd->savadrregs[rd->savadrreguse++] = i;
195 rd->tmpadrregs[rd->tmpadrreguse++] = i;
198 rd->argadrregs[rd->adrreg_argnum++] = i;
205 /* setup the float register table */
206 rd->fltreg_argnum = 0;
207 rd->tmpfltregcnt = 0;
208 rd->savfltregcnt = 0;
210 for (rd->fltregsnum = 0; nregdescfloat[rd->fltregsnum] != REG_END; rd->fltregsnum++) {
211 switch (nregdescfloat[rd->fltregsnum]) {
224 rd->argfltregs = DMNEW(s4, rd->fltreg_argnum);
225 rd->tmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
226 rd->savfltregs = DMNEW(s4, rd->savfltregcnt);
227 rd->freeargfltregs = DMNEW(s4, rd->fltreg_argnum);
228 rd->freetmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
229 rd->freesavfltregs = DMNEW(s4, rd->savfltregcnt);
231 rd->fltreg_argnum = 0;
232 rd->argfltreguse = 0;
233 rd->tmpfltreguse = 0;
234 rd->savfltreguse = 0;
236 for (i = 0; i < rd->fltregsnum; i++) {
237 switch (nregdescfloat[i]) {
242 rd->savfltregs[rd->savfltreguse++] = i;
245 rd->tmpfltregs[rd->tmpfltreguse++] = i;
248 rd->argfltregs[rd->fltreg_argnum++] = i;
255 rd->freemem = DMNEW(s4, id->cummaxstack);
256 #if defined(NEW_MEMORY) && defined(HAS_4BYTE_STACKSLOT)
257 rd->freemem_2 = DMNEW(s4, id->cummaxstack);
259 rd->locals = DMNEW(varinfo5, id->cumlocals);
260 rd->interfaces = DMNEW(varinfo5, id->cummaxstack);
261 for (v = rd->locals, i = id->cumlocals; i > 0; v++, i--) {
262 v[0][TYPE_INT].type = -1;
263 v[0][TYPE_LNG].type = -1;
264 v[0][TYPE_FLT].type = -1;
265 v[0][TYPE_DBL].type = -1;
266 v[0][TYPE_ADR].type = -1;
269 for (v = rd->interfaces, i = id->cummaxstack; i > 0; v++, i--) {
270 v[0][TYPE_INT].type = -1;
271 v[0][TYPE_INT].flags = 0;
272 v[0][TYPE_LNG].type = -1;
273 v[0][TYPE_LNG].flags = 0;
274 v[0][TYPE_FLT].type = -1;
275 v[0][TYPE_FLT].flags = 0;
276 v[0][TYPE_DBL].type = -1;
277 v[0][TYPE_DBL].flags = 0;
278 v[0][TYPE_ADR].type = -1;
279 v[0][TYPE_ADR].flags = 0;
282 #if defined(SPECIALMEMUSE)
283 # if defined(__DARWIN__)
284 rd->ifmemuse = LA_WORD_SIZE + INT_ARG_CNT; /* 6*4=24 byte linkage area + 8*4=32 byte minimum parameter Area */
286 rd->ifmemuse = LA_WORD_SIZE;
289 rd->ifmemuse = 0; /* init to zero -> analyse_stack will set it to a higher value, if appropriate */
292 #if defined(HAS_ADDRESS_REGISTER_FILE)
293 rd->argadrreguse = 0;
294 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
295 rd->argintreguse = 0;/*Set argintreguse to rd->intreg_argnum to not use unused arguments as temp register*/
296 rd->argfltreguse = 0;/*Set argfltreguse to rd->fltreg_argnum to not use unused arguments as temp register*/
300 /* function reg_free ***********************************************************
302 releases all allocated space for registers
304 *******************************************************************************/
306 void reg_free(methodinfo *m, registerdata *rd)
312 /* reg_close *******************************************************************
316 *******************************************************************************/
324 /* function interface_regalloc *************************************************
326 allocates registers for all interface variables
328 *******************************************************************************/
330 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
332 interface_regalloc(m, cd, rd);
333 allocate_scratch_registers(m, rd);
334 local_regalloc(m, cd, rd);
335 #ifdef INVOKE_NEW_DEBUG
336 if (compileverbose) {
337 printf("maxmemuse by reg.inc: %3i\n",rd->maxmemuse);
343 /* function interface_regalloc *************************************************
345 allocates registers for all interface variables
347 *******************************************************************************/
349 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
352 int intalloc, fltalloc; /* ?per Interface slot only one flt or one int type can be allocated to a register? */
354 int intregsneeded = 0;
357 /* rd->ifmemuse was already set in stack.c to allocate stack space for */
358 /* passing arguments to called methods */
360 #if defined(__I386__)
361 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
362 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
363 if (rd->ifmemuse < 1)
367 #ifdef INVOKE_NEW_DEBUG
368 if (compileverbose) {
369 if (checksync && (m->flags & ACC_SYNCHRONIZED))
370 printf("ACC_SYNCHRONIZED\n");
371 printf("analyse: argintru %3i argfltru %3i ifmemu %3i\n", rd->argintreguse, rd->argfltreguse, rd->ifmemuse);
375 rd->iftmpintregcnt = rd->tmpintregcnt;
376 rd->ifsavintregcnt = rd->savintregcnt;
377 rd->iftmpfltregcnt = rd->tmpfltregcnt;
378 rd->ifsavfltregcnt = rd->savfltregcnt;
379 #ifdef HAS_ADDRESS_REGISTER_FILE
380 rd->iftmpadrregcnt = rd->tmpadrregcnt;
381 rd->ifsavadrregcnt = rd->savadrregcnt;
383 rd->ifargintregcnt = rd->argintreguse;
384 rd->ifargfltregcnt = rd->argfltreguse;
385 for (s = 0; s < cd->maxstack; s++) {
386 intalloc = -1; fltalloc = -1;
387 saved = (rd->interfaces[s][TYPE_INT].flags |
388 rd->interfaces[s][TYPE_LNG].flags |
389 rd->interfaces[s][TYPE_FLT].flags |
390 rd->interfaces[s][TYPE_DBL].flags |
391 rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
393 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
394 v = &rd->interfaces[s][t];
396 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
397 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
399 #if defined(HAS_4BYTE_STACKSLOT)
400 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
403 #if defined(HAS_ADDRESS_REGISTER_FILE)
405 if (!m->isleafmethod &&(rd->ifargadrregcnt < rd->adrreg_argnum)) {
406 v->regoff = rd->argadrregs[rd->ifargadrregcnt++];
408 if (rd->iftmpadrregcnt > 0) {
409 rd->iftmpadrregcnt--;
410 v->regoff = rd->tmpadrregs[rd->iftmpadrregcnt];
412 else if (rd->ifsavadrregcnt > 0) {
413 rd->ifsavadrregcnt--;
414 v->regoff = rd->savadrregs[rd->ifsavadrregcnt];
417 v->flags |= INMEMORY;
418 v->regoff = rd->ifmemuse;
422 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
423 if (IS_FLT_DBL_TYPE(t)) {
425 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
426 v->regoff = rd->interfaces[s][fltalloc].regoff;
428 else if (!m->isleafmethod &&(rd->ifargfltregcnt < rd->fltreg_argnum)) {
429 v->regoff = rd->argfltregs[rd->ifargfltregcnt++];
431 else if (rd->iftmpfltregcnt > 0) {
432 rd->iftmpfltregcnt--;
433 v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
435 else if (rd->ifsavfltregcnt > 0) {
436 rd->ifsavfltregcnt--;
437 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
440 v->flags |= INMEMORY;
441 v->regoff = rd->ifmemuse;
442 rd->ifmemuse += memneeded + 1;
447 /* #if defined(__I386__) */
448 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
450 * for i386 put all longs in memory
452 if (IS_2_WORD_TYPE(t)) {
453 v->flags |= INMEMORY;
454 v->regoff = rd->ifmemuse;
455 rd->ifmemuse += memneeded + 1;
457 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
458 /* #if !defined(HAS_4BYTE_STACKSLOT) */
460 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
461 v->regoff = rd->interfaces[s][intalloc].regoff;
464 /* #endif *//* !defined(HAS_4BYTE_STACKSLOT) */
465 if (!m->isleafmethod &&(rd->ifargintregcnt + intregsneeded < rd->intreg_argnum)) {
466 v->regoff = rd->argintregs[rd->ifargintregcnt];
467 rd->ifargintregcnt += intregsneeded + 1;
469 else if (rd->iftmpintregcnt > intregsneeded) {
470 rd->iftmpintregcnt -= intregsneeded + 1;
471 v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
473 else if (rd->ifsavintregcnt > intregsneeded) {
474 rd->ifsavintregcnt -= intregsneeded + 1;
475 v->regoff = rd->savintregs[rd->ifsavintregcnt];
478 v->flags |= INMEMORY;
479 v->regoff = rd->ifmemuse;
480 rd->ifmemuse += memneeded + 1;
485 #ifdef HAS_ADDRESS_REGISTER_FILE
490 #ifdef HAS_ADDRESS_REGISTER_FILE
492 if (rd->ifsavadrregcnt > 0) {
493 rd->ifsavadrregcnt--;
494 v->regoff = rd->savadrregs[rd->ifsavadrregcnt];
497 v->flags |= INMEMORY;
498 v->regoff = rd->ifmemuse;
503 if (IS_FLT_DBL_TYPE(t)) {
505 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
506 v->regoff = rd->interfaces[s][fltalloc].regoff;
508 if (rd->ifsavfltregcnt > 0) {
509 rd->ifsavfltregcnt--;
510 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
513 v->flags |= INMEMORY;
514 v->regoff = rd->ifmemuse;
515 rd->ifmemuse += memneeded + 1;
520 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
522 * for i386 put all longs in memory
524 if (IS_2_WORD_TYPE(t)) {
525 v->flags |= INMEMORY;
526 v->regoff = rd->ifmemuse;
527 rd->ifmemuse += memneeded + 1;
530 /* #if !defined(HAS_4BYTE_STACKSLOT) */
532 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
533 v->regoff = rd->interfaces[s][intalloc].regoff;
536 if (rd->ifsavintregcnt > intregsneeded) {
537 rd->ifsavintregcnt -= intregsneeded + 1;
538 v->regoff = rd->savintregs[rd->ifsavintregcnt];
541 v->flags |= INMEMORY;
542 v->regoff = rd->ifmemuse;
543 rd->ifmemuse += memneeded + 1;
547 #ifdef HAS_ADDRESS_REGISTER_FILE
551 } /* if (type >= 0) */
555 rd->maxmemuse = rd->ifmemuse;
557 rd->maxargintreguse = rd->ifargintregcnt;
558 rd->maxargfltreguse = rd->ifargfltregcnt;
560 rd->maxtmpintreguse = rd->iftmpintregcnt;
561 rd->maxsavintreguse = rd->ifsavintregcnt;
563 rd->maxtmpfltreguse = rd->iftmpfltregcnt;
564 rd->maxsavfltreguse = rd->ifsavfltregcnt;
566 #if defined(HAS_ADDRESS_REGISTER_FILE)
568 rd->maxargadrreguse = rd->ifargadrregcnt;
569 rd->maxtmpadrreguse = rd->iftmpadrregcnt;
570 rd->maxsavadrreguse = rd->ifsavadrregcnt;
576 /* function local_regalloc *****************************************************
578 allocates registers for all local variables
580 *******************************************************************************/
582 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
585 int intalloc, fltalloc;
587 int intregsneeded = 0;
589 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
590 int fargcnt, iargcnt;
591 #ifdef HAS_ADDRESS_REGISTER_FILE
594 /* if (cd->maxlocals > 0) */
595 /* for (tt=0; tt<=4; tt++) { */
596 /* t = typeloop[tt]; */
597 /* printf("s %3i t %3i tt %3i rd->locals[0][t].type %3i \n",s,t,tt,rd->locals[0][t].type); */
600 if (m->isleafmethod) {
601 methoddesc *md = m->parseddesc;
603 iargcnt = md->argintreguse;
604 fargcnt = md->argfltreguse;
605 #ifdef HAS_ADDRESS_REGISTER_FILE
606 aargcnt = md->argadrreguse;
608 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
609 intalloc = -1; fltalloc = -1;
610 for (tt = 0; tt <= 4; tt++) {
612 v = &rd->locals[s][t];
617 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
618 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
620 #if defined(HAS_4BYTE_STACKSLOT)
621 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
627 * #ifdef HAS_ADDRESS_REGISTER_FILE
634 * } else { / int & lng
638 * must not to be changed!
641 #ifdef HAS_ADDRESS_REGISTER_FILE
642 if (IS_ADR_TYPE(t)) {
643 if ((p < md->paramcount) && !md->params[p].inmemory) {
645 v->regoff = rd->argadrregs[md->params[p].regoff];
647 if (rd->maxtmpadrreguse > 0) {
648 rd->maxtmpadrreguse--;
650 v->regoff = rd->tmpadrregs[rd->maxtmpadrreguse];
652 else if (rd->maxsavadrreguse > 0) {
653 rd->maxsavadrreguse--;
655 v->regoff = rd->savadrregs[rd->maxsavadrreguse];
657 /* use unused argument registers as local registers */
658 else if ((p >= m->paramcount) &&
659 (aargcnt < rd->adrreg_argnum)) {
661 v->regoff = rd->argadrregs[aargcnt];
665 v->flags |= INMEMORY;
666 v->regoff = rd->ifmemuse;
671 if (IS_FLT_DBL_TYPE(t)) {
673 v->flags = rd->locals[s][fltalloc].flags;
674 v->regoff = rd->locals[s][fltalloc].regoff;
676 else if ((p < md->paramcount) &&
677 !md->params[p].inmemory) {
679 v->regoff = rd->argfltregs[md->params[p].regoff];
681 else if (rd->maxtmpfltreguse > 0) {
682 rd->maxtmpfltreguse--;
684 v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
686 else if (rd->maxsavfltreguse > 0) {
687 rd->maxsavfltreguse--;
689 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
691 /* use unused argument registers as local registers */
692 /* else if ((p >= m->paramcount) && */
693 /* (fargcnt < rd->fltreg_argnum)) { */
695 /* v->regoff = rd->argfltregs[fargcnt]; */
700 v->regoff = rd->maxmemuse;
701 rd->maxmemuse += memneeded + 1;
706 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
708 * for i386 put all longs in memory
710 if (IS_2_WORD_TYPE(t)) {
712 v->regoff = rd->maxmemuse;
713 rd->maxmemuse += memneeded + 1;
717 v->flags = rd->locals[s][intalloc].flags;
718 v->regoff = rd->locals[s][intalloc].regoff;
720 else if ((p < md->paramcount) &&
721 !md->params[p].inmemory) {
724 rd->argintregs[md->params[p].regoff];
726 else if (rd->maxtmpintreguse > intregsneeded) {
727 rd->maxtmpintreguse -= intregsneeded + 1;
729 v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
731 else if (rd->maxsavintreguse > intregsneeded) {
732 rd->maxsavintreguse -= intregsneeded + 1;
734 v->regoff = rd->savintregs[rd->maxsavintreguse];
737 * use unused argument registers as local registers
739 /* else if ((p >= m->paramcount) && */
740 /* (iargcnt < rd->intreg_argnum)) { */
742 /* v->regoff = rd->argintregs[iargcnt]; */
747 v->regoff = rd->maxmemuse;
748 rd->maxmemuse += memneeded + 1;
750 #if defined(__I386__)
755 #ifdef HAS_ADDRESS_REGISTER_FILE
758 } /* for (tt=0;...) */
760 /* If the current parameter is a 2-word type, the next local slot */
763 if (p < md->paramcount)
764 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
770 for (s = 0; s < cd->maxlocals; s++) {
771 intalloc = -1; fltalloc = -1;
772 for (tt=0; tt<=4; tt++) {
774 v = &rd->locals[s][t];
775 /* printf("s %3i t %3i tt %3i rd->locals[s][t].type %3i v->type %3i\n",s,t,tt,rd->locals[s][t].type, v->type); */
777 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
778 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
780 #if defined(HAS_4BYTE_STACKSLOT)
781 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
783 #ifdef HAS_ADDRESS_REGISTER_FILE
784 if ( t == TYPE_ADR ) {
785 if (rd->maxsavadrreguse > 0) {
786 rd->maxsavadrreguse--;
788 v->regoff = rd->savadrregs[rd->maxsavadrreguse];
792 v->regoff = rd->maxmemuse;
797 if (IS_FLT_DBL_TYPE(t)) {
799 v->flags = rd->locals[s][fltalloc].flags;
800 v->regoff = rd->locals[s][fltalloc].regoff;
802 else if (rd->maxsavfltreguse > 0) {
803 rd->maxsavfltreguse--;
805 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
809 #if defined(NEW_MEMORY)
810 if ( (memneeded) && (rd->maxmemuse&1))
813 v->regoff = rd->maxmemuse;
814 rd->maxmemuse += memneeded + 1;
819 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
821 * for i386 put all longs in memory
823 if (IS_2_WORD_TYPE(t)) {
825 v->regoff = rd->maxmemuse;
826 rd->maxmemuse += memneeded + 1;
830 v->flags = rd->locals[s][intalloc].flags;
831 v->regoff = rd->locals[s][intalloc].regoff;
833 else if (rd->maxsavintreguse > intregsneeded) {
834 rd->maxsavintreguse -= intregsneeded+1;
836 v->regoff = rd->savintregs[rd->maxsavintreguse];
840 v->regoff = rd->maxmemuse;
841 rd->maxmemuse += memneeded + 1;
843 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
848 #ifdef HAS_ADDRESS_REGISTER_FILE
857 static void reg_init_temp(methodinfo *m, registerdata *rd)
860 #if defined(NEW_MEMORY) && defined(HAS_4BYTE_STACKSLOT)
861 rd->freememtop_2 = 0;
863 rd->memuse = rd->ifmemuse;
865 rd->freetmpinttop = 0;
866 rd->freesavinttop = 0;
867 rd->freetmpflttop = 0;
868 rd->freesavflttop = 0;
869 #ifdef HAS_ADDRESS_REGISTER_FILE
870 rd->freetmpadrtop = 0;
871 rd->freesavadrtop = 0;
874 rd->tmpintreguse = rd->iftmpintregcnt;
875 rd->savintreguse = rd->ifsavintregcnt;
876 rd->tmpfltreguse = rd->iftmpfltregcnt;
877 rd->savfltreguse = rd->ifsavfltregcnt;
878 #ifdef HAS_ADDRESS_REGISTER_FILE
879 rd->tmpadrreguse = rd->iftmpadrregcnt;
880 rd->savadrreguse = rd->ifsavadrregcnt;
883 rd->freearginttop = 0;
884 rd->freeargflttop = 0;
885 #ifdef HAS_ADDRESS_REGISTER_FILE
886 rd->freeargadrtop = 0;
890 if (!m->isleafmethod) {
891 rd->argintreguse = rd->ifargintregcnt;
892 rd->argfltreguse = rd->ifargfltregcnt;
893 #ifdef HAS_ADDRESS_REGISTER_FILE
894 rd->argadrreguse = rd->ifargadrregcnt;
898 rd->argintreguse = rd->intreg_argnum;
899 rd->argfltreguse = rd->fltreg_argnum;
900 #ifdef HAS_ADDRESS_REGISTER_FILE
901 rd->argadrreguse = rd->adrreg_argnum;
908 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
911 static void reg_new_temp_func(registerdata *rd, stackptr s)
917 /* Try to allocate a saved register if there is no temporary one */
918 /* available. This is what happens during the second run. */
919 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
921 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
922 intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
926 #if defined(HAS_4BYTE_STACKSLOT)
927 memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
932 for(; tryagain; --tryagain) {
934 if (!(s->flags & SAVEDVAR))
935 s->flags |= SAVEDTMP;
936 #ifdef HAS_ADDRESS_REGISTER_FILE
937 if (s->type == TYPE_ADR) {
938 if (rd->freesavadrtop > 0) {
940 s->regoff = rd->freesavadrregs[rd->freesavadrtop];
943 } else if (rd->savadrreguse > 0) {
945 if (rd->savadrreguse < rd->maxsavadrreguse)
946 rd->maxsavadrreguse = rd->savadrreguse;
947 s->regoff = rd->savadrregs[rd->savadrreguse];
952 if (IS_FLT_DBL_TYPE(s->type)) {
953 if (rd->freesavflttop > 0) {
955 s->regoff = rd->freesavfltregs[rd->freesavflttop];
958 } else if (rd->savfltreguse > 0) {
960 if (rd->savfltreguse < rd->maxsavfltreguse)
961 rd->maxsavfltreguse = rd->savfltreguse;
962 s->regoff = rd->savfltregs[rd->savfltreguse];
967 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
969 * for i386 put all longs in memory
971 if (!IS_2_WORD_TYPE(s->type)) {
973 if (rd->freesavinttop > intregsneeded) {
974 rd->freesavinttop -= intregsneeded + 1;
975 s->regoff = rd->freesavintregs[rd->freesavinttop];
978 } else if (rd->savintreguse > intregsneeded) {
979 rd->savintreguse -= intregsneeded + 1;
980 if (rd->savintreguse < rd->maxsavintreguse)
981 rd->maxsavintreguse = rd->savintreguse;
982 s->regoff = rd->savintregs[rd->savintreguse];
985 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
989 #ifdef HAS_ADDRESS_REGISTER_FILE
993 #ifdef HAS_ADDRESS_REGISTER_FILE
994 if (s->type == TYPE_ADR) {
995 if (rd->freetmpadrtop > 0) {
997 s->regoff = rd->freetmpadrregs[rd->freetmpadrtop];
1000 } else if (rd->tmpadrreguse > 0) {
1002 if (rd->tmpadrreguse < rd->maxtmpadrreguse)
1003 rd->maxtmpadrreguse = rd->tmpadrreguse;
1004 s->regoff = rd->tmpadrregs[rd->tmpadrreguse];
1009 if (IS_FLT_DBL_TYPE(s->type)) {
1010 if (rd->freeargflttop > 0) {
1011 rd->freeargflttop --;
1012 s->regoff = rd->freeargfltregs[rd->freeargflttop];
1015 } else if (rd->argfltreguse < rd->fltreg_argnum) {
1016 if (rd->argfltreguse > rd->maxargfltreguse)
1017 rd->maxargfltreguse = rd->argfltreguse;
1018 s->regoff = rd->argfltregs[rd->argfltreguse++];
1021 } else if (rd->freetmpflttop > 0) {
1022 rd->freetmpflttop--;
1023 s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
1026 } else if (rd->tmpfltreguse > 0) {
1028 if (rd->tmpfltreguse < rd->maxtmpfltreguse)
1029 rd->maxtmpfltreguse = rd->tmpfltreguse;
1030 s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
1035 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1037 * for i386 put all longs in memory
1039 if (!IS_2_WORD_TYPE(s->type)) {
1041 if (rd->freearginttop > intregsneeded) {
1042 rd->freearginttop -= intregsneeded + 1;
1043 s->regoff = rd->freeargintregs[rd->freearginttop];
1046 } else if (rd->argintreguse < rd->intreg_argnum - intregsneeded) {
1047 if (rd->argintreguse > rd->maxargintreguse)
1048 rd->maxargintreguse = rd->argintreguse;
1049 s->regoff = rd->argintregs[rd->argintreguse];
1051 rd->argintreguse += intregsneeded + 1;
1053 } else if (rd->freetmpinttop > intregsneeded) {
1054 rd->freetmpinttop -= intregsneeded + 1;
1055 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
1058 } else if (rd->tmpintreguse > intregsneeded) {
1059 rd->tmpintreguse -= intregsneeded + 1;
1060 if (rd->tmpintreguse < rd->maxtmpintreguse)
1061 rd->maxtmpintreguse = rd->tmpintreguse;
1062 s->regoff = rd->tmpintregs[rd->tmpintreguse];
1065 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1069 #ifdef HAS_ADDRESS_REGISTER_FILE
1075 #if defined(NEW_MEMORY)
1076 #if defined(HAS_4BYTE_STACKSLOT)
1077 if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
1079 s->regoff = rd->freemem_2[rd->freememtop_2];
1081 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1082 if ((memneeded == 0) && (rd->freememtop > 0)) {
1084 s->regoff = rd->freemem[rd->freememtop];
1086 #if defined(HAS_4BYTE_STACKSLOT)
1087 /* align 2 Word Types */
1088 /* if ((memneeded) && (rd->memuse & 1 == 1)) { */
1089 /* rd->freemem[rd->freememtop] = rd->memuse; */
1090 /* rd->freememtop++; */
1093 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1094 s->regoff = rd->memuse;
1095 rd->memuse += memneeded + 1;
1096 if (rd->memuse > rd->maxmemuse)
1097 rd->maxmemuse = rd->memuse;
1099 #else /* defined(NEW_MEMORY) */
1100 if ((rd->freememtop > memneeded) && (memneeded == 0)) {
1101 rd->freememtop -= memneeded + 1;
1102 s->regoff = rd->freemem[rd->freememtop];
1104 s->regoff = rd->memuse;
1105 rd->memuse += memneeded + 1;
1106 if (rd->memuse > rd->maxmemuse)
1107 rd->maxmemuse = rd->memuse;
1109 #endif /* defined(NEW_MEMORY) */
1110 s->flags |= INMEMORY;
1114 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
1117 static void reg_free_temp_func(registerdata *rd, stackptr s)
1122 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1123 intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
1127 #if defined(HAS_4BYTE_STACKSLOT)
1128 memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
1133 if (s->flags & INMEMORY) {
1134 #if defined(NEW_MEMORY) && defined(HAS_4BYTE_STACKSLOT)
1135 if (memneeded > 0) {
1136 rd->freemem_2[rd->freememtop_2] = s->regoff;
1139 rd->freemem[rd->freememtop] = s->regoff;
1143 rd->freemem[rd->freememtop] = s->regoff;
1145 rd->freemem[rd->freememtop + 1] = s->regoff + 1;
1146 rd->freememtop += memneeded + 1;
1147 #endif /* defined(NEW_MEMORY) && defined(HAS_4BYTE_STACKSLOT */
1148 #ifdef HAS_ADDRESS_REGISTER_FILE
1149 } else if (s->type == TYPE_ADR) {
1150 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1151 s->flags &= ~SAVEDTMP;
1152 rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
1155 rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
1157 } else if (IS_FLT_DBL_TYPE(s->type)) {
1158 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1159 s->flags &= ~SAVEDTMP;
1160 rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
1162 if (s->flags & TMPARG) {
1163 s->flags &= ~TMPARG;
1164 rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
1166 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
1168 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1169 s->flags &= ~SAVEDTMP;
1170 rd->freesavintregs[rd->freesavinttop] = s->regoff;
1171 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1173 rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
1175 rd->freesavinttop += intregsneeded + 1;
1177 } else if (s->flags & TMPARG) {
1178 s->flags &= ~TMPARG;
1179 rd->freeargintregs[rd->freearginttop] = s->regoff;
1180 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1182 rd->freeargintregs[rd->freearginttop + 1] = rd->secondregs[s->regoff];
1184 rd->freearginttop += intregsneeded + 1;
1186 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
1187 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1189 rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
1191 rd->freetmpinttop += intregsneeded + 1;
1198 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
1208 bptr = m->basicblocks;
1210 while (bptr != NULL) {
1211 if (bptr->flags >= BBREACHED) {
1212 dst = bptr->instack;
1214 /* initialize temp registers */
1215 reg_init_temp(m, rd);
1217 iptr = bptr->iinstr;
1220 while (--len >= 0) {
1230 case ICMD_ELSE_ICONST:
1231 case ICMD_CHECKNULL:
1232 case ICMD_CHECKASIZE:
1233 case ICMD_CHECKEXCEPTION:
1239 case ICMD_PUTSTATICCONST:
1240 case ICMD_INLINE_START:
1241 case ICMD_INLINE_END:
1244 /* pop 0 push 1 const */
1252 /* pop 0 push 1 load */
1259 reg_new_temp(rd, dst);
1273 reg_free_temp(rd, src);
1274 reg_free_temp(rd, src->prev);
1275 reg_new_temp(rd, dst);
1289 reg_free_temp(rd, src);
1290 reg_free_temp(rd, src->prev);
1291 reg_free_temp(rd, src->prev->prev);
1294 /* pop 1 push 0 store */
1314 case ICMD_PUTSTATIC:
1315 case ICMD_PUTFIELDCONST:
1317 /* pop 1 push 0 branch */
1320 case ICMD_IFNONNULL:
1336 /* pop 1 push 0 table branch */
1338 case ICMD_TABLESWITCH:
1339 case ICMD_LOOKUPSWITCH:
1341 case ICMD_MONITORENTER:
1342 case ICMD_MONITOREXIT:
1343 reg_free_temp(rd, src);
1346 /* pop 2 push 0 branch */
1348 case ICMD_IF_ICMPEQ:
1349 case ICMD_IF_ICMPNE:
1350 case ICMD_IF_ICMPLT:
1351 case ICMD_IF_ICMPGE:
1352 case ICMD_IF_ICMPGT:
1353 case ICMD_IF_ICMPLE:
1355 case ICMD_IF_LCMPEQ:
1356 case ICMD_IF_LCMPNE:
1357 case ICMD_IF_LCMPLT:
1358 case ICMD_IF_LCMPGE:
1359 case ICMD_IF_LCMPGT:
1360 case ICMD_IF_LCMPLE:
1362 case ICMD_IF_ACMPEQ:
1363 case ICMD_IF_ACMPNE:
1371 case ICMD_IASTORECONST:
1372 case ICMD_LASTORECONST:
1373 case ICMD_AASTORECONST:
1374 case ICMD_BASTORECONST:
1375 case ICMD_CASTORECONST:
1376 case ICMD_SASTORECONST:
1377 reg_free_temp(rd, src);
1378 reg_free_temp(rd, src->prev);
1381 /* pop 0 push 1 dup */
1384 reg_new_temp(rd, dst);
1387 /* pop 0 push 2 dup */
1390 reg_new_temp(rd, dst->prev);
1391 reg_new_temp(rd, dst);
1394 /* pop 2 push 3 dup */
1397 reg_free_temp(rd, src);
1398 reg_new_temp(rd, dst);
1399 reg_free_temp(rd, src->prev);
1400 reg_new_temp(rd, dst->prev);
1401 reg_new_temp(rd, dst->prev->prev);
1404 /* pop 3 push 4 dup */
1407 reg_free_temp(rd, src);
1408 reg_new_temp(rd, dst);
1409 reg_free_temp(rd, src->prev);
1410 reg_new_temp(rd, dst->prev);
1411 reg_free_temp(rd, src->prev->prev);
1412 reg_new_temp(rd, dst->prev->prev);
1413 reg_new_temp(rd, dst->prev->prev->prev);
1416 /* pop 3 push 5 dup */
1419 reg_free_temp(rd, src);
1420 reg_new_temp(rd, dst);
1421 reg_free_temp(rd, src->prev);
1422 reg_new_temp(rd, dst->prev);
1423 reg_free_temp(rd, src->prev->prev);
1424 reg_new_temp(rd, dst->prev->prev);
1425 reg_new_temp(rd, dst->prev->prev->prev);
1426 reg_new_temp(rd, dst->prev->prev->prev->prev);
1429 /* pop 4 push 6 dup */
1432 reg_free_temp(rd, src);
1433 reg_new_temp(rd, dst);
1434 reg_free_temp(rd, src->prev);
1435 reg_new_temp(rd, dst->prev);
1436 reg_free_temp(rd, src->prev->prev);
1437 reg_new_temp(rd, dst->prev->prev);
1438 reg_free_temp(rd, src->prev->prev->prev);
1439 reg_new_temp(rd, dst->prev->prev->prev);
1440 reg_new_temp(rd, dst->prev->prev->prev->prev);
1441 reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1444 /* pop 2 push 2 swap */
1447 reg_free_temp(rd, src);
1448 reg_new_temp(rd, dst->prev);
1449 reg_free_temp(rd, src->prev);
1450 reg_new_temp(rd, dst);
1499 reg_free_temp(rd, src);
1500 reg_free_temp(rd, src->prev);
1501 reg_new_temp(rd, dst);
1506 case ICMD_IADDCONST:
1507 case ICMD_ISUBCONST:
1508 case ICMD_IMULCONST:
1512 case ICMD_IANDCONST:
1514 case ICMD_IXORCONST:
1515 case ICMD_ISHLCONST:
1516 case ICMD_ISHRCONST:
1517 case ICMD_IUSHRCONST:
1519 case ICMD_LADDCONST:
1520 case ICMD_LSUBCONST:
1521 case ICMD_LMULCONST:
1525 case ICMD_LANDCONST:
1527 case ICMD_LXORCONST:
1528 case ICMD_LSHLCONST:
1529 case ICMD_LSHRCONST:
1530 case ICMD_LUSHRCONST:
1532 case ICMD_IFEQ_ICONST:
1533 case ICMD_IFNE_ICONST:
1534 case ICMD_IFLT_ICONST:
1535 case ICMD_IFGE_ICONST:
1536 case ICMD_IFGT_ICONST:
1537 case ICMD_IFLE_ICONST:
1542 case ICMD_INT2SHORT:
1560 case ICMD_CHECKCAST:
1562 case ICMD_ARRAYLENGTH:
1563 case ICMD_INSTANCEOF:
1566 case ICMD_ANEWARRAY:
1569 reg_free_temp(rd, src);
1570 reg_new_temp(rd, dst);
1575 case ICMD_GETSTATIC:
1578 reg_new_temp(rd, dst);
1581 /* pop many push any */
1583 case ICMD_INVOKESTATIC:
1584 case ICMD_INVOKESPECIAL:
1585 case ICMD_INVOKEVIRTUAL:
1586 case ICMD_INVOKEINTERFACE:
1589 reg_free_temp(rd, src);
1592 if (((unresolved_method *) iptr->target)->methodref->parseddesc.md->returntype.type != TYPE_VOID)
1593 reg_new_temp(rd, dst);
1599 reg_free_temp(rd, src);
1602 if (((builtintable_entry *) iptr->val.a)->md->returntype.type != TYPE_VOID)
1603 reg_new_temp(rd, dst);
1606 case ICMD_MULTIANEWARRAY:
1609 reg_free_temp(rd, src);
1612 reg_new_temp(rd, dst);
1616 throw_cacao_exception_exit(string_java_lang_InternalError,
1617 "Unknown ICMD %d during register allocation",
1621 } /* while instructions */
1624 } /* while blocks */
1629 void reg_make_statistics( methodinfo *m, codegendata *cd, registerdata *rd) {
1632 stackptr src, src_old;
1636 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1643 /* count how many local variables are held in memory or register */
1644 for(i=0; i < cd->maxlocals; i++)
1645 for (type=0; type <=4; type++)
1646 if (rd->locals[i][type].type != -1) { /* valid local */
1647 if (rd->locals[i][type].flags & INMEMORY) {
1648 count_locals_spilled++;
1652 count_locals_register++;
1654 /* count how many stack slots are held in memory or register */
1656 bptr = m->basicblocks;
1657 while (bptr != NULL) {
1658 if (bptr->flags >= BBREACHED) {
1663 /* check for memory moves from interface to BB instack */
1664 dst = bptr->instack;
1665 len = bptr->indepth;
1667 if (len > size_interface) size_interface = len;
1669 while (dst != NULL) {
1671 if (dst->varkind != STACKVAR) {
1672 if ( (dst->flags & INMEMORY) ||
1673 (rd->interfaces[len][dst->type].flags & INMEMORY) ||
1674 ( (dst->flags & INMEMORY) &&
1675 (rd->interfaces[len][dst->type].flags & INMEMORY) &&
1676 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1678 /* one in memory or both inmemory at different offsets */
1679 count_mem_move_bb++;
1687 /* check for memory moves from BB outstack to interface */
1688 dst = bptr->outstack;
1689 len = bptr->outdepth;
1690 if (len > size_interface) size_interface = len;
1694 if (dst->varkind != STACKVAR) {
1695 if ( (dst->flags & INMEMORY) || \
1696 (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1697 ( (dst->flags & INMEMORY) && \
1698 (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1699 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1701 /* one in memory or both inmemory at different offsets */
1702 count_mem_move_bb++;
1714 dst = bptr->instack;
1715 iptr = bptr->iinstr;
1719 while (--len >= 0) {
1723 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1724 switch (src->varkind) {
1727 if (!(src->flags & INMEMORY))
1728 count_ss_register++;
1734 /* case LOCALVAR: */
1735 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1736 /* count_ss_register++; */
1738 /* count_ss_spilled++; */
1741 if (!(src->flags & INMEMORY))
1742 count_argument_mem_ss++;
1744 count_argument_reg_ss++;
1748 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1749 /* if (src->varnum < FLT_ARG_CNT) { */
1750 /* count_ss_register++; */
1754 /* #if defined(__POWERPC__) */
1755 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1757 /* if (src->varnum < INT_ARG_CNT) { */
1759 /* count_ss_register++; */
1763 /* count_ss_spilled++; */
1770 } /* while instructions */
1773 } /* while blocks */
1774 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1775 if (in_register) count_method_in_register++;
1779 * These are local overrides for various environment variables in Emacs.
1780 * Please do not remove this and leave it at the end of the file, where
1781 * Emacs will automagically detect them.
1782 * ---------------------------------------------------------------------
1785 * indent-tabs-mode: t