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:
parent
77f6a6fc31
commit
b571bd2ce9
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
// The original source code covered by the above license above has been
|
// The original source code covered by the above license above has been
|
||||||
// modified significantly by Google Inc.
|
// 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_
|
#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.
|
// RelocInfo.
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
// The original source code covered by the above license above has been
|
// The original source code covered by the above license above has been
|
||||||
// modified significantly by Google Inc.
|
// 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_
|
#ifndef V8_MIPS_ASSEMBLER_MIPS_H_
|
||||||
@ -182,12 +182,7 @@ struct FPURegister {
|
|||||||
kNumReservedRegisters;
|
kNumReservedRegisters;
|
||||||
|
|
||||||
|
|
||||||
static int ToAllocationIndex(FPURegister reg) {
|
inline static int ToAllocationIndex(FPURegister reg);
|
||||||
ASSERT(reg.code() % 2 == 0);
|
|
||||||
ASSERT(reg.code() / 2 < kNumAllocatableRegisters);
|
|
||||||
ASSERT(reg.is_valid());
|
|
||||||
return (reg.code() / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static FPURegister FromAllocationIndex(int index) {
|
static FPURegister FromAllocationIndex(int index) {
|
||||||
ASSERT(index >= 0 && index < kNumAllocatableRegisters);
|
ASSERT(index >= 0 && index < kNumAllocatableRegisters);
|
||||||
@ -302,6 +297,14 @@ const FPURegister f29 = { 29 };
|
|||||||
const FPURegister f30 = { 30 };
|
const FPURegister f30 = { 30 };
|
||||||
const FPURegister f31 = { 31 };
|
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;
|
static const FPURegister& kDoubleRegZero = f28;
|
||||||
|
|
||||||
// FPU (coprocessor 1) control registers.
|
// FPU (coprocessor 1) control registers.
|
||||||
|
@ -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
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
// met:
|
// met:
|
||||||
@ -34,7 +34,6 @@ namespace v8 {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
static const Register kSavedValueRegister = kLithiumScratchReg;
|
static const Register kSavedValueRegister = kLithiumScratchReg;
|
||||||
static const DoubleRegister kSavedDoubleValueRegister = kLithiumScratchDouble;
|
|
||||||
|
|
||||||
LGapResolver::LGapResolver(LCodeGen* owner)
|
LGapResolver::LGapResolver(LCodeGen* owner)
|
||||||
: cgen_(owner),
|
: cgen_(owner),
|
||||||
@ -175,9 +174,9 @@ void LGapResolver::BreakCycle(int index) {
|
|||||||
} else if (source->IsStackSlot()) {
|
} else if (source->IsStackSlot()) {
|
||||||
__ lw(kSavedValueRegister, cgen_->ToMemOperand(source));
|
__ lw(kSavedValueRegister, cgen_->ToMemOperand(source));
|
||||||
} else if (source->IsDoubleRegister()) {
|
} else if (source->IsDoubleRegister()) {
|
||||||
__ mov_d(kSavedDoubleValueRegister, cgen_->ToDoubleRegister(source));
|
__ mov_d(kLithiumScratchDouble, cgen_->ToDoubleRegister(source));
|
||||||
} else if (source->IsDoubleStackSlot()) {
|
} else if (source->IsDoubleStackSlot()) {
|
||||||
__ ldc1(kSavedDoubleValueRegister, cgen_->ToMemOperand(source));
|
__ ldc1(kLithiumScratchDouble, cgen_->ToMemOperand(source));
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -190,16 +189,16 @@ void LGapResolver::RestoreValue() {
|
|||||||
ASSERT(in_cycle_);
|
ASSERT(in_cycle_);
|
||||||
ASSERT(saved_destination_ != NULL);
|
ASSERT(saved_destination_ != NULL);
|
||||||
|
|
||||||
// Spilled value is in kSavedValueRegister or kSavedDoubleValueRegister.
|
// Spilled value is in kSavedValueRegister or kLithiumScratchDouble.
|
||||||
if (saved_destination_->IsRegister()) {
|
if (saved_destination_->IsRegister()) {
|
||||||
__ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
|
__ mov(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
|
||||||
} else if (saved_destination_->IsStackSlot()) {
|
} else if (saved_destination_->IsStackSlot()) {
|
||||||
__ sw(kSavedValueRegister, cgen_->ToMemOperand(saved_destination_));
|
__ sw(kSavedValueRegister, cgen_->ToMemOperand(saved_destination_));
|
||||||
} else if (saved_destination_->IsDoubleRegister()) {
|
} else if (saved_destination_->IsDoubleRegister()) {
|
||||||
__ mov_d(cgen_->ToDoubleRegister(saved_destination_),
|
__ mov_d(cgen_->ToDoubleRegister(saved_destination_),
|
||||||
kSavedDoubleValueRegister);
|
kLithiumScratchDouble);
|
||||||
} else if (saved_destination_->IsDoubleStackSlot()) {
|
} else if (saved_destination_->IsDoubleStackSlot()) {
|
||||||
__ sdc1(kSavedDoubleValueRegister,
|
__ sdc1(kLithiumScratchDouble,
|
||||||
cgen_->ToMemOperand(saved_destination_));
|
cgen_->ToMemOperand(saved_destination_));
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
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
|
// 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.
|
// destroys 'at', since that happens before the value is read.
|
||||||
// This uses only a single reg of the double reg-pair.
|
// This uses only a single reg of the double reg-pair.
|
||||||
__ lwc1(kSavedDoubleValueRegister, source_operand);
|
__ lwc1(kLithiumScratchDouble, source_operand);
|
||||||
__ swc1(kSavedDoubleValueRegister, destination_operand);
|
__ swc1(kLithiumScratchDouble, destination_operand);
|
||||||
} else {
|
} else {
|
||||||
__ lw(at, source_operand);
|
__ lw(at, source_operand);
|
||||||
__ sw(at, destination_operand);
|
__ sw(at, destination_operand);
|
||||||
@ -291,7 +290,7 @@ void LGapResolver::EmitMove(int index) {
|
|||||||
ASSERT(destination->IsDoubleStackSlot());
|
ASSERT(destination->IsDoubleStackSlot());
|
||||||
MemOperand destination_operand = cgen_->ToMemOperand(destination);
|
MemOperand destination_operand = cgen_->ToMemOperand(destination);
|
||||||
if (in_cycle_) {
|
if (in_cycle_) {
|
||||||
// kSavedDoubleValueRegister was used to break the cycle,
|
// kLithiumScratchDouble was used to break the cycle,
|
||||||
// but kSavedValueRegister is free.
|
// but kSavedValueRegister is free.
|
||||||
MemOperand source_high_operand =
|
MemOperand source_high_operand =
|
||||||
cgen_->ToHighMemOperand(source);
|
cgen_->ToHighMemOperand(source);
|
||||||
@ -302,8 +301,8 @@ void LGapResolver::EmitMove(int index) {
|
|||||||
__ lw(kSavedValueRegister, source_high_operand);
|
__ lw(kSavedValueRegister, source_high_operand);
|
||||||
__ sw(kSavedValueRegister, destination_high_operand);
|
__ sw(kSavedValueRegister, destination_high_operand);
|
||||||
} else {
|
} else {
|
||||||
__ ldc1(kSavedDoubleValueRegister, source_operand);
|
__ ldc1(kLithiumScratchDouble, source_operand);
|
||||||
__ sdc1(kSavedDoubleValueRegister, destination_operand);
|
__ sdc1(kLithiumScratchDouble, destination_operand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,16 +51,6 @@ class JumpTarget;
|
|||||||
// MIPS generated code calls C code, it must be via t9 register.
|
// 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.
|
// Flags used for the AllocateInNewSpace functions.
|
||||||
enum AllocationFlags {
|
enum AllocationFlags {
|
||||||
// No special flags.
|
// No special flags.
|
||||||
|
Loading…
Reference in New Issue
Block a user