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 # 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
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();
00091 masm->ftst();
00092 masm->fwait();
00093 masm->fnstsw_ax();
00094 masm->fpop();
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
00123 case zero : masm->fldz(); break;
00124 case one : masm->fld1(); break;
00125
00126
00127 case abs : masm->fabs(); break;
00128 case negated : masm->fchs(); break;
00129 case squared : masm->fmul(0); break;
00130 case sqrt : masm->int3(); break;
00131 case sin : masm->int3(); break;
00132 case cos : masm->int3(); break;
00133 case tan : masm->int3(); break;
00134 case exp : masm->int3(); break;
00135 case ln : masm->int3(); break;
00136
00137
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
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(); break;
00148
00149
00150
00151
00152
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
00185
00186
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
00196 generate(masm, zero);
00197 generate(masm, one);
00198
00199
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
00211 generate(masm, add);
00212 generate(masm, subtract);
00213 generate(masm, multiply);
00214 generate(masm, divide);
00215 generate(masm, modulo);
00216
00217
00218 generate(masm, oopify);
00219 generate(masm, is_zero);
00220 generate(masm, is_not_zero);
00221
00222
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 }