x86_mapping.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.30 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 
00026 # ifdef DELTA_COMPILER
00027 # include "incls/_x86_mapping.cpp.incl"
00028 
00029 
00030 // stack mapping
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 // local registers
00047 Location Mapping::_localRegisters[nofLocalRegisters + 1]; // allow for 0 local registers
00048                                                           // C++ won't compile array with 0 elements
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 // parameter passing
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 // stack allocation (Note: offsets are always in oops!)
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   // Floats must be 8byte aligned in order to a void massive time penalties.
00100   // They're accessed via a base register which holds the 8byte aligned value
00101   // of ebp. The byte-offset of the first float must be a multiple of floatSize
00102   // => need an extra filler word besides the Floats::magic value.
00103   //
00104   // base - 1: Floats::magic
00105   // base - 2: filler word - undefined
00106   // base - 3: (global) float 0 hi word
00107   // base - 4: (global) float 0 lo word
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 // context temporaries
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   // computes the byte offset within the context object
00130   return tempNo*oopSize + contextOopDesc::temp0_byte_offset();
00131 }
00132 
00133 
00134 // predicates
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 // helper functions for code generation
00151 void Mapping::load(Location src, Register dst) {
00152   switch (src.mode()) {
00153     case specialLoc: {
00154       if (src == resultOfNLR) {
00155         // treat as NLR_result_reg
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       // nothing to do, value is on stack already
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       // nothing to do, value is on stack already
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

Generated on Mon Oct 9 13:37:30 2006 for Strongtalk VM by  doxygen 1.4.7