Commit 11291891 authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

Reland "PPC/s390: Fix arguement handling"

This is a reland of af49af00
Original change's description:
> PPC/s390: Fix arguement handling
> 
> 1. in AssembleMove and AssembleSwap, we need to distinguish Double and Float
> 2. in 32-bit mode, double needs to be counted as 2 slots in stack
> 
> R=joransiu@ca.ibm.com, jbarboza@ca.ibm.com, michael_dawson@ca.ibm.com, mmallick@ca.ibm.com
> 
> Bug: 
> Change-Id: Iffe1844aa72e9d4c9492034c3df9a994e1304a27
> Reviewed-on: https://chromium-review.googlesource.com/720676
> Reviewed-by: Joran Siu <joransiu@ca.ibm.com>
> Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
> Cr-Commit-Position: refs/heads/master@{#48593}

Change-Id: If91125e71b82c92f54f537345e4c213bd185e786
Reviewed-on: https://chromium-review.googlesource.com/721419Reviewed-by: 's avatarJoran Siu <joransiu@ca.ibm.com>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#48610}
parent e60edd95
......@@ -1721,11 +1721,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case kPPC_Push:
if (instr->InputAt(0)->IsFPRegister()) {
__ stfdu(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
LocationOperand* op = LocationOperand::cast(instr->InputAt(0));
if (op->representation() == MachineRepresentation::kFloat64) {
__ StoreDoubleU(i.InputDoubleRegister(0),
MemOperand(sp, -kDoubleSize), r0);
} else {
DCHECK_EQ(MachineRepresentation::kFloat32, op->representation());
__ StoreSingleU(i.InputDoubleRegister(0),
MemOperand(sp, -kPointerSize), r0);
}
} else {
__ Push(i.InputRegister(0));
frame_access_state()->IncreaseSPDelta(1);
__ StorePU(i.InputRegister(0), MemOperand(sp, -kPointerSize), r0);
}
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
......@@ -2576,10 +2582,60 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
}
// Swaping contents in source and destination.
// source and destination could be:
// Register,
// FloatRegister,
// DoubleRegister,
// StackSlot,
// FloatStackSlot,
// or DoubleStackSlot
void CodeGenerator::AssembleSwap(InstructionOperand* source,
InstructionOperand* destination) {
PPCOperandConverter g(this, nullptr);
if (source->IsRegister()) {
Register src = g.ToRegister(source);
if (destination->IsRegister()) {
__ SwapP(src, g.ToRegister(destination), kScratchReg);
} else {
DCHECK(destination->IsStackSlot());
__ SwapP(src, g.ToMemOperand(destination), kScratchReg);
}
} else if (source->IsStackSlot()) {
DCHECK(destination->IsStackSlot());
__ SwapP(g.ToMemOperand(source), g.ToMemOperand(destination), kScratchReg,
r0);
} else if (source->IsFloatRegister()) {
DoubleRegister src = g.ToDoubleRegister(source);
if (destination->IsFloatRegister()) {
__ SwapFloat32(src, g.ToDoubleRegister(destination), kScratchDoubleReg);
} else {
DCHECK(destination->IsFloatStackSlot());
__ SwapFloat32(src, g.ToMemOperand(destination), kScratchDoubleReg);
}
} else if (source->IsDoubleRegister()) {
DoubleRegister src = g.ToDoubleRegister(source);
if (destination->IsDoubleRegister()) {
__ SwapDouble(src, g.ToDoubleRegister(destination), kScratchDoubleReg);
} else {
DCHECK(destination->IsDoubleStackSlot());
__ SwapDouble(src, g.ToMemOperand(destination), kScratchDoubleReg);
}
} else if (source->IsFloatStackSlot()) {
DCHECK(destination->IsFloatStackSlot());
__ SwapFloat32(g.ToMemOperand(source), g.ToMemOperand(destination),
kScratchDoubleReg, d0);
} else if (source->IsDoubleStackSlot()) {
DCHECK(destination->IsDoubleStackSlot());
__ SwapDouble(g.ToMemOperand(source), g.ToMemOperand(destination),
kScratchDoubleReg, d0);
} else if (source->IsSimd128Register()) {
UNREACHABLE();
} else {
UNREACHABLE();
}
return;
// Dispatch on the source and destination operand kinds. Not all
// combinations are possible.
if (source->IsRegister()) {
......
......@@ -1995,21 +1995,10 @@ void InstructionSelector::EmitPrepareArguments(
}
} else {
// Push any stack arguments.
int num_slots = static_cast<int>(descriptor->StackParameterCount());
int slot = 0;
for (PushParameter input : (*arguments)) {
if (slot == 0) {
DCHECK(input.node());
Emit(kPPC_PushFrame, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(num_slots));
} else {
// Skip any alignment holes in pushed nodes.
if (input.node()) {
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(slot));
}
}
++slot;
for (PushParameter input : base::Reversed(*arguments)) {
// Skip any alignment holes in pushed nodes.
if (input.node() == nullptr) continue;
Emit(kPPC_Push, g.NoOutput(), g.UseRegister(input.node()));
}
}
}
......
......@@ -1964,11 +1964,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ CanonicalizeNaN(result, value);
break;
}
case kS390_StackClaim: {
int num_slots = i.InputInt32(0);
__ lay(sp, MemOperand(sp, -num_slots * kPointerSize));
frame_access_state()->IncreaseSPDelta(num_slots);
break;
}
case kS390_Push:
if (instr->InputAt(0)->IsFPRegister()) {
__ lay(sp, MemOperand(sp, -kDoubleSize));
__ StoreDouble(i.InputDoubleRegister(0), MemOperand(sp));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
LocationOperand* op = LocationOperand::cast(instr->InputAt(0));
if (op->representation() == MachineRepresentation::kFloat64) {
__ lay(sp, MemOperand(sp, -kDoubleSize));
__ StoreDouble(i.InputDoubleRegister(0), MemOperand(sp));
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
} else {
DCHECK_EQ(MachineRepresentation::kFloat32, op->representation());
__ lay(sp, MemOperand(sp, -kPointerSize));
__ StoreFloat32(i.InputDoubleRegister(0), MemOperand(sp));
frame_access_state()->IncreaseSPDelta(1);
}
} else {
__ Push(i.InputRegister(0));
frame_access_state()->IncreaseSPDelta(1);
......@@ -2883,7 +2897,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
__ LoadDoubleLiteral(dst, value, kScratchReg);
}
if (destination->IsFPStackSlot()) {
if (destination->IsFloatStackSlot()) {
__ StoreFloat32(dst, g.ToMemOperand(destination));
} else if (destination->IsDoubleStackSlot()) {
__ StoreDouble(dst, g.ToMemOperand(destination));
}
}
......@@ -2927,71 +2943,56 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
}
// Swaping contents in source and destination.
// source and destination could be:
// Register,
// FloatRegister,
// DoubleRegister,
// StackSlot,
// FloatStackSlot,
// or DoubleStackSlot
void CodeGenerator::AssembleSwap(InstructionOperand* source,
InstructionOperand* destination) {
S390OperandConverter g(this, nullptr);
// Dispatch on the source and destination operand kinds. Not all
// combinations are possible.
if (source->IsRegister()) {
// Register-register.
Register temp = kScratchReg;
Register src = g.ToRegister(source);
if (destination->IsRegister()) {
Register dst = g.ToRegister(destination);
__ LoadRR(temp, src);
__ LoadRR(src, dst);
__ LoadRR(dst, temp);
__ SwapP(src, g.ToRegister(destination), kScratchReg);
} else {
DCHECK(destination->IsStackSlot());
MemOperand dst = g.ToMemOperand(destination);
__ LoadRR(temp, src);
__ LoadP(src, dst);
__ StoreP(temp, dst);
__ SwapP(src, g.ToMemOperand(destination), kScratchReg);
}
#if V8_TARGET_ARCH_S390X
} else if (source->IsStackSlot() || source->IsFPStackSlot()) {
#else
} else if (source->IsStackSlot()) {
DCHECK(destination->IsStackSlot());
#endif
Register temp_0 = kScratchReg;
Register temp_1 = r0;
MemOperand src = g.ToMemOperand(source);
MemOperand dst = g.ToMemOperand(destination);
__ LoadP(temp_0, src);
__ LoadP(temp_1, dst);
__ StoreP(temp_0, dst);
__ StoreP(temp_1, src);
} else if (source->IsFPRegister()) {
DoubleRegister temp = kScratchDoubleReg;
__ SwapP(g.ToMemOperand(source), g.ToMemOperand(destination), kScratchReg,
r0);
} else if (source->IsFloatRegister()) {
DoubleRegister src = g.ToDoubleRegister(source);
if (destination->IsFPRegister()) {
DoubleRegister dst = g.ToDoubleRegister(destination);
__ ldr(temp, src);
__ ldr(src, dst);
__ ldr(dst, temp);
if (destination->IsFloatRegister()) {
__ SwapFloat32(src, g.ToDoubleRegister(destination), kScratchDoubleReg);
} else {
DCHECK(destination->IsFPStackSlot());
MemOperand dst = g.ToMemOperand(destination);
__ ldr(temp, src);
__ LoadDouble(src, dst);
__ StoreDouble(temp, dst);
DCHECK(destination->IsFloatStackSlot());
__ SwapFloat32(src, g.ToMemOperand(destination), kScratchDoubleReg);
}
#if !V8_TARGET_ARCH_S390X
} else if (source->IsFPStackSlot()) {
DCHECK(destination->IsFPStackSlot());
DoubleRegister temp_0 = kScratchDoubleReg;
DoubleRegister temp_1 = d0;
MemOperand src = g.ToMemOperand(source);
MemOperand dst = g.ToMemOperand(destination);
// TODO(joransiu): MVC opportunity
__ LoadDouble(temp_0, src);
__ LoadDouble(temp_1, dst);
__ StoreDouble(temp_0, dst);
__ StoreDouble(temp_1, src);
#endif
} else if (source->IsDoubleRegister()) {
DoubleRegister src = g.ToDoubleRegister(source);
if (destination->IsDoubleRegister()) {
__ SwapDouble(src, g.ToDoubleRegister(destination), kScratchDoubleReg);
} else {
DCHECK(destination->IsDoubleStackSlot());
__ SwapDouble(src, g.ToMemOperand(destination), kScratchDoubleReg);
}
} else if (source->IsFloatStackSlot()) {
DCHECK(destination->IsFloatStackSlot());
__ SwapFloat32(g.ToMemOperand(source), g.ToMemOperand(destination),
kScratchDoubleReg, d0);
} else if (source->IsDoubleStackSlot()) {
DCHECK(destination->IsDoubleStackSlot());
__ SwapDouble(g.ToMemOperand(source), g.ToMemOperand(destination),
kScratchDoubleReg, d0);
} else if (source->IsSimd128Register()) {
UNREACHABLE();
} else {
// No other combinations are possible.
UNREACHABLE();
}
}
......
......@@ -97,6 +97,7 @@ namespace compiler {
V(S390_Tst64) \
V(S390_Push) \
V(S390_PushFrame) \
V(S390_StackClaim) \
V(S390_StoreToStackSlot) \
V(S390_ExtendSignWord8) \
V(S390_ExtendSignWord16) \
......
......@@ -164,6 +164,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kS390_Push:
case kS390_PushFrame:
case kS390_StoreToStackSlot:
case kS390_StackClaim:
return kHasSideEffect;
#define CASE(Name) case k##Name:
......
......@@ -2357,22 +2357,28 @@ void InstructionSelector::EmitPrepareArguments(
}
} else {
// Push any stack arguments.
int num_slots = static_cast<int>(descriptor->StackParameterCount());
int num_slots = 0;
int slot = 0;
for (PushParameter input : (*arguments)) {
if (slot == 0) {
DCHECK(input.node());
Emit(kS390_PushFrame, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(num_slots));
} else {
// Skip any alignment holes in pushed nodes.
if (input.node()) {
Emit(kS390_StoreToStackSlot, g.NoOutput(),
g.UseRegister(input.node()), g.TempImmediate(slot));
}
for (PushParameter input : *arguments) {
if (input.node() == nullptr) continue;
num_slots +=
input.type().representation() == MachineRepresentation::kFloat64
? kDoubleSize / kPointerSize
: 1;
}
Emit(kS390_StackClaim, g.NoOutput(), g.TempImmediate(num_slots));
for (PushParameter input : *arguments) {
// Skip any alignment holes in pushed nodes.
if (input.node()) {
Emit(kS390_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
g.TempImmediate(slot));
slot += input.type().representation() == MachineRepresentation::kFloat64
? (kDoubleSize / kPointerSize)
: 1;
}
++slot;
}
DCHECK(num_slots == slot);
}
}
......
......@@ -341,7 +341,7 @@ typedef DoubleRegister Simd128Register;
constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
DOUBLE_REGISTERS(DEFINE_REGISTER)
#undef DEFINE_REGISTER
constexpr Register no_dreg = Register::no_reg();
constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
constexpr DoubleRegister kFirstCalleeSavedDoubleReg = d14;
constexpr DoubleRegister kLastCalleeSavedDoubleReg = d31;
......@@ -461,12 +461,10 @@ class MemOperand BASE_EMBEDDED {
// PowerPC - base register
Register ra() const {
DCHECK(ra_ != no_reg);
return ra_;
}
Register rb() const {
DCHECK(offset_ == 0 && rb_ != no_reg);
return rb_;
}
......
......@@ -2946,6 +2946,90 @@ Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2, Register reg3,
UNREACHABLE();
}
void TurboAssembler::SwapP(Register src, Register dst, Register scratch) {
if (src == dst) return;
DCHECK(!AreAliased(src, dst, scratch));
mr(scratch, src);
mr(src, dst);
mr(dst, scratch);
}
void TurboAssembler::SwapP(Register src, MemOperand dst, Register scratch) {
if (dst.ra() != r0) DCHECK(!AreAliased(src, dst.ra(), scratch));
if (dst.rb() != r0) DCHECK(!AreAliased(src, dst.rb(), scratch));
DCHECK(!AreAliased(src, scratch));
mr(scratch, src);
LoadP(src, dst);
StoreP(scratch, dst);
}
void TurboAssembler::SwapP(MemOperand src, MemOperand dst, Register scratch_0,
Register scratch_1) {
if (src.ra() != r0) DCHECK(!AreAliased(src.ra(), scratch_0, scratch_1));
if (src.rb() != r0) DCHECK(!AreAliased(src.rb(), scratch_0, scratch_1));
if (dst.ra() != r0) DCHECK(!AreAliased(dst.ra(), scratch_0, scratch_1));
if (dst.rb() != r0) DCHECK(!AreAliased(dst.rb(), scratch_0, scratch_1));
DCHECK(!AreAliased(scratch_0, scratch_1));
LoadP(scratch_0, src);
LoadP(scratch_1, dst);
StoreP(scratch_0, dst);
StoreP(scratch_1, src);
}
void TurboAssembler::SwapFloat32(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch) {
if (src == dst) return;
DCHECK(!AreAliased(src, dst, scratch));
fmr(scratch, src);
fmr(src, dst);
fmr(dst, scratch);
}
void TurboAssembler::SwapFloat32(DoubleRegister src, MemOperand dst,
DoubleRegister scratch) {
DCHECK(!AreAliased(src, scratch));
fmr(scratch, src);
LoadSingle(src, dst);
StoreSingle(scratch, dst);
}
void TurboAssembler::SwapFloat32(MemOperand src, MemOperand dst,
DoubleRegister scratch_0,
DoubleRegister scratch_1) {
DCHECK(!AreAliased(scratch_0, scratch_1));
LoadSingle(scratch_0, src);
LoadSingle(scratch_1, dst);
StoreSingle(scratch_0, dst);
StoreSingle(scratch_1, src);
}
void TurboAssembler::SwapDouble(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch) {
if (src == dst) return;
DCHECK(!AreAliased(src, dst, scratch));
fmr(scratch, src);
fmr(src, dst);
fmr(dst, scratch);
}
void TurboAssembler::SwapDouble(DoubleRegister src, MemOperand dst,
DoubleRegister scratch) {
DCHECK(!AreAliased(src, scratch));
fmr(scratch, src);
LoadDouble(src, dst);
StoreDouble(scratch, dst);
}
void TurboAssembler::SwapDouble(MemOperand src, MemOperand dst,
DoubleRegister scratch_0,
DoubleRegister scratch_1) {
DCHECK(!AreAliased(scratch_0, scratch_1));
LoadDouble(scratch_0, src);
LoadDouble(scratch_1, dst);
StoreDouble(scratch_0, dst);
StoreDouble(scratch_1, src);
}
#ifdef DEBUG
bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
Register reg5, Register reg6, Register reg7, Register reg8,
......@@ -2970,6 +3054,31 @@ bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
return n_of_valid_regs != n_of_non_aliasing_regs;
}
bool AreAliased(DoubleRegister reg1, DoubleRegister reg2, DoubleRegister reg3,
DoubleRegister reg4, DoubleRegister reg5, DoubleRegister reg6,
DoubleRegister reg7, DoubleRegister reg8, DoubleRegister reg9,
DoubleRegister reg10) {
int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + reg3.is_valid() +
reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
reg7.is_valid() + reg8.is_valid() + reg9.is_valid() +
reg10.is_valid();
RegList regs = 0;
if (reg1.is_valid()) regs |= reg1.bit();
if (reg2.is_valid()) regs |= reg2.bit();
if (reg3.is_valid()) regs |= reg3.bit();
if (reg4.is_valid()) regs |= reg4.bit();
if (reg5.is_valid()) regs |= reg5.bit();
if (reg6.is_valid()) regs |= reg6.bit();
if (reg7.is_valid()) regs |= reg7.bit();
if (reg8.is_valid()) regs |= reg8.bit();
if (reg9.is_valid()) regs |= reg9.bit();
if (reg10.is_valid()) regs |= reg10.bit();
int n_of_non_aliasing_regs = NumRegs(regs);
return n_of_valid_regs != n_of_non_aliasing_regs;
}
#endif
......
......@@ -66,6 +66,11 @@ bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
Register reg6 = no_reg, Register reg7 = no_reg,
Register reg8 = no_reg, Register reg9 = no_reg,
Register reg10 = no_reg);
bool AreAliased(DoubleRegister reg1, DoubleRegister reg2,
DoubleRegister reg3 = no_dreg, DoubleRegister reg4 = no_dreg,
DoubleRegister reg5 = no_dreg, DoubleRegister reg6 = no_dreg,
DoubleRegister reg7 = no_dreg, DoubleRegister reg8 = no_dreg,
DoubleRegister reg9 = no_dreg, DoubleRegister reg10 = no_dreg);
#endif
// These exist to provide portability between 32 and 64bit
......@@ -339,6 +344,21 @@ class TurboAssembler : public Assembler {
void LoadRoot(Register destination, Heap::RootListIndex index,
Condition cond = al);
void SwapP(Register src, Register dst, Register scratch);
void SwapP(Register src, MemOperand dst, Register scratch);
void SwapP(MemOperand src, MemOperand dst, Register scratch_0,
Register scratch_1);
void SwapFloat32(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch);
void SwapFloat32(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
void SwapFloat32(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
DoubleRegister scratch_1);
void SwapDouble(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch);
void SwapDouble(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
void SwapDouble(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
DoubleRegister scratch_1);
// Before calling a C-function from generated code, align arguments on stack.
// After aligning the frame, non-register arguments must be stored in
// sp[0], sp[4], etc., not pushed. The argument count assumes all arguments
......
......@@ -3575,25 +3575,27 @@ void TurboAssembler::LoadP(Register dst, const MemOperand& mem,
Register scratch) {
int offset = mem.offset();
if (scratch != no_reg && !is_int20(offset)) {
/* cannot use d-form */
LoadIntLiteral(scratch, offset);
#if V8_TARGET_ARCH_S390X
lg(dst, MemOperand(mem.rb(), scratch));
MemOperand src = mem;
if (!is_int20(offset)) {
DCHECK(scratch != no_reg && scratch != r0 && mem.rx() == r0);
DCHECK(scratch != mem.rb());
LoadIntLiteral(scratch, offset);
src = MemOperand(mem.rb(), scratch);
}
lg(dst, src);
#else
l(dst, MemOperand(mem.rb(), scratch));
#endif
if (is_uint12(offset)) {
l(dst, mem);
} else if (is_int20(offset)) {
ly(dst, mem);
} else {
#if V8_TARGET_ARCH_S390X
lg(dst, mem);
#else
if (is_uint12(offset)) {
l(dst, mem);
} else {
ly(dst, mem);
}
#endif
DCHECK(scratch != no_reg && scratch != r0 && mem.rx() == r0);
DCHECK(scratch != mem.rb());
LoadIntLiteral(scratch, offset);
l(dst, MemOperand(mem.rb(), scratch));
}
#endif
}
// Store a "pointer" sized value to the memory location
......@@ -4288,6 +4290,90 @@ void TurboAssembler::Popcnt64(Register dst, Register src) {
}
#endif
void TurboAssembler::SwapP(Register src, Register dst, Register scratch) {
if (src == dst) return;
DCHECK(!AreAliased(src, dst, scratch));
LoadRR(scratch, src);
LoadRR(src, dst);
LoadRR(dst, scratch);
}
void TurboAssembler::SwapP(Register src, MemOperand dst, Register scratch) {
if (dst.rx() != r0) DCHECK(!AreAliased(src, dst.rx(), scratch));
if (dst.rb() != r0) DCHECK(!AreAliased(src, dst.rb(), scratch));
DCHECK(!AreAliased(src, scratch));
LoadRR(scratch, src);
LoadP(src, dst);
StoreP(scratch, dst);
}
void TurboAssembler::SwapP(MemOperand src, MemOperand dst, Register scratch_0,
Register scratch_1) {
if (src.rx() != r0) DCHECK(!AreAliased(src.rx(), scratch_0, scratch_1));
if (src.rb() != r0) DCHECK(!AreAliased(src.rb(), scratch_0, scratch_1));
if (dst.rx() != r0) DCHECK(!AreAliased(dst.rx(), scratch_0, scratch_1));
if (dst.rb() != r0) DCHECK(!AreAliased(dst.rb(), scratch_0, scratch_1));
DCHECK(!AreAliased(scratch_0, scratch_1));
LoadP(scratch_0, src);
LoadP(scratch_1, dst);
StoreP(scratch_0, dst);
StoreP(scratch_1, src);
}
void TurboAssembler::SwapFloat32(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch) {
if (src == dst) return;
DCHECK(!AreAliased(src, dst, scratch));
ldr(scratch, src);
ldr(src, dst);
ldr(dst, scratch);
}
void TurboAssembler::SwapFloat32(DoubleRegister src, MemOperand dst,
DoubleRegister scratch) {
DCHECK(!AreAliased(src, scratch));
ldr(scratch, src);
LoadFloat32(src, dst);
StoreFloat32(scratch, dst);
}
void TurboAssembler::SwapFloat32(MemOperand src, MemOperand dst,
DoubleRegister scratch_0,
DoubleRegister scratch_1) {
DCHECK(!AreAliased(scratch_0, scratch_1));
LoadFloat32(scratch_0, src);
LoadFloat32(scratch_1, dst);
StoreFloat32(scratch_0, dst);
StoreFloat32(scratch_1, src);
}
void TurboAssembler::SwapDouble(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch) {
if (src == dst) return;
DCHECK(!AreAliased(src, dst, scratch));
ldr(scratch, src);
ldr(src, dst);
ldr(dst, scratch);
}
void TurboAssembler::SwapDouble(DoubleRegister src, MemOperand dst,
DoubleRegister scratch) {
DCHECK(!AreAliased(src, scratch));
ldr(scratch, src);
LoadDouble(src, dst);
StoreDouble(scratch, dst);
}
void TurboAssembler::SwapDouble(MemOperand src, MemOperand dst,
DoubleRegister scratch_0,
DoubleRegister scratch_1) {
DCHECK(!AreAliased(scratch_0, scratch_1));
LoadDouble(scratch_0, src);
LoadDouble(scratch_1, dst);
StoreDouble(scratch_0, dst);
StoreDouble(scratch_1, src);
}
#ifdef DEBUG
bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
Register reg5, Register reg6, Register reg7, Register reg8,
......@@ -4312,6 +4398,30 @@ bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
return n_of_valid_regs != n_of_non_aliasing_regs;
}
bool AreAliased(DoubleRegister reg1, DoubleRegister reg2, DoubleRegister reg3,
DoubleRegister reg4, DoubleRegister reg5, DoubleRegister reg6,
DoubleRegister reg7, DoubleRegister reg8, DoubleRegister reg9,
DoubleRegister reg10) {
int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + reg3.is_valid() +
reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
reg7.is_valid() + reg8.is_valid() + reg9.is_valid() +
reg10.is_valid();
RegList regs = 0;
if (reg1.is_valid()) regs |= reg1.bit();
if (reg2.is_valid()) regs |= reg2.bit();
if (reg3.is_valid()) regs |= reg3.bit();
if (reg4.is_valid()) regs |= reg4.bit();
if (reg5.is_valid()) regs |= reg5.bit();
if (reg6.is_valid()) regs |= reg6.bit();
if (reg7.is_valid()) regs |= reg7.bit();
if (reg8.is_valid()) regs |= reg8.bit();
if (reg9.is_valid()) regs |= reg9.bit();
if (reg10.is_valid()) regs |= reg10.bit();
int n_of_non_aliasing_regs = NumRegs(regs);
return n_of_valid_regs != n_of_non_aliasing_regs;
}
#endif
} // namespace internal
......
......@@ -71,6 +71,11 @@ bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
Register reg6 = no_reg, Register reg7 = no_reg,
Register reg8 = no_reg, Register reg9 = no_reg,
Register reg10 = no_reg);
bool AreAliased(DoubleRegister reg1, DoubleRegister reg2,
DoubleRegister reg3 = no_dreg, DoubleRegister reg4 = no_dreg,
DoubleRegister reg5 = no_dreg, DoubleRegister reg6 = no_dreg,
DoubleRegister reg7 = no_dreg, DoubleRegister reg8 = no_dreg,
DoubleRegister reg9 = no_dreg, DoubleRegister reg10 = no_dreg);
#endif
// These exist to provide portability between 32 and 64bit
......@@ -782,6 +787,21 @@ class TurboAssembler : public Assembler {
void LoadMultipleW(Register dst1, Register dst2, const MemOperand& mem);
void StoreMultipleW(Register dst1, Register dst2, const MemOperand& mem);
void SwapP(Register src, Register dst, Register scratch);
void SwapP(Register src, MemOperand dst, Register scratch);
void SwapP(MemOperand src, MemOperand dst, Register scratch_0,
Register scratch_1);
void SwapFloat32(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch);
void SwapFloat32(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
void SwapFloat32(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
DoubleRegister scratch_1);
void SwapDouble(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch);
void SwapDouble(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
void SwapDouble(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
DoubleRegister scratch_1);
// Cleanse pointer address on 31bit by zero out top bit.
// This is a NOP on 64-bit.
void CleanseP(Register src) {
......
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