| OLD | NEW | 
|    1 // Copyright 2015 the V8 project authors. All rights reserved. |    1 // Copyright 2015 the V8 project authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "src/s390/codegen-s390.h" |    5 #include "src/s390/codegen-s390.h" | 
|    6  |    6  | 
|    7 #if V8_TARGET_ARCH_S390 |    7 #if V8_TARGET_ARCH_S390 | 
|    8  |    8  | 
|    9 #include "src/codegen.h" |    9 #include "src/codegen.h" | 
|   10 #include "src/macro-assembler.h" |   10 #include "src/macro-assembler.h" | 
|   11 #include "src/s390/simulator-s390.h" |   11 #include "src/s390/simulator-s390.h" | 
|   12  |   12  | 
|   13 namespace v8 { |   13 namespace v8 { | 
|   14 namespace internal { |   14 namespace internal { | 
|   15  |   15  | 
|   16 #define __ masm. |   16 #define __ masm. | 
|   17  |   17  | 
|   18 #if defined(USE_SIMULATOR) |  | 
|   19 byte* fast_exp_s390_machine_code = nullptr; |  | 
|   20 double fast_exp_simulator(double x, Isolate* isolate) { |  | 
|   21   return Simulator::current(isolate)->CallFPReturnsDouble( |  | 
|   22       fast_exp_s390_machine_code, x, 0); |  | 
|   23 } |  | 
|   24 #endif |  | 
|   25  |  | 
|   26 UnaryMathFunctionWithIsolate CreateExpFunction(Isolate* isolate) { |  | 
|   27   size_t actual_size; |  | 
|   28   byte* buffer = |  | 
|   29       static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); |  | 
|   30   if (buffer == nullptr) return nullptr; |  | 
|   31   ExternalReference::InitializeMathExpData(); |  | 
|   32  |  | 
|   33   MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size), |  | 
|   34                       CodeObjectRequired::kNo); |  | 
|   35  |  | 
|   36   { |  | 
|   37     DoubleRegister input = d0; |  | 
|   38     DoubleRegister result = d2; |  | 
|   39     DoubleRegister double_scratch1 = d3; |  | 
|   40     DoubleRegister double_scratch2 = d4; |  | 
|   41     Register temp1 = r6; |  | 
|   42     Register temp2 = r7; |  | 
|   43     Register temp3 = r8; |  | 
|   44  |  | 
|   45     __ Push(temp3, temp2, temp1); |  | 
|   46     MathExpGenerator::EmitMathExp(&masm, input, result, double_scratch1, |  | 
|   47                                   double_scratch2, temp1, temp2, temp3); |  | 
|   48     __ Pop(temp3, temp2, temp1); |  | 
|   49     __ ldr(d0, result); |  | 
|   50     __ Ret(); |  | 
|   51   } |  | 
|   52  |  | 
|   53   CodeDesc desc; |  | 
|   54   masm.GetCode(&desc); |  | 
|   55   DCHECK(ABI_USES_FUNCTION_DESCRIPTORS || !RelocInfo::RequiresRelocation(desc)); |  | 
|   56  |  | 
|   57   Assembler::FlushICache(isolate, buffer, actual_size); |  | 
|   58   base::OS::ProtectCode(buffer, actual_size); |  | 
|   59  |  | 
|   60 #if !defined(USE_SIMULATOR) |  | 
|   61   return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer); |  | 
|   62 #else |  | 
|   63   fast_exp_s390_machine_code = buffer; |  | 
|   64   return &fast_exp_simulator; |  | 
|   65 #endif |  | 
|   66 } |  | 
|   67  |  | 
|   68 UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) { |   18 UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) { | 
|   69 #if defined(USE_SIMULATOR) |   19 #if defined(USE_SIMULATOR) | 
|   70   return nullptr; |   20   return nullptr; | 
|   71 #else |   21 #else | 
|   72   size_t actual_size; |   22   size_t actual_size; | 
|   73   byte* buffer = |   23   byte* buffer = | 
|   74       static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); |   24       static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); | 
|   75   if (buffer == nullptr) return nullptr; |   25   if (buffer == nullptr) return nullptr; | 
|   76  |   26  | 
|   77   MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size), |   27   MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size), | 
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  500   // Two-byte string. |  450   // Two-byte string. | 
|  501   __ ShiftLeftP(result, index, Operand(1)); |  451   __ ShiftLeftP(result, index, Operand(1)); | 
|  502   __ LoadLogicalHalfWordP(result, MemOperand(string, result)); |  452   __ LoadLogicalHalfWordP(result, MemOperand(string, result)); | 
|  503   __ b(&done, Label::kNear); |  453   __ b(&done, Label::kNear); | 
|  504   __ bind(&one_byte); |  454   __ bind(&one_byte); | 
|  505   // One-byte string. |  455   // One-byte string. | 
|  506   __ LoadlB(result, MemOperand(string, index)); |  456   __ LoadlB(result, MemOperand(string, index)); | 
|  507   __ bind(&done); |  457   __ bind(&done); | 
|  508 } |  458 } | 
|  509  |  459  | 
|  510 static MemOperand ExpConstant(int index, Register base) { |  | 
|  511   return MemOperand(base, index * kDoubleSize); |  | 
|  512 } |  | 
|  513  |  | 
|  514 void MathExpGenerator::EmitMathExp(MacroAssembler* masm, DoubleRegister input, |  | 
|  515                                    DoubleRegister result, |  | 
|  516                                    DoubleRegister double_scratch1, |  | 
|  517                                    DoubleRegister double_scratch2, |  | 
|  518                                    Register temp1, Register temp2, |  | 
|  519                                    Register temp3) { |  | 
|  520   DCHECK(!input.is(result)); |  | 
|  521   DCHECK(!input.is(double_scratch1)); |  | 
|  522   DCHECK(!input.is(double_scratch2)); |  | 
|  523   DCHECK(!result.is(double_scratch1)); |  | 
|  524   DCHECK(!result.is(double_scratch2)); |  | 
|  525   DCHECK(!double_scratch1.is(double_scratch2)); |  | 
|  526   DCHECK(!temp1.is(temp2)); |  | 
|  527   DCHECK(!temp1.is(temp3)); |  | 
|  528   DCHECK(!temp2.is(temp3)); |  | 
|  529   DCHECK(ExternalReference::math_exp_constants(0).address() != NULL); |  | 
|  530   DCHECK(!masm->serializer_enabled());  // External references not serializable. |  | 
|  531  |  | 
|  532   Label zero, infinity, done; |  | 
|  533  |  | 
|  534   __ mov(temp3, Operand(ExternalReference::math_exp_constants(0))); |  | 
|  535  |  | 
|  536   __ LoadDouble(double_scratch1, ExpConstant(0, temp3)); |  | 
|  537   __ cdbr(double_scratch1, input); |  | 
|  538   __ ldr(result, input); |  | 
|  539   __ bunordered(&done, Label::kNear); |  | 
|  540   __ bge(&zero, Label::kNear); |  | 
|  541  |  | 
|  542   __ LoadDouble(double_scratch2, ExpConstant(1, temp3)); |  | 
|  543   __ cdbr(input, double_scratch2); |  | 
|  544   __ bge(&infinity, Label::kNear); |  | 
|  545  |  | 
|  546   __ LoadDouble(double_scratch1, ExpConstant(3, temp3)); |  | 
|  547   __ LoadDouble(result, ExpConstant(4, temp3)); |  | 
|  548  |  | 
|  549   // Do not generate madbr, as intermediate result are not |  | 
|  550   // rounded properly |  | 
|  551   __ mdbr(double_scratch1, input); |  | 
|  552   __ adbr(double_scratch1, result); |  | 
|  553  |  | 
|  554   // Move low word of double_scratch1 to temp2 |  | 
|  555   __ lgdr(temp2, double_scratch1); |  | 
|  556   __ nihf(temp2, Operand::Zero()); |  | 
|  557  |  | 
|  558   __ sdbr(double_scratch1, result); |  | 
|  559   __ LoadDouble(result, ExpConstant(6, temp3)); |  | 
|  560   __ LoadDouble(double_scratch2, ExpConstant(5, temp3)); |  | 
|  561   __ mdbr(double_scratch1, double_scratch2); |  | 
|  562   __ sdbr(double_scratch1, input); |  | 
|  563   __ sdbr(result, double_scratch1); |  | 
|  564   __ ldr(double_scratch2, double_scratch1); |  | 
|  565   __ mdbr(double_scratch2, double_scratch2); |  | 
|  566   __ mdbr(result, double_scratch2); |  | 
|  567   __ LoadDouble(double_scratch2, ExpConstant(7, temp3)); |  | 
|  568   __ mdbr(result, double_scratch2); |  | 
|  569   __ sdbr(result, double_scratch1); |  | 
|  570   __ LoadDouble(double_scratch2, ExpConstant(8, temp3)); |  | 
|  571   __ adbr(result, double_scratch2); |  | 
|  572   __ ShiftRight(temp1, temp2, Operand(11)); |  | 
|  573   __ AndP(temp2, Operand(0x7ff)); |  | 
|  574   __ AddP(temp1, Operand(0x3ff)); |  | 
|  575  |  | 
|  576   // Must not call ExpConstant() after overwriting temp3! |  | 
|  577   __ mov(temp3, Operand(ExternalReference::math_exp_log_table())); |  | 
|  578   __ ShiftLeft(temp2, temp2, Operand(3)); |  | 
|  579  |  | 
|  580   __ lg(temp2, MemOperand(temp2, temp3)); |  | 
|  581   __ sllg(temp1, temp1, Operand(52)); |  | 
|  582   __ ogr(temp2, temp1); |  | 
|  583   __ ldgr(double_scratch1, temp2); |  | 
|  584  |  | 
|  585   __ mdbr(result, double_scratch1); |  | 
|  586   __ b(&done, Label::kNear); |  | 
|  587  |  | 
|  588   __ bind(&zero); |  | 
|  589   __ lzdr(kDoubleRegZero); |  | 
|  590   __ ldr(result, kDoubleRegZero); |  | 
|  591   __ b(&done, Label::kNear); |  | 
|  592  |  | 
|  593   __ bind(&infinity); |  | 
|  594   __ LoadDouble(result, ExpConstant(2, temp3)); |  | 
|  595  |  | 
|  596   __ bind(&done); |  | 
|  597 } |  | 
|  598  |  | 
|  599 #undef __ |  460 #undef __ | 
|  600  |  461  | 
|  601 CodeAgingHelper::CodeAgingHelper(Isolate* isolate) { |  462 CodeAgingHelper::CodeAgingHelper(Isolate* isolate) { | 
|  602   USE(isolate); |  463   USE(isolate); | 
|  603   DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength); |  464   DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength); | 
|  604   // Since patcher is a large object, allocate it dynamically when needed, |  465   // Since patcher is a large object, allocate it dynamically when needed, | 
|  605   // to avoid overloading the stack in stress conditions. |  466   // to avoid overloading the stack in stress conditions. | 
|  606   // DONT_FLUSH is used because the CodeAgingHelper is initialized early in |  467   // DONT_FLUSH is used because the CodeAgingHelper is initialized early in | 
|  607   // the process, before ARM simulator ICache is setup. |  468   // the process, before ARM simulator ICache is setup. | 
|  608   base::SmartPointer<CodePatcher> patcher( |  469   base::SmartPointer<CodePatcher> patcher( | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  666       //       (kNoCodeAgeSequenceLength - kCodeAgingSequenceLength) bytes. |  527       //       (kNoCodeAgeSequenceLength - kCodeAgingSequenceLength) bytes. | 
|  667       patcher.masm()->nop();  // 2-byte nops(). |  528       patcher.masm()->nop();  // 2-byte nops(). | 
|  668     } |  529     } | 
|  669   } |  530   } | 
|  670 } |  531 } | 
|  671  |  532  | 
|  672 }  // namespace internal |  533 }  // namespace internal | 
|  673 }  // namespace v8 |  534 }  // namespace v8 | 
|  674  |  535  | 
|  675 #endif  // V8_TARGET_ARCH_S390 |  536 #endif  // V8_TARGET_ARCH_S390 | 
| OLD | NEW |