Fix fixed-point vcvt_f64_s32 immediate value encoding

The (32 - fraction_bits) value should be encoded so that the least
significant bit is set to bit 5 and the four next bits to bits 0-3. Fix
the previously incorrect encoding. This bug did not cause behavioral
issues before, since in existing uses of the function the order of the
bits in the immediate value does not matter, as they are all 1.

BUG=3256
LOG=N
R=ulan@chromium.org

Review URL: https://codereview.chromium.org/223623003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20508 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
rmcilroy@chromium.org 2014-04-04 11:12:40 +00:00
parent 8072cd2935
commit 3eb418df78
5 changed files with 9 additions and 8 deletions

View File

@ -2827,8 +2827,9 @@ void Assembler::vcvt_f64_s32(const DwVfpRegister dst,
ASSERT(CpuFeatures::IsSupported(VFP3));
int vd, d;
dst.split_code(&vd, &d);
int i = ((32 - fraction_bits) >> 4) & 1;
int imm4 = (32 - fraction_bits) & 0xf;
int imm5 = 32 - fraction_bits;
int i = imm5 & 1;
int imm4 = (imm5 >> 1) & 0xf;
emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 |
vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4);
}

View File

@ -1272,7 +1272,7 @@ void Decoder::DecodeTypeVFP(Instruction* instr) {
} else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
(instr->Bit(8) == 1)) {
// vcvt.f64.s32 Dd, Dd, #<fbits>
int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0));
int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5));
Format(instr, "vcvt'cond.f64.s32 'Dd, 'Dd");
out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
", #%d", fraction_bits);

View File

@ -2936,7 +2936,7 @@ void Simulator::DecodeTypeVFP(Instruction* instr) {
} else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
(instr->Bit(8) == 1)) {
// vcvt.f64.s32 Dd, Dd, #<fbits>
int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0));
int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5));
int fixed_value = get_sinteger_from_s_register(vd * 2);
double divide = 1 << fraction_bits;
set_d_register_from_double(vd, fixed_value / divide);

View File

@ -292,9 +292,9 @@ TEST(4) {
__ vstr(d4, r4, OFFSET_OF(T, f));
// Convert from fixed point to floating point.
__ mov(lr, Operand(1234));
__ mov(lr, Operand(2468));
__ vmov(s8, lr);
__ vcvt_f64_s32(d4, 1);
__ vcvt_f64_s32(d4, 2);
__ vstr(d4, r4, OFFSET_OF(T, j));
// Test vabs.

View File

@ -592,8 +592,8 @@ TEST(Vfp) {
"eeb80be0 vcvt.f64.s32 d0, s1");
COMPARE(vcvt_f32_s32(s0, s2),
"eeb80ac1 vcvt.f32.s32 s0, s2");
COMPARE(vcvt_f64_s32(d0, 1),
"eeba0bef vcvt.f64.s32 d0, d0, #1");
COMPARE(vcvt_f64_s32(d0, 2),
"eeba0bcf vcvt.f64.s32 d0, d0, #2");
if (CpuFeatures::IsSupported(VFP32DREGS)) {
COMPARE(vmov(d3, d27),