floats.cpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996, LongView Technologies L.L.C. $Revision: 1.12 $ */
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 # include "incls/_floats.cpp.incl"
00026 
00027 
00028 char* Floats::_function_table[max_number_of_functions];
00029 char* Floats::_function_names[] = {
00030   "zero", "one",
00031   "abs", "negated", "squared", "sqrt", "sin", "cos", "tan", "exp", "ln",
00032   "add", "subtract", "multiply", "divide", "modulo",
00033   "is_zero", "is_not_zero", "oopify",
00034   "is_equal", "is_not_equal", "is_less", "is_less_equal", "is_greater", "is_greater_equal"
00035 };
00036 
00037 
00038 char* Floats::function_name_for(Function f) {
00039   assert(0 <= f && f < number_of_functions, "illegal function");
00040   return _function_names[f];
00041 }
00042 
00043 
00044 bool Floats::has_selector_for(Function f) {
00045   if (f == undefined)   return false;
00046   if (f == zero)        return false;
00047   if (f == one)         return false;
00048   return true;
00049 }
00050 
00051 
00052 symbolOop Floats::selector_for(Function f) {
00053   switch(f) {
00054     case abs             : return vmSymbols::abs();                     break;
00055     case negated         : return vmSymbols::negated();                 break;
00056     case squared         : return vmSymbols::squared();                 break;
00057     case sqrt            : return vmSymbols::sqrt();                    break;
00058     case sin             : return vmSymbols::sin();                     break;
00059     case cos             : return vmSymbols::cos();                     break;
00060     case tan             : return vmSymbols::tan();                     break;
00061     case exp             : return vmSymbols::exp();                     break;
00062     case ln              : return vmSymbols::ln();                      break;
00063     case add             : return vmSymbols::plus();                    break;
00064     case subtract        : return vmSymbols::minus();                   break;
00065     case multiply        : return vmSymbols::multiply();                break;
00066     case divide          : return vmSymbols::divide();                  break;
00067     case modulo          : return vmSymbols::mod();                     break;
00068     case is_zero         : return vmSymbols::equal();                   break;
00069     case is_not_zero     : return vmSymbols::not_equal();               break;
00070     case oopify          : return vmSymbols::as_float();                break;
00071     case is_equal        : return vmSymbols::equal();                   break;
00072     case is_not_equal    : return vmSymbols::not_equal();               break;
00073     case is_less         : return vmSymbols::less_than();               break;
00074     case is_less_equal   : return vmSymbols::less_than_or_equal();      break;
00075     case is_greater      : return vmSymbols::greater_than();            break;
00076     case is_greater_equal: return vmSymbols::greater_than_or_equal();   break;
00077     case floatify        : return vmSymbols::as_float_value();          break;
00078   }
00079   return NULL;
00080 }
00081 
00082 
00083 // Initialization/debugging
00084 
00085 void Floats::generate_tst(MacroAssembler* masm, Assembler::Condition cc) {
00086   int mask;
00087   Assembler::Condition cond;
00088   MacroAssembler::fpu_mask_and_cond_for(cc, mask, cond);
00089   Label L;
00090   masm->int3(); // remove this if it works
00091   masm->ftst();
00092   masm->fwait();
00093   masm->fnstsw_ax();
00094   masm->fpop();         // explicitly pop argument
00095   masm->testl(eax, mask);
00096   masm->movl(eax, Address((int)&trueObj, relocInfo::external_word_type));
00097   masm->jcc(cond, L);
00098   masm->movl(eax, Address((int)&falseObj, relocInfo::external_word_type));
00099   masm->bind(L);
00100 }
00101 
00102 
00103 void Floats::generate_cmp(MacroAssembler* masm, Assembler::Condition cc) {
00104   int mask;
00105   Assembler::Condition cond;
00106   MacroAssembler::fpu_mask_and_cond_for(cc, mask, cond);
00107   Label L;
00108   masm->fcompp();
00109   masm->fwait();
00110   masm->fnstsw_ax();
00111   masm->testl(eax, mask);
00112   masm->movl(eax, Address((int)&trueObj, relocInfo::external_word_type));
00113   masm->jcc(cond, L);
00114   masm->movl(eax, Address((int)&falseObj, relocInfo::external_word_type));
00115   masm->bind(L);
00116 }
00117 
00118 
00119 void Floats::generate(MacroAssembler* masm, Function f) {
00120   char* entry_point = masm->pc();
00121   switch (f) {
00122     // nullary functions
00123     case zero            : masm->fldz();                                break;
00124     case one             : masm->fld1();                                break;
00125 
00126     // unary functions
00127     case abs             : masm->fabs();                                break;
00128     case negated         : masm->fchs();                                break;
00129     case squared         : masm->fmul(0);                               break;
00130     case sqrt            : masm->int3(); /* Unimplemented */            break;
00131     case sin             : masm->int3(); /* Unimplemented */            break;
00132     case cos             : masm->int3(); /* Unimplemented */            break;
00133     case tan             : masm->int3(); /* Unimplemented */            break;
00134     case exp             : masm->int3(); /* Unimplemented */            break;
00135     case ln              : masm->int3(); /* Unimplemented */            break;
00136 
00137     // binary functions
00138     case add             : masm->faddp();                               break;
00139     case subtract        : masm->fsubp();                               break;
00140     case multiply        : masm->fmulp();                               break;
00141     case divide          : masm->fdivp();                               break;
00142     case modulo          : masm->fxch(); masm->fprem();                 break;
00143 
00144     // unary functions to oop
00145     case is_zero         : generate_tst(masm, Assembler::zero);         break;
00146     case is_not_zero     : generate_tst(masm, Assembler::notZero);      break;
00147     case oopify          : masm->hlt(); /* see InterpreterGenerator */  break;
00148 
00149     // binary functions to oop
00150     // (Note: This is comparing ST(1) with ST while the bits in the FPU
00151     //        status word (assume comparison of ST with ST(1) -> reverse
00152     //        the conditions).
00153     case is_equal        : generate_cmp(masm, Assembler::equal);        break;
00154     case is_not_equal    : generate_cmp(masm, Assembler::notEqual);     break;
00155     case is_less         : generate_cmp(masm, Assembler::greater);      break;
00156     case is_less_equal   : generate_cmp(masm, Assembler::greaterEqual); break;
00157     case is_greater      : generate_cmp(masm, Assembler::less);         break;
00158     case is_greater_equal: generate_cmp(masm, Assembler::lessEqual);    break;
00159 
00160     default              : ShouldNotReachHere();
00161   }
00162   masm->ret(0);
00163   _function_table[f] = entry_point;
00164 
00165   if (!Disclaimer::is_product() && PrintInterpreter) {
00166     int length = masm->pc() - entry_point;
00167     char* name = function_name_for(f);
00168     std->print("Float function %d: %s (%d bytes), entry point = 0x%x\n", f, name, length, entry_point);
00169     masm->code()->decode();
00170     std->cr();
00171   }
00172 }
00173 
00174 
00175 bool Floats::_is_initialized = false;
00176 
00177 void Floats::init(MacroAssembler* masm) {
00178   if (is_initialized()) return;
00179 
00180   if (sizeof(_function_names) / sizeof(char*) != number_of_functions) {
00181     fatal("Floats: number of _functions_names not equal number_of_functions");
00182   }
00183 
00184   // pre-initialize whole table
00185   // (make sure there's an entry for each index so that illegal indices
00186   // can be caught during execution without additional index range check)
00187   for (int i = max_number_of_functions; i-- > 0;) _function_table[i] = masm->pc();
00188   masm->hlt();
00189   if (!Disclaimer::is_product() && PrintInterpreter) {
00190     std->print("Undefined float functions entry point\n");
00191     masm->code()->decode();
00192     std->cr();
00193   }
00194 
00195   // nullary functions
00196   generate(masm, zero);
00197   generate(masm, one);
00198 
00199   // unary functions
00200   generate(masm, abs);
00201   generate(masm, negated);
00202   generate(masm, squared);
00203   generate(masm, sqrt);
00204   generate(masm, sin);
00205   generate(masm, cos);
00206   generate(masm, tan);
00207   generate(masm, exp);
00208   generate(masm, ln);
00209   
00210   // binary functions
00211   generate(masm, add);
00212   generate(masm, subtract);
00213   generate(masm, multiply);
00214   generate(masm, divide);
00215   generate(masm, modulo);
00216   
00217   // unary functions to oop
00218   generate(masm, oopify);
00219   generate(masm, is_zero);
00220   generate(masm, is_not_zero);
00221   
00222   // binary functions to oop
00223   generate(masm, is_equal);
00224   generate(masm, is_not_equal);
00225   generate(masm, is_less);
00226   generate(masm, is_less_equal);
00227   generate(masm, is_greater);
00228   generate(masm, is_greater_equal);
00229   
00230   _is_initialized = true;
00231 }
00232 
00233 
00234 void Floats::print() {
00235   if (_is_initialized) {
00236     std->print_cr("Float functions:");
00237     for (int i = 0; i < number_of_functions; i++) {
00238       std->print("%3d: 0x%x %s\n", i, _function_table[i], function_name_for(Function(i)));
00239     }
00240   } else {
00241     std->print_cr("Floats not yet initialized");
00242   }
00243   std->cr();
00244 }

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