BasicRegisterMapper.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.dx.ssa; 18 19import com.android.dx.rop.code.RegisterSpec; 20import com.android.dx.rop.code.RegisterSpecList; 21import com.android.dx.util.IntList; 22 23/** 24 * This class maps one register space into another, with 25 * each mapping built up individually and added via addMapping() 26 */ 27public class BasicRegisterMapper 28 extends RegisterMapper { 29 30 /** indexed by old register, containing new name */ 31 private IntList oldToNew; 32 33 /** Running count of used registers in new namespace */ 34 private int runningCountNewRegisters; 35 36 /** 37 * Creates a new OneToOneRegisterMapper 38 * @param countOldRegisters the number of registers in the old name space 39 */ 40 public BasicRegisterMapper(int countOldRegisters) { 41 oldToNew = new IntList(countOldRegisters); 42 } 43 44 /** {@inheritDoc} */ 45 @Override 46 public int getNewRegisterCount() { 47 return runningCountNewRegisters; 48 } 49 50 /** {@inheritDoc} */ 51 @Override 52 public RegisterSpec map(RegisterSpec registerSpec) { 53 if (registerSpec == null) { 54 return null; 55 } 56 57 int newReg; 58 try { 59 newReg = oldToNew.get(registerSpec.getReg()); 60 } catch (IndexOutOfBoundsException ex) { 61 newReg = -1; 62 } 63 64 if (newReg < 0) { 65 throw new RuntimeException("no mapping specified for register"); 66 } 67 68 return registerSpec.withReg(newReg); 69 } 70 71 /** 72 * Returns the new-namespace mapping for the specified 73 * old-namespace register, or -1 if one exists 74 * 75 * @param oldReg >=0; old-namespace register 76 * @return new-namespace register or -1 if none. 77 */ 78 public int oldToNew(int oldReg) { 79 if(oldReg >= oldToNew.size()) { 80 return -1; 81 } 82 return oldToNew.get(oldReg); 83 } 84 85 /** {@inheritDoc} */ 86 public String toHuman() { 87 StringBuilder sb = new StringBuilder(); 88 89 sb.append("Old\tNew\n"); 90 int sz = oldToNew.size(); 91 for(int i = 0; i < sz; i++) { 92 sb.append(i); 93 sb.append('\t'); 94 sb.append(oldToNew.get(i)); 95 sb.append('\n'); 96 } 97 98 sb.append("new reg count:"); 99 100 sb.append(runningCountNewRegisters); 101 sb.append('\n'); 102 103 return sb.toString(); 104 } 105 106 /** 107 * adds a mapping to the mapper. If oldReg has already been mapped, 108 * overwrites previous mapping with new mapping. 109 * 110 * @param oldReg >=0 111 * @param newReg >=0 112 * @param category width of reg (1 or 2) 113 */ 114 public void addMapping(int oldReg, int newReg, int category) { 115 if (oldReg >= oldToNew.size()) { 116 // expand the array as necessary 117 for (int i = oldReg - oldToNew.size(); i >= 0; i--) { 118 oldToNew.add(-1); 119 } 120 } 121 oldToNew.set(oldReg, newReg); 122 123 if (runningCountNewRegisters < (newReg + category)) { 124 runningCountNewRegisters = newReg + category; 125 } 126 } 127} 128