~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to VEX/priv/host-generic/reg_alloc2.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-06-26 00:17:17 UTC
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: james.westby@ubuntu.com-20060626001717-qi51nzty57cb12q6
Tags: upstream-3.2.0
Import upstream version 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
   This file is part of LibVEX, a library for dynamic binary
11
11
   instrumentation and translation.
12
12
 
13
 
   Copyright (C) 2004-2005 OpenWorks LLP.  All rights reserved.
 
13
   Copyright (C) 2004-2006 OpenWorks LLP.  All rights reserved.
14
14
 
15
15
   This library is made available under a dual licensing scheme.
16
16
 
155
155
 
156
156
/* Does this instruction mention a particular reg? */
157
157
static Bool instrMentionsReg ( 
158
 
   void (*getRegUsage) (HRegUsage*, HInstr*),
 
158
   void (*getRegUsage) (HRegUsage*, HInstr*, Bool),
159
159
   HInstr* instr, 
160
 
   HReg r 
 
160
   HReg r,
 
161
   Bool mode64
161
162
)
162
163
{
163
164
   Int       i;
164
165
   HRegUsage reg_usage;
165
 
   (*getRegUsage)(&reg_usage, instr);
 
166
   (*getRegUsage)(&reg_usage, instr, mode64);
166
167
   for (i = 0; i < reg_usage.n_used; i++)
167
168
      if (reg_usage.hreg[i] == r)
168
169
         return True;
184
185
   spill, or -1 if none was found.  */
185
186
static
186
187
Int findMostDistantlyMentionedVReg ( 
187
 
   void (*getRegUsage) (HRegUsage*, HInstr*),
 
188
   void (*getRegUsage) (HRegUsage*, HInstr*, Bool),
188
189
   HInstrArray* instrs_in,
189
190
   Int          search_from_instr,
190
191
   RRegState*   state,
191
 
   Int          n_state
 
192
   Int          n_state,
 
193
   Bool         mode64
192
194
)
193
195
{
194
196
   Int k, m;
201
203
      vassert(state[k].disp == Bound);
202
204
      for (m = search_from_instr; m < instrs_in->arr_used; m++) {
203
205
         if (instrMentionsReg(getRegUsage, 
204
 
                              instrs_in->arr[m], state[k].vreg))
 
206
                              instrs_in->arr[m], state[k].vreg, mode64))
205
207
            break;
206
208
      }
207
209
      if (m > furthest) {
258
260
 
259
261
   /* Return True iff the given insn is a reg-reg move, in which
260
262
      case also return the src and dst regs. */
261
 
   Bool (*isMove) (HInstr*, HReg*, HReg*),
 
263
   Bool (*isMove) ( HInstr*, HReg*, HReg* ),
262
264
 
263
265
   /* Get info about register usage in this insn. */
264
 
   void (*getRegUsage) (HRegUsage*, HInstr*),
 
266
   void (*getRegUsage) ( HRegUsage*, HInstr*, Bool ),
265
267
 
266
268
   /* Apply a reg-reg mapping to an insn. */
267
 
   void (*mapRegs) (HRegRemap*, HInstr*),
 
269
   void (*mapRegs) ( HRegRemap*, HInstr*, Bool ),
268
270
 
269
271
   /* Return an insn to spill/restore a real reg to a spill slot
270
272
      byte offset. */
271
 
   HInstr* (*genSpill) ( HReg, Int ),
272
 
   HInstr* (*genReload) ( HReg, Int ),
 
273
   HInstr* (*genSpill) ( HReg, Int, Bool ),
 
274
   HInstr* (*genReload) ( HReg, Int, Bool ),
273
275
   Int     guest_sizeB,
274
276
 
275
277
   /* For debug printing only. */
276
 
   void (*ppInstr) ( HInstr* ),
277
 
   void (*ppReg) ( HReg )
 
278
   void (*ppInstr) ( HInstr*, Bool ),
 
279
   void (*ppReg) ( HReg ),
 
280
 
 
281
   /* 32/64bit mode */
 
282
   Bool mode64
278
283
)
279
284
{
280
285
#  define N_SPILL64S  (LibVEX_N_SPILL_BYTES / 8)
336
341
        HInstr* _tmp = (_instr);              \
337
342
        if (DEBUG_REGALLOC) {                 \
338
343
           vex_printf("**  ");                \
339
 
           (*ppInstr)(_tmp);                  \
 
344
           (*ppInstr)(_tmp, mode64);          \
340
345
           vex_printf("\n\n");                \
341
346
        }                                     \
342
347
        addHInstr ( instrs_out, _tmp );       \
451
456
 
452
457
   for (ii = 0; ii < instrs_in->arr_used; ii++) {
453
458
 
454
 
      (*getRegUsage)( &reg_usage, instrs_in->arr[ii] );
 
459
      (*getRegUsage)( &reg_usage, instrs_in->arr[ii], mode64 );
455
460
 
456
461
#     if 0
457
462
      vex_printf("\n%d  stage1: ", ii);
458
 
      (*ppInstr)(instrs_in->arr[ii]);
 
463
      (*ppInstr)(instrs_in->arr[ii], mode64);
459
464
      vex_printf("\n");
460
465
      ppHRegUsage(&reg_usage);
461
466
#     endif
472
477
         k = hregNumber(vreg);
473
478
         if (k < 0 || k >= n_vregs) {
474
479
            vex_printf("\n");
475
 
            (*ppInstr)(instrs_in->arr[ii]);
 
480
            (*ppInstr)(instrs_in->arr[ii], mode64);
476
481
            vex_printf("\n");
477
482
            vex_printf("vreg %d, n_vregs %d\n", k, n_vregs);
478
483
            vpanic("doRegisterAllocation: out-of-range vreg");
561
566
                  (*ppReg)(available_real_regs[k]);
562
567
                  vex_printf("\n");
563
568
                  vex_printf("\nOFFENDING instr = ");
564
 
                  (*ppInstr)(instrs_in->arr[ii]);
 
569
                  (*ppInstr)(instrs_in->arr[ii], mode64);
565
570
                  vex_printf("\n");
566
571
                  vpanic("doRegisterAllocation: "
567
572
                         "first event for rreg is Read");
574
579
                  (*ppReg)(available_real_regs[k]);
575
580
                  vex_printf("\n");
576
581
                  vex_printf("\nOFFENDING instr = ");
577
 
                  (*ppInstr)(instrs_in->arr[ii]);
 
582
                  (*ppInstr)(instrs_in->arr[ii], mode64);
578
583
                  vex_printf("\n");
579
584
                  vpanic("doRegisterAllocation: "
580
585
                         "first event for rreg is Modify");
786
791
#     if DEBUG_REGALLOC
787
792
      vex_printf("\n====----====---- Insn %d ----====----====\n", ii);
788
793
      vex_printf("---- ");
789
 
      (*ppInstr)(instrs_in->arr[ii]);
 
794
      (*ppInstr)(instrs_in->arr[ii], mode64);
790
795
      vex_printf("\n\nInitial state:\n");
791
796
      PRINT_STATE;
792
797
      vex_printf("\n");
1009
1014
               if (vreg_lrs[m].dead_before > ii) {
1010
1015
                  vassert(vreg_lrs[m].reg_class != HRcINVALID);
1011
1016
                  EMIT_INSTR( (*genSpill)( rreg_state[k].rreg,
1012
 
                                           vreg_lrs[m].spill_offset ) );
 
1017
                                           vreg_lrs[m].spill_offset,
 
1018
                                           mode64 ) );
1013
1019
               }
1014
1020
            }
1015
1021
            rreg_state[k].disp = Unavail;
1033
1039
         We also build up the final vreg->rreg mapping to be applied
1034
1040
         to the insn. */
1035
1041
      
1036
 
      (*getRegUsage)( &reg_usage, instrs_in->arr[ii] );
 
1042
      (*getRegUsage)( &reg_usage, instrs_in->arr[ii], mode64 );
1037
1043
 
1038
1044
      initHRegRemap(&remap);
1039
1045
 
1098
1104
            if (reg_usage.mode[j] != HRmWrite) {
1099
1105
               vassert(vreg_lrs[m].reg_class != HRcINVALID);
1100
1106
               EMIT_INSTR( (*genReload)( rreg_state[k].rreg,
1101
 
                                         vreg_lrs[m].spill_offset ) );
 
1107
                                         vreg_lrs[m].spill_offset,
 
1108
                                         mode64 ) );
1102
1109
            }
1103
1110
            continue;
1104
1111
         }
1133
1140
            of consequent reloads required. */
1134
1141
         spillee
1135
1142
            = findMostDistantlyMentionedVReg ( 
1136
 
                 getRegUsage, instrs_in, ii+1, rreg_state, n_rregs );
 
1143
                 getRegUsage, instrs_in, ii+1, rreg_state, n_rregs, mode64 );
1137
1144
 
1138
1145
         if (spillee == -1) {
1139
1146
            /* Hmmmmm.  There don't appear to be any spill candidates.
1161
1168
         vassert(vreg_lrs[m].dead_before > ii);
1162
1169
         vassert(vreg_lrs[m].reg_class != HRcINVALID);
1163
1170
         EMIT_INSTR( (*genSpill)( rreg_state[spillee].rreg,
1164
 
                                  vreg_lrs[m].spill_offset ) );
 
1171
                                  vreg_lrs[m].spill_offset,
 
1172
                                  mode64 ) );
1165
1173
 
1166
1174
         /* Update the rreg_state to reflect the new assignment for this
1167
1175
            rreg. */
1177
1185
         if (reg_usage.mode[j] != HRmWrite) {
1178
1186
            vassert(vreg_lrs[m].reg_class != HRcINVALID);
1179
1187
            EMIT_INSTR( (*genReload)( rreg_state[spillee].rreg,
1180
 
                                      vreg_lrs[m].spill_offset ) );
 
1188
                                      vreg_lrs[m].spill_offset,
 
1189
                                      mode64 ) );
1181
1190
         }
1182
1191
 
1183
1192
         /* So after much twisting and turning, we have vreg mapped to
1198
1207
      */
1199
1208
 
1200
1209
      /* NOTE, DESTRUCTIVELY MODIFIES instrs_in->arr[ii]. */
1201
 
      (*mapRegs)( &remap, instrs_in->arr[ii] );
 
1210
      (*mapRegs)( &remap, instrs_in->arr[ii], mode64 );
1202
1211
      EMIT_INSTR( instrs_in->arr[ii] );
1203
1212
 
1204
1213
#     if DEBUG_REGALLOC