Revision: 7086
Author: [email protected]
Date: Tue Mar 8 02:29:40 2011
Log: ARM: Implement MathPowStub and DoMathPowHalf.
Review URL: http://codereview.chromium.org/6613015
http://code.google.com/p/v8/source/detail?r=7086
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.h
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Mar 3 23:36:52
2011
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Tue Mar 8 02:29:40
2011
@@ -4054,6 +4054,106 @@
UNREACHABLE();
}
}
+
+
+void MathPowStub::Generate(MacroAssembler* masm) {
+ Label call_runtime;
+
+ if (CpuFeatures::IsSupported(VFP3)) {
+ CpuFeatures::Scope scope(VFP3);
+
+ Label base_not_smi;
+ Label exponent_not_smi;
+ Label convert_exponent;
+
+ const Register base = r0;
+ const Register exponent = r1;
+ const Register heapnumbermap = r5;
+ const Register heapnumber = r6;
+ const DoubleRegister double_base = d0;
+ const DoubleRegister double_exponent = d1;
+ const DoubleRegister double_result = d2;
+ const SwVfpRegister single_scratch = s0;
+ const Register scratch = r9;
+ const Register scratch2 = r7;
+
+ __ LoadRoot(heapnumbermap, Heap::kHeapNumberMapRootIndex);
+ __ ldr(base, MemOperand(sp, 1 * kPointerSize));
+ __ ldr(exponent, MemOperand(sp, 0 * kPointerSize));
+
+ // Convert base to double value and store it in d0.
+ __ JumpIfNotSmi(base, &base_not_smi);
+ // Base is a Smi. Untag and convert it.
+ __ SmiUntag(base);
+ __ vmov(single_scratch, base);
+ __ vcvt_f64_s32(double_base, single_scratch);
+ __ b(&convert_exponent);
+
+ __ bind(&base_not_smi);
+ __ ldr(scratch, FieldMemOperand(base, JSObject::kMapOffset));
+ __ cmp(scratch, heapnumbermap);
+ __ b(ne, &call_runtime);
+ // Base is a heapnumber. Load it into double register.
+ __ vldr(double_base, FieldMemOperand(base, HeapNumber::kValueOffset));
+
+ __ bind(&convert_exponent);
+ __ JumpIfNotSmi(exponent, &exponent_not_smi);
+ __ SmiUntag(exponent);
+
+ // The base is in a double register and the exponent is
+ // an untagged smi. Allocate a heap number and call a
+ // C function for integer exponents. The register containing
+ // the heap number is callee-saved.
+ __ AllocateHeapNumber(heapnumber,
+ scratch,
+ scratch2,
+ heapnumbermap,
+ &call_runtime);
+ __ push(lr);
+ __ PrepareCallCFunction(3, scratch);
+ __ mov(r2, exponent);
+ __ vmov(r0, r1, double_base);
+ __ CallCFunction(ExternalReference::power_double_int_function(), 3);
+ __ pop(lr);
+ __ GetCFunctionDoubleResult(double_result);
+ __ vstr(double_result,
+ FieldMemOperand(heapnumber, HeapNumber::kValueOffset));
+ __ mov(r0, heapnumber);
+ __ Ret(2 * kPointerSize);
+
+ __ bind(&exponent_not_smi);
+ __ ldr(scratch, FieldMemOperand(exponent, JSObject::kMapOffset));
+ __ cmp(scratch, heapnumbermap);
+ __ b(ne, &call_runtime);
+ // Exponent is a heapnumber. Load it into double register.
+ __ vldr(double_exponent,
+ FieldMemOperand(exponent, HeapNumber::kValueOffset));
+
+ // The base and the exponent are in double registers.
+ // Allocate a heap number and call a C function for
+ // double exponents. The register containing
+ // the heap number is callee-saved.
+ __ AllocateHeapNumber(heapnumber,
+ scratch,
+ scratch2,
+ heapnumbermap,
+ &call_runtime);
+ __ push(lr);
+ __ PrepareCallCFunction(4, scratch);
+ __ vmov(r0, r1, double_base);
+ __ vmov(r2, r3, double_exponent);
+ __ CallCFunction(ExternalReference::power_double_double_function(), 4);
+ __ pop(lr);
+ __ GetCFunctionDoubleResult(double_result);
+ __ vstr(double_result,
+ FieldMemOperand(heapnumber, HeapNumber::kValueOffset));
+ __ mov(r0, heapnumber);
+ __ Ret(2 * kPointerSize);
+ }
+
+ __ bind(&call_runtime);
+ __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Mar 7 11:23:46
2011
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Tue Mar 8 02:29:40
2011
@@ -2858,7 +2858,8 @@
ASSERT(args->length() == 2);
VisitForStackValue(args->at(0));
VisitForStackValue(args->at(1));
- __ CallRuntime(Runtime::kMath_pow, 2);
+ MathPowStub stub;
+ __ CallStub(&stub);
context()->Plug(r0);
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Mon Mar 7 03:52:36 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Mar 8 02:29:40 2011
@@ -1230,8 +1230,7 @@
case kMathRound:
return AssignEnvironment(DefineAsRegister(result));
case kMathPowHalf:
- Abort("MathPowHalf LUnaryMathOperation not implemented");
- return NULL;
+ return DefineSameAsFirst(result);
default:
UNREACHABLE();
return NULL;
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Mar 7
03:52:36 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Mar 8
02:29:40 2011
@@ -745,10 +745,6 @@
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
- case CodeStub::MathPow: {
- Abort("MathPowStub unimplemented.");
- break;
- }
case CodeStub::NumberToString: {
NumberToStringStub stub;
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
@@ -2644,6 +2640,22 @@
ASSERT(ToDoubleRegister(instr->result()).is(input));
__ vsqrt(input, input);
}
+
+
+void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
+ DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
+ Register scratch = scratch0();
+ SwVfpRegister single_scratch = double_scratch0().low();
+ DoubleRegister double_scratch = double_scratch0();
+ ASSERT(ToDoubleRegister(instr->result()).is(input));
+
+ // Add +0 to convert -0 to +0.
+ __ mov(scratch, Operand(0));
+ __ vmov(single_scratch, scratch);
+ __ vcvt_f64_s32(double_scratch, single_scratch);
+ __ vadd(input, input, double_scratch);
+ __ vsqrt(input, input);
+}
void LCodeGen::DoPower(LPower* instr) {
@@ -2742,6 +2754,9 @@
case kMathSqrt:
DoMathSqrt(instr);
break;
+ case kMathPowHalf:
+ DoMathPowHalf(instr);
+ break;
case kMathCos:
DoMathCos(instr);
break;
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Mon Mar 7
03:52:36 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Tue Mar 8
02:29:40 2011
@@ -210,6 +210,7 @@
void DoMathFloor(LUnaryMathOperation* instr);
void DoMathRound(LUnaryMathOperation* instr);
void DoMathSqrt(LUnaryMathOperation* instr);
+ void DoMathPowHalf(LUnaryMathOperation* instr);
void DoMathLog(LUnaryMathOperation* instr);
void DoMathCos(LUnaryMathOperation* instr);
void DoMathSin(LUnaryMathOperation* instr);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Mar 7
03:52:36 2011
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Mar 8
02:29:40 2011
@@ -748,11 +748,6 @@
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
- case CodeStub::MathPow: {
- MathPowStub stub;
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
- break;
- }
case CodeStub::NumberToString: {
NumberToStringStub stub;
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon Mar 7
03:52:36 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Mar 8
02:29:40 2011
@@ -725,11 +725,6 @@
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
break;
}
- case CodeStub::MathPow: {
- MathPowStub stub;
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
- break;
- }
case CodeStub::NumberToString: {
NumberToStringStub stub;
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev