Increases the number of ARM floating-point registers.
This is to be consistent with VFPv3_D32. Later, we'll detect VFPv3_D16 at runtime. R=regis@google.com Review URL: https://codereview.chromium.org//19806005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25352 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -917,18 +917,20 @@ void Assembler::vstms(BlockAddressMode am, Register base,
|
||||
|
||||
|
||||
void Assembler::vldmd(BlockAddressMode am, Register base,
|
||||
DRegister first, DRegister last, Condition cond) {
|
||||
DRegister first, intptr_t count, Condition cond) {
|
||||
ASSERT((am == IA) || (am == IA_W) || (am == DB_W));
|
||||
ASSERT(last > first);
|
||||
EmitMultiVDMemOp(cond, am, true, base, first, last - first + 1);
|
||||
ASSERT(count <= 16);
|
||||
ASSERT(first + count <= kNumberOfDRegisters);
|
||||
EmitMultiVDMemOp(cond, am, true, base, first, count);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::vstmd(BlockAddressMode am, Register base,
|
||||
DRegister first, DRegister last, Condition cond) {
|
||||
DRegister first, intptr_t count, Condition cond) {
|
||||
ASSERT((am == IA) || (am == IA_W) || (am == DB_W));
|
||||
ASSERT(last > first);
|
||||
EmitMultiVDMemOp(cond, am, false, base, first, last - first + 1);
|
||||
ASSERT(count <= 16);
|
||||
ASSERT(first + count <= kNumberOfDRegisters);
|
||||
EmitMultiVDMemOp(cond, am, false, base, first, count);
|
||||
}
|
||||
|
||||
|
||||
@@ -2281,7 +2283,13 @@ void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
|
||||
// Preserve all volatile FPU registers.
|
||||
DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg);
|
||||
DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg);
|
||||
vstmd(DB_W, SP, firstv, lastv);
|
||||
if ((lastv - firstv + 1) >= 16) {
|
||||
DRegister mid = static_cast<DRegister>(firstv + 16);
|
||||
vstmd(DB_W, SP, mid, lastv - mid + 1);
|
||||
vstmd(DB_W, SP, firstv, 16);
|
||||
} else {
|
||||
vstmd(DB_W, SP, firstv, lastv - firstv + 1);
|
||||
}
|
||||
|
||||
ReserveAlignedFrameSpace(frame_space);
|
||||
}
|
||||
@@ -2299,7 +2307,13 @@ void Assembler::LeaveCallRuntimeFrame() {
|
||||
// Restore all volatile FPU registers.
|
||||
DRegister firstv = EvenDRegisterOf(kDartFirstVolatileFpuReg);
|
||||
DRegister lastv = OddDRegisterOf(kDartLastVolatileFpuReg);
|
||||
vldmd(IA_W, SP, firstv, lastv);
|
||||
if ((lastv - firstv + 1) > 16) {
|
||||
DRegister mid = static_cast<DRegister>(firstv + 16);
|
||||
vldmd(IA_W, SP, firstv, 16);
|
||||
vldmd(IA_W, SP, mid, lastv - mid + 1);
|
||||
} else {
|
||||
vldmd(IA_W, SP, firstv, lastv - firstv + 1);
|
||||
}
|
||||
|
||||
// Restore volatile CPU registers.
|
||||
LeaveFrame(kDartVolatileCpuRegs | (1 << FP) | (1 << LR));
|
||||
|
||||
@@ -461,9 +461,9 @@ class Assembler : public ValueObject {
|
||||
SRegister first, SRegister last, Condition cond = AL);
|
||||
|
||||
void vldmd(BlockAddressMode am, Register base,
|
||||
DRegister first, DRegister last, Condition cond = AL);
|
||||
DRegister first, intptr_t count, Condition cond = AL);
|
||||
void vstmd(BlockAddressMode am, Register base,
|
||||
DRegister first, DRegister last, Condition cond = AL);
|
||||
DRegister first, intptr_t count, Condition cond = AL);
|
||||
|
||||
void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
|
||||
void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
|
||||
|
||||
@@ -1094,13 +1094,13 @@ ASSEMBLER_TEST_GENERATE(VstmdVldmd, assembler) {
|
||||
__ LoadDImmediate(D2, 2.0, R0);
|
||||
__ LoadDImmediate(D3, 3.0, R0);
|
||||
__ LoadDImmediate(D4, 4.0, R0);
|
||||
__ vstmd(DB_W, SP, D0, D4); // Push D0 - D4 onto the stack, dec SP
|
||||
__ vstmd(DB_W, SP, D0, 5); // Push D0 - D4 onto the stack, dec SP
|
||||
__ LoadDImmediate(D0, 0.0, R0);
|
||||
__ LoadDImmediate(D1, 0.0, R0);
|
||||
__ LoadDImmediate(D2, 0.0, R0);
|
||||
__ LoadDImmediate(D3, 0.0, R0);
|
||||
__ LoadDImmediate(D4, 0.0, R0);
|
||||
__ vldmd(IA_W, SP, D0, D4); // Pop stack into D0 - D4, inc SP
|
||||
__ vldmd(IA_W, SP, D0, 5); // Pop stack into D0 - D4, inc SP
|
||||
|
||||
// Load success value into R0
|
||||
__ mov(R0, ShifterOperand(42));
|
||||
@@ -1200,12 +1200,12 @@ ASSEMBLER_TEST_GENERATE(VstmdVldmd1, assembler) {
|
||||
__ LoadDImmediate(D2, 2.0, R0);
|
||||
__ LoadDImmediate(D3, 3.0, R0);
|
||||
__ LoadDImmediate(D4, 4.0, R0);
|
||||
__ vstmd(DB_W, SP, D1, D4); // Push D1 - D4 onto the stack, dec SP
|
||||
__ vstmd(DB_W, SP, D1, 4); // Push D1 - D4 onto the stack, dec SP
|
||||
__ LoadDImmediate(D1, 0.0, R0);
|
||||
__ LoadDImmediate(D2, 0.0, R0);
|
||||
__ LoadDImmediate(D3, 0.0, R0);
|
||||
__ LoadDImmediate(D4, 0.0, R0);
|
||||
__ vldmd(IA_W, SP, D1, D4); // Pop stack into D1 - D4, inc SP
|
||||
__ vldmd(IA_W, SP, D1, 4); // Pop stack into D1 - D4, inc SP
|
||||
|
||||
// Load success value into R0
|
||||
__ mov(R0, ShifterOperand(42));
|
||||
@@ -1306,8 +1306,8 @@ ASSEMBLER_TEST_GENERATE(VstmdVldmd_off, assembler) {
|
||||
__ LoadDImmediate(D3, 3.0, R0);
|
||||
__ LoadDImmediate(D4, 4.0, R0);
|
||||
__ LoadDImmediate(D5, 5.0, R0);
|
||||
__ vstmd(DB_W, SP, D0, D4); // Push D0 - D4 onto the stack, dec SP
|
||||
__ vldmd(IA_W, SP, D5, D9); // Pop stack into D5 - D9, inc SP
|
||||
__ vstmd(DB_W, SP, D0, 5); // Push D0 - D4 onto the stack, dec SP
|
||||
__ vldmd(IA_W, SP, D5, 5); // Pop stack into D5 - D9, inc SP
|
||||
|
||||
// Load success value into R0
|
||||
__ mov(R0, ShifterOperand(42));
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace dart {
|
||||
// We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at
|
||||
// a time.
|
||||
// TODO(zra): Detect number of registers at runtime by querying /proc/cpuinfo.
|
||||
#define VFPv3_D16
|
||||
#define VFPv3_D32
|
||||
#if defined(VFPv3_D16) == defined(VFPv3_D32)
|
||||
#error "Exactly one of VFPv3_D16 or VFPv3_D32 can be defined at a time."
|
||||
#endif
|
||||
|
||||
@@ -2947,8 +2947,9 @@ LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
|
||||
const intptr_t kNumTemps = 0;
|
||||
LocationSummary* summary =
|
||||
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
||||
summary->set_in(0, Location::RequiresFpuRegister());
|
||||
summary->set_out(Location::RequiresFpuRegister());
|
||||
// Low (< Q7) Q registers are needed for the vcvtds instruction.
|
||||
summary->set_in(0, Location::FpuRegisterLocation(Q5));
|
||||
summary->set_out(Location::FpuRegisterLocation(Q6));
|
||||
return summary;
|
||||
}
|
||||
|
||||
@@ -3009,7 +3010,8 @@ LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const {
|
||||
summary->set_in(1, Location::RequiresFpuRegister());
|
||||
summary->set_in(2, Location::RequiresFpuRegister());
|
||||
summary->set_in(3, Location::RequiresFpuRegister());
|
||||
summary->set_out(Location::RequiresFpuRegister());
|
||||
// Low (< 7) Q registers are needed for the vcvtsd instruction.
|
||||
summary->set_out(Location::FpuRegisterLocation(Q6));
|
||||
return summary;
|
||||
}
|
||||
|
||||
@@ -3179,7 +3181,8 @@ LocationSummary* Float32x4WithInstr::MakeLocationSummary() const {
|
||||
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
||||
summary->set_in(0, Location::RequiresFpuRegister());
|
||||
summary->set_in(1, Location::RequiresFpuRegister());
|
||||
summary->set_out(Location::RequiresFpuRegister());
|
||||
// Low (< 7) Q registers are needed for the vmovs instruction.
|
||||
summary->set_out(Location::FpuRegisterLocation(Q6));
|
||||
return summary;
|
||||
}
|
||||
|
||||
@@ -3246,7 +3249,8 @@ LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const {
|
||||
const intptr_t kNumTemps = 0;
|
||||
LocationSummary* summary =
|
||||
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
||||
summary->set_in(0, Location::RequiresFpuRegister());
|
||||
// Low (< 7) Q registers are needed for the vmovrs instruction.
|
||||
summary->set_in(0, Location::FpuRegisterLocation(Q6));
|
||||
summary->set_out(Location::RequiresRegister());
|
||||
return summary;
|
||||
}
|
||||
|
||||
+17
-13
@@ -2504,20 +2504,24 @@ void Simulator::DecodeType6(Instr* instr) {
|
||||
} else {
|
||||
int32_t regs_cnt = imm_val >> 1;
|
||||
int32_t start = (instr->Bit(22) << 4) | instr->Bits(12, 4);
|
||||
for (int i = start; i < start + regs_cnt; i++) {
|
||||
DRegister dd = static_cast<DRegister>(i);
|
||||
if (instr->Bit(20) == 1) {
|
||||
// Format(instr, "vldmd'cond'pu 'rn'w, 'dlist");
|
||||
int64_t dd_val = Utils::LowHighTo64Bits(ReadW(addr, instr),
|
||||
ReadW(addr + 4, instr));
|
||||
set_dregister_bits(dd, dd_val);
|
||||
} else {
|
||||
// Format(instr, "vstmd'cond'pu 'rn'w, 'dlist");
|
||||
int64_t dd_val = get_dregister_bits(dd);
|
||||
WriteW(addr, Utils::Low32Bits(dd_val), instr);
|
||||
WriteW(addr + 4, Utils::High32Bits(dd_val), instr);
|
||||
if ((regs_cnt <= 16) && (start + regs_cnt <= kNumberOfDRegisters)) {
|
||||
for (int i = start; i < start + regs_cnt; i++) {
|
||||
DRegister dd = static_cast<DRegister>(i);
|
||||
if (instr->Bit(20) == 1) {
|
||||
// Format(instr, "vldmd'cond'pu 'rn'w, 'dlist");
|
||||
int64_t dd_val = Utils::LowHighTo64Bits(ReadW(addr, instr),
|
||||
ReadW(addr + 4, instr));
|
||||
set_dregister_bits(dd, dd_val);
|
||||
} else {
|
||||
// Format(instr, "vstmd'cond'pu 'rn'w, 'dlist");
|
||||
int64_t dd_val = get_dregister_bits(dd);
|
||||
WriteW(addr, Utils::Low32Bits(dd_val), instr);
|
||||
WriteW(addr + 4, Utils::High32Bits(dd_val), instr);
|
||||
}
|
||||
addr += 8;
|
||||
}
|
||||
addr += 8;
|
||||
} else {
|
||||
UnimplementedInstruction(instr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +352,12 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
|
||||
// lowest address.
|
||||
__ PushList(kAllCpuRegistersList);
|
||||
ASSERT(kFpuRegisterSize == 4 * kWordSize);
|
||||
__ vstmd(DB_W, SP, D0, static_cast<DRegister>(kNumberOfDRegisters - 1));
|
||||
if (kNumberOfDRegisters > 16) {
|
||||
__ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16);
|
||||
__ vstmd(DB_W, SP, D0, 16);
|
||||
} else {
|
||||
__ vstmd(DB_W, SP, D0, kNumberOfDRegisters);
|
||||
}
|
||||
|
||||
__ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block.
|
||||
__ ReserveAlignedFrameSpace(0);
|
||||
|
||||
Reference in New Issue
Block a user