MIPS: Fix for an ARM register allocation bug.

Port r10374 (03bbe39).

Note: the MIPS version was not affected by the bug. This is merely a style cleanup.

Original commit message:
An off-by-one in the register allocator could lead to allocating (and
clobbering) the reserved 0.0 double register.  This required a function with
14 or more live double values.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9150025
Patch from Daniel Kalmar <kalmard@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10440 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kmillikin@chromium.org 2012-01-19 13:41:11 +00:00
parent 77f6a6fc31
commit b571bd2ce9
4 changed files with 32 additions and 30 deletions

View File

@ -30,7 +30,7 @@
// The original source code covered by the above license above has been
// modified significantly by Google Inc.
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
#ifndef V8_MIPS_ASSEMBLER_MIPS_INL_H_
@ -78,6 +78,16 @@ bool Operand::is_reg() const {
}
int FPURegister::ToAllocationIndex(FPURegister reg) {
ASSERT(reg.code() % 2 == 0);
ASSERT(reg.code() / 2 < kNumAllocatableRegisters);
ASSERT(reg.is_valid());
ASSERT(!reg.is(kDoubleRegZero));
ASSERT(!reg.is(kLithiumScratchDouble));
return (reg.code() / 2);
}
// -----------------------------------------------------------------------------
// RelocInfo.

View File

@ -30,7 +30,7 @@
// The original source code covered by the above license above has been
// modified significantly by Google Inc.
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
#ifndef V8_MIPS_ASSEMBLER_MIPS_H_
@ -182,12 +182,7 @@ struct FPURegister {
kNumReservedRegisters;
static int ToAllocationIndex(FPURegister reg) {
ASSERT(reg.code() % 2 == 0);
ASSERT(reg.code() / 2 < kNumAllocatableRegisters);
ASSERT(reg.is_valid());
return (reg.code() / 2);
}
inline static int ToAllocationIndex(FPURegister reg);
static FPURegister FromAllocationIndex(int index) {
ASSERT(index >= 0 && index < kNumAllocatableRegisters);
@ -302,6 +297,14 @@ const FPURegister f29 = { 29 };
const FPURegister f30 = { 30 };
const FPURegister f31 = { 31 };
// Register aliases.
// cp is assumed to be a callee saved register.
static const Register& kLithiumScratchReg = s3; // Scratch register.
static const Register& kLithiumScratchReg2 = s4; // Scratch register.
static const Register& kRootRegister = s6; // Roots array pointer.
static const Register& cp = s7; // JavaScript context pointer.
static const Register& fp = s8_fp; // Alias for fp.
static const DoubleRegister& kLithiumScratchDouble = f30;
static const FPURegister& kDoubleRegZero = f28;
// FPU (coprocessor 1) control registers.

View File

@ -1,4 +1,4 @@
// Copyright 2011 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@ -34,7 +34,6 @@ namespace v8 {
namespace internal {
static const Register kSavedValueRegister = kLithiumScratchReg;
static const DoubleRegister kSavedDoubleValueRegister = kLithiumScratchDouble;
LGapResolver::LGapResolver(LCodeGen* owner)
: cgen_(owner),
@ -175,9 +174,9 @@ void LGapResolver::BreakCycle(int index) {
} else if (source->IsStackSlot()) {
__ lw(kSavedValueRegister, cgen_->ToMemOperand(source));
} else if (source->IsDoubleRegister()) {
__ mov_d(kSavedDoubleValueRegister, cgen_->ToDoubleRegister(source));
__ mov_d(kLithiumScratchDouble, cgen_->ToDoubleRegister(source));
} else if (source->IsDoubleStackSlot()) {
__ ldc1(kSavedDoubleValueRegister, cgen_->ToMemOperand(source));
__ ldc1(kLithiumScratchDouble, cgen_->ToMemOperand(source));
} else {
UNREACHABLE();
}
@ -190,16 +189,16 @@ void LGapResolver::RestoreValue() {
ASSERT(in_cycle_);
ASSERT(saved_destination_ != NULL);
// Spilled value is in kSavedValueRegister or kSavedDoubleValueRegister.
// Spilled value is in kSavedValueRegister or kLithiumScratchDouble.
if (saved_destination_->IsRegister()) {
__ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
} else if (saved_destination_->IsStackSlot()) {
__ sw(kSavedValueRegister, cgen_->ToMemOperand(saved_destination_));
} else if (saved_destination_->IsDoubleRegister()) {
__ mov_d(cgen_->ToDoubleRegister(saved_destination_),
kSavedDoubleValueRegister);
kLithiumScratchDouble);
} else if (saved_destination_->IsDoubleStackSlot()) {
__ sdc1(kSavedDoubleValueRegister,
__ sdc1(kLithiumScratchDouble,
cgen_->ToMemOperand(saved_destination_));
} else {
UNREACHABLE();
@ -239,8 +238,8 @@ void LGapResolver::EmitMove(int index) {
// Therefore we can't use 'at'. It is OK if the read from the source
// destroys 'at', since that happens before the value is read.
// This uses only a single reg of the double reg-pair.
__ lwc1(kSavedDoubleValueRegister, source_operand);
__ swc1(kSavedDoubleValueRegister, destination_operand);
__ lwc1(kLithiumScratchDouble, source_operand);
__ swc1(kLithiumScratchDouble, destination_operand);
} else {
__ lw(at, source_operand);
__ sw(at, destination_operand);
@ -291,7 +290,7 @@ void LGapResolver::EmitMove(int index) {
ASSERT(destination->IsDoubleStackSlot());
MemOperand destination_operand = cgen_->ToMemOperand(destination);
if (in_cycle_) {
// kSavedDoubleValueRegister was used to break the cycle,
// kLithiumScratchDouble was used to break the cycle,
// but kSavedValueRegister is free.
MemOperand source_high_operand =
cgen_->ToHighMemOperand(source);
@ -302,8 +301,8 @@ void LGapResolver::EmitMove(int index) {
__ lw(kSavedValueRegister, source_high_operand);
__ sw(kSavedValueRegister, destination_high_operand);
} else {
__ ldc1(kSavedDoubleValueRegister, source_operand);
__ sdc1(kSavedDoubleValueRegister, destination_operand);
__ ldc1(kLithiumScratchDouble, source_operand);
__ sdc1(kLithiumScratchDouble, destination_operand);
}
}
} else {

View File

@ -51,16 +51,6 @@ class JumpTarget;
// MIPS generated code calls C code, it must be via t9 register.
// Register aliases.
// cp is assumed to be a callee saved register.
const Register kLithiumScratchReg = s3; // Scratch register.
const Register kLithiumScratchReg2 = s4; // Scratch register.
const Register kCondReg = s5; // Simulated (partial) condition code for mips.
const Register kRootRegister = s6; // Roots array pointer.
const Register cp = s7; // JavaScript context pointer.
const Register fp = s8_fp; // Alias for fp.
const DoubleRegister kLithiumScratchDouble = f30; // Double scratch register.
// Flags used for the AllocateInNewSpace functions.
enum AllocationFlags {
// No special flags.