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:
parent
72e9f1bea1
commit
c467b2659f
@ -1975,6 +1975,7 @@ static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
|
|||||||
|
|
||||||
void Assembler::vmov(const DwVfpRegister dst,
|
void Assembler::vmov(const DwVfpRegister dst,
|
||||||
double imm,
|
double imm,
|
||||||
|
const Register scratch,
|
||||||
const Condition cond) {
|
const Condition cond) {
|
||||||
// Dd = immediate
|
// Dd = immediate
|
||||||
// Instruction details available in ARM DDI 0406B, A8-640.
|
// 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.
|
// using vldr from a constant pool.
|
||||||
uint32_t lo, hi;
|
uint32_t lo, hi;
|
||||||
DoubleAsTwoUInt32(imm, &lo, &hi);
|
DoubleAsTwoUInt32(imm, &lo, &hi);
|
||||||
|
|
||||||
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));
|
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
|
// Move the low part of the double into the lower of the corresponsing S
|
||||||
// registers of D register dst.
|
// registers of D register dst.
|
||||||
mov(ip, Operand(lo));
|
|
||||||
vmov(dst.low(), ip, cond);
|
vmov(dst.low(), ip, cond);
|
||||||
|
|
||||||
// Move the high part of the double into the higher of the corresponsing S
|
// Move the high part of the double into the higher of the corresponsing S
|
||||||
// registers of D register dst.
|
// registers of D register dst.
|
||||||
mov(ip, Operand(hi));
|
mov(ip, Operand(hi));
|
||||||
vmov(dst.high(), ip, cond);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1053,6 +1053,7 @@ class Assembler : public AssemblerBase {
|
|||||||
|
|
||||||
void vmov(const DwVfpRegister dst,
|
void vmov(const DwVfpRegister dst,
|
||||||
double imm,
|
double imm,
|
||||||
|
const Register scratch = no_reg,
|
||||||
const Condition cond = al);
|
const Condition cond = al);
|
||||||
void vmov(const SwVfpRegister dst,
|
void vmov(const SwVfpRegister dst,
|
||||||
const SwVfpRegister src,
|
const SwVfpRegister src,
|
||||||
|
@ -3636,13 +3636,13 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
|||||||
Label not_plus_half;
|
Label not_plus_half;
|
||||||
|
|
||||||
// Test for 0.5.
|
// Test for 0.5.
|
||||||
__ vmov(double_scratch, 0.5);
|
__ vmov(double_scratch, 0.5, scratch);
|
||||||
__ VFPCompareAndSetFlags(double_exponent, double_scratch);
|
__ VFPCompareAndSetFlags(double_exponent, double_scratch);
|
||||||
__ b(ne, ¬_plus_half);
|
__ b(ne, ¬_plus_half);
|
||||||
|
|
||||||
// Calculates square root of base. Check for the special case of
|
// Calculates square root of base. Check for the special case of
|
||||||
// Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
|
// 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);
|
__ VFPCompareAndSetFlags(double_base, double_scratch);
|
||||||
__ vneg(double_result, double_scratch, eq);
|
__ vneg(double_result, double_scratch, eq);
|
||||||
__ b(eq, &done);
|
__ b(eq, &done);
|
||||||
@ -3653,20 +3653,20 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
|||||||
__ jmp(&done);
|
__ jmp(&done);
|
||||||
|
|
||||||
__ bind(¬_plus_half);
|
__ bind(¬_plus_half);
|
||||||
__ vmov(double_scratch, -0.5);
|
__ vmov(double_scratch, -0.5, scratch);
|
||||||
__ VFPCompareAndSetFlags(double_exponent, double_scratch);
|
__ VFPCompareAndSetFlags(double_exponent, double_scratch);
|
||||||
__ b(ne, &call_runtime);
|
__ b(ne, &call_runtime);
|
||||||
|
|
||||||
// Calculates square root of base. Check for the special case of
|
// Calculates square root of base. Check for the special case of
|
||||||
// Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
|
// 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);
|
__ VFPCompareAndSetFlags(double_base, double_scratch);
|
||||||
__ vmov(double_result, kDoubleRegZero, eq);
|
__ vmov(double_result, kDoubleRegZero, eq);
|
||||||
__ b(eq, &done);
|
__ b(eq, &done);
|
||||||
|
|
||||||
// Add +0 to convert -0 to +0.
|
// Add +0 to convert -0 to +0.
|
||||||
__ vadd(double_scratch, double_base, kDoubleRegZero);
|
__ vadd(double_scratch, double_base, kDoubleRegZero);
|
||||||
__ vmov(double_result, 1.0);
|
__ vmov(double_result, 1.0, scratch);
|
||||||
__ vsqrt(double_scratch, double_scratch);
|
__ vsqrt(double_scratch, double_scratch);
|
||||||
__ vdiv(double_result, double_result, double_scratch);
|
__ vdiv(double_result, double_result, double_scratch);
|
||||||
__ jmp(&done);
|
__ jmp(&done);
|
||||||
@ -3701,7 +3701,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
|||||||
__ mov(exponent, scratch);
|
__ mov(exponent, scratch);
|
||||||
}
|
}
|
||||||
__ vmov(double_scratch, double_base); // Back up base.
|
__ vmov(double_scratch, double_base); // Back up base.
|
||||||
__ vmov(double_result, 1.0);
|
__ vmov(double_result, 1.0, scratch2);
|
||||||
|
|
||||||
// Get absolute value of exponent.
|
// Get absolute value of exponent.
|
||||||
__ cmp(scratch, Operand(0));
|
__ cmp(scratch, Operand(0));
|
||||||
@ -3717,7 +3717,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ cmp(exponent, Operand(0));
|
__ cmp(exponent, Operand(0));
|
||||||
__ b(ge, &done);
|
__ b(ge, &done);
|
||||||
__ vmov(double_scratch, 1.0);
|
__ vmov(double_scratch, 1.0, scratch);
|
||||||
__ vdiv(double_result, double_scratch, double_result);
|
__ vdiv(double_result, double_scratch, double_result);
|
||||||
// Test whether result is zero. Bail out to check for subnormal 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.
|
// Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
|
||||||
|
@ -1551,7 +1551,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
|
|||||||
ASSERT(instr->result()->IsDoubleRegister());
|
ASSERT(instr->result()->IsDoubleRegister());
|
||||||
DwVfpRegister result = ToDoubleRegister(instr->result());
|
DwVfpRegister result = ToDoubleRegister(instr->result());
|
||||||
double v = instr->value();
|
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));
|
__ cmp(scratch, Operand(HeapNumber::kExponentBias + 32));
|
||||||
DeoptimizeIf(ge, instr->environment());
|
DeoptimizeIf(ge, instr->environment());
|
||||||
|
|
||||||
|
__ Vmov(double_scratch0(), 0.5, scratch);
|
||||||
|
__ vadd(double_scratch0(), input, double_scratch0());
|
||||||
|
|
||||||
// Save the original sign for later comparison.
|
// Save the original sign for later comparison.
|
||||||
__ and_(scratch, result, Operand(HeapNumber::kSignMask));
|
__ 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
|
// Check sign of the result: if the sign changed, the input
|
||||||
// value was in ]0.5, 0[ and the result should be -0.
|
// value was in ]0.5, 0[ and the result should be -0.
|
||||||
__ vmov(result, double_scratch0().high());
|
__ vmov(result, double_scratch0().high());
|
||||||
@ -3584,7 +3584,7 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
|
|||||||
// Math.pow(-Infinity, 0.5) == Infinity
|
// Math.pow(-Infinity, 0.5) == Infinity
|
||||||
// Math.sqrt(-Infinity) == NaN
|
// Math.sqrt(-Infinity) == NaN
|
||||||
Label done;
|
Label done;
|
||||||
__ vmov(temp, -V8_INFINITY);
|
__ vmov(temp, -V8_INFINITY, scratch0());
|
||||||
__ VFPCompareAndSetFlags(input, temp);
|
__ VFPCompareAndSetFlags(input, temp);
|
||||||
__ vneg(result, temp, eq);
|
__ vneg(result, temp, eq);
|
||||||
__ b(&done, eq);
|
__ b(&done, eq);
|
||||||
@ -4066,7 +4066,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
|
|||||||
// Only load canonical NaN if the comparison above set the overflow.
|
// Only load canonical NaN if the comparison above set the overflow.
|
||||||
__ Vmov(value,
|
__ Vmov(value,
|
||||||
FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
|
FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
|
||||||
vs);
|
no_reg, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
__ vstr(value, scratch, instr->additional_index() << element_size_shift);
|
__ vstr(value, scratch, instr->additional_index() << element_size_shift);
|
||||||
|
@ -789,6 +789,7 @@ void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
|
|||||||
|
|
||||||
void MacroAssembler::Vmov(const DwVfpRegister dst,
|
void MacroAssembler::Vmov(const DwVfpRegister dst,
|
||||||
const double imm,
|
const double imm,
|
||||||
|
const Register scratch,
|
||||||
const Condition cond) {
|
const Condition cond) {
|
||||||
ASSERT(CpuFeatures::IsEnabled(VFP2));
|
ASSERT(CpuFeatures::IsEnabled(VFP2));
|
||||||
static const DoubleRepresentation minus_zero(-0.0);
|
static const DoubleRepresentation minus_zero(-0.0);
|
||||||
@ -800,7 +801,7 @@ void MacroAssembler::Vmov(const DwVfpRegister dst,
|
|||||||
} else if (value.bits == minus_zero.bits) {
|
} else if (value.bits == minus_zero.bits) {
|
||||||
vneg(dst, kDoubleRegZero, cond);
|
vneg(dst, kDoubleRegZero, cond);
|
||||||
} else {
|
} 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.
|
// Double value is >= 255, return 255.
|
||||||
bind(&above_zero);
|
bind(&above_zero);
|
||||||
Vmov(temp_double_reg, 255.0);
|
Vmov(temp_double_reg, 255.0, result_reg);
|
||||||
VFPCompareAndSetFlags(input_reg, temp_double_reg);
|
VFPCompareAndSetFlags(input_reg, temp_double_reg);
|
||||||
b(le, &in_bounds);
|
b(le, &in_bounds);
|
||||||
mov(result_reg, Operand(255));
|
mov(result_reg, Operand(255));
|
||||||
|
@ -483,6 +483,7 @@ class MacroAssembler: public Assembler {
|
|||||||
|
|
||||||
void Vmov(const DwVfpRegister dst,
|
void Vmov(const DwVfpRegister dst,
|
||||||
const double imm,
|
const double imm,
|
||||||
|
const Register scratch = no_reg,
|
||||||
const Condition cond = al);
|
const Condition cond = al);
|
||||||
|
|
||||||
// Enter exit frame.
|
// Enter exit frame.
|
||||||
|
Loading…
Reference in New Issue
Block a user