Commit 593c388b authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Fix for bug 512 from Subrato De, CodeAurora.

Review URL: http://codereview.chromium.org/464016

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3435 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 584cc173
......@@ -13,10 +13,11 @@ Daniel James <dnljms@gmail.com>
Jan de Mooij <jandemooij@gmail.com>
Jay Freeman <saurik@saurik.com>
Joel Stanley <joel.stan@gmail.com>
John Jozwiak <jjozwiak@codeaurora.org>
Matt Hanselman <mjhanselman@gmail.com>
Paolo Giarrusso <p.giarrusso@gmail.com>
Rafal Krypa <rafal@krypa.net>
Rene Rebe <rene@exactcode.de>
Ryan Dahl <coldredlemur@gmail.com>
Patrick Gansterer <paroga@paroga.com>
John Jozwiak <jjozwiak@codeaurora.org>
Subrato K De <subratokde@codeaurora.org>
......@@ -114,55 +114,55 @@ CRegister cr15 = { 15 };
// Support for the VFP registers s0 to s31 (d0 to d15).
// Note that "sN:sM" is the same as "dN/2".
Register s0 = { 0 };
Register s1 = { 1 };
Register s2 = { 2 };
Register s3 = { 3 };
Register s4 = { 4 };
Register s5 = { 5 };
Register s6 = { 6 };
Register s7 = { 7 };
Register s8 = { 8 };
Register s9 = { 9 };
Register s10 = { 10 };
Register s11 = { 11 };
Register s12 = { 12 };
Register s13 = { 13 };
Register s14 = { 14 };
Register s15 = { 15 };
Register s16 = { 16 };
Register s17 = { 17 };
Register s18 = { 18 };
Register s19 = { 19 };
Register s20 = { 20 };
Register s21 = { 21 };
Register s22 = { 22 };
Register s23 = { 23 };
Register s24 = { 24 };
Register s25 = { 25 };
Register s26 = { 26 };
Register s27 = { 27 };
Register s28 = { 28 };
Register s29 = { 29 };
Register s30 = { 30 };
Register s31 = { 31 };
Register d0 = { 0 };
Register d1 = { 1 };
Register d2 = { 2 };
Register d3 = { 3 };
Register d4 = { 4 };
Register d5 = { 5 };
Register d6 = { 6 };
Register d7 = { 7 };
Register d8 = { 8 };
Register d9 = { 9 };
Register d10 = { 10 };
Register d11 = { 11 };
Register d12 = { 12 };
Register d13 = { 13 };
Register d14 = { 14 };
Register d15 = { 15 };
SwVfpRegister s0 = { 0 };
SwVfpRegister s1 = { 1 };
SwVfpRegister s2 = { 2 };
SwVfpRegister s3 = { 3 };
SwVfpRegister s4 = { 4 };
SwVfpRegister s5 = { 5 };
SwVfpRegister s6 = { 6 };
SwVfpRegister s7 = { 7 };
SwVfpRegister s8 = { 8 };
SwVfpRegister s9 = { 9 };
SwVfpRegister s10 = { 10 };
SwVfpRegister s11 = { 11 };
SwVfpRegister s12 = { 12 };
SwVfpRegister s13 = { 13 };
SwVfpRegister s14 = { 14 };
SwVfpRegister s15 = { 15 };
SwVfpRegister s16 = { 16 };
SwVfpRegister s17 = { 17 };
SwVfpRegister s18 = { 18 };
SwVfpRegister s19 = { 19 };
SwVfpRegister s20 = { 20 };
SwVfpRegister s21 = { 21 };
SwVfpRegister s22 = { 22 };
SwVfpRegister s23 = { 23 };
SwVfpRegister s24 = { 24 };
SwVfpRegister s25 = { 25 };
SwVfpRegister s26 = { 26 };
SwVfpRegister s27 = { 27 };
SwVfpRegister s28 = { 28 };
SwVfpRegister s29 = { 29 };
SwVfpRegister s30 = { 30 };
SwVfpRegister s31 = { 31 };
DwVfpRegister d0 = { 0 };
DwVfpRegister d1 = { 1 };
DwVfpRegister d2 = { 2 };
DwVfpRegister d3 = { 3 };
DwVfpRegister d4 = { 4 };
DwVfpRegister d5 = { 5 };
DwVfpRegister d6 = { 6 };
DwVfpRegister d7 = { 7 };
DwVfpRegister d8 = { 8 };
DwVfpRegister d9 = { 9 };
DwVfpRegister d10 = { 10 };
DwVfpRegister d11 = { 11 };
DwVfpRegister d12 = { 12 };
DwVfpRegister d13 = { 13 };
DwVfpRegister d14 = { 14 };
DwVfpRegister d15 = { 15 };
// -----------------------------------------------------------------------------
// Implementation of RelocInfo
......@@ -1371,11 +1371,10 @@ void Assembler::stc2(Coprocessor coproc,
// Support for VFP.
void Assembler::fmdrr(const Register dst,
const Register src1,
const Register src2,
const SBit s,
const Condition cond) {
void Assembler::vmov(const DwVfpRegister dst,
const Register src1,
const Register src2,
const Condition cond) {
// Dm = <Rt,Rt2>.
// Instruction details available in ARM DDI 0406A, A8-646.
// cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) |
......@@ -1387,11 +1386,10 @@ void Assembler::fmdrr(const Register dst,
}
void Assembler::fmrrd(const Register dst1,
const Register dst2,
const Register src,
const SBit s,
const Condition cond) {
void Assembler::vmov(const Register dst1,
const Register dst2,
const DwVfpRegister src,
const Condition cond) {
// <Rt,Rt2> = Dm.
// Instruction details available in ARM DDI 0406A, A8-646.
// cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) |
......@@ -1403,9 +1401,8 @@ void Assembler::fmrrd(const Register dst1,
}
void Assembler::fmsr(const Register dst,
void Assembler::vmov(const SwVfpRegister dst,
const Register src,
const SBit s,
const Condition cond) {
// Sn = Rt.
// Instruction details available in ARM DDI 0406A, A8-642.
......@@ -1418,9 +1415,8 @@ void Assembler::fmsr(const Register dst,
}
void Assembler::fmrs(const Register dst,
const Register src,
const SBit s,
void Assembler::vmov(const Register dst,
const SwVfpRegister src,
const Condition cond) {
// Rt = Sn.
// Instruction details available in ARM DDI 0406A, A8-642.
......@@ -1433,10 +1429,9 @@ void Assembler::fmrs(const Register dst,
}
void Assembler::fsitod(const Register dst,
const Register src,
const SBit s,
const Condition cond) {
void Assembler::vcvt(const DwVfpRegister dst,
const SwVfpRegister src,
const Condition cond) {
// Dd = Sm (integer in Sm converted to IEEE 64-bit doubles in Dd).
// Instruction details available in ARM DDI 0406A, A8-576.
// cond(31-28) | 11101(27-23)| D=?(22) | 11(21-20) | 1(19) |opc2=000(18-16) |
......@@ -1448,10 +1443,9 @@ void Assembler::fsitod(const Register dst,
}
void Assembler::ftosid(const Register dst,
const Register src,
const SBit s,
const Condition cond) {
void Assembler::vcvt(const SwVfpRegister dst,
const DwVfpRegister src,
const Condition cond) {
// Sd = Dm (IEEE 64-bit doubles in Dm converted to 32 bit integer in Sd).
// Instruction details available in ARM DDI 0406A, A8-576.
// cond(31-28) | 11101(27-23)| D=?(22) | 11(21-20) | 1(19) | opc2=101(18-16)|
......@@ -1463,12 +1457,11 @@ void Assembler::ftosid(const Register dst,
}
void Assembler::faddd(const Register dst,
const Register src1,
const Register src2,
const SBit s,
const Condition cond) {
// Dd = faddd(Dn, Dm) double precision floating point addition.
void Assembler::vadd(const DwVfpRegister dst,
const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond) {
// Dd = vadd(Dn, Dm) double precision floating point addition.
// Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
// Instruction details available in ARM DDI 0406A, A8-536.
// cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) |
......@@ -1479,12 +1472,11 @@ void Assembler::faddd(const Register dst,
}
void Assembler::fsubd(const Register dst,
const Register src1,
const Register src2,
const SBit s,
const Condition cond) {
// Dd = fsubd(Dn, Dm) double precision floating point subtraction.
void Assembler::vsub(const DwVfpRegister dst,
const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond) {
// Dd = vsub(Dn, Dm) double precision floating point subtraction.
// Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
// Instruction details available in ARM DDI 0406A, A8-784.
// cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) |
......@@ -1495,12 +1487,11 @@ void Assembler::fsubd(const Register dst,
}
void Assembler::fmuld(const Register dst,
const Register src1,
const Register src2,
const SBit s,
const Condition cond) {
// Dd = fmuld(Dn, Dm) double precision floating point multiplication.
void Assembler::vmul(const DwVfpRegister dst,
const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond) {
// Dd = vmul(Dn, Dm) double precision floating point multiplication.
// Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
// Instruction details available in ARM DDI 0406A, A8-784.
// cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) |
......@@ -1511,12 +1502,11 @@ void Assembler::fmuld(const Register dst,
}
void Assembler::fdivd(const Register dst,
const Register src1,
const Register src2,
const SBit s,
const Condition cond) {
// Dd = fdivd(Dn, Dm) double precision floating point division.
void Assembler::vdiv(const DwVfpRegister dst,
const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond) {
// Dd = vdiv(Dn, Dm) double precision floating point division.
// Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
// Instruction details available in ARM DDI 0406A, A8-584.
// cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) |
......@@ -1527,8 +1517,8 @@ void Assembler::fdivd(const Register dst,
}
void Assembler::fcmp(const Register src1,
const Register src2,
void Assembler::vcmp(const DwVfpRegister src1,
const DwVfpRegister src2,
const SBit s,
const Condition cond) {
// vcmp(Dd, Dm) double precision floating point comparison.
......
......@@ -103,57 +103,94 @@ extern Register sp;
extern Register lr;
extern Register pc;
// Support for VFP registers s0 to s32 (d0 to d16).
// Note that "sN:sM" is the same as "dN/2".
extern Register s0;
extern Register s1;
extern Register s2;
extern Register s3;
extern Register s4;
extern Register s5;
extern Register s6;
extern Register s7;
extern Register s8;
extern Register s9;
extern Register s10;
extern Register s11;
extern Register s12;
extern Register s13;
extern Register s14;
extern Register s15;
extern Register s16;
extern Register s17;
extern Register s18;
extern Register s19;
extern Register s20;
extern Register s21;
extern Register s22;
extern Register s23;
extern Register s24;
extern Register s25;
extern Register s26;
extern Register s27;
extern Register s28;
extern Register s29;
extern Register s30;
extern Register s31;
extern Register d0;
extern Register d1;
extern Register d2;
extern Register d3;
extern Register d4;
extern Register d5;
extern Register d6;
extern Register d7;
extern Register d8;
extern Register d9;
extern Register d10;
extern Register d11;
extern Register d12;
extern Register d13;
extern Register d14;
extern Register d15;
// Single word VFP register.
struct SwVfpRegister {
bool is_valid() const { return 0 <= code_ && code_ < 32; }
bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
int code() const {
ASSERT(is_valid());
return code_;
}
int bit() const {
ASSERT(is_valid());
return 1 << code_;
}
int code_;
};
// Double word VFP register.
struct DwVfpRegister {
// Supporting d0 to d15, can be later extended to d31.
bool is_valid() const { return 0 <= code_ && code_ < 16; }
bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
int code() const {
ASSERT(is_valid());
return code_;
}
int bit() const {
ASSERT(is_valid());
return 1 << code_;
}
int code_;
};
// Support for VFP registers s0 to s31 (d0 to d15).
// Note that "s(N):s(N+1)" is the same as "d(N/2)".
extern SwVfpRegister s0;
extern SwVfpRegister s1;
extern SwVfpRegister s2;
extern SwVfpRegister s3;
extern SwVfpRegister s4;
extern SwVfpRegister s5;
extern SwVfpRegister s6;
extern SwVfpRegister s7;
extern SwVfpRegister s8;
extern SwVfpRegister s9;
extern SwVfpRegister s10;
extern SwVfpRegister s11;
extern SwVfpRegister s12;
extern SwVfpRegister s13;
extern SwVfpRegister s14;
extern SwVfpRegister s15;
extern SwVfpRegister s16;
extern SwVfpRegister s17;
extern SwVfpRegister s18;
extern SwVfpRegister s19;
extern SwVfpRegister s20;
extern SwVfpRegister s21;
extern SwVfpRegister s22;
extern SwVfpRegister s23;
extern SwVfpRegister s24;
extern SwVfpRegister s25;
extern SwVfpRegister s26;
extern SwVfpRegister s27;
extern SwVfpRegister s28;
extern SwVfpRegister s29;
extern SwVfpRegister s30;
extern SwVfpRegister s31;
extern DwVfpRegister d0;
extern DwVfpRegister d1;
extern DwVfpRegister d2;
extern DwVfpRegister d3;
extern DwVfpRegister d4;
extern DwVfpRegister d5;
extern DwVfpRegister d6;
extern DwVfpRegister d7;
extern DwVfpRegister d8;
extern DwVfpRegister d9;
extern DwVfpRegister d10;
extern DwVfpRegister d11;
extern DwVfpRegister d12;
extern DwVfpRegister d13;
extern DwVfpRegister d14;
extern DwVfpRegister d15;
// Coprocessor register
struct CRegister {
......@@ -759,55 +796,45 @@ class Assembler : public Malloced {
// However, some simple modifications can allow
// these APIs to support D16 to D31.
void fmdrr(const Register dst,
const Register src1,
const Register src2,
const SBit s = LeaveCC,
const Condition cond = al);
void fmrrd(const Register dst1,
const Register dst2,
const Register src,
const SBit s = LeaveCC,
const Condition cond = al);
void fmsr(const Register dst,
const Register src,
const SBit s = LeaveCC,
void vmov(const DwVfpRegister dst,
const Register src1,
const Register src2,
const Condition cond = al);
void vmov(const Register dst1,
const Register dst2,
const DwVfpRegister src,
const Condition cond = al);
void fmrs(const Register dst,
void vmov(const SwVfpRegister dst,
const Register src,
const SBit s = LeaveCC,
const Condition cond = al);
void fsitod(const Register dst,
const Register src,
const SBit s = LeaveCC,
const Condition cond = al);
void ftosid(const Register dst,
const Register src,
const SBit s = LeaveCC,
const Condition cond = al);
void faddd(const Register dst,
const Register src1,
const Register src2,
const SBit s = LeaveCC,
const Condition cond = al);
void fsubd(const Register dst,
const Register src1,
const Register src2,
const SBit s = LeaveCC,
const Condition cond = al);
void fmuld(const Register dst,
const Register src1,
const Register src2,
const SBit s = LeaveCC,
const Condition cond = al);
void fdivd(const Register dst,
const Register src1,
const Register src2,
const SBit s = LeaveCC,
const Condition cond = al);
void fcmp(const Register src1,
const Register src2,
void vmov(const Register dst,
const SwVfpRegister src,
const Condition cond = al);
void vcvt(const DwVfpRegister dst,
const SwVfpRegister src,
const Condition cond = al);
void vcvt(const SwVfpRegister dst,
const DwVfpRegister src,
const Condition cond = al);
void vadd(const DwVfpRegister dst,
const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond = al);
void vsub(const DwVfpRegister dst,
const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond = al);
void vmul(const DwVfpRegister dst,
const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond = al);
void vdiv(const DwVfpRegister dst,
const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond = al);
void vcmp(const DwVfpRegister src1,
const DwVfpRegister src2,
const SBit s = LeaveCC,
const Condition cond = al);
void vmrs(const Register dst,
......
......@@ -5061,10 +5061,10 @@ void CompareStub::Generate(MacroAssembler* masm) {
if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
// ARMv7 VFP3 instructions to implement double precision comparison.
__ fmdrr(d6, r0, r1);
__ fmdrr(d7, r2, r3);
__ vmov(d6, r0, r1);
__ vmov(d7, r2, r3);
__ fcmp(d6, d7);
__ vcmp(d6, d7);
__ vmrs(pc);
__ mov(r0, Operand(0), LeaveCC, eq);
__ mov(r0, Operand(1), LeaveCC, lt);
......@@ -5331,22 +5331,22 @@ static void HandleBinaryOpSlowCases(MacroAssembler* masm,
CpuFeatures::Scope scope(VFP3);
// ARMv7 VFP3 instructions to implement
// double precision, add, subtract, multiply, divide.
__ fmdrr(d6, r0, r1);
__ fmdrr(d7, r2, r3);
__ vmov(d6, r0, r1);
__ vmov(d7, r2, r3);
if (Token::MUL == operation) {
__ fmuld(d5, d6, d7);
__ vmul(d5, d6, d7);
} else if (Token::DIV == operation) {
__ fdivd(d5, d6, d7);
__ vdiv(d5, d6, d7);
} else if (Token::ADD == operation) {
__ faddd(d5, d6, d7);
__ vadd(d5, d6, d7);
} else if (Token::SUB == operation) {
__ fsubd(d5, d6, d7);
__ vsub(d5, d6, d7);
} else {
UNREACHABLE();
}
__ fmrrd(r0, r1, d5);
__ vmov(r0, r1, d5);
__ str(r0, FieldMemOperand(r5, HeapNumber::kValueOffset));
__ str(r1, FieldMemOperand(r5, HeapNumber::kValueOffset + 4));
......@@ -5435,9 +5435,9 @@ static void GetInt32(MacroAssembler* masm,
// ARMv7 VFP3 instructions implementing double precision to integer
// conversion using round to zero.
__ ldr(scratch2, FieldMemOperand(source, HeapNumber::kMantissaOffset));
__ fmdrr(d7, scratch2, scratch);
__ ftosid(s15, d7);
__ fmrs(dest, s15);
__ vmov(d7, scratch2, scratch);
__ vcvt(s15, d7);
__ vmov(dest, s15);
} else {
// Get the top bits of the mantissa.
__ and_(scratch2, scratch, Operand(HeapNumber::kMantissaMask));
......
......@@ -897,15 +897,14 @@ void Decoder::DecodeUnconditional(Instr* instr) {
// void Decoder::DecodeTypeVFP(Instr* instr)
// Implements the following VFP instructions:
// fmsr: Sn = Rt
// fmrs: Rt = Sn
// fsitod: Dd = Sm
// ftosid: Sd = Dm
// Dd = faddd(Dn, Dm)
// Dd = fsubd(Dn, Dm)
// Dd = fmuld(Dn, Dm)
// Dd = fdivd(Dn, Dm)
// vmov: Sn = Rt
// vmov: Rt = Sn
// vcvt: Dd = Sm
// vcvt: Sd = Dm
// Dd = vadd(Dn, Dm)
// Dd = vsub(Dn, Dm)
// Dd = vmul(Dn, Dm)
// Dd = vdiv(Dn, Dm)
// vcmp(Dd, Dm)
// VMRS
void Decoder::DecodeTypeVFP(Instr* instr) {
......@@ -997,8 +996,8 @@ void Decoder::DecodeTypeVFP(Instr* instr) {
// Decode Type 6 coprocessor instructions.
// Dm = fmdrr(Rt, Rt2)
// <Rt, Rt2> = fmrrd(Dm)
// Dm = vmov(Rt, Rt2)
// <Rt, Rt2> = vmov(Dm)
void Decoder::DecodeType6CoprocessorIns(Instr* instr) {
ASSERT((instr->TypeField() == 6));
......
......@@ -994,9 +994,9 @@ void MacroAssembler::IntegerToDoubleConversionWithVFP3(Register inReg,
Register outLowReg) {
// ARMv7 VFP3 instructions to implement integer to double conversion.
mov(r7, Operand(inReg, ASR, kSmiTagSize));
fmsr(s15, r7);
fsitod(d7, s15);
fmrrd(outLowReg, outHighReg, d7);
vmov(s15, r7);
vcvt(d7, s15);
vmov(outLowReg, outHighReg, d7);
}
......
......@@ -1893,14 +1893,14 @@ void Simulator::DecodeUnconditional(Instr* instr) {
// void Simulator::DecodeTypeVFP(Instr* instr)
// The Following ARMv7 VFPv instructions are currently supported.
// fmsr :Sn = Rt
// fmrs :Rt = Sn
// fsitod: Dd = Sm
// ftosid: Sd = Dm
// Dd = faddd(Dn, Dm)
// Dd = fsubd(Dn, Dm)
// Dd = fmuld(Dn, Dm)
// Dd = fdivd(Dn, Dm)
// vmov :Sn = Rt
// vmov :Rt = Sn
// vcvt: Dd = Sm
// vcvt: Sd = Dm
// Dd = vadd(Dn, Dm)
// Dd = vsub(Dn, Dm)
// Dd = vmul(Dn, Dm)
// Dd = vdiv(Dn, Dm)
// vcmp(Dd, Dm)
// VMRS
void Simulator::DecodeTypeVFP(Instr* instr) {
......@@ -2020,8 +2020,8 @@ void Simulator::DecodeTypeVFP(Instr* instr) {
// void Simulator::DecodeType6CoprocessorIns(Instr* instr)
// Decode Type 6 coprocessor instructions.
// Dm = fmdrr(Rt, Rt2)
// <Rt, Rt2> = fmrrd(Dm)
// Dm = vmov(Rt, Rt2)
// <Rt, Rt2> = vmov(Dm)
void Simulator::DecodeType6CoprocessorIns(Instr* instr) {
ASSERT((instr->TypeField() == 6));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment