PPC/s390: [builtins] Introduce proper Float64Exp operator.
Port d5f2ac5e33
Original commit message:
Import base::ieee754::exp() from FreeBSD msun and introduce a Float64Exp
TurboFan operator based on that, similar to what we do for Float64Log.
Rewrite Math.exp() as TurboFan builtin and use that operator to also
inline Math.exp() into optimized TurboFan functions.
R=bmeurer@chromium.org, mvstanton@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com
BUG=v8:3266,v8:3468,v8:3493,v8:5086,v8:5108,chromium:620786
LOG=N
Review-Url: https://codereview.chromium.org/2075263002
Cr-Commit-Position: refs/heads/master@{#37073}
This commit is contained in:
parent
c781e83194
commit
a54e289e68
@ -1263,6 +1263,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
case kIeee754Float64Atan2:
|
||||
ASSEMBLE_IEEE754_BINOP(atan2);
|
||||
break;
|
||||
case kIeee754Float64Exp:
|
||||
ASSEMBLE_IEEE754_UNOP(exp);
|
||||
break;
|
||||
case kIeee754Float64Log:
|
||||
ASSEMBLE_IEEE754_UNOP(log);
|
||||
break;
|
||||
|
@ -1252,6 +1252,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
case kIeee754Float64Atan2:
|
||||
ASSEMBLE_IEEE754_BINOP(atan2);
|
||||
break;
|
||||
case kIeee754Float64Exp:
|
||||
ASSEMBLE_IEEE754_UNOP(exp);
|
||||
break;
|
||||
case kIeee754Float64Log:
|
||||
ASSEMBLE_IEEE754_UNOP(log);
|
||||
break;
|
||||
|
@ -3774,20 +3774,13 @@ void LCodeGen::DoPower(LPower* instr) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoMathExp(LMathExp* instr) {
|
||||
DoubleRegister input = ToDoubleRegister(instr->value());
|
||||
DoubleRegister result = ToDoubleRegister(instr->result());
|
||||
DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
|
||||
DoubleRegister double_scratch2 = double_scratch0();
|
||||
Register temp1 = ToRegister(instr->temp1());
|
||||
Register temp2 = ToRegister(instr->temp2());
|
||||
|
||||
MathExpGenerator::EmitMathExp(masm(), input, result, double_scratch1,
|
||||
double_scratch2, temp1, temp2, scratch0());
|
||||
__ PrepareCallCFunction(0, 1, scratch0());
|
||||
__ MovToFloatParameter(ToDoubleRegister(instr->value()));
|
||||
__ CallCFunction(ExternalReference::ieee754_exp_function(isolate()), 0, 1);
|
||||
__ MovFromFloatResult(ToDoubleRegister(instr->result()));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoMathLog(LMathLog* instr) {
|
||||
__ PrepareCallCFunction(0, 1, scratch0());
|
||||
__ MovToFloatParameter(ToDoubleRegister(instr->value()));
|
||||
@ -3795,7 +3788,6 @@ void LCodeGen::DoMathLog(LMathLog* instr) {
|
||||
__ MovFromFloatResult(ToDoubleRegister(instr->result()));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoMathClz32(LMathClz32* instr) {
|
||||
Register input = ToRegister(instr->value());
|
||||
Register result = ToRegister(instr->result());
|
||||
|
@ -1146,8 +1146,8 @@ LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
|
||||
LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
|
||||
DCHECK(instr->representation().IsDouble());
|
||||
DCHECK(instr->value()->representation().IsDouble());
|
||||
LOperand* input = UseFixedDouble(instr->value(), d1);
|
||||
return MarkAsCall(DefineFixedDouble(new (zone()) LMathLog(input), d1), instr);
|
||||
LOperand* input = UseFixedDouble(instr->value(), d0);
|
||||
return MarkAsCall(DefineFixedDouble(new (zone()) LMathLog(input), d0), instr);
|
||||
}
|
||||
|
||||
|
||||
@ -1161,12 +1161,8 @@ LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
|
||||
LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
|
||||
DCHECK(instr->representation().IsDouble());
|
||||
DCHECK(instr->value()->representation().IsDouble());
|
||||
LOperand* input = UseRegister(instr->value());
|
||||
LOperand* temp1 = TempRegister();
|
||||
LOperand* temp2 = TempRegister();
|
||||
LOperand* double_temp = TempDoubleRegister();
|
||||
LMathExp* result = new (zone()) LMathExp(input, double_temp, temp1, temp2);
|
||||
return DefineAsRegister(result);
|
||||
LOperand* input = UseFixedDouble(instr->value(), d0);
|
||||
return MarkAsCall(DefineFixedDouble(new (zone()) LMathExp(input), d0), instr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -902,21 +902,11 @@ class LMathClz32 final : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LMathExp final : public LTemplateInstruction<1, 1, 3> {
|
||||
class LMathExp final : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
LMathExp(LOperand* value, LOperand* double_temp, LOperand* temp1,
|
||||
LOperand* temp2) {
|
||||
inputs_[0] = value;
|
||||
temps_[0] = temp1;
|
||||
temps_[1] = temp2;
|
||||
temps_[2] = double_temp;
|
||||
ExternalReference::InitializeMathExpData();
|
||||
}
|
||||
explicit LMathExp(LOperand* value) { inputs_[0] = value; }
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
LOperand* temp1() { return temps_[0]; }
|
||||
LOperand* temp2() { return temps_[1]; }
|
||||
LOperand* double_temp() { return temps_[2]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
|
||||
};
|
||||
|
@ -3670,15 +3670,10 @@ void LCodeGen::DoPower(LPower* instr) {
|
||||
}
|
||||
|
||||
void LCodeGen::DoMathExp(LMathExp* instr) {
|
||||
DoubleRegister input = ToDoubleRegister(instr->value());
|
||||
DoubleRegister result = ToDoubleRegister(instr->result());
|
||||
DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
|
||||
DoubleRegister double_scratch2 = double_scratch0();
|
||||
Register temp1 = ToRegister(instr->temp1());
|
||||
Register temp2 = ToRegister(instr->temp2());
|
||||
|
||||
MathExpGenerator::EmitMathExp(masm(), input, result, double_scratch1,
|
||||
double_scratch2, temp1, temp2, scratch0());
|
||||
__ PrepareCallCFunction(0, 1, scratch0());
|
||||
__ MovToFloatParameter(ToDoubleRegister(instr->value()));
|
||||
__ CallCFunction(ExternalReference::ieee754_exp_function(isolate()), 0, 1);
|
||||
__ MovFromFloatResult(ToDoubleRegister(instr->result()));
|
||||
}
|
||||
|
||||
void LCodeGen::DoMathLog(LMathLog* instr) {
|
||||
|
@ -1034,8 +1034,8 @@ LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
|
||||
LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
|
||||
DCHECK(instr->representation().IsDouble());
|
||||
DCHECK(instr->value()->representation().IsDouble());
|
||||
LOperand* input = UseFixedDouble(instr->value(), d1);
|
||||
return MarkAsCall(DefineFixedDouble(new (zone()) LMathLog(input), d1), instr);
|
||||
LOperand* input = UseFixedDouble(instr->value(), d0);
|
||||
return MarkAsCall(DefineFixedDouble(new (zone()) LMathLog(input), d0), instr);
|
||||
}
|
||||
|
||||
LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
|
||||
@ -1047,12 +1047,8 @@ LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
|
||||
LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
|
||||
DCHECK(instr->representation().IsDouble());
|
||||
DCHECK(instr->value()->representation().IsDouble());
|
||||
LOperand* input = UseRegister(instr->value());
|
||||
LOperand* temp1 = TempRegister();
|
||||
LOperand* temp2 = TempRegister();
|
||||
LOperand* double_temp = TempDoubleRegister();
|
||||
LMathExp* result = new (zone()) LMathExp(input, double_temp, temp1, temp2);
|
||||
return DefineAsRegister(result);
|
||||
LOperand* input = UseFixedDouble(instr->value(), d0);
|
||||
return MarkAsCall(DefineFixedDouble(new (zone()) LMathExp(input), d0), instr);
|
||||
}
|
||||
|
||||
LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
|
||||
|
@ -836,21 +836,11 @@ class LMathClz32 final : public LTemplateInstruction<1, 1, 0> {
|
||||
DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32")
|
||||
};
|
||||
|
||||
class LMathExp final : public LTemplateInstruction<1, 1, 3> {
|
||||
class LMathExp final : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
LMathExp(LOperand* value, LOperand* double_temp, LOperand* temp1,
|
||||
LOperand* temp2) {
|
||||
inputs_[0] = value;
|
||||
temps_[0] = temp1;
|
||||
temps_[1] = temp2;
|
||||
temps_[2] = double_temp;
|
||||
ExternalReference::InitializeMathExpData();
|
||||
}
|
||||
explicit LMathExp(LOperand* value) { inputs_[0] = value; }
|
||||
|
||||
LOperand* value() { return inputs_[0]; }
|
||||
LOperand* temp1() { return temps_[0]; }
|
||||
LOperand* temp2() { return temps_[1]; }
|
||||
LOperand* double_temp() { return temps_[2]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
|
||||
};
|
||||
|
@ -16,62 +16,6 @@ namespace internal {
|
||||
|
||||
#define __ masm.
|
||||
|
||||
|
||||
#if defined(USE_SIMULATOR)
|
||||
byte* fast_exp_ppc_machine_code = nullptr;
|
||||
double fast_exp_simulator(double x, Isolate* isolate) {
|
||||
return Simulator::current(isolate)
|
||||
->CallFPReturnsDouble(fast_exp_ppc_machine_code, x, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
UnaryMathFunctionWithIsolate CreateExpFunction(Isolate* isolate) {
|
||||
size_t actual_size;
|
||||
byte* buffer =
|
||||
static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
|
||||
if (buffer == nullptr) return nullptr;
|
||||
ExternalReference::InitializeMathExpData();
|
||||
|
||||
MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size),
|
||||
CodeObjectRequired::kNo);
|
||||
|
||||
{
|
||||
DoubleRegister input = d1;
|
||||
DoubleRegister result = d2;
|
||||
DoubleRegister double_scratch1 = d3;
|
||||
DoubleRegister double_scratch2 = d4;
|
||||
Register temp1 = r7;
|
||||
Register temp2 = r8;
|
||||
Register temp3 = r9;
|
||||
|
||||
// Called from C
|
||||
__ function_descriptor();
|
||||
|
||||
__ Push(temp3, temp2, temp1);
|
||||
MathExpGenerator::EmitMathExp(&masm, input, result, double_scratch1,
|
||||
double_scratch2, temp1, temp2, temp3);
|
||||
__ Pop(temp3, temp2, temp1);
|
||||
__ fmr(d1, result);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
CodeDesc desc;
|
||||
masm.GetCode(&desc);
|
||||
DCHECK(ABI_USES_FUNCTION_DESCRIPTORS || !RelocInfo::RequiresRelocation(desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, actual_size);
|
||||
base::OS::ProtectCode(buffer, actual_size);
|
||||
|
||||
#if !defined(USE_SIMULATOR)
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
#else
|
||||
fast_exp_ppc_machine_code = buffer;
|
||||
return &fast_exp_simulator;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
#if defined(USE_SIMULATOR)
|
||||
return nullptr;
|
||||
@ -513,96 +457,6 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, Register string,
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
|
||||
static MemOperand ExpConstant(int index, Register base) {
|
||||
return MemOperand(base, index * kDoubleSize);
|
||||
}
|
||||
|
||||
|
||||
void MathExpGenerator::EmitMathExp(MacroAssembler* masm, DoubleRegister input,
|
||||
DoubleRegister result,
|
||||
DoubleRegister double_scratch1,
|
||||
DoubleRegister double_scratch2,
|
||||
Register temp1, Register temp2,
|
||||
Register temp3) {
|
||||
DCHECK(!input.is(result));
|
||||
DCHECK(!input.is(double_scratch1));
|
||||
DCHECK(!input.is(double_scratch2));
|
||||
DCHECK(!result.is(double_scratch1));
|
||||
DCHECK(!result.is(double_scratch2));
|
||||
DCHECK(!double_scratch1.is(double_scratch2));
|
||||
DCHECK(!temp1.is(temp2));
|
||||
DCHECK(!temp1.is(temp3));
|
||||
DCHECK(!temp2.is(temp3));
|
||||
DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
|
||||
DCHECK(!masm->serializer_enabled()); // External references not serializable.
|
||||
|
||||
Label zero, infinity, done;
|
||||
|
||||
__ mov(temp3, Operand(ExternalReference::math_exp_constants(0)));
|
||||
|
||||
__ lfd(double_scratch1, ExpConstant(0, temp3));
|
||||
__ fcmpu(double_scratch1, input);
|
||||
__ fmr(result, input);
|
||||
__ bunordered(&done);
|
||||
__ bge(&zero);
|
||||
|
||||
__ lfd(double_scratch2, ExpConstant(1, temp3));
|
||||
__ fcmpu(input, double_scratch2);
|
||||
__ bge(&infinity);
|
||||
|
||||
__ lfd(double_scratch1, ExpConstant(3, temp3));
|
||||
__ lfd(result, ExpConstant(4, temp3));
|
||||
__ fmul(double_scratch1, double_scratch1, input);
|
||||
__ fadd(double_scratch1, double_scratch1, result);
|
||||
__ MovDoubleLowToInt(temp2, double_scratch1);
|
||||
__ fsub(double_scratch1, double_scratch1, result);
|
||||
__ lfd(result, ExpConstant(6, temp3));
|
||||
__ lfd(double_scratch2, ExpConstant(5, temp3));
|
||||
__ fmul(double_scratch1, double_scratch1, double_scratch2);
|
||||
__ fsub(double_scratch1, double_scratch1, input);
|
||||
__ fsub(result, result, double_scratch1);
|
||||
__ fmul(double_scratch2, double_scratch1, double_scratch1);
|
||||
__ fmul(result, result, double_scratch2);
|
||||
__ lfd(double_scratch2, ExpConstant(7, temp3));
|
||||
__ fmul(result, result, double_scratch2);
|
||||
__ fsub(result, result, double_scratch1);
|
||||
__ lfd(double_scratch2, ExpConstant(8, temp3));
|
||||
__ fadd(result, result, double_scratch2);
|
||||
__ srwi(temp1, temp2, Operand(11));
|
||||
__ andi(temp2, temp2, Operand(0x7ff));
|
||||
__ addi(temp1, temp1, Operand(0x3ff));
|
||||
|
||||
// Must not call ExpConstant() after overwriting temp3!
|
||||
__ mov(temp3, Operand(ExternalReference::math_exp_log_table()));
|
||||
__ slwi(temp2, temp2, Operand(3));
|
||||
#if V8_TARGET_ARCH_PPC64
|
||||
__ ldx(temp2, MemOperand(temp3, temp2));
|
||||
__ sldi(temp1, temp1, Operand(52));
|
||||
__ orx(temp2, temp1, temp2);
|
||||
__ MovInt64ToDouble(double_scratch1, temp2);
|
||||
#else
|
||||
__ add(ip, temp3, temp2);
|
||||
__ lwz(temp3, MemOperand(ip, Register::kExponentOffset));
|
||||
__ lwz(temp2, MemOperand(ip, Register::kMantissaOffset));
|
||||
__ slwi(temp1, temp1, Operand(20));
|
||||
__ orx(temp3, temp1, temp3);
|
||||
__ MovInt64ToDouble(double_scratch1, temp3, temp2);
|
||||
#endif
|
||||
|
||||
__ fmul(result, result, double_scratch1);
|
||||
__ b(&done);
|
||||
|
||||
__ bind(&zero);
|
||||
__ fmr(result, kDoubleRegZero);
|
||||
__ b(&done);
|
||||
|
||||
__ bind(&infinity);
|
||||
__ lfd(result, ExpConstant(2, temp3));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
CodeAgingHelper::CodeAgingHelper(Isolate* isolate) {
|
||||
|
@ -23,18 +23,6 @@ class StringCharLoadGenerator : public AllStatic {
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(StringCharLoadGenerator);
|
||||
};
|
||||
|
||||
class MathExpGenerator : public AllStatic {
|
||||
public:
|
||||
// Register input isn't modified. All other registers are clobbered.
|
||||
static void EmitMathExp(MacroAssembler* masm, DoubleRegister input,
|
||||
DoubleRegister result, DoubleRegister double_scratch1,
|
||||
DoubleRegister double_scratch2, Register temp1,
|
||||
Register temp2, Register temp3);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(MathExpGenerator);
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -15,56 +15,6 @@ namespace internal {
|
||||
|
||||
#define __ masm.
|
||||
|
||||
#if defined(USE_SIMULATOR)
|
||||
byte* fast_exp_s390_machine_code = nullptr;
|
||||
double fast_exp_simulator(double x, Isolate* isolate) {
|
||||
return Simulator::current(isolate)->CallFPReturnsDouble(
|
||||
fast_exp_s390_machine_code, x, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
UnaryMathFunctionWithIsolate CreateExpFunction(Isolate* isolate) {
|
||||
size_t actual_size;
|
||||
byte* buffer =
|
||||
static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
|
||||
if (buffer == nullptr) return nullptr;
|
||||
ExternalReference::InitializeMathExpData();
|
||||
|
||||
MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size),
|
||||
CodeObjectRequired::kNo);
|
||||
|
||||
{
|
||||
DoubleRegister input = d0;
|
||||
DoubleRegister result = d2;
|
||||
DoubleRegister double_scratch1 = d3;
|
||||
DoubleRegister double_scratch2 = d4;
|
||||
Register temp1 = r6;
|
||||
Register temp2 = r7;
|
||||
Register temp3 = r8;
|
||||
|
||||
__ Push(temp3, temp2, temp1);
|
||||
MathExpGenerator::EmitMathExp(&masm, input, result, double_scratch1,
|
||||
double_scratch2, temp1, temp2, temp3);
|
||||
__ Pop(temp3, temp2, temp1);
|
||||
__ ldr(d0, result);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
CodeDesc desc;
|
||||
masm.GetCode(&desc);
|
||||
DCHECK(ABI_USES_FUNCTION_DESCRIPTORS || !RelocInfo::RequiresRelocation(desc));
|
||||
|
||||
Assembler::FlushICache(isolate, buffer, actual_size);
|
||||
base::OS::ProtectCode(buffer, actual_size);
|
||||
|
||||
#if !defined(USE_SIMULATOR)
|
||||
return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
||||
#else
|
||||
fast_exp_s390_machine_code = buffer;
|
||||
return &fast_exp_simulator;
|
||||
#endif
|
||||
}
|
||||
|
||||
UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
||||
#if defined(USE_SIMULATOR)
|
||||
return nullptr;
|
||||
@ -507,95 +457,6 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, Register string,
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
static MemOperand ExpConstant(int index, Register base) {
|
||||
return MemOperand(base, index * kDoubleSize);
|
||||
}
|
||||
|
||||
void MathExpGenerator::EmitMathExp(MacroAssembler* masm, DoubleRegister input,
|
||||
DoubleRegister result,
|
||||
DoubleRegister double_scratch1,
|
||||
DoubleRegister double_scratch2,
|
||||
Register temp1, Register temp2,
|
||||
Register temp3) {
|
||||
DCHECK(!input.is(result));
|
||||
DCHECK(!input.is(double_scratch1));
|
||||
DCHECK(!input.is(double_scratch2));
|
||||
DCHECK(!result.is(double_scratch1));
|
||||
DCHECK(!result.is(double_scratch2));
|
||||
DCHECK(!double_scratch1.is(double_scratch2));
|
||||
DCHECK(!temp1.is(temp2));
|
||||
DCHECK(!temp1.is(temp3));
|
||||
DCHECK(!temp2.is(temp3));
|
||||
DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
|
||||
DCHECK(!masm->serializer_enabled()); // External references not serializable.
|
||||
|
||||
Label zero, infinity, done;
|
||||
|
||||
__ mov(temp3, Operand(ExternalReference::math_exp_constants(0)));
|
||||
|
||||
__ LoadDouble(double_scratch1, ExpConstant(0, temp3));
|
||||
__ cdbr(double_scratch1, input);
|
||||
__ ldr(result, input);
|
||||
__ bunordered(&done, Label::kNear);
|
||||
__ bge(&zero, Label::kNear);
|
||||
|
||||
__ LoadDouble(double_scratch2, ExpConstant(1, temp3));
|
||||
__ cdbr(input, double_scratch2);
|
||||
__ bge(&infinity, Label::kNear);
|
||||
|
||||
__ LoadDouble(double_scratch1, ExpConstant(3, temp3));
|
||||
__ LoadDouble(result, ExpConstant(4, temp3));
|
||||
|
||||
// Do not generate madbr, as intermediate result are not
|
||||
// rounded properly
|
||||
__ mdbr(double_scratch1, input);
|
||||
__ adbr(double_scratch1, result);
|
||||
|
||||
// Move low word of double_scratch1 to temp2
|
||||
__ lgdr(temp2, double_scratch1);
|
||||
__ nihf(temp2, Operand::Zero());
|
||||
|
||||
__ sdbr(double_scratch1, result);
|
||||
__ LoadDouble(result, ExpConstant(6, temp3));
|
||||
__ LoadDouble(double_scratch2, ExpConstant(5, temp3));
|
||||
__ mdbr(double_scratch1, double_scratch2);
|
||||
__ sdbr(double_scratch1, input);
|
||||
__ sdbr(result, double_scratch1);
|
||||
__ ldr(double_scratch2, double_scratch1);
|
||||
__ mdbr(double_scratch2, double_scratch2);
|
||||
__ mdbr(result, double_scratch2);
|
||||
__ LoadDouble(double_scratch2, ExpConstant(7, temp3));
|
||||
__ mdbr(result, double_scratch2);
|
||||
__ sdbr(result, double_scratch1);
|
||||
__ LoadDouble(double_scratch2, ExpConstant(8, temp3));
|
||||
__ adbr(result, double_scratch2);
|
||||
__ ShiftRight(temp1, temp2, Operand(11));
|
||||
__ AndP(temp2, Operand(0x7ff));
|
||||
__ AddP(temp1, Operand(0x3ff));
|
||||
|
||||
// Must not call ExpConstant() after overwriting temp3!
|
||||
__ mov(temp3, Operand(ExternalReference::math_exp_log_table()));
|
||||
__ ShiftLeft(temp2, temp2, Operand(3));
|
||||
|
||||
__ lg(temp2, MemOperand(temp2, temp3));
|
||||
__ sllg(temp1, temp1, Operand(52));
|
||||
__ ogr(temp2, temp1);
|
||||
__ ldgr(double_scratch1, temp2);
|
||||
|
||||
__ mdbr(result, double_scratch1);
|
||||
__ b(&done, Label::kNear);
|
||||
|
||||
__ bind(&zero);
|
||||
__ lzdr(kDoubleRegZero);
|
||||
__ ldr(result, kDoubleRegZero);
|
||||
__ b(&done, Label::kNear);
|
||||
|
||||
__ bind(&infinity);
|
||||
__ LoadDouble(result, ExpConstant(2, temp3));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
CodeAgingHelper::CodeAgingHelper(Isolate* isolate) {
|
||||
|
@ -25,19 +25,6 @@ class StringCharLoadGenerator : public AllStatic {
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(StringCharLoadGenerator);
|
||||
};
|
||||
|
||||
class MathExpGenerator : public AllStatic {
|
||||
public:
|
||||
// Register input isn't modified. All other registers are clobbered.
|
||||
static void EmitMathExp(MacroAssembler* masm, DoubleRegister input,
|
||||
DoubleRegister result, DoubleRegister double_scratch1,
|
||||
DoubleRegister double_scratch2, Register temp1,
|
||||
Register temp2, Register temp3);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(MathExpGenerator);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user