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,
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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, ¬_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(¬_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.
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user