Revision: 13086
Author: [email protected]
Date: Thu Nov 29 01:09:39 2012
Log: MIPS: ARM: Fast path for integer inputs to EmitVFPTruncate
Port r12676 (7d5e7e81)
BUG=
TEST=
Review URL: https://codereview.chromium.org/11308134
Patch from Akos Palfi <[email protected]>.
http://code.google.com/p/v8/source/detail?r=13086
Modified:
/branches/bleeding_edge/src/mips/code-stubs-mips.cc
/branches/bleeding_edge/src/mips/code-stubs-mips.h
/branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
/branches/bleeding_edge/src/mips/lithium-mips.cc
/branches/bleeding_edge/src/mips/macro-assembler-mips.cc
/branches/bleeding_edge/src/mips/macro-assembler-mips.h
/branches/bleeding_edge/src/mips/stub-cache-mips.cc
=======================================
--- /branches/bleeding_edge/src/mips/code-stubs-mips.cc Wed Nov 21 23:05:20
2012
+++ /branches/bleeding_edge/src/mips/code-stubs-mips.cc Thu Nov 29 01:09:39
2012
@@ -816,6 +816,7 @@
Register object,
Destination destination,
DoubleRegister
double_dst,
+ DoubleRegister
double_scratch,
Register dst1,
Register dst2,
Register heap_number_map,
@@ -851,9 +852,10 @@
Register except_flag = scratch2;
__ EmitFPUTruncate(kRoundToZero,
- single_scratch,
+ scratch1,
double_dst,
- scratch1,
+ at,
+ double_scratch,
except_flag,
kCheckForInexactConversion);
@@ -895,7 +897,8 @@
Register scratch1,
Register scratch2,
Register scratch3,
- DoubleRegister double_scratch,
+ DoubleRegister double_scratch0,
+ DoubleRegister double_scratch1,
Label* not_int32) {
ASSERT(!dst.is(object));
ASSERT(!scratch1.is(object) && !scratch2.is(object)
&& !scratch3.is(object));
@@ -918,22 +921,19 @@
if (CpuFeatures::IsSupported(FPU)) {
CpuFeatures::Scope scope(FPU);
// Load the double value.
- __ ldc1(double_scratch, FieldMemOperand(object,
HeapNumber::kValueOffset));
+ __ ldc1(double_scratch0, FieldMemOperand(object,
HeapNumber::kValueOffset));
- FPURegister single_scratch = double_scratch.low();
Register except_flag = scratch2;
__ EmitFPUTruncate(kRoundToZero,
- single_scratch,
- double_scratch,
+ dst,
+ double_scratch0,
scratch1,
+ double_scratch1,
except_flag,
kCheckForInexactConversion);
// Jump to not_int32 if the operation did not succeed.
__ Branch(not_int32, ne, except_flag, Operand(zero_reg));
- // Get the result in the destination register.
- __ mfc1(dst, single_scratch);
-
} else {
// Load the double value in the destination registers.
__ lw(scratch2, FieldMemOperand(object, HeapNumber::kExponentOffset));
@@ -2955,6 +2955,7 @@
right,
destination,
f14,
+ f16,
a2,
a3,
heap_number_map,
@@ -2966,6 +2967,7 @@
left,
destination,
f12,
+ f16,
t0,
t1,
heap_number_map,
@@ -3002,9 +3004,10 @@
Register except_flag = scratch2;
__ EmitFPUTruncate(kRoundToZero,
- single_scratch,
- f10,
scratch1,
+ f10,
+ at,
+ f16,
except_flag);
if (result_type_ <= BinaryOpIC::INT32) {
@@ -3013,7 +3016,6 @@
}
// Check if the result fits in a smi.
- __ mfc1(scratch1, single_scratch);
__ Addu(scratch2, scratch1, Operand(0x40000000));
// If not try to return a heap number.
__ Branch(&return_heap_number, lt, scratch2, Operand(zero_reg));
@@ -3108,6 +3110,7 @@
scratch2,
scratch3,
f0,
+ f2,
&transition);
FloatingPointHelper::LoadNumberAsInt32(masm,
right,
@@ -3117,6 +3120,7 @@
scratch2,
scratch3,
f0,
+ f2,
&transition);
// The ECMA-262 standard specifies that, for shift operations, only
the
@@ -3683,9 +3687,10 @@
Label int_exponent_convert;
// Detect integer exponents stored as double.
__ EmitFPUTruncate(kRoundToMinusInf,
- single_scratch,
+ scratch,
double_exponent,
- scratch,
+ at,
+ double_scratch,
scratch2,
kCheckForInexactConversion);
// scratch2 == 0 means there was no conversion error.
@@ -3743,7 +3748,7 @@
__ push(ra);
{
AllowExternalCallThatCantCauseGC scope(masm);
- __ PrepareCallCFunction(0, 2, scratch);
+ __ PrepareCallCFunction(0, 2, scratch2);
__ SetCallCDoubleArguments(double_base, double_exponent);
__ CallCFunction(
ExternalReference::power_double_double_function(masm->isolate()),
@@ -3754,7 +3759,6 @@
__ jmp(&done);
__ bind(&int_exponent_convert);
- __ mfc1(scratch, single_scratch);
}
// Calculate power with integer exponent.
=======================================
--- /branches/bleeding_edge/src/mips/code-stubs-mips.h Tue Nov 20 06:11:53
2012
+++ /branches/bleeding_edge/src/mips/code-stubs-mips.h Thu Nov 29 01:09:39
2012
@@ -657,6 +657,7 @@
Register object,
Destination destination,
FPURegister double_dst,
+ FPURegister double_scratch,
Register dst1,
Register dst2,
Register heap_number_map,
@@ -678,7 +679,8 @@
Register scratch1,
Register scratch2,
Register scratch3,
- FPURegister double_scratch,
+ FPURegister double_scratch0,
+ FPURegister double_scratch1,
Label* not_int32);
// Generate non FPU code to check if a double can be exactly represented
by a
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Nov 28
23:38:00 2012
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Thu Nov 29
01:09:39 2012
@@ -3262,22 +3262,19 @@
void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister(instr->result());
- FPURegister single_scratch = double_scratch0().low();
Register scratch1 = scratch0();
Register except_flag = ToRegister(instr->temp());
__ EmitFPUTruncate(kRoundToMinusInf,
- single_scratch,
+ result,
input,
scratch1,
+ double_scratch0(),
except_flag);
// Deopt if the operation did not succeed.
DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
- // Load the result.
- __ mfc1(result, single_scratch);
-
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Test for -0.
Label done;
@@ -3293,6 +3290,7 @@
void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister(instr->result());
+ DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
Register scratch = scratch0();
Label done, check_sign_on_zero;
@@ -3344,17 +3342,15 @@
}
Register except_flag = scratch;
-
__ EmitFPUTruncate(kRoundToMinusInf,
- double_scratch0().low(),
- double_scratch0(),
result,
+ double_scratch0(),
+ at,
+ double_scratch1,
except_flag);
DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
- __ mfc1(result, double_scratch0().low());
-
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Test for -0.
__ Branch(&done, ne, result, Operand(zero_reg));
@@ -4391,7 +4387,7 @@
Register scratch1 = scratch0();
Register scratch2 = ToRegister(instr->temp());
DoubleRegister double_scratch = double_scratch0();
- FPURegister single_scratch = double_scratch.low();
+ DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3());
ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
@@ -4407,7 +4403,7 @@
if (instr->truncating()) {
Register scratch3 = ToRegister(instr->temp2());
- DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3());
+ FPURegister single_scratch = double_scratch.low();
ASSERT(!scratch3.is(input_reg) &&
!scratch3.is(scratch1) &&
!scratch3.is(scratch2));
@@ -4442,18 +4438,16 @@
Register except_flag = scratch2;
__ EmitFPUTruncate(kRoundToZero,
- single_scratch,
+ input_reg,
double_scratch,
scratch1,
+ double_scratch2,
except_flag,
kCheckForInexactConversion);
// Deopt if the operation did not succeed.
DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
- // Load the result.
- __ mfc1(input_reg, single_scratch);
-
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ Branch(&done, ne, input_reg, Operand(zero_reg));
@@ -4515,10 +4509,10 @@
Register scratch1 = scratch0();
Register scratch2 = ToRegister(instr->temp());
DoubleRegister double_input = ToDoubleRegister(instr->value());
- FPURegister single_scratch = double_scratch0().low();
if (instr->truncating()) {
Register scratch3 = ToRegister(instr->temp2());
+ FPURegister single_scratch = double_scratch0().low();
__ EmitECMATruncate(result_reg,
double_input,
single_scratch,
@@ -4529,17 +4523,15 @@
Register except_flag = scratch2;
__ EmitFPUTruncate(kRoundToMinusInf,
- single_scratch,
+ result_reg,
double_input,
scratch1,
+ double_scratch0(),
except_flag,
kCheckForInexactConversion);
// Deopt if the operation did not succeed (except_flag != 0).
DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg));
-
- // Load the result.
- __ mfc1(result_reg, single_scratch);
}
}
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Mon Nov 26 08:14:49
2012
+++ /branches/bleeding_edge/src/mips/lithium-mips.cc Thu Nov 29 01:09:39
2012
@@ -1049,7 +1049,9 @@
return DefineFixedDouble(result, f4);
} else {
LOperand* input = UseRegisterAtStart(instr->value());
- LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
+
+ LOperand* temp = (op == kMathRound) ? FixedTemp(f6) :
+ (op == kMathFloor) ? TempRegister() : NULL;
LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input,
temp);
switch (op) {
case kMathAbs:
@@ -1566,8 +1568,7 @@
LOperand* temp1 = TempRegister();
LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
: NULL;
- LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(f22)
- : NULL;
+ LOperand* temp3 = FixedTemp(f22);
res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
temp1,
temp2,
=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Wed Nov 21
01:54:53 2012
+++ /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Thu Nov 29
01:09:39 2012
@@ -1395,49 +1395,68 @@
void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode,
- FPURegister result,
+ Register result,
DoubleRegister double_input,
- Register scratch1,
+ Register scratch,
+ DoubleRegister double_scratch,
Register except_flag,
CheckForInexactConversion
check_inexact) {
+ ASSERT(!result.is(scratch));
+ ASSERT(!double_input.is(double_scratch));
+ ASSERT(!except_flag.is(scratch));
+
ASSERT(CpuFeatures::IsSupported(FPU));
CpuFeatures::Scope scope(FPU);
+ Label done;
+
+ // Clear the except flag (0 = no exception)
+ mov(except_flag, zero_reg);
+
+ // Test for values that can be exactly represented as a signed 32-bit
integer.
+ cvt_w_d(double_scratch, double_input);
+ mfc1(result, double_scratch);
+ cvt_d_w(double_scratch, double_scratch);
+ BranchF(&done, NULL, eq, double_input, double_scratch);
int32_t except_mask = kFCSRFlagMask; // Assume interested in all
exceptions.
if (check_inexact == kDontCheckForInexactConversion) {
- // Ingore inexact exceptions.
+ // Ignore inexact exceptions.
except_mask &= ~kFCSRInexactFlagMask;
}
// Save FCSR.
- cfc1(scratch1, FCSR);
+ cfc1(scratch, FCSR);
// Disable FPU exceptions.
ctc1(zero_reg, FCSR);
// Do operation based on rounding mode.
switch (rounding_mode) {
case kRoundToNearest:
- Round_w_d(result, double_input);
+ Round_w_d(double_scratch, double_input);
break;
case kRoundToZero:
- Trunc_w_d(result, double_input);
+ Trunc_w_d(double_scratch, double_input);
break;
case kRoundToPlusInf:
- Ceil_w_d(result, double_input);
+ Ceil_w_d(double_scratch, double_input);
break;
case kRoundToMinusInf:
- Floor_w_d(result, double_input);
+ Floor_w_d(double_scratch, double_input);
break;
} // End of switch-statement.
// Retrieve FCSR.
cfc1(except_flag, FCSR);
// Restore FCSR.
- ctc1(scratch1, FCSR);
+ ctc1(scratch, FCSR);
+ // Move the converted value into the result register.
+ mfc1(result, double_scratch);
// Check for fpu exceptions.
And(except_flag, except_flag, Operand(except_mask));
+
+ bind(&done);
}
=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.h Fri Nov 23
07:39:25 2012
+++ /branches/bleeding_edge/src/mips/macro-assembler-mips.h Thu Nov 29
01:09:39 2012
@@ -753,14 +753,16 @@
FPURegister double_scratch,
Label *not_int32);
- // Truncates a double using a specific rounding mode.
+ // Truncates a double using a specific rounding mode, and writes the
value
+ // to the result register.
// The except_flag will contain any exceptions caused by the instruction.
- // If check_inexact is kDontCheckForInexactConversion, then the inexacat
+ // If check_inexact is kDontCheckForInexactConversion, then the inexact
// exception is masked.
void EmitFPUTruncate(FPURoundingMode rounding_mode,
- FPURegister result,
+ Register result,
DoubleRegister double_input,
- Register scratch1,
+ Register scratch,
+ DoubleRegister double_scratch,
Register except_flag,
CheckForInexactConversion check_inexact
= kDontCheckForInexactConversion);
=======================================
--- /branches/bleeding_edge/src/mips/stub-cache-mips.cc Thu Nov 29 00:40:39
2012
+++ /branches/bleeding_edge/src/mips/stub-cache-mips.cc Thu Nov 29 01:09:39
2012
@@ -3695,6 +3695,7 @@
Register scratch0,
Register scratch1,
FPURegister double_scratch0,
+ FPURegister double_scratch1,
Label* fail) {
if (CpuFeatures::IsSupported(FPU)) {
CpuFeatures::Scope scope(FPU);
@@ -3710,15 +3711,15 @@
DONT_DO_SMI_CHECK);
__ ldc1(double_scratch0, FieldMemOperand(key,
HeapNumber::kValueOffset));
__ EmitFPUTruncate(kRoundToZero,
+ scratch0,
double_scratch0,
- double_scratch0,
- scratch0,
+ at,
+ double_scratch1,
scratch1,
kCheckForInexactConversion);
__ Branch(fail, ne, scratch1, Operand(zero_reg));
- __ mfc1(scratch0, double_scratch0);
__ SmiTagCheckOverflow(key, scratch0, scratch1);
__ BranchOnOverflow(fail, scratch1);
__ bind(&key_ok);
@@ -3746,7 +3747,7 @@
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key, t0, t1, f2, f4, &miss_force_generic);
__ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
// a3: elements array
@@ -4088,7 +4089,7 @@
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key, t0, t1, f2, f4, &miss_force_generic);
__ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
@@ -4477,7 +4478,7 @@
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, a0, t0, t1, f2, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, a0, t0, t1, f2, f4, &miss_force_generic);
// Get the elements array.
__ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset));
@@ -4528,7 +4529,7 @@
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic);
// Get the elements array.
__ lw(elements_reg,
@@ -4602,7 +4603,7 @@
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic);
if (IsFastSmiElementsKind(elements_kind)) {
__ JumpIfNotSmi(value_reg, &transition_elements_kind);
@@ -4771,7 +4772,7 @@
// have been verified by the caller to not be a smi.
// Check that the key is a smi or a heap number convertible to a smi.
- GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);
+ GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic);
__ lw(elements_reg,
FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev