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
|
||||
// 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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user