Commit 0b491c89 authored by Anisha Rohra's avatar Anisha Rohra Committed by Commit Bot

s390/PPC: Make Register et al. real classes

Port 9e995e12
Port 408f252b

  Up to now, each architecture defined all Register types as structs,
  with lots of redundancy. An often found comment noted that they cannot
  be classes due to initialization order problems. As these problems are
  gone with C++11 constexpr constants, I now tried making Registers
  classes again.
  All register types now inherit from RegisterBase, which provides a
  default set of methods and named constructors (like ::from_code,
  code(), bit(), is_valid(), ...).
  This design allows to guarantee an interesting property: Each register
  is either valid, or it's the no_reg register. There are no other
  invalid registers. This is guaranteed statically by the constexpr
  constructor, and dynamically by ::from_code.

  I decided to disallow the default constructor completely, so instead of
  "Register reg;" you now need "Register reg = no_reg;". This makes
  explicit how the Register is initialized.

  I did this change to the x64, ia32, arm, arm64, mips and mips64 ports.
  Overall, code got much more compact and more safe. In theory, it should
  also increase performance (since the is_valid() check is simpler), but
  this is probably not measurable.

R=bjaideep@ca.ibm.com, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Change-Id: I2e87efc8790290c64fd6c0a2d093326710b30ed3
Reviewed-on: https://chromium-review.googlesource.com/658065Reviewed-by: 's avatarJaideep Bajwa <bjaideep@ca.ibm.com>
Commit-Queue: Jaideep Bajwa <bjaideep@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#47933}
parent 4de946d9
......@@ -1654,9 +1654,9 @@ void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
Register scratch0 = r5;
Register scratch1 = r7;
CHECK(!scratch0.is(r3) && !scratch0.is(r6) && !scratch0.is(r4));
CHECK(!scratch1.is(r3) && !scratch1.is(r6) && !scratch1.is(r4));
CHECK(!scratch0.is(scratch1));
CHECK(scratch0 != r3 && scratch0 != r6 && scratch0 != r4);
CHECK(scratch1 != r3 && scratch1 != r6 && scratch1 != r4);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
......@@ -1700,8 +1700,8 @@ void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
__ LoadP(shared,
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
CHECK(!r8.is(target) && !r8.is(scratch0) && !r8.is(scratch1));
CHECK(!r9.is(target) && !r9.is(scratch0) && !r9.is(scratch1));
CHECK(r8 != target && r8 != scratch0 && r8 != scratch1);
CHECK(r9 != target && r9 != scratch0 && r9 != scratch1);
__ StoreP(target_builtin,
FieldMemOperand(shared, SharedFunctionInfo::kCodeOffset), r0);
......
......@@ -1649,9 +1649,9 @@ void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
Register scratch0 = r4;
Register scratch1 = r6;
CHECK(!scratch0.is(r2) && !scratch0.is(r5) && !scratch0.is(r3));
CHECK(!scratch1.is(r2) && !scratch1.is(r5) && !scratch1.is(r3));
CHECK(!scratch0.is(scratch1));
CHECK(scratch0 != r2 && scratch0 != r5 && scratch0 != r3);
CHECK(scratch1 != r2 && scratch1 != r5 && scratch1 != r3);
CHECK(scratch0 != scratch1);
// Load the builtin id for lazy deserialization from SharedFunctionInfo.
......@@ -1695,8 +1695,8 @@ void Builtins::Generate_DeserializeLazy(MacroAssembler* masm) {
__ LoadP(shared,
FieldMemOperand(target, JSFunction::kSharedFunctionInfoOffset));
CHECK(!r7.is(target) && !r7.is(scratch0) && !r7.is(scratch1));
CHECK(!r8.is(target) && !r8.is(scratch0) && !r8.is(scratch1));
CHECK(r7 != target && r7 != scratch0 && r7 != scratch1);
CHECK(r8 != target && r8 != scratch0 && r8 != scratch1);
__ StoreP(target_builtin,
FieldMemOperand(shared, SharedFunctionInfo::kCodeOffset));
......
This diff is collapsed.
This diff is collapsed.
......@@ -44,9 +44,9 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
__ Push(cp, value());
if (accessor_index >= 0) {
DCHECK(!holder.is(scratch));
DCHECK(!receiver.is(scratch));
DCHECK(!value().is(scratch));
DCHECK(holder != scratch);
DCHECK(receiver != scratch);
DCHECK(value() != scratch);
// Call the JavaScript setter with receiver and value on the stack.
if (map->IsJSGlobalObjectMap()) {
// Swap in the global receiver.
......@@ -100,7 +100,7 @@ void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
MacroAssembler* masm, Label* miss_label, Register receiver,
Handle<Name> name, Register scratch0, Register scratch1) {
DCHECK(name->IsUniqueName());
DCHECK(!receiver.is(scratch0));
DCHECK(receiver != scratch0);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
__ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
......@@ -165,14 +165,14 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall(
Handle<Map> receiver_map, Register receiver, Register scratch_in,
bool is_store, Register store_parameter, Register accessor_holder,
int accessor_index) {
DCHECK(!accessor_holder.is(scratch_in));
DCHECK(!receiver.is(scratch_in));
DCHECK(accessor_holder != scratch_in);
DCHECK(receiver != scratch_in);
__ Push(accessor_holder);
__ Push(receiver);
// Write the arguments to stack frame.
if (is_store) {
DCHECK(!receiver.is(store_parameter));
DCHECK(!scratch_in.is(store_parameter));
DCHECK(receiver != store_parameter);
DCHECK(scratch_in != store_parameter);
__ Push(store_parameter);
}
DCHECK(optimization.is_simple_api_call());
......@@ -277,9 +277,9 @@ Register PropertyHandlerCompiler::CheckPrototypes(
Handle<Map> receiver_map = map();
// Make sure there's no overlap between holder and object registers.
DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
!scratch2.is(scratch1));
DCHECK(scratch1 != object_reg && scratch1 != holder_reg);
DCHECK(scratch2 != object_reg && scratch2 != holder_reg &&
scratch2 != scratch1);
Handle<Cell> validity_cell =
Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
......
......@@ -254,28 +254,20 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
}
}
Operand::Operand(intptr_t immediate, RelocInfo::Mode rmode) {
rm_ = no_reg;
Operand::Operand(intptr_t immediate, RelocInfo::Mode rmode) : rmode_(rmode) {
value_.immediate = immediate;
rmode_ = rmode;
}
Operand::Operand(const ExternalReference& f) {
rm_ = no_reg;
Operand::Operand(const ExternalReference& f)
: rmode_(RelocInfo::EXTERNAL_REFERENCE) {
value_.immediate = reinterpret_cast<intptr_t>(f.address());
rmode_ = RelocInfo::EXTERNAL_REFERENCE;
}
Operand::Operand(Smi* value) {
rm_ = no_reg;
Operand::Operand(Smi* value) : rmode_(kRelocInfo_NONEPTR) {
value_.immediate = reinterpret_cast<intptr_t>(value);
rmode_ = kRelocInfo_NONEPTR;
}
Operand::Operand(Register rm) {
rm_ = rm;
rmode_ = kRelocInfo_NONEPTR; // PPC -why doesn't ARM do this?
}
Operand::Operand(Register rm) : rm_(rm), rmode_(kRelocInfo_NONEPTR) {}
void Assembler::CheckBuffer() {
if (buffer_space() <= kGap) {
......@@ -374,7 +366,7 @@ bool Assembler::IsConstantPoolLoadStart(Address pc,
ConstantPoolEntry::Access* access) {
Instr instr = instr_at(pc);
uint32_t opcode = instr & kOpcodeMask;
if (!GetRA(instr).is(kConstantPoolRegister)) return false;
if (GetRA(instr) != kConstantPoolRegister) return false;
bool overflowed = (opcode == ADDIS);
#ifdef DEBUG
if (overflowed) {
......@@ -396,10 +388,10 @@ bool Assembler::IsConstantPoolLoadEnd(Address pc,
uint32_t opcode = instr & kOpcodeMask;
bool overflowed = false;
if (!(opcode == kLoadIntptrOpcode || opcode == LFD)) return false;
if (!GetRA(instr).is(kConstantPoolRegister)) {
if (GetRA(instr) != kConstantPoolRegister) {
instr = instr_at(pc - kInstrSize);
opcode = instr & kOpcodeMask;
if ((opcode != ADDIS) || !GetRA(instr).is(kConstantPoolRegister)) {
if ((opcode != ADDIS) || GetRA(instr) != kConstantPoolRegister) {
return false;
}
overflowed = true;
......
......@@ -208,18 +208,11 @@ Operand Operand::EmbeddedCode(CodeStub* stub) {
return result;
}
MemOperand::MemOperand(Register rn, int32_t offset) {
ra_ = rn;
rb_ = no_reg;
offset_ = offset;
}
MemOperand::MemOperand(Register rn, int32_t offset)
: ra_(rn), offset_(offset), rb_(no_reg) {}
MemOperand::MemOperand(Register ra, Register rb) {
ra_ = ra;
rb_ = rb;
offset_ = 0;
}
MemOperand::MemOperand(Register ra, Register rb)
: ra_(ra), offset_(0), rb_(rb) {}
void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
for (auto& request : heap_object_requests_) {
......@@ -308,12 +301,12 @@ Condition Assembler::GetCondition(Instr instr) {
bool Assembler::IsLis(Instr instr) {
return ((instr & kOpcodeMask) == ADDIS) && GetRA(instr).is(r0);
return ((instr & kOpcodeMask) == ADDIS) && GetRA(instr) == r0;
}
bool Assembler::IsLi(Instr instr) {
return ((instr & kOpcodeMask) == ADDI) && GetRA(instr).is(r0);
return ((instr & kOpcodeMask) == ADDI) && GetRA(instr) == r0;
}
......@@ -327,16 +320,12 @@ bool Assembler::IsBranch(Instr instr) { return ((instr & kOpcodeMask) == BCX); }
Register Assembler::GetRA(Instr instr) {
Register reg;
reg.reg_code = Instruction::RAValue(instr);
return reg;
return Register::from_code(Instruction::RAValue(instr));
}
Register Assembler::GetRB(Instr instr) {
Register reg;
reg.reg_code = Instruction::RBValue(instr);
return reg;
return Register::from_code(Instruction::RBValue(instr));
}
......@@ -914,13 +903,13 @@ void Assembler::divwu(Register dst, Register src1, Register src2, OEBit o,
void Assembler::addi(Register dst, Register src, const Operand& imm) {
DCHECK(!src.is(r0)); // use li instead to show intent
DCHECK(src != r0); // use li instead to show intent
d_form(ADDI, dst, src, imm.immediate(), true);
}
void Assembler::addis(Register dst, Register src, const Operand& imm) {
DCHECK(!src.is(r0)); // use lis instead to show intent
DCHECK(src != r0); // use lis instead to show intent
d_form(ADDIS, dst, src, imm.immediate(), true);
}
......@@ -1031,31 +1020,31 @@ void Assembler::mr(Register dst, Register src) {
void Assembler::lbz(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(LBZ, dst, src.ra(), src.offset(), true);
}
void Assembler::lhz(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(LHZ, dst, src.ra(), src.offset(), true);
}
void Assembler::lwz(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(LWZ, dst, src.ra(), src.offset(), true);
}
void Assembler::lwzu(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(LWZU, dst, src.ra(), src.offset(), true);
}
void Assembler::lha(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(LHA, dst, src.ra(), src.offset(), true);
}
......@@ -1063,7 +1052,7 @@ void Assembler::lha(Register dst, const MemOperand& src) {
void Assembler::lwa(Register dst, const MemOperand& src) {
#if V8_TARGET_ARCH_PPC64
int offset = src.offset();
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
CHECK(!(offset & 3) && is_int16(offset));
offset = kImm16Mask & offset;
emit(LD | dst.code() * B21 | src.ra().code() * B16 | offset | 2);
......@@ -1073,25 +1062,25 @@ void Assembler::lwa(Register dst, const MemOperand& src) {
}
void Assembler::stb(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(STB, dst, src.ra(), src.offset(), true);
}
void Assembler::sth(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(STH, dst, src.ra(), src.offset(), true);
}
void Assembler::stw(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(STW, dst, src.ra(), src.offset(), true);
}
void Assembler::stwu(Register dst, const MemOperand& src) {
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
d_form(STWU, dst, src.ra(), src.offset(), true);
}
......@@ -1105,7 +1094,7 @@ void Assembler::neg(Register rt, Register ra, OEBit o, RCBit r) {
// 64bit specific instructions
void Assembler::ld(Register rd, const MemOperand& src) {
int offset = src.offset();
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
CHECK(!(offset & 3) && is_int16(offset));
offset = kImm16Mask & offset;
emit(LD | rd.code() * B21 | src.ra().code() * B16 | offset);
......@@ -1114,7 +1103,7 @@ void Assembler::ld(Register rd, const MemOperand& src) {
void Assembler::ldu(Register rd, const MemOperand& src) {
int offset = src.offset();
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
CHECK(!(offset & 3) && is_int16(offset));
offset = kImm16Mask & offset;
emit(LD | rd.code() * B21 | src.ra().code() * B16 | offset | 1);
......@@ -1123,7 +1112,7 @@ void Assembler::ldu(Register rd, const MemOperand& src) {
void Assembler::std(Register rs, const MemOperand& src) {
int offset = src.offset();
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
CHECK(!(offset & 3) && is_int16(offset));
offset = kImm16Mask & offset;
emit(STD | rs.code() * B21 | src.ra().code() * B16 | offset);
......@@ -1132,7 +1121,7 @@ void Assembler::std(Register rs, const MemOperand& src) {
void Assembler::stdu(Register rs, const MemOperand& src) {
int offset = src.offset();
DCHECK(!src.ra_.is(r0));
DCHECK(src.ra_ != r0);
CHECK(!(offset & 3) && is_int16(offset));
offset = kImm16Mask & offset;
emit(STD | rs.code() * B21 | src.ra().code() * B16 | offset | 1);
......@@ -1272,9 +1261,9 @@ bool Assembler::use_constant_pool_for_mov(Register dst, const Operand& src,
}
intptr_t value = src.immediate();
#if V8_TARGET_ARCH_PPC64
bool allowOverflow = !((canOptimize && is_int32(value)) || dst.is(r0));
bool allowOverflow = !((canOptimize && is_int32(value)) || dst == r0);
#else
bool allowOverflow = !(canOptimize || dst.is(r0));
bool allowOverflow = !(canOptimize || dst == r0);
#endif
if (canOptimize && is_int16(value)) {
// Prefer a single-instruction load-immediate.
......@@ -1664,7 +1653,7 @@ void Assembler::isync() { emit(EXT1 | ISYNC); }
void Assembler::lfd(const DoubleRegister frt, const MemOperand& src) {
int offset = src.offset();
Register ra = src.ra();
DCHECK(!ra.is(r0));
DCHECK(ra != r0);
CHECK(is_int16(offset));
int imm16 = offset & kImm16Mask;
// could be x_form instruction with some casting magic
......@@ -1675,7 +1664,7 @@ void Assembler::lfd(const DoubleRegister frt, const MemOperand& src) {
void Assembler::lfdu(const DoubleRegister frt, const MemOperand& src) {
int offset = src.offset();
Register ra = src.ra();
DCHECK(!ra.is(r0));
DCHECK(ra != r0);
CHECK(is_int16(offset));
int imm16 = offset & kImm16Mask;
// could be x_form instruction with some casting magic
......@@ -1687,7 +1676,7 @@ void Assembler::lfs(const DoubleRegister frt, const MemOperand& src) {
int offset = src.offset();
Register ra = src.ra();
CHECK(is_int16(offset));
DCHECK(!ra.is(r0));
DCHECK(ra != r0);
int imm16 = offset & kImm16Mask;
// could be x_form instruction with some casting magic
emit(LFS | frt.code() * B21 | ra.code() * B16 | imm16);
......@@ -1698,7 +1687,7 @@ void Assembler::lfsu(const DoubleRegister frt, const MemOperand& src) {
int offset = src.offset();
Register ra = src.ra();
CHECK(is_int16(offset));
DCHECK(!ra.is(r0));
DCHECK(ra != r0);
int imm16 = offset & kImm16Mask;
// could be x_form instruction with some casting magic
emit(LFSU | frt.code() * B21 | ra.code() * B16 | imm16);
......@@ -1709,7 +1698,7 @@ void Assembler::stfd(const DoubleRegister frs, const MemOperand& src) {
int offset = src.offset();
Register ra = src.ra();
CHECK(is_int16(offset));
DCHECK(!ra.is(r0));
DCHECK(ra != r0);
int imm16 = offset & kImm16Mask;
// could be x_form instruction with some casting magic
emit(STFD | frs.code() * B21 | ra.code() * B16 | imm16);
......@@ -1720,7 +1709,7 @@ void Assembler::stfdu(const DoubleRegister frs, const MemOperand& src) {
int offset = src.offset();
Register ra = src.ra();
CHECK(is_int16(offset));
DCHECK(!ra.is(r0));
DCHECK(ra != r0);
int imm16 = offset & kImm16Mask;
// could be x_form instruction with some casting magic
emit(STFDU | frs.code() * B21 | ra.code() * B16 | imm16);
......@@ -1731,7 +1720,7 @@ void Assembler::stfs(const DoubleRegister frs, const MemOperand& src) {
int offset = src.offset();
Register ra = src.ra();
CHECK(is_int16(offset));
DCHECK(!ra.is(r0));
DCHECK(ra != r0);
int imm16 = offset & kImm16Mask;
// could be x_form instruction with some casting magic
emit(STFS | frs.code() * B21 | ra.code() * B16 | imm16);
......@@ -1742,7 +1731,7 @@ void Assembler::stfsu(const DoubleRegister frs, const MemOperand& src) {
int offset = src.offset();
Register ra = src.ra();
CHECK(is_int16(offset));
DCHECK(!ra.is(r0));
DCHECK(ra != r0);
int imm16 = offset & kImm16Mask;
// could be x_form instruction with some casting magic
emit(STFSU | frs.code() * B21 | ra.code() * B16 | imm16);
......
This diff is collapsed.
......@@ -55,7 +55,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
__ push(scratch);
// Account for saved regs if input is sp.
if (input_reg.is(sp)) double_offset += kPointerSize;
if (input_reg == sp) double_offset += kPointerSize;
if (!skip_fastpath()) {
// Load double input.
......@@ -79,7 +79,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
__ Push(scratch_high, scratch_low);
// Account for saved regs if input is sp.
if (input_reg.is(sp)) double_offset += 2 * kPointerSize;
if (input_reg == sp) double_offset += 2 * kPointerSize;
__ lwz(scratch_high,
MemOperand(input_reg, double_offset + Register::kExponentOffset));
......@@ -198,7 +198,7 @@ void RestoreRegistersStateStub::Generate(MacroAssembler* masm) {
void MathPowStub::Generate(MacroAssembler* masm) {
const Register exponent = MathPowTaggedDescriptor::exponent();
DCHECK(exponent.is(r5));
DCHECK(exponent == r5);
const DoubleRegister double_base = d1;
const DoubleRegister double_exponent = d2;
const DoubleRegister double_result = d3;
......@@ -466,14 +466,11 @@ void CEntryStub::Generate(MacroAssembler* masm) {
// r3:r4: result
// sp: stack pointer
// fp: frame pointer
Register argc;
if (argv_in_register()) {
// We don't want to pop arguments so set argc to no_reg.
argc = no_reg;
} else {
// r14: still holds argc (callee-saved).
argc = r14;
}
Register argc = argv_in_register()
// We don't want to pop arguments so set argc to no_reg.
? no_reg
// r14: still holds argc (callee-saved).
: r14;
__ LeaveExitFrame(save_doubles(), argc, true);
__ blr();
......@@ -862,7 +859,7 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(
__ add(tmp, properties, ip);
__ LoadP(entity_name, FieldMemOperand(tmp, kElementsStartOffset));
DCHECK(!tmp.is(entity_name));
DCHECK(tmp != entity_name);
__ LoadRoot(tmp, Heap::kUndefinedValueRootIndex);
__ cmp(entity_name, tmp);
__ beq(done);
......@@ -1085,10 +1082,9 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode());
int argument_count = 3;
__ PrepareCallCFunction(argument_count, regs_.scratch0());
Register address =
r3.is(regs_.address()) ? regs_.scratch0() : regs_.address();
DCHECK(!address.is(regs_.object()));
DCHECK(!address.is(r3));
Register address = r3 == regs_.address() ? regs_.scratch0() : regs_.address();
DCHECK(address != regs_.object());
DCHECK(address != r3);
__ mr(address, regs_.address());
__ mr(r3, regs_.object());
__ mr(r4, address);
......@@ -1575,7 +1571,7 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
ExternalReference::handle_scope_level_address(isolate), next_address);
// Additional parameter is the address of the actual callback.
DCHECK(function_address.is(r4) || function_address.is(r5));
DCHECK(function_address == r4 || function_address == r5);
Register scratch = r6;
__ mov(scratch, Operand(ExternalReference::is_profiling_address(isolate)));
......@@ -1801,7 +1797,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
DCHECK(!api_function_address.is(r3) && !scratch.is(r3));
DCHECK(api_function_address != r3 && scratch != r3);
// r3 = FunctionCallbackInfo&
// Arguments is after the return address.
__ addi(r3, sp, Operand(kFunctionCallbackInfoOffset));
......
......@@ -147,7 +147,10 @@ class RecordWriteStub : public PlatformCodeStub {
class RegisterAllocation {
public:
RegisterAllocation(Register object, Register address, Register scratch0)
: object_(object), address_(address), scratch0_(scratch0) {
: object_(object),
address_(address),
scratch0_(scratch0),
scratch1_(no_reg) {
DCHECK(!AreAliased(scratch0, object, address, no_reg));
scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_);
}
......
This diff is collapsed.
......@@ -9,25 +9,26 @@
#include "src/bailout-reason.h"
#include "src/double.h"
#include "src/globals.h"
#include "src/ppc/assembler-ppc.h"
namespace v8 {
namespace internal {
// Give alias names to registers for calling conventions.
const Register kReturnRegister0 = {Register::kCode_r3};
const Register kReturnRegister1 = {Register::kCode_r4};
const Register kReturnRegister2 = {Register::kCode_r5};
const Register kJSFunctionRegister = {Register::kCode_r4};
const Register kContextRegister = {Register::kCode_r30};
const Register kAllocateSizeRegister = {Register::kCode_r4};
const Register kInterpreterAccumulatorRegister = {Register::kCode_r3};
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r15};
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r16};
const Register kInterpreterDispatchTableRegister = {Register::kCode_r17};
const Register kJavaScriptCallArgCountRegister = {Register::kCode_r3};
const Register kJavaScriptCallNewTargetRegister = {Register::kCode_r6};
const Register kRuntimeCallFunctionRegister = {Register::kCode_r4};
const Register kRuntimeCallArgCountRegister = {Register::kCode_r3};
const Register kReturnRegister0 = r3;
const Register kReturnRegister1 = r4;
const Register kReturnRegister2 = r5;
const Register kJSFunctionRegister = r4;
const Register kContextRegister = r30;
const Register kAllocateSizeRegister = r4;
const Register kInterpreterAccumulatorRegister = r3;
const Register kInterpreterBytecodeOffsetRegister = r15;
const Register kInterpreterBytecodeArrayRegister = r16;
const Register kInterpreterDispatchTableRegister = r17;
const Register kJavaScriptCallArgCountRegister = r3;
const Register kJavaScriptCallNewTargetRegister = r6;
const Register kRuntimeCallFunctionRegister = r4;
const Register kRuntimeCallArgCountRegister = r3;
// ----------------------------------------------------------------------------
// Static helper functions
......@@ -1149,9 +1150,6 @@ class MacroAssembler : public TurboAssembler {
inline void GetMarkBits(Register addr_reg, Register bitmap_reg,
Register mask_reg);
static const RegList kSafepointSavedRegisters;
static const int kNumSafepointSavedRegisters;
// Compute memory operands for safepoint stack slots.
static int SafepointRegisterStackIndex(int reg_code);
......
......@@ -1231,13 +1231,13 @@ void RegExpMacroAssemblerPPC::SafeCallTarget(Label* name) {
void RegExpMacroAssemblerPPC::Push(Register source) {
DCHECK(!source.is(backtrack_stackpointer()));
DCHECK(source != backtrack_stackpointer());
__ StorePU(source, MemOperand(backtrack_stackpointer(), -kPointerSize));
}
void RegExpMacroAssemblerPPC::Pop(Register target) {
DCHECK(!target.is(backtrack_stackpointer()));
DCHECK(target != backtrack_stackpointer());
__ LoadP(target, MemOperand(backtrack_stackpointer()));
__ addi(backtrack_stackpointer(), backtrack_stackpointer(),
Operand(kPointerSize));
......
......@@ -1174,14 +1174,14 @@ void RegExpMacroAssemblerS390::SafeCallTarget(Label* name) {
}
void RegExpMacroAssemblerS390::Push(Register source) {
DCHECK(!source.is(backtrack_stackpointer()));
DCHECK(source != backtrack_stackpointer());
__ lay(backtrack_stackpointer(),
MemOperand(backtrack_stackpointer(), -kPointerSize));
__ StoreP(source, MemOperand(backtrack_stackpointer()));
}
void RegExpMacroAssemblerS390::Pop(Register target) {
DCHECK(!target.is(backtrack_stackpointer()));
DCHECK(target != backtrack_stackpointer());
__ LoadP(target, MemOperand(backtrack_stackpointer()));
__ la(backtrack_stackpointer(),
MemOperand(backtrack_stackpointer(), kPointerSize));
......
......@@ -233,28 +233,20 @@ void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
}
// Operand constructors
Operand::Operand(intptr_t immediate, RelocInfo::Mode rmode) {
rm_ = no_reg;
Operand::Operand(intptr_t immediate, RelocInfo::Mode rmode) : rmode_(rmode) {
value_.immediate = immediate;
rmode_ = rmode;
}
Operand::Operand(const ExternalReference& f) {
rm_ = no_reg;
Operand::Operand(const ExternalReference& f)
: rmode_(RelocInfo::EXTERNAL_REFERENCE) {
value_.immediate = reinterpret_cast<intptr_t>(f.address());
rmode_ = RelocInfo::EXTERNAL_REFERENCE;
}
Operand::Operand(Smi* value) {
rm_ = no_reg;
Operand::Operand(Smi* value) : rmode_(kRelocInfo_NONEPTR) {
value_.immediate = reinterpret_cast<intptr_t>(value);
rmode_ = kRelocInfo_NONEPTR;
}
Operand::Operand(Register rm) {
rm_ = rm;
rmode_ = kRelocInfo_NONEPTR; // S390 -why doesn't ARM do this?
}
Operand::Operand(Register rm) : rm_(rm), rmode_(kRelocInfo_NONEPTR) {}
void Assembler::CheckBuffer() {
if (buffer_space() <= kGap) {
......
......@@ -310,17 +310,11 @@ Operand Operand::EmbeddedNumber(double value) {
return result;
}
MemOperand::MemOperand(Register rn, int32_t offset) {
baseRegister = rn;
indexRegister = r0;
offset_ = offset;
}
MemOperand::MemOperand(Register rn, int32_t offset)
: baseRegister(rn), indexRegister(r0), offset_(offset) {}
MemOperand::MemOperand(Register rx, Register rb, int32_t offset) {
baseRegister = rb;
indexRegister = rx;
offset_ = offset;
}
MemOperand::MemOperand(Register rx, Register rb, int32_t offset)
: baseRegister(rb), indexRegister(rx), offset_(offset) {}
void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
for (auto& request : heap_object_requests_) {
......@@ -1636,7 +1630,7 @@ void Assembler::EnsureSpaceFor(int space_needed) {
// Rotate Left Single Logical (32)
void Assembler::rll(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(RLL, r1, r3, opnd, 0);
}
......@@ -1653,7 +1647,7 @@ void Assembler::rll(Register r1, Register r3, Register r2,
// Rotate Left Single Logical (64)
void Assembler::rllg(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(RLLG, r1, r3, opnd, 0);
}
......@@ -1670,7 +1664,7 @@ void Assembler::rllg(Register r1, Register r3, Register r2,
// Shift Left Single Logical (32)
void Assembler::sll(Register r1, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rs_form(SLL, r1, r0, opnd, 0);
}
......@@ -1681,7 +1675,7 @@ void Assembler::sll(Register r1, const Operand& opnd) {
// Shift Left Single Logical (32)
void Assembler::sllk(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(SLLK, r1, r3, opnd, 0);
}
......@@ -1692,7 +1686,7 @@ void Assembler::sllk(Register r1, Register r3, const Operand& opnd) {
// Shift Left Single Logical (64)
void Assembler::sllg(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(SLLG, r1, r3, opnd, 0);
}
......@@ -1709,7 +1703,7 @@ void Assembler::sldl(Register r1, Register b2, const Operand& opnd) {
// Shift Right Single Logical (32)
void Assembler::srl(Register r1, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rs_form(SRL, r1, r0, opnd, 0);
}
......@@ -1732,7 +1726,7 @@ void Assembler::srl(Register r1, const Operand& opnd) {
// Shift Right Single Logical (32)
void Assembler::srlk(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(SRLK, r1, r3, opnd, 0);
}
......@@ -1743,7 +1737,7 @@ void Assembler::srlk(Register r1, Register r3, const Operand& opnd) {
// Shift Right Single Logical (64)
void Assembler::srlg(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(SRLG, r1, r3, opnd, 0);
}
......@@ -1754,7 +1748,7 @@ void Assembler::srlg(Register r1, Register r3, const Operand& opnd) {
// Shift Left Single (32)
void Assembler::sla(Register r1, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rs_form(SLA, r1, r0, opnd, 0);
}
......@@ -1765,7 +1759,7 @@ void Assembler::sla(Register r1, const Operand& opnd) {
// Shift Left Single (32)
void Assembler::slak(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(SLAK, r1, r3, opnd, 0);
}
......@@ -1776,7 +1770,7 @@ void Assembler::slak(Register r1, Register r3, const Operand& opnd) {
// Shift Left Single (64)
void Assembler::slag(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(SLAG, r1, r3, opnd, 0);
}
......@@ -1787,7 +1781,7 @@ void Assembler::slag(Register r1, Register r3, const Operand& opnd) {
// Shift Right Single (32)
void Assembler::sra(Register r1, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rs_form(SRA, r1, r0, opnd, 0);
}
......@@ -1798,7 +1792,7 @@ void Assembler::sra(Register r1, const Operand& opnd) {
// Shift Right Single (32)
void Assembler::srak(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(SRAK, r1, r3, opnd, 0);
}
......@@ -1809,7 +1803,7 @@ void Assembler::srak(Register r1, Register r3, const Operand& opnd) {
// Shift Right Single (64)
void Assembler::srag(Register r1, Register r3, Register opnd) {
DCHECK(!opnd.is(r0));
DCHECK(opnd != r0);
rsy_form(SRAG, r1, r3, opnd, 0);
}
......
......@@ -98,6 +98,10 @@ namespace internal {
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
V(d8) V(d9) V(d10) V(d11) V(d12) V(d15) V(d0)
#define C_REGISTERS(V) \
V(cr0) V(cr1) V(cr2) V(cr3) V(cr4) V(cr5) V(cr6) V(cr7) \
V(cr8) V(cr9) V(cr10) V(cr11) V(cr12) V(cr15)
// clang-format on
// Register list in load/store instructions
......@@ -187,8 +191,8 @@ const int kNumSafepointRegisters = 16;
// Define the list of registers actually saved at safepoints.
// Note that the number of saved registers may be smaller than the reserved
// space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
// const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
// const int kNumSafepointSavedRegisters = kNumJSCallerSaved + kNumCalleeSaved;
const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
const int kNumSafepointSavedRegisters = kNumJSCallerSaved + kNumCalleeSaved;
// The following constants describe the stack frame linkage area as
// defined by the ABI.
......@@ -235,70 +239,15 @@ const int kCalleeRegisterSaveAreaSize = 96;
const int kCalleeRegisterSaveAreaSize = 0;
#endif
// CPU Registers.
//
// 1) We would prefer to use an enum, but enum values are assignment-
// compatible with int, which has caused code-generation bugs.
//
// 2) We would prefer to use a class instead of a struct but we don't like
// the register initialization to depend on the particular initialization
// order (which appears to be different on OS X, Linux, and Windows for the
// installed versions of C++ we tried). Using a struct permits C-style
// "initialization". Also, the Register objects cannot be const as this
// forces initialization stubs in MSVC, making us dependent on initialization
// order.
//
// 3) By not using an enum, we are possibly preventing the compiler from
// doing certain constant folds, which may significantly reduce the
// code generated for some assembly instructions (because they boil down
// to a few constants). If this is a problem, we could change the code
// such that we use an enum in optimized mode, and the struct in debug
// mode. This way we get the compile-time error checking in debug mode
// and best performance in optimized code.
struct Register {
enum Code {
#define REGISTER_CODE(R) kCode_##R,
GENERAL_REGISTERS(REGISTER_CODE)
enum RegisterCode {
#define REGISTER_CODE(R) kRegCode_##R,
GENERAL_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kAfterLast,
kCode_no_reg = -1
};
static constexpr int kNumRegisters = Code::kAfterLast;
#define REGISTER_COUNT(R) 1 +
static constexpr int kNumAllocatable =
ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0;
#undef REGISTER_COUNT
#define REGISTER_BIT(R) 1 << kCode_##R |
static constexpr RegList kAllocatable =
ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT) 0;
#undef REGISTER_BIT
static Register from_code(int code) {
DCHECK(code >= 0);
DCHECK(code < kNumRegisters);
Register r = {code};
return r;
}
bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
bool is(Register reg) const { return reg_code == reg.reg_code; }
int code() const {
DCHECK(is_valid());
return reg_code;
}
int bit() const {
DCHECK(is_valid());
return 1 << reg_code;
}
void set_code(int code) {
reg_code = code;
DCHECK(is_valid());
}
kRegAfterLast
};
class Register : public RegisterBase<Register, kRegAfterLast> {
public:
#if V8_TARGET_LITTLE_ENDIAN
static constexpr int kMantissaOffset = 0;
static constexpr int kExponentOffset = 4;
......@@ -307,16 +256,20 @@ struct Register {
static constexpr int kExponentOffset = 0;
#endif
// Unfortunately we can't make this private in a struct.
int reg_code;
private:
friend class RegisterBase;
explicit constexpr Register(int code) : RegisterBase(code) {}
};
typedef struct Register Register;
static_assert(IS_TRIVIALLY_COPYABLE(Register) &&
sizeof(Register) == sizeof(int),
"Register can efficiently be passed by value");
#define DEFINE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
#define DEFINE_REGISTER(R) \
constexpr Register R = Register::from_code<kRegCode_##R>();
GENERAL_REGISTERS(DEFINE_REGISTER)
#undef DEFINE_REGISTER
constexpr Register no_reg = {Register::kCode_no_reg};
constexpr Register no_reg = Register::no_reg();
// Register aliases
constexpr Register kLithiumScratch = r1; // lithium scratch.
......@@ -326,83 +279,67 @@ constexpr Register cp = r13; // JavaScript context pointer.
constexpr bool kSimpleFPAliasing = true;
constexpr bool kSimdMaskRegisters = false;
// Double word FP register.
struct DoubleRegister {
enum Code {
#define REGISTER_CODE(R) kCode_##R,
DOUBLE_REGISTERS(REGISTER_CODE)
enum DoubleRegisterCode {
#define REGISTER_CODE(R) kDoubleCode_##R,
DOUBLE_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kAfterLast,
kCode_no_reg = -1
};
static constexpr int kNumRegisters = Code::kAfterLast;
static constexpr int kMaxNumRegisters = kNumRegisters;
bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
int code() const {
DCHECK(is_valid());
return reg_code;
}
kDoubleAfterLast
};
int bit() const {
DCHECK(is_valid());
return 1 << reg_code;
}
// Double word VFP register.
class DoubleRegister : public RegisterBase<DoubleRegister, kDoubleAfterLast> {
public:
// A few double registers are reserved: one as a scratch register and one to
// hold 0.0, that does not fit in the immediate field of vmov instructions.
// d14: 0.0
// d15: scratch register.
static constexpr int kSizeInBytes = 8;
inline static int NumRegisters();
static DoubleRegister from_code(int code) {
DoubleRegister r = {code};
return r;
}
private:
friend class RegisterBase;
int reg_code;
explicit constexpr DoubleRegister(int code) : RegisterBase(code) {}
};
static_assert(IS_TRIVIALLY_COPYABLE(DoubleRegister) &&
sizeof(DoubleRegister) == sizeof(int),
"DoubleRegister can efficiently be passed by value");
typedef DoubleRegister FloatRegister;
// TODO(john.yan) Define SIMD registers.
typedef DoubleRegister Simd128Register;
#define DEFINE_REGISTER(R) \
constexpr DoubleRegister R = {DoubleRegister::kCode_##R};
constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
DOUBLE_REGISTERS(DEFINE_REGISTER)
#undef DEFINE_REGISTER
constexpr Register no_dreg = {Register::kCode_no_reg};
constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
constexpr DoubleRegister kDoubleRegZero = d14;
constexpr DoubleRegister kScratchDoubleReg = d13;
Register ToRegister(int num);
// Coprocessor register
struct CRegister {
bool is_valid() const { return 0 <= reg_code && reg_code < 8; }
bool is(CRegister creg) const { return reg_code == creg.reg_code; }
int code() const {
DCHECK(is_valid());
return reg_code;
}
int bit() const {
DCHECK(is_valid());
return 1 << reg_code;
}
// Unfortunately we can't make this private in a struct.
int reg_code;
enum CRegisterCode {
#define REGISTER_CODE(R) kCCode_##R,
C_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kCAfterLast
};
constexpr CRegister no_creg = {-1};
// Coprocessor register
class CRegister : public RegisterBase<CRegister, kCAfterLast> {
friend class RegisterBase;
explicit constexpr CRegister(int code) : RegisterBase(code) {}
};
constexpr CRegister cr0 = {0};
constexpr CRegister cr1 = {1};
constexpr CRegister cr2 = {2};
constexpr CRegister cr3 = {3};
constexpr CRegister cr4 = {4};
constexpr CRegister cr5 = {5};
constexpr CRegister cr6 = {6};
constexpr CRegister cr7 = {7};
constexpr CRegister no_creg = CRegister::no_reg();
#define DECLARE_C_REGISTER(R) \
constexpr CRegister R = CRegister::from_code<kCCode_##R>();
C_REGISTERS(DECLARE_C_REGISTER)
#undef DECLARE_C_REGISTER
// -----------------------------------------------------------------------------
// Machine instruction Operands
......@@ -476,7 +413,7 @@ class Operand BASE_EMBEDDED {
RelocInfo::Mode rmode() const { return rmode_; }
private:
Register rm_;
Register rm_ = no_reg;
union Value {
Value() {}
HeapObjectRequest heap_object_request; // if is_heap_object_request_
......@@ -507,7 +444,7 @@ class MemOperand BASE_EMBEDDED {
// Base register
Register rb() const {
DCHECK(!baseRegister.is(no_reg));
DCHECK(baseRegister != no_reg);
return baseRegister;
}
......@@ -515,7 +452,7 @@ class MemOperand BASE_EMBEDDED {
// Index Register
Register rx() const {
DCHECK(!indexRegister.is(no_reg));
DCHECK(indexRegister != no_reg);
return indexRegister;
}
Register getIndexRegister() const { return rx(); }
......
......@@ -53,7 +53,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
__ push(scratch);
// Account for saved regs if input is sp.
if (input_reg.is(sp)) double_offset += kPointerSize;
if (input_reg == sp) double_offset += kPointerSize;
if (!skip_fastpath()) {
// Load double input.
......@@ -69,7 +69,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
__ Push(scratch_high, scratch_low);
// Account for saved regs if input is sp.
if (input_reg.is(sp)) double_offset += 2 * kPointerSize;
if (input_reg == sp) double_offset += 2 * kPointerSize;
__ LoadlW(scratch_high,
MemOperand(input_reg, double_offset + Register::kExponentOffset));
......@@ -186,7 +186,7 @@ void RestoreRegistersStateStub::Generate(MacroAssembler* masm) {
void MathPowStub::Generate(MacroAssembler* masm) {
const Register exponent = MathPowTaggedDescriptor::exponent();
DCHECK(exponent.is(r4));
DCHECK(exponent == r4);
const DoubleRegister double_base = d1;
const DoubleRegister double_exponent = d2;
const DoubleRegister double_result = d3;
......@@ -444,14 +444,11 @@ void CEntryStub::Generate(MacroAssembler* masm) {
// r2:r3: result
// sp: stack pointer
// fp: frame pointer
Register argc;
if (argv_in_register()) {
// We don't want to pop arguments so set argc to no_reg.
argc = no_reg;
} else {
// r6: still holds argc (callee-saved).
argc = r6;
}
Register argc = argv_in_register()
// We don't want to pop arguments so set argc to no_reg.
? no_reg
// r6: still holds argc (callee-saved).
: r6;
__ LeaveExitFrame(save_doubles(), argc, true);
__ b(r14);
......@@ -845,7 +842,7 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(
__ AddP(tmp, properties, ip);
__ LoadP(entity_name, FieldMemOperand(tmp, kElementsStartOffset));
DCHECK(!tmp.is(entity_name));
DCHECK(tmp != entity_name);
__ CompareRoot(entity_name, Heap::kUndefinedValueRootIndex);
__ beq(done);
......@@ -1061,10 +1058,9 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode());
int argument_count = 3;
__ PrepareCallCFunction(argument_count, regs_.scratch0());
Register address =
r2.is(regs_.address()) ? regs_.scratch0() : regs_.address();
DCHECK(!address.is(regs_.object()));
DCHECK(!address.is(r2));
Register address = r2 == regs_.address() ? regs_.scratch0() : regs_.address();
DCHECK(address != regs_.object());
DCHECK(address != r2);
__ LoadRR(address, regs_.address());
__ LoadRR(r2, regs_.object());
__ LoadRR(r3, address);
......@@ -1554,7 +1550,7 @@ static void CallApiFunctionAndReturn(MacroAssembler* masm,
ExternalReference::handle_scope_level_address(isolate), next_address);
// Additional parameter is the address of the actual callback.
DCHECK(function_address.is(r3) || function_address.is(r4));
DCHECK(function_address == r3 || function_address == r4);
Register scratch = r5;
__ mov(scratch, Operand(ExternalReference::is_profiling_address(isolate)));
......@@ -1773,7 +1769,7 @@ void CallApiCallbackStub::Generate(MacroAssembler* masm) {
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
DCHECK(!api_function_address.is(r2) && !scratch.is(r2));
DCHECK(api_function_address != r2 && scratch != r2);
// r2 = FunctionCallbackInfo&
// Arguments is after the return address.
__ AddP(r2, sp, Operand(kFunctionCallbackInfoOffset));
......
......@@ -176,7 +176,10 @@ class RecordWriteStub : public PlatformCodeStub {
class RegisterAllocation {
public:
RegisterAllocation(Register object, Register address, Register scratch0)
: object_(object), address_(address), scratch0_(scratch0) {
: object_(object),
address_(address),
scratch0_(scratch0),
scratch1_(no_reg) {
DCHECK(!AreAliased(scratch0, object, address, no_reg));
scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_);
}
......
This diff is collapsed.
......@@ -8,25 +8,26 @@
#include "src/assembler.h"
#include "src/bailout-reason.h"
#include "src/globals.h"
#include "src/s390/assembler-s390.h"
namespace v8 {
namespace internal {
// Give alias names to registers for calling conventions.
const Register kReturnRegister0 = {Register::kCode_r2};
const Register kReturnRegister1 = {Register::kCode_r3};
const Register kReturnRegister2 = {Register::kCode_r4};
const Register kJSFunctionRegister = {Register::kCode_r3};
const Register kContextRegister = {Register::kCode_r13};
const Register kAllocateSizeRegister = {Register::kCode_r3};
const Register kInterpreterAccumulatorRegister = {Register::kCode_r2};
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r6};
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r7};
const Register kInterpreterDispatchTableRegister = {Register::kCode_r8};
const Register kJavaScriptCallArgCountRegister = {Register::kCode_r2};
const Register kJavaScriptCallNewTargetRegister = {Register::kCode_r5};
const Register kRuntimeCallFunctionRegister = {Register::kCode_r3};
const Register kRuntimeCallArgCountRegister = {Register::kCode_r2};
const Register kReturnRegister0 = r2;
const Register kReturnRegister1 = r3;
const Register kReturnRegister2 = r4;
const Register kJSFunctionRegister = r3;
const Register kContextRegister = r13;
const Register kAllocateSizeRegister = r3;
const Register kInterpreterAccumulatorRegister = r2;
const Register kInterpreterBytecodeOffsetRegister = r6;
const Register kInterpreterBytecodeArrayRegister = r7;
const Register kInterpreterDispatchTableRegister = r8;
const Register kJavaScriptCallArgCountRegister = r2;
const Register kJavaScriptCallNewTargetRegister = r5;
const Register kRuntimeCallFunctionRegister = r3;
const Register kRuntimeCallArgCountRegister = r2;
// ----------------------------------------------------------------------------
// Static helper functions
......@@ -567,16 +568,16 @@ class TurboAssembler : public Assembler {
// Push five registers. Pushes leftmost register first (to highest address).
void Push(Register src1, Register src2, Register src3, Register src4,
Register src5) {
DCHECK(!src1.is(src2));
DCHECK(!src1.is(src3));
DCHECK(!src2.is(src3));
DCHECK(!src1.is(src4));
DCHECK(!src2.is(src4));
DCHECK(!src3.is(src4));
DCHECK(!src1.is(src5));
DCHECK(!src2.is(src5));
DCHECK(!src3.is(src5));
DCHECK(!src4.is(src5));
DCHECK(src1 != src2);
DCHECK(src1 != src3);
DCHECK(src2 != src3);
DCHECK(src1 != src4);
DCHECK(src2 != src4);
DCHECK(src3 != src4);
DCHECK(src1 != src5);
DCHECK(src2 != src5);
DCHECK(src3 != src5);
DCHECK(src4 != src5);
lay(sp, MemOperand(sp, -kPointerSize * 5));
StoreP(src1, MemOperand(sp, kPointerSize * 4));
......@@ -889,7 +890,7 @@ class TurboAssembler : public Assembler {
} else {
if (rangeEnd > 0) // Don't need to shift if rangeEnd is zero.
ShiftRightP(dst, src, Operand(rangeEnd));
else if (!dst.is(src)) // If we didn't shift, we might need to copy
else if (dst != src) // If we didn't shift, we might need to copy
LoadRR(dst, src);
int width = rangeStart - rangeEnd + 1;
#if V8_TARGET_ARCH_S390X
......@@ -1451,9 +1452,6 @@ class MacroAssembler : public TurboAssembler {
inline void GetMarkBits(Register addr_reg, Register bitmap_reg,
Register mask_reg);
static const RegList kSafepointSavedRegisters;
static const int kNumSafepointSavedRegisters;
// Compute memory operands for safepoint stack slots.
static int SafepointRegisterStackIndex(int reg_code);
......
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