00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025
00026 # ifdef DELTA_COMPILER
00027 # include "incls/_x86_mapping.cpp.incl"
00028
00029
00030
00031
00032 void Mapping::initialize() {
00033 _localRegisters[0] = asLocation(eax);
00034 _localRegisters[1] = asLocation(edi);
00035 _localRegisters[2] = asLocation(esi);
00036 int i;
00037 for (i = 0; i < nofRegisters ; i++) _localRegisterIndex[i] = -1;
00038 for (i = 0; i < nofLocalRegisters; i++) _localRegisterIndex[_localRegisters[i].number()] = i;
00039 for (i = 0; i < nofLocalRegisters; i++) {
00040 Register r = asRegister(_localRegisters[i]);
00041 assert((r != temp1) && (r != temp2) && (r != temp3), "local registers must be disjoint from temporary registers");
00042 }
00043 }
00044
00045
00046
00047 Location Mapping::_localRegisters[nofLocalRegisters + 1];
00048
00049 int Mapping::_localRegisterIndex[nofRegisters + 1];
00050
00051 Location Mapping::localRegister(int i) {
00052 assert(0 <= i && i < nofLocalRegisters, "illegal local register index");
00053 return _localRegisters[i];
00054 }
00055
00056
00057 int Mapping::localRegisterIndex(Location l) {
00058 assert(0 <= l.number() && l.number() < nofRegisters, "illegal local register");
00059 int res = _localRegisterIndex[l.number()];
00060 assert(res >= 0, "not a local register");
00061 assert(localRegister(res) == l, "incorrect mapping");
00062 return res;
00063 }
00064
00065
00066
00067 Location Mapping::incomingArg(int i, int nofArgs) {
00068 assert((0 <= i) && (i < nofArgs), "illegal arg number");
00069 return Location::stackLocation(nofArgs - i + 1);
00070 }
00071
00072
00073 Location Mapping::outgoingArg(int i, int nofArgs) {
00074 assert((0 <= i) && (i < nofArgs), "illegal arg number");
00075 return topOfStack;
00076 }
00077
00078
00079
00080 Location Mapping::localTemporary(int i) {
00081 assert(i >= 0, "illegal temporary number");
00082 int floats = theCompiler->totalNofFloatTemporaries();
00083 int offset = (floats > 0 ? first_float_offset - floats*(floatSize/oopSize) : first_temp_offset) - i;
00084 return Location::stackLocation(offset);
00085 }
00086
00087
00088 int Mapping::localTemporaryIndex(Location l) {
00089 int floats = theCompiler->totalNofFloatTemporaries();
00090 int i = (floats > 0 ? first_float_offset - floats*(floatSize/oopSize) : first_temp_offset) - l.offset();
00091 assert(localTemporary(i) == l, "incorrect mapping");
00092 return i;
00093 }
00094
00095
00096 Location Mapping::floatTemporary(int scope_id, int i) {
00097 InlinedScope* scope = theCompiler->scopes->at(scope_id);
00098 assert(scope->firstFloatIndex() >= 0, "firstFloatIndex not computed yet");
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 assert(floatSize == 2*oopSize, "check this code");
00109 Location loc = Location::stackLocation(first_float_offset - (scope->firstFloatIndex() + i)*(floatSize/oopSize));
00110 assert((loc.offset() * oopSize) % floatSize == 0, "offset is not correctly aligned");
00111 return loc;
00112 }
00113
00114
00115
00116 Location Mapping::contextTemporary(int contextNo, int i, int scope_offset) {
00117 assert((0 <= contextNo) && (0 <= i), "illegal context or temporary no");
00118 return Location::compiledContextLocation(contextNo, i, scope_offset);
00119 }
00120
00121
00122 Location* Mapping::new_contextTemporary(int contextNo, int i, int scope_id) {
00123 assert((0 <= contextNo) && (0 <= i), "illegal context or temporary no");
00124 return new Location(contextLoc1, contextNo, i, scope_id);
00125 }
00126
00127
00128 int Mapping::contextOffset(int tempNo) {
00129
00130 return tempNo*oopSize + contextOopDesc::temp0_byte_offset();
00131 }
00132
00133
00134
00135 bool Mapping::isNormalTemporary(Location loc) {
00136 assert(!loc.isFloatLocation(), "must have been converted into stackLoc by register allocation");
00137 return loc.isStackLocation() && !isFloatTemporary(loc);
00138 }
00139
00140
00141 bool Mapping::isFloatTemporary(Location loc) {
00142 assert(!loc.isFloatLocation(), "must have been converted into stackLoc by register allocation");
00143 if (!loc.isStackLocation()) return false;
00144 int floats = theCompiler->totalNofFloatTemporaries();
00145 int offset = loc.offset();
00146 return floats > 0 && first_float_offset + 2 >= offset && offset > first_float_offset - floats*(floatSize/oopSize);
00147 }
00148
00149
00150
00151 void Mapping::load(Location src, Register dst) {
00152 switch (src.mode()) {
00153 case specialLoc: {
00154 if (src == resultOfNLR) {
00155
00156 if (NLR_result_reg != dst) theMacroAssm->movl(dst, NLR_result_reg);
00157 } else {
00158 ShouldNotReachHere();
00159 }
00160 break;
00161 }
00162 case registerLoc: {
00163 Register s = asRegister(src);
00164 if (s != dst) theMacroAssm->movl(dst, s);
00165 break;
00166 }
00167 case stackLoc: {
00168 assert(isNormalTemporary(src), "must be a normal temporary location");
00169 theMacroAssm->Load(ebp, src.offset() * oopSize, dst);
00170 break;
00171 }
00172 case contextLoc1: {
00173 PReg* base = theCompiler->contextList->at(src.contextNo())->context();
00174 load(base->loc, dst);
00175 theMacroAssm->Load(dst, contextOffset(src.tempNo()), dst);
00176 break;
00177 }
00178 default: {
00179 ShouldNotReachHere();
00180 break;
00181 }
00182 }
00183 }
00184
00185
00186 void Mapping::store(Register src, Location dst, Register temp1, Register temp2, bool needsStoreCheck) {
00187 assert(src != temp1 && src != temp2 && temp1 != temp2, "registers must be different");
00188 switch (dst.mode()) {
00189 case specialLoc: {
00190 if (dst == topOfStack) {
00191 theMacroAssm->pushl(src);
00192 } else {
00193 ShouldNotReachHere();
00194 }
00195 break;
00196 }
00197 case registerLoc: {
00198 Register d = asRegister(dst);
00199 if (d != src) theMacroAssm->movl(d, src);
00200 break;
00201 }
00202 case stackLoc: {
00203 assert(isNormalTemporary(dst), "must be a normal temporary location");
00204 theMacroAssm->Store(src, ebp, dst.offset()*oopSize);
00205 break;
00206 }
00207 case contextLoc1: {
00208 PReg* base = theCompiler->contextList->at(dst.contextNo())->context();
00209 load(base->loc, temp1);
00210 theMacroAssm->Store(src, temp1, contextOffset(dst.tempNo()));
00211 if (needsStoreCheck) theMacroAssm->store_check(temp1, temp2);
00212 break;
00213 }
00214 default: {
00215 ShouldNotReachHere();
00216 break;
00217 }
00218 }
00219 }
00220
00221
00222 void Mapping::storeO(oop obj, Location dst, Register temp1, Register temp2, bool needsStoreCheck) {
00223 assert(temp1 != temp2, "registers must be different");
00224 switch (dst.mode()) {
00225 case specialLoc: {
00226 if (dst == topOfStack) {
00227 theMacroAssm->pushl(obj);
00228 } else {
00229 ShouldNotReachHere();
00230 }
00231 break;
00232 }
00233 case registerLoc: {
00234 theMacroAssm->movl(asRegister(dst), obj);
00235 break;
00236 }
00237 case stackLoc: {
00238 assert(isNormalTemporary(dst), "must be a normal temporary location");
00239 theMacroAssm->movl(Address(ebp, dst.offset()*oopSize), obj);
00240 break;
00241 }
00242 case contextLoc1: {
00243 PReg* base = theCompiler->contextList->at(dst.contextNo())->context();
00244 load(base->loc, temp1);
00245 theMacroAssm->movl(Address(temp1, contextOffset(dst.tempNo())), obj);
00246 if (needsStoreCheck) theMacroAssm->store_check(temp1, temp2);
00247 break;
00248 }
00249 default: {
00250 ShouldNotReachHere();
00251 break;
00252 }
00253 }
00254 }
00255
00256
00257 void Mapping::fload(Location src, Register base) {
00258 if (src == topOfFloatStack) {
00259 if (UseFPUStack) {
00260
00261 } else {
00262 ShouldNotReachHere();
00263 }
00264 } else {
00265 assert(isFloatTemporary(src), "must be a float location");
00266 assert((src.offset()*oopSize) % floatSize == 0, "float is not aligned");
00267 theMacroAssm->fld_d(Address(base, src.offset()*oopSize));
00268 }
00269 }
00270
00271
00272 void Mapping::fstore(Location dst, Register base) {
00273 if (dst == topOfFloatStack) {
00274 if (UseFPUStack) {
00275
00276 } else {
00277 ShouldNotReachHere();
00278 }
00279 } else {
00280 assert(isFloatTemporary(dst), "must be a float location");
00281 assert((dst.offset()*oopSize) % floatSize == 0, "float is not aligned");
00282 theMacroAssm->fstp_d(Address(base, dst.offset()*oopSize));
00283 }
00284 }
00285
00286
00287 void mapping_init() {
00288 Mapping::initialize();
00289 }
00290
00291 # endif