Commit f53fda63 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: Remove register index/code indirection

Port 5cf1c0bc

Original commit message:
    Previous to this patch, both the lithium and TurboFan register
    allocators tracked allocated registers by "indices", rather than
    the register codes used elsewhere in the runtime. This patch
    ensures that codes are used everywhere, and in the process cleans
    up a bunch of redundant code and adds more structure to how the
    set of allocatable registers is defined.

    Some highlights of changes:

    * TurboFan's RegisterConfiguration class moved to V8's top level
      so that it can be shared with Crankshaft.
    * Various "ToAllocationIndex" and related methods removed.
    * Code that can be easily shared between Register classes on
      different platforms is now shared.
    * The list of allocatable registers on each platform is declared
      as a list rather than implicitly via the register index <->
      code mapping.

R=danno@chromium.org, bmeurer@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, dstence@us.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1381383002

Cr-Commit-Position: refs/heads/master@{#31114}
parent 57ca0f36
......@@ -128,16 +128,6 @@ Register ToRegister(int num) {
}
const char* DoubleRegister::AllocationIndexToString(int index) {
DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
const char* const names[] = {
"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10",
"d11", "d12", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
"d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
return names[index];
}
// -----------------------------------------------------------------------------
// Implementation of RelocInfo
......@@ -286,14 +276,14 @@ bool Assembler::IsBranch(Instr instr) { return ((instr & kOpcodeMask) == BCX); }
Register Assembler::GetRA(Instr instr) {
Register reg;
reg.code_ = Instruction::RAValue(instr);
reg.reg_code = Instruction::RAValue(instr);
return reg;
}
Register Assembler::GetRB(Instr instr) {
Register reg;
reg.code_ = Instruction::RBValue(instr);
reg.reg_code = Instruction::RBValue(instr);
return reg;
}
......
This diff is collapsed.
......@@ -14,45 +14,18 @@ namespace internal {
// formatting. See for example the command "objdump -d <binary file>".
const char* Registers::names_[kNumRegisters] = {
"r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
"r11", "ip", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
"r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "fp"};
// List of alias names which can be used when referring to PPC registers.
const Registers::RegisterAlias Registers::aliases_[] = {{10, "sl"},
{11, "r11"},
{12, "r12"},
{13, "r13"},
{14, "r14"},
{15, "r15"},
{kNoRegister, NULL}};
const char* Registers::Name(int reg) {
const char* result;
if ((0 <= reg) && (reg < kNumRegisters)) {
result = names_[reg];
} else {
result = "noreg";
}
return result;
}
const char* FPRegisters::names_[kNumFPRegisters] = {
const char* DoubleRegisters::names_[kNumDoubleRegisters] = {
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10",
"d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21",
"d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
const char* FPRegisters::Name(int reg) {
DCHECK((0 <= reg) && (reg < kNumFPRegisters));
return names_[reg];
}
int FPRegisters::Number(const char* name) {
for (int i = 0; i < kNumFPRegisters; i++) {
int DoubleRegisters::Number(const char* name) {
for (int i = 0; i < kNumDoubleRegisters; i++) {
if (strcmp(names_[i], name) == 0) {
return i;
}
......@@ -71,15 +44,6 @@ int Registers::Number(const char* name) {
}
}
// Look through the alias names.
int i = 0;
while (aliases_[i].reg != kNoRegister) {
if (strcmp(aliases_[i].name, name) == 0) {
return aliases_[i].reg;
}
i++;
}
// No register with the requested name found.
return kNoRegister;
}
......
......@@ -18,8 +18,7 @@ namespace internal {
const int kNumRegisters = 32;
// FP support.
const int kNumFPDoubleRegisters = 32;
const int kNumFPRegisters = kNumFPDoubleRegisters;
const int kNumDoubleRegisters = 32;
const int kNoRegister = -1;
......@@ -564,33 +563,21 @@ class Instruction {
// Helper functions for converting between register numbers and names.
class Registers {
public:
// Return the name of the register.
static const char* Name(int reg);
// Lookup the register number for the name provided.
static int Number(const char* name);
struct RegisterAlias {
int reg;
const char* name;
};
private:
static const char* names_[kNumRegisters];
static const RegisterAlias aliases_[];
};
// Helper functions for converting between FP register numbers and names.
class FPRegisters {
class DoubleRegisters {
public:
// Return the name of the register.
static const char* Name(int reg);
// Lookup the register number for the name provided.
static int Number(const char* name);
private:
static const char* names_[kNumFPRegisters];
static const char* names_[kNumDoubleRegisters];
};
} // namespace internal
} // namespace v8
......
......@@ -5,6 +5,7 @@
#include "src/codegen.h"
#include "src/deoptimizer.h"
#include "src/full-codegen/full-codegen.h"
#include "src/register-configuration.h"
#include "src/safepoint-table.h"
namespace v8 {
......@@ -99,7 +100,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
}
input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0);
}
......@@ -123,7 +124,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters(
void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) {
for (int i = 0; i < DoubleRegister::kNumRegisters; ++i) {
double double_value = input_->GetDoubleRegister(i);
output_frame->SetDoubleRegister(i, double_value);
}
......@@ -150,15 +151,16 @@ void Deoptimizer::TableEntryGenerator::Generate() {
RegList restored_regs = kJSCallerSaved | kCalleeSaved;
RegList saved_regs = restored_regs | sp.bit();
const int kDoubleRegsSize =
kDoubleSize * DoubleRegister::kMaxNumAllocatableRegisters;
const int kDoubleRegsSize = kDoubleSize * DoubleRegister::kNumRegisters;
// Save all FPU registers before messing with them.
// Save all double registers before messing with them.
__ subi(sp, sp, Operand(kDoubleRegsSize));
for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) {
DoubleRegister fpu_reg = DoubleRegister::FromAllocationIndex(i);
int offset = i * kDoubleSize;
__ stfd(fpu_reg, MemOperand(sp, offset));
const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
const DoubleRegister dreg = DoubleRegister::from_code(code);
int offset = code * kDoubleSize;
__ stfd(dreg, MemOperand(sp, offset));
}
// Push saved_regs (needed to populate FrameDescription::registers_).
......@@ -215,11 +217,12 @@ void Deoptimizer::TableEntryGenerator::Generate() {
}
int double_regs_offset = FrameDescription::double_registers_offset();
// Copy VFP registers to
// double_registers_[DoubleRegister::kNumAllocatableRegisters]
for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
int dst_offset = i * kDoubleSize + double_regs_offset;
int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
// Copy double registers to
// double_registers_[DoubleRegister::kNumRegisters]
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
int dst_offset = code * kDoubleSize + double_regs_offset;
int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize;
__ lfd(d0, MemOperand(sp, src_offset));
__ stfd(d0, MemOperand(r4, dst_offset));
}
......@@ -291,9 +294,10 @@ void Deoptimizer::TableEntryGenerator::Generate() {
__ blt(&outer_push_loop);
__ LoadP(r4, MemOperand(r3, Deoptimizer::input_offset()));
for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) {
const DoubleRegister dreg = DoubleRegister::FromAllocationIndex(i);
int src_offset = i * kDoubleSize + double_regs_offset;
for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int code = config->GetAllocatableDoubleCode(i);
const DoubleRegister dreg = DoubleRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ lfd(dreg, MemOperand(r4, src_offset));
}
......
......@@ -116,7 +116,9 @@ void Decoder::PrintRegister(int reg) {
// Print the double FP register name according to the active name converter.
void Decoder::PrintDRegister(int reg) { Print(FPRegisters::Name(reg)); }
void Decoder::PrintDRegister(int reg) {
Print(DoubleRegister::from_code(reg).ToString());
}
// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
......@@ -1349,7 +1351,7 @@ const char* NameConverter::NameOfConstant(byte* addr) const {
const char* NameConverter::NameOfCPURegister(int reg) const {
return v8::internal::Registers::Name(reg);
return v8::internal::Register::from_code(reg).ToString();
}
const char* NameConverter::NameOfByteCPURegister(int reg) const {
......
......@@ -70,6 +70,8 @@ const RegList kCallerSavedDoubles = 1 << 0 | // d0
1 << 12 | // d12
1 << 13; // d13
const int kNumCallerSavedDoubles = 14;
const RegList kCalleeSavedDoubles = 1 << 14 | // d14
1 << 15 | // d15
1 << 16 | // d16
......
......@@ -73,7 +73,7 @@ void LCodeGen::SaveCallerDoubles() {
BitVector* doubles = chunk()->allocated_double_registers();
BitVector::Iterator save_iterator(doubles);
while (!save_iterator.Done()) {
__ stfd(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
__ stfd(DoubleRegister::from_code(save_iterator.Current()),
MemOperand(sp, count * kDoubleSize));
save_iterator.Advance();
count++;
......@@ -89,7 +89,7 @@ void LCodeGen::RestoreCallerDoubles() {
BitVector::Iterator save_iterator(doubles);
int count = 0;
while (!save_iterator.Done()) {
__ lfd(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
__ lfd(DoubleRegister::from_code(save_iterator.Current()),
MemOperand(sp, count * kDoubleSize));
save_iterator.Advance();
count++;
......@@ -394,13 +394,13 @@ bool LCodeGen::GenerateSafepointTable() {
}
Register LCodeGen::ToRegister(int index) const {
return Register::FromAllocationIndex(index);
Register LCodeGen::ToRegister(int code) const {
return Register::from_code(code);
}
DoubleRegister LCodeGen::ToDoubleRegister(int index) const {
return DoubleRegister::FromAllocationIndex(index);
DoubleRegister LCodeGen::ToDoubleRegister(int code) const {
return DoubleRegister::from_code(code);
}
......
......@@ -137,7 +137,7 @@ class LCodeGen : public LCodeGenBase {
Scope* scope() const { return scope_; }
Register scratch0() { return r11; }
Register scratch0() { return kLithiumScratch; }
DoubleRegister double_scratch0() { return kScratchDoubleReg; }
LInstruction* GetNextInstruction();
......
......@@ -457,14 +457,13 @@ LPlatformChunk* LChunkBuilder::Build() {
LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
Register::ToAllocationIndex(reg));
return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
}
LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
return new (zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
DoubleRegister::ToAllocationIndex(reg));
return new (zone())
LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
}
......
......@@ -12,9 +12,11 @@
#include "src/bootstrapper.h"
#include "src/codegen.h"
#include "src/debug/debug.h"
#include "src/ppc/macro-assembler-ppc.h"
#include "src/register-configuration.h"
#include "src/runtime/runtime.h"
#include "src/ppc/macro-assembler-ppc.h"
namespace v8 {
namespace internal {
......@@ -564,7 +566,7 @@ void MacroAssembler::PopFixedFrame(Register marker_reg) {
const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable;
const int MacroAssembler::kNumSafepointSavedRegisters =
Register::kMaxNumAllocatableRegisters;
Register::kNumAllocatable;
// Push and pop all registers that can hold pointers.
void MacroAssembler::PushSafepointRegisters() {
......@@ -623,7 +625,8 @@ MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
// General purpose registers are pushed last on the stack.
int doubles_size = DoubleRegister::NumAllocatableRegisters() * kDoubleSize;
const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
int doubles_size = config->num_allocatable_double_registers() * kDoubleSize;
int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
return MemOperand(sp, doubles_size + register_offset);
}
......@@ -863,7 +866,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
MultiPushDoubles(kCallerSavedDoubles);
// Note that d0 will be accessible at
// fp - ExitFrameConstants::kFrameSize -
// kNumVolatileRegisters * kDoubleSize,
// kNumCallerSavedDoubles * kDoubleSize,
// since the sp slot and code slot were pushed after the fp.
}
......@@ -922,7 +925,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
// Optionally restore all double registers.
if (save_doubles) {
// Calculate the stack location of the saved doubles and restore them.
const int kNumRegs = DoubleRegister::kNumVolatileRegisters;
const int kNumRegs = kNumCallerSavedDoubles;
const int offset =
(ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize);
addi(r6, fp, Operand(-offset));
......@@ -4250,8 +4253,10 @@ Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2, Register reg3,
if (reg5.is_valid()) regs |= reg5.bit();
if (reg6.is_valid()) regs |= reg6.bit();
for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
Register candidate = Register::FromAllocationIndex(i);
const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
for (int i = 0; i < config->num_allocatable_general_registers(); ++i) {
int code = config->GetAllocatableGeneralCode(i);
Register candidate = Register::from_code(code);
if (regs & candidate.bit()) continue;
return candidate;
}
......
......@@ -14,17 +14,17 @@ namespace v8 {
namespace internal {
// Give alias names to registers for calling conventions.
const Register kReturnRegister0 = {kRegister_r3_Code};
const Register kReturnRegister1 = {kRegister_r4_Code};
const Register kJSFunctionRegister = {kRegister_r4_Code};
const Register kContextRegister = {kRegister_r30_Code};
const Register kInterpreterAccumulatorRegister = {kRegister_r3_Code};
const Register kInterpreterRegisterFileRegister = {kRegister_r14_Code};
const Register kInterpreterBytecodeOffsetRegister = {kRegister_r15_Code};
const Register kInterpreterBytecodeArrayRegister = {kRegister_r16_Code};
const Register kInterpreterDispatchTableRegister = {kRegister_r17_Code};
const Register kRuntimeCallFunctionRegister = {kRegister_r4_Code};
const Register kRuntimeCallArgCountRegister = {kRegister_r3_Code};
const Register kReturnRegister0 = {Register::kCode_r3};
const Register kReturnRegister1 = {Register::kCode_r4};
const Register kJSFunctionRegister = {Register::kCode_r4};
const Register kContextRegister = {Register::kCode_r30};
const Register kInterpreterAccumulatorRegister = {Register::kCode_r3};
const Register kInterpreterRegisterFileRegister = {Register::kCode_r14};
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r15};
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r16};
const Register kInterpreterDispatchTableRegister = {Register::kCode_r17};
const Register kRuntimeCallFunctionRegister = {Register::kCode_r4};
const Register kRuntimeCallArgCountRegister = {Register::kCode_r3};
// ----------------------------------------------------------------------------
// Static helper functions
......
......@@ -164,7 +164,7 @@ bool PPCDebugger::GetValue(const char* desc, intptr_t* value) {
bool PPCDebugger::GetFPDoubleValue(const char* desc, double* value) {
int regnum = FPRegisters::Number(desc);
int regnum = DoubleRegisters::Number(desc);
if (regnum != kNoRegister) {
*value = sim_->get_double_from_d_register(regnum);
return true;
......@@ -313,7 +313,8 @@ void PPCDebugger::Debug() {
if (strcmp(arg1, "all") == 0) {
for (int i = 0; i < kNumRegisters; i++) {
value = GetRegisterValue(i);
PrintF(" %3s: %08" V8PRIxPTR, Registers::Name(i), value);
PrintF(" %3s: %08" V8PRIxPTR,
Register::from_code(i).ToString(), value);
if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
(i % 2) == 0) {
dvalue = GetRegisterPairDoubleValue(i);
......@@ -332,7 +333,7 @@ void PPCDebugger::Debug() {
for (int i = 0; i < kNumRegisters; i++) {
value = GetRegisterValue(i);
PrintF(" %3s: %08" V8PRIxPTR " %11" V8PRIdPTR,
Registers::Name(i), value, value);
Register::from_code(i).ToString(), value, value);
if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
(i % 2) == 0) {
dvalue = GetRegisterPairDoubleValue(i);
......@@ -351,7 +352,8 @@ void PPCDebugger::Debug() {
for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
dvalue = GetFPDoubleRegisterValue(i);
uint64_t as_words = bit_cast<uint64_t>(dvalue);
PrintF("%3s: %f 0x%08x %08x\n", FPRegisters::Name(i), dvalue,
PrintF("%3s: %f 0x%08x %08x\n",
DoubleRegister::from_code(i).ToString(), dvalue,
static_cast<uint32_t>(as_words >> 32),
static_cast<uint32_t>(as_words & 0xffffffff));
}
......
......@@ -69,6 +69,10 @@ class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount,
kMaxAllocatableDoubleRegisterCount,
#elif V8_TARGET_ARCH_PPC
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount,
kMaxAllocatableDoubleRegisterCount,
#else
GetAllocatableGeneralRegisterCount(),
GetAllocatableDoubleRegisterCount(),
......
......@@ -99,7 +99,7 @@ TEST(DisasmPPC) {
COMPARE(addc(r9, r7, r9), "7d274814 addc r9, r7, r9");
COMPARE(addic(r3, r5, Operand(20)), "30650014 addic r3, r5, 20");
COMPARE(addi(r0, ip, Operand(63)), "380c003f addi r0, r12, 63");
COMPARE(addi(r0, ip, Operand(63)), "380c003f addi r0, ip, 63");
COMPARE(add(r5, r7, r0), "7ca70214 add r5, r7, r0");
COMPARE(addze(r0, r0, LeaveOE, SetRC), "7c000195 addze. r0, r0");
COMPARE(andi(r0, r3, Operand(4)), "70600004 andi. r0, r3, 4");
......@@ -130,8 +130,8 @@ TEST(DisasmPPC) {
COMPARE(lfd(d0, MemOperand(sp, 128)), "c8010080 lfd d0, 128(sp)");
COMPARE(li(r0, Operand(16)), "38000010 li r0, 16");
COMPARE(lis(r8, Operand(22560)), "3d005820 lis r8, 22560");
COMPARE(lwz(ip, MemOperand(r19, 44)), "8193002c lwz r12, 44(r19)");
COMPARE(lwzx(r0, MemOperand(r5, ip)), "7c05602e lwzx r0, r5, r12");
COMPARE(lwz(ip, MemOperand(r19, 44)), "8193002c lwz ip, 44(r19)");
COMPARE(lwzx(r0, MemOperand(r5, ip)), "7c05602e lwzx r0, r5, ip");
COMPARE(mflr(r0), "7c0802a6 mflr r0");
COMPARE(mr(r15, r4), "7c8f2378 mr r15, r4");
COMPARE(mtctr(r0), "7c0903a6 mtctr r0");
......
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