ARM: Small optimisation of VFP immediate creation

Save an instruction in VFP immediate creation by passing a scratch register.

BUG=none
TEST=none

Review URL: https://chromiumcodereview.appspot.com/10990024
Patch from Martyn Capewell <m.m.capewell@googlemail.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12605 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
danno@chromium.org 2012-09-25 14:32:07 +00:00
parent 72e9f1bea1
commit c467b2659f
6 changed files with 26 additions and 22 deletions

View File

@ -1975,6 +1975,7 @@ static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
void Assembler::vmov(const DwVfpRegister dst,
double imm,
const Register scratch,
const Condition cond) {
// Dd = immediate
// Instruction details available in ARM DDI 0406B, A8-640.
@ -1989,22 +1990,22 @@ void Assembler::vmov(const DwVfpRegister dst,
// using vldr from a constant pool.
uint32_t lo, hi;
DoubleAsTwoUInt32(imm, &lo, &hi);
mov(ip, Operand(lo));
if (lo == hi) {
// If the lo and hi parts of the double are equal, the literal is easier
// to create. This is the case with 0.0.
mov(ip, Operand(lo));
vmov(dst, ip, ip);
} else {
if (scratch.is(no_reg)) {
// Move the low part of the double into the lower of the corresponsing S
// registers of D register dst.
mov(ip, Operand(lo));
vmov(dst.low(), ip, cond);
// Move the high part of the double into the higher of the corresponsing S
// registers of D register dst.
mov(ip, Operand(hi));
vmov(dst.high(), ip, cond);
} else {
// Move the low and high parts of the double to a D register in one
// instruction.
mov(scratch, Operand(hi));
vmov(dst, ip, scratch, cond);
}
}
}

View File

@ -1053,6 +1053,7 @@ class Assembler : public AssemblerBase {
void vmov(const DwVfpRegister dst,
double imm,
const Register scratch = no_reg,
const Condition cond = al);
void vmov(const SwVfpRegister dst,
const SwVfpRegister src,

View File

@ -3636,13 +3636,13 @@ void MathPowStub::Generate(MacroAssembler* masm) {
Label not_plus_half;
// Test for 0.5.
__ vmov(double_scratch, 0.5);
__ vmov(double_scratch, 0.5, scratch);
__ VFPCompareAndSetFlags(double_exponent, double_scratch);
__ b(ne, &not_plus_half);
// Calculates square root of base. Check for the special case of
// Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
__ vmov(double_scratch, -V8_INFINITY);
__ vmov(double_scratch, -V8_INFINITY, scratch);
__ VFPCompareAndSetFlags(double_base, double_scratch);
__ vneg(double_result, double_scratch, eq);
__ b(eq, &done);
@ -3653,20 +3653,20 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ jmp(&done);
__ bind(&not_plus_half);
__ vmov(double_scratch, -0.5);
__ vmov(double_scratch, -0.5, scratch);
__ VFPCompareAndSetFlags(double_exponent, double_scratch);
__ b(ne, &call_runtime);
// Calculates square root of base. Check for the special case of
// Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
__ vmov(double_scratch, -V8_INFINITY);
__ vmov(double_scratch, -V8_INFINITY, scratch);
__ VFPCompareAndSetFlags(double_base, double_scratch);
__ vmov(double_result, kDoubleRegZero, eq);
__ b(eq, &done);
// Add +0 to convert -0 to +0.
__ vadd(double_scratch, double_base, kDoubleRegZero);
__ vmov(double_result, 1.0);
__ vmov(double_result, 1.0, scratch);
__ vsqrt(double_scratch, double_scratch);
__ vdiv(double_result, double_result, double_scratch);
__ jmp(&done);
@ -3701,7 +3701,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ mov(exponent, scratch);
}
__ vmov(double_scratch, double_base); // Back up base.
__ vmov(double_result, 1.0);
__ vmov(double_result, 1.0, scratch2);
// Get absolute value of exponent.
__ cmp(scratch, Operand(0));
@ -3717,7 +3717,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ cmp(exponent, Operand(0));
__ b(ge, &done);
__ vmov(double_scratch, 1.0);
__ vmov(double_scratch, 1.0, scratch);
__ vdiv(double_result, double_scratch, double_result);
// Test whether result is zero. Bail out to check for subnormal result.
// Due to subnormals, x^-y == (1/x)^y does not hold in all cases.

View File

@ -1551,7 +1551,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
ASSERT(instr->result()->IsDoubleRegister());
DwVfpRegister result = ToDoubleRegister(instr->result());
double v = instr->value();
__ Vmov(result, v);
__ Vmov(result, v, scratch0());
}
@ -3530,12 +3530,12 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
__ cmp(scratch, Operand(HeapNumber::kExponentBias + 32));
DeoptimizeIf(ge, instr->environment());
__ Vmov(double_scratch0(), 0.5, scratch);
__ vadd(double_scratch0(), input, double_scratch0());
// Save the original sign for later comparison.
__ and_(scratch, result, Operand(HeapNumber::kSignMask));
__ Vmov(double_scratch0(), 0.5);
__ vadd(double_scratch0(), input, double_scratch0());
// Check sign of the result: if the sign changed, the input
// value was in ]0.5, 0[ and the result should be -0.
__ vmov(result, double_scratch0().high());
@ -3584,7 +3584,7 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
// Math.pow(-Infinity, 0.5) == Infinity
// Math.sqrt(-Infinity) == NaN
Label done;
__ vmov(temp, -V8_INFINITY);
__ vmov(temp, -V8_INFINITY, scratch0());
__ VFPCompareAndSetFlags(input, temp);
__ vneg(result, temp, eq);
__ b(&done, eq);
@ -4066,7 +4066,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
// Only load canonical NaN if the comparison above set the overflow.
__ Vmov(value,
FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
vs);
no_reg, vs);
}
__ vstr(value, scratch, instr->additional_index() << element_size_shift);

View File

@ -789,6 +789,7 @@ void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
void MacroAssembler::Vmov(const DwVfpRegister dst,
const double imm,
const Register scratch,
const Condition cond) {
ASSERT(CpuFeatures::IsEnabled(VFP2));
static const DoubleRepresentation minus_zero(-0.0);
@ -800,7 +801,7 @@ void MacroAssembler::Vmov(const DwVfpRegister dst,
} else if (value.bits == minus_zero.bits) {
vneg(dst, kDoubleRegZero, cond);
} else {
vmov(dst, imm, cond);
vmov(dst, imm, scratch, cond);
}
}
@ -3676,7 +3677,7 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
// Double value is >= 255, return 255.
bind(&above_zero);
Vmov(temp_double_reg, 255.0);
Vmov(temp_double_reg, 255.0, result_reg);
VFPCompareAndSetFlags(input_reg, temp_double_reg);
b(le, &in_bounds);
mov(result_reg, Operand(255));

View File

@ -483,6 +483,7 @@ class MacroAssembler: public Assembler {
void Vmov(const DwVfpRegister dst,
const double imm,
const Register scratch = no_reg,
const Condition cond = al);
// Enter exit frame.