Commit b4275a70 authored by akos.palfi's avatar akos.palfi Committed by Commit bot

[turbofan] Add CalleeSavedFPRegisters to CallDescriptor.

This change makes possible to save and restore the FP registers
in the Prologue and Return parts for the CallAddress kind functions.

TEST=test-simplified-lowering/RunNumberDivide_2_TruncatingToUint32,
     test-simplified-lowering/RunNumberMultiply_TruncatingToUint32

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

Cr-Commit-Position: refs/heads/master@{#29378}
parent e60ce8d1
...@@ -962,16 +962,28 @@ void CodeGenerator::AssemblePrologue() { ...@@ -962,16 +962,28 @@ void CodeGenerator::AssemblePrologue() {
__ mov(fp, sp); __ mov(fp, sp);
saved_pp = false; saved_pp = false;
} }
int register_save_area_size = saved_pp ? kPointerSize : 0;
const RegList saves = descriptor->CalleeSavedRegisters(); const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0 || saved_pp) { if (saves != 0 || saved_pp) {
// Save callee-saved registers. // Save callee-saved registers.
int register_save_area_size = saved_pp ? kPointerSize : 0;
for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
if (!((1 << i) & saves)) continue;
register_save_area_size += kPointerSize;
}
frame()->SetRegisterSaveAreaSize(register_save_area_size);
__ stm(db_w, sp, saves); __ stm(db_w, sp, saves);
register_save_area_size +=
kPointerSize * base::bits::CountPopulation32(saves);
}
const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
if (saves_fp != 0) {
// Save callee-saved FP registers.
STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32);
uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1;
uint32_t first = base::bits::CountTrailingZeros32(saves_fp);
DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp));
__ vstm(db_w, sp, DwVfpRegister::from_code(first),
DwVfpRegister::from_code(last));
register_save_area_size += 2 * kPointerSize * (last - first + 1);
}
if (register_save_area_size > 0) {
frame()->SetRegisterSaveAreaSize(register_save_area_size);
} }
} else if (descriptor->IsJSFunctionCall()) { } else if (descriptor->IsJSFunctionCall()) {
CompilationInfo* info = this->info(); CompilationInfo* info = this->info();
...@@ -1015,6 +1027,15 @@ void CodeGenerator::AssembleReturn() { ...@@ -1015,6 +1027,15 @@ void CodeGenerator::AssembleReturn() {
if (stack_slots > 0) { if (stack_slots > 0) {
__ add(sp, sp, Operand(stack_slots * kPointerSize)); __ add(sp, sp, Operand(stack_slots * kPointerSize));
} }
// Restore FP registers.
const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
if (saves_fp != 0) {
STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32);
uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1;
uint32_t first = base::bits::CountTrailingZeros32(saves_fp);
__ vldm(ia_w, sp, DwVfpRegister::from_code(first),
DwVfpRegister::from_code(last));
}
// Restore registers. // Restore registers.
const RegList saves = descriptor->CalleeSavedRegisters(); const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) { if (saves != 0) {
......
...@@ -23,6 +23,11 @@ struct ArmLinkageHelperTraits { ...@@ -23,6 +23,11 @@ struct ArmLinkageHelperTraits {
return r4.bit() | r5.bit() | r6.bit() | r7.bit() | r8.bit() | r9.bit() | return r4.bit() | r5.bit() | r6.bit() | r7.bit() | r8.bit() | r9.bit() |
r10.bit(); r10.bit();
} }
static RegList CCalleeSaveFPRegisters() {
return (1 << d8.code()) | (1 << d9.code()) | (1 << d10.code()) |
(1 << d11.code()) | (1 << d12.code()) | (1 << d13.code()) |
(1 << d14.code()) | (1 << d15.code());
}
static Register CRegisterParameter(int i) { static Register CRegisterParameter(int i) {
static Register register_parameters[] = {r0, r1, r2, r3}; static Register register_parameters[] = {r0, r1, r2, r3};
return register_parameters[i]; return register_parameters[i];
......
...@@ -1094,9 +1094,23 @@ void CodeGenerator::AssemblePrologue() { ...@@ -1094,9 +1094,23 @@ void CodeGenerator::AssemblePrologue() {
__ SetStackPointer(csp); __ SetStackPointer(csp);
__ Push(lr, fp); __ Push(lr, fp);
__ Mov(fp, csp); __ Mov(fp, csp);
// TODO(dcarney): correct callee saved registers.
__ PushCalleeSavedRegisters(); // Save FP registers.
frame()->SetRegisterSaveAreaSize(20 * kPointerSize); CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
descriptor->CalleeSavedFPRegisters());
DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list());
int saved_count = saves_fp.Count();
__ PushCPURegList(saves_fp);
// Save registers.
CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
descriptor->CalleeSavedRegisters());
// TODO(palfia): TF save list is not in sync with
// CPURegList::GetCalleeSaved(): x30 is missing.
// DCHECK(saves.list() == CPURegList::GetCalleeSaved().list());
saved_count += saves.Count();
__ PushCPURegList(saves);
frame()->SetRegisterSaveAreaSize(saved_count * kPointerSize);
} else if (descriptor->IsJSFunctionCall()) { } else if (descriptor->IsJSFunctionCall()) {
CompilationInfo* info = this->info(); CompilationInfo* info = this->info();
__ SetStackPointer(jssp); __ SetStackPointer(jssp);
...@@ -1145,10 +1159,18 @@ void CodeGenerator::AssembleReturn() { ...@@ -1145,10 +1159,18 @@ void CodeGenerator::AssembleReturn() {
if (stack_slots > 0) { if (stack_slots > 0) {
__ Add(csp, csp, AlignedStackSlots(stack_slots) * kPointerSize); __ Add(csp, csp, AlignedStackSlots(stack_slots) * kPointerSize);
} }
// Restore registers. // Restore registers.
// TODO(dcarney): correct callee saved registers. CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
__ PopCalleeSavedRegisters(); descriptor->CalleeSavedRegisters());
__ PopCPURegList(saves);
CPURegList saves_fp =
CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
descriptor->CalleeSavedFPRegisters());
__ PopCPURegList(saves_fp);
} }
__ Mov(csp, fp); __ Mov(csp, fp);
__ Pop(fp, lr); __ Pop(fp, lr);
__ Ret(); __ Ret();
......
...@@ -20,8 +20,15 @@ struct Arm64LinkageHelperTraits { ...@@ -20,8 +20,15 @@ struct Arm64LinkageHelperTraits {
static Register RuntimeCallFunctionReg() { return x1; } static Register RuntimeCallFunctionReg() { return x1; }
static Register RuntimeCallArgCountReg() { return x0; } static Register RuntimeCallArgCountReg() { return x0; }
static RegList CCalleeSaveRegisters() { static RegList CCalleeSaveRegisters() {
// TODO(dcarney): correct callee saved registers. return (1 << x19.code()) | (1 << x20.code()) | (1 << x21.code()) |
return 0; (1 << x22.code()) | (1 << x23.code()) | (1 << x24.code()) |
(1 << x25.code()) | (1 << x26.code()) | (1 << x27.code()) |
(1 << x28.code()) | (1 << x29.code()) | (1 << x30.code());
}
static RegList CCalleeSaveFPRegisters() {
return (1 << d8.code()) | (1 << d9.code()) | (1 << d10.code()) |
(1 << d11.code()) | (1 << d12.code()) | (1 << d13.code()) |
(1 << d14.code()) | (1 << d15.code());
} }
static Register CRegisterParameter(int i) { static Register CRegisterParameter(int i) {
static Register register_parameters[] = {x0, x1, x2, x3, x4, x5, x6, x7}; static Register register_parameters[] = {x0, x1, x2, x3, x4, x5, x6, x7};
......
...@@ -22,6 +22,7 @@ struct IA32LinkageHelperTraits { ...@@ -22,6 +22,7 @@ struct IA32LinkageHelperTraits {
static RegList CCalleeSaveRegisters() { static RegList CCalleeSaveRegisters() {
return esi.bit() | edi.bit() | ebx.bit(); return esi.bit() | edi.bit() | ebx.bit();
} }
static RegList CCalleeSaveFPRegisters() { return 0; }
static Register CRegisterParameter(int i) { return no_reg; } static Register CRegisterParameter(int i) { return no_reg; }
static int CRegisterParametersLength() { return 0; } static int CRegisterParametersLength() { return 0; }
static int CStackBackingStoreLength() { return 0; } static int CStackBackingStoreLength() { return 0; }
......
...@@ -70,6 +70,7 @@ class LinkageHelper { ...@@ -70,6 +70,7 @@ class LinkageHelper {
js_parameter_count, // js_parameter_count js_parameter_count, // js_parameter_count
Operator::kNoProperties, // properties Operator::kNoProperties, // properties
kNoCalleeSaved, // callee-saved kNoCalleeSaved, // callee-saved
kNoCalleeSaved, // callee-saved fp
flags, // flags flags, // flags
"js-call"); "js-call");
} }
...@@ -131,6 +132,7 @@ class LinkageHelper { ...@@ -131,6 +132,7 @@ class LinkageHelper {
js_parameter_count, // js_parameter_count js_parameter_count, // js_parameter_count
properties, // properties properties, // properties
kNoCalleeSaved, // callee-saved kNoCalleeSaved, // callee-saved
kNoCalleeSaved, // callee-saved fp
flags, // flags flags, // flags
function->name); // debug name function->name); // debug name
} }
...@@ -191,6 +193,7 @@ class LinkageHelper { ...@@ -191,6 +193,7 @@ class LinkageHelper {
js_parameter_count, // js_parameter_count js_parameter_count, // js_parameter_count
properties, // properties properties, // properties
kNoCalleeSaved, // callee-saved registers kNoCalleeSaved, // callee-saved registers
kNoCalleeSaved, // callee-saved fp
flags, // flags flags, // flags
descriptor.DebugName(isolate)); descriptor.DebugName(isolate));
} }
...@@ -217,16 +220,17 @@ class LinkageHelper { ...@@ -217,16 +220,17 @@ class LinkageHelper {
// The target for C calls is always an address (i.e. machine pointer). // The target for C calls is always an address (i.e. machine pointer).
MachineType target_type = kMachPtr; MachineType target_type = kMachPtr;
LinkageLocation target_loc = LinkageLocation::AnyRegister(); LinkageLocation target_loc = LinkageLocation::AnyRegister();
return new (zone) CallDescriptor( // -- return new (zone) CallDescriptor( // --
CallDescriptor::kCallAddress, // kind CallDescriptor::kCallAddress, // kind
target_type, // target MachineType target_type, // target MachineType
target_loc, // target location target_loc, // target location
msig, // machine_sig msig, // machine_sig
locations.Build(), // location_sig locations.Build(), // location_sig
0, // js_parameter_count 0, // js_parameter_count
Operator::kNoProperties, // properties Operator::kNoProperties, // properties
LinkageTraits::CCalleeSaveRegisters(), // callee-saved registers LinkageTraits::CCalleeSaveRegisters(), // callee-saved registers
CallDescriptor::kNoFlags, // flags LinkageTraits::CCalleeSaveFPRegisters(), // callee-saved fp regs
CallDescriptor::kNoFlags, // flags
"c-call"); "c-call");
} }
......
...@@ -83,7 +83,8 @@ class CallDescriptor final : public ZoneObject { ...@@ -83,7 +83,8 @@ class CallDescriptor final : public ZoneObject {
const MachineSignature* machine_sig, const MachineSignature* machine_sig,
LocationSignature* location_sig, size_t js_param_count, LocationSignature* location_sig, size_t js_param_count,
Operator::Properties properties, Operator::Properties properties,
RegList callee_saved_registers, Flags flags, RegList callee_saved_registers,
RegList callee_saved_fp_registers, Flags flags,
const char* debug_name = "") const char* debug_name = "")
: kind_(kind), : kind_(kind),
target_type_(target_type), target_type_(target_type),
...@@ -93,6 +94,7 @@ class CallDescriptor final : public ZoneObject { ...@@ -93,6 +94,7 @@ class CallDescriptor final : public ZoneObject {
js_param_count_(js_param_count), js_param_count_(js_param_count),
properties_(properties), properties_(properties),
callee_saved_registers_(callee_saved_registers), callee_saved_registers_(callee_saved_registers),
callee_saved_fp_registers_(callee_saved_fp_registers),
flags_(flags), flags_(flags),
debug_name_(debug_name) { debug_name_(debug_name) {
DCHECK(machine_sig->return_count() == location_sig->return_count()); DCHECK(machine_sig->return_count() == location_sig->return_count());
...@@ -156,6 +158,9 @@ class CallDescriptor final : public ZoneObject { ...@@ -156,6 +158,9 @@ class CallDescriptor final : public ZoneObject {
// Get the callee-saved registers, if any, across this call. // Get the callee-saved registers, if any, across this call.
RegList CalleeSavedRegisters() const { return callee_saved_registers_; } RegList CalleeSavedRegisters() const { return callee_saved_registers_; }
// Get the callee-saved FP registers, if any, across this call.
RegList CalleeSavedFPRegisters() const { return callee_saved_fp_registers_; }
const char* debug_name() const { return debug_name_; } const char* debug_name() const { return debug_name_; }
bool UsesOnlyRegisters() const; bool UsesOnlyRegisters() const;
...@@ -173,6 +178,7 @@ class CallDescriptor final : public ZoneObject { ...@@ -173,6 +178,7 @@ class CallDescriptor final : public ZoneObject {
const size_t js_param_count_; const size_t js_param_count_;
const Operator::Properties properties_; const Operator::Properties properties_;
const RegList callee_saved_registers_; const RegList callee_saved_registers_;
const RegList callee_saved_fp_registers_;
const Flags flags_; const Flags flags_;
const char* const debug_name_; const char* const debug_name_;
......
...@@ -1078,17 +1078,20 @@ void CodeGenerator::AssemblePrologue() { ...@@ -1078,17 +1078,20 @@ void CodeGenerator::AssemblePrologue() {
if (descriptor->kind() == CallDescriptor::kCallAddress) { if (descriptor->kind() == CallDescriptor::kCallAddress) {
__ Push(ra, fp); __ Push(ra, fp);
__ mov(fp, sp); __ mov(fp, sp);
const RegList saves = descriptor->CalleeSavedRegisters(); const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) { // Save callee-saved registers. // Save callee-saved registers.
// TODO(plind): make callee save size const, possibly DCHECK it. __ MultiPush(saves);
int register_save_area_size = 0; DCHECK(kNumCalleeSaved == base::bits::CountPopulation32(saves));
for (int i = Register::kNumRegisters - 1; i >= 0; i--) { int register_save_area_size = kNumCalleeSaved * kPointerSize;
if (!((1 << i) & saves)) continue;
register_save_area_size += kPointerSize; const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
} // Save callee-saved FPU registers.
frame()->SetRegisterSaveAreaSize(register_save_area_size); __ MultiPushFPU(saves_fpu);
__ MultiPush(saves); DCHECK(kNumCalleeSavedFPU == base::bits::CountPopulation32(saves_fpu));
} register_save_area_size += kNumCalleeSavedFPU * kDoubleSize * kPointerSize;
frame()->SetRegisterSaveAreaSize(register_save_area_size);
} else if (descriptor->IsJSFunctionCall()) { } else if (descriptor->IsJSFunctionCall()) {
CompilationInfo* info = this->info(); CompilationInfo* info = this->info();
__ Prologue(info->IsCodePreAgingActive()); __ Prologue(info->IsCodePreAgingActive());
...@@ -1131,11 +1134,13 @@ void CodeGenerator::AssembleReturn() { ...@@ -1131,11 +1134,13 @@ void CodeGenerator::AssembleReturn() {
if (stack_slots > 0) { if (stack_slots > 0) {
__ Addu(sp, sp, Operand(stack_slots * kPointerSize)); __ Addu(sp, sp, Operand(stack_slots * kPointerSize));
} }
// Restore registers. // Restore FPU registers.
const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
__ MultiPopFPU(saves_fpu);
// Restore GP registers.
const RegList saves = descriptor->CalleeSavedRegisters(); const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) { __ MultiPop(saves);
__ MultiPop(saves);
}
} }
__ mov(sp, fp); __ mov(sp, fp);
__ Pop(ra, fp); __ Pop(ra, fp);
......
...@@ -23,6 +23,10 @@ struct MipsLinkageHelperTraits { ...@@ -23,6 +23,10 @@ struct MipsLinkageHelperTraits {
return s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() | return s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() |
s6.bit() | s7.bit(); s6.bit() | s7.bit();
} }
static RegList CCalleeSaveFPRegisters() {
return f20.bit() | f22.bit() | f24.bit() | f26.bit() | f28.bit() |
f30.bit();
}
static Register CRegisterParameter(int i) { static Register CRegisterParameter(int i) {
static Register register_parameters[] = {a0, a1, a2, a3}; static Register register_parameters[] = {a0, a1, a2, a3};
return register_parameters[i]; return register_parameters[i];
......
...@@ -1151,17 +1151,20 @@ void CodeGenerator::AssemblePrologue() { ...@@ -1151,17 +1151,20 @@ void CodeGenerator::AssemblePrologue() {
if (descriptor->kind() == CallDescriptor::kCallAddress) { if (descriptor->kind() == CallDescriptor::kCallAddress) {
__ Push(ra, fp); __ Push(ra, fp);
__ mov(fp, sp); __ mov(fp, sp);
const RegList saves = descriptor->CalleeSavedRegisters(); const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) { // Save callee-saved registers. // Save callee-saved registers.
// TODO(plind): make callee save size const, possibly DCHECK it. __ MultiPush(saves);
int register_save_area_size = 0; DCHECK(kNumCalleeSaved == base::bits::CountPopulation32(saves));
for (int i = Register::kNumRegisters - 1; i >= 0; i--) { int register_save_area_size = kNumCalleeSaved * kPointerSize;
if (!((1 << i) & saves)) continue;
register_save_area_size += kPointerSize; const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
} // Save callee-saved FPU registers.
frame()->SetRegisterSaveAreaSize(register_save_area_size); __ MultiPushFPU(saves_fpu);
__ MultiPush(saves); DCHECK(kNumCalleeSavedFPU == base::bits::CountPopulation32(saves_fpu));
} register_save_area_size += kNumCalleeSavedFPU * kDoubleSize * kPointerSize;
frame()->SetRegisterSaveAreaSize(register_save_area_size);
} else if (descriptor->IsJSFunctionCall()) { } else if (descriptor->IsJSFunctionCall()) {
CompilationInfo* info = this->info(); CompilationInfo* info = this->info();
__ Prologue(info->IsCodePreAgingActive()); __ Prologue(info->IsCodePreAgingActive());
...@@ -1204,11 +1207,13 @@ void CodeGenerator::AssembleReturn() { ...@@ -1204,11 +1207,13 @@ void CodeGenerator::AssembleReturn() {
if (stack_slots > 0) { if (stack_slots > 0) {
__ Daddu(sp, sp, Operand(stack_slots * kPointerSize)); __ Daddu(sp, sp, Operand(stack_slots * kPointerSize));
} }
// Restore registers. // Restore FPU registers.
const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
__ MultiPopFPU(saves_fpu);
// Restore GP registers.
const RegList saves = descriptor->CalleeSavedRegisters(); const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) { __ MultiPop(saves);
__ MultiPop(saves);
}
} }
__ mov(sp, fp); __ mov(sp, fp);
__ Pop(ra, fp); __ Pop(ra, fp);
......
...@@ -23,6 +23,10 @@ struct MipsLinkageHelperTraits { ...@@ -23,6 +23,10 @@ struct MipsLinkageHelperTraits {
return s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() | return s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() |
s6.bit() | s7.bit(); s6.bit() | s7.bit();
} }
static RegList CCalleeSaveFPRegisters() {
return f20.bit() | f22.bit() | f24.bit() | f26.bit() | f28.bit() |
f30.bit();
}
static Register CRegisterParameter(int i) { static Register CRegisterParameter(int i) {
static Register register_parameters[] = {a0, a1, a2, a3, a4, a5, a6, a7}; static Register register_parameters[] = {a0, a1, a2, a3, a4, a5, a6, a7};
return register_parameters[i]; return register_parameters[i];
......
...@@ -25,6 +25,7 @@ struct PPCLinkageHelperTraits { ...@@ -25,6 +25,7 @@ struct PPCLinkageHelperTraits {
r24.bit() | r25.bit() | r26.bit() | r27.bit() | r28.bit() | r24.bit() | r25.bit() | r26.bit() | r27.bit() | r28.bit() |
r29.bit() | r30.bit() | fp.bit(); r29.bit() | r30.bit() | fp.bit();
} }
static RegList CCalleeSaveFPRegisters() { return 0; }
static Register CRegisterParameter(int i) { static Register CRegisterParameter(int i) {
static Register register_parameters[] = {r3, r4, r5, r6, r7, r8, r9, r10}; static Register register_parameters[] = {r3, r4, r5, r6, r7, r8, r9, r10};
return register_parameters[i]; return register_parameters[i];
......
...@@ -1469,14 +1469,31 @@ void CodeGenerator::AssemblePrologue() { ...@@ -1469,14 +1469,31 @@ void CodeGenerator::AssemblePrologue() {
if (descriptor->kind() == CallDescriptor::kCallAddress) { if (descriptor->kind() == CallDescriptor::kCallAddress) {
__ pushq(rbp); __ pushq(rbp);
__ movq(rbp, rsp); __ movq(rbp, rsp);
int register_save_area_size = 0;
const RegList saves = descriptor->CalleeSavedRegisters(); const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) { // Save callee-saved registers. if (saves != 0) { // Save callee-saved registers.
int register_save_area_size = 0;
for (int i = Register::kNumRegisters - 1; i >= 0; i--) { for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
if (!((1 << i) & saves)) continue; if (!((1 << i) & saves)) continue;
__ pushq(Register::from_code(i)); __ pushq(Register::from_code(i));
register_save_area_size += kPointerSize; register_save_area_size += kPointerSize;
} }
}
const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
if (saves_fp != 0) { // Save callee-saved XMM registers.
const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
const int stack_size = saves_fp_count * 16;
// Adjust the stack pointer.
__ subp(rsp, Immediate(stack_size));
// Store the registers on the stack.
int slot_idx = 0;
for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
if (!((1 << i) & saves_fp)) continue;
__ movdqu(Operand(rsp, 16 * slot_idx), XMMRegister::from_code(i));
slot_idx++;
}
register_save_area_size += stack_size;
}
if (register_save_area_size > 0) {
frame()->SetRegisterSaveAreaSize(register_save_area_size); frame()->SetRegisterSaveAreaSize(register_save_area_size);
} }
} else if (descriptor->IsJSFunctionCall()) { } else if (descriptor->IsJSFunctionCall()) {
...@@ -1521,8 +1538,22 @@ void CodeGenerator::AssembleReturn() { ...@@ -1521,8 +1538,22 @@ void CodeGenerator::AssembleReturn() {
if (stack_slots > 0) { if (stack_slots > 0) {
__ addq(rsp, Immediate(stack_slots * kPointerSize)); __ addq(rsp, Immediate(stack_slots * kPointerSize));
} }
const RegList saves = descriptor->CalleeSavedRegisters();
// Restore registers. // Restore registers.
const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
if (saves_fp != 0) {
const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
const int stack_size = saves_fp_count * 16;
// Load the registers from the stack.
int slot_idx = 0;
for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
if (!((1 << i) & saves_fp)) continue;
__ movdqu(XMMRegister::from_code(i), Operand(rsp, 16 * slot_idx));
slot_idx++;
}
// Adjust the stack pointer.
__ addp(rsp, Immediate(stack_size));
}
const RegList saves = descriptor->CalleeSavedRegisters();
if (saves != 0) { if (saves != 0) {
for (int i = 0; i < Register::kNumRegisters; i++) { for (int i = 0; i < Register::kNumRegisters; i++) {
if (!((1 << i) & saves)) continue; if (!((1 << i) & saves)) continue;
......
...@@ -33,6 +33,16 @@ struct X64LinkageHelperTraits { ...@@ -33,6 +33,16 @@ struct X64LinkageHelperTraits {
return rbx.bit() | r12.bit() | r13.bit() | r14.bit() | r15.bit(); return rbx.bit() | r12.bit() | r13.bit() | r14.bit() | r15.bit();
} }
} }
static RegList CCalleeSaveFPRegisters() {
if (kWin64) {
return (1 << xmm6.code()) | (1 << xmm7.code()) | (1 << xmm8.code()) |
(1 << xmm9.code()) | (1 << xmm10.code()) | (1 << xmm11.code()) |
(1 << xmm12.code()) | (1 << xmm13.code()) | (1 << xmm14.code()) |
(1 << xmm15.code());
} else {
return 0;
}
}
static Register CRegisterParameter(int i) { static Register CRegisterParameter(int i) {
if (kWin64) { if (kWin64) {
static Register register_parameters[] = {rcx, rdx, r8, r9}; static Register register_parameters[] = {rcx, rdx, r8, r9};
......
...@@ -272,8 +272,6 @@ ...@@ -272,8 +272,6 @@
'test-api/ExternalArrays': [PASS, NO_VARIANTS], 'test-api/ExternalArrays': [PASS, NO_VARIANTS],
# TODO(mips-team): Currently fails on mips board. # TODO(mips-team): Currently fails on mips board.
'test-simplified-lowering/RunNumberMultiply_TruncatingToUint32': [SKIP],
'test-simplified-lowering/RunNumberDivide_2_TruncatingToUint32': [SKIP],
'test-parsing/TooManyArguments': [SKIP], 'test-parsing/TooManyArguments': [SKIP],
'test-api/Threading3': [SKIP], 'test-api/Threading3': [SKIP],
}], # 'arch == mips' }], # 'arch == mips'
......
...@@ -33,7 +33,7 @@ TEST_F(TailCallOptimizationTest, CallCodeObject0) { ...@@ -33,7 +33,7 @@ TEST_F(TailCallOptimizationTest, CallCodeObject0) {
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0, new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
Operator::kNoProperties, 0, CallDescriptor::kNoFlags); Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
Node* p0 = Parameter(0); Node* p0 = Parameter(0);
Node* p1 = Parameter(1); Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1, Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
...@@ -53,7 +53,7 @@ TEST_F(TailCallOptimizationTest, CallCodeObject1) { ...@@ -53,7 +53,7 @@ TEST_F(TailCallOptimizationTest, CallCodeObject1) {
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0, new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
Operator::kNoProperties, 0, CallDescriptor::kSupportsTailCalls); Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
Node* p0 = Parameter(0); Node* p0 = Parameter(0);
Node* p1 = Parameter(1); Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1, Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
...@@ -77,7 +77,7 @@ TEST_F(TailCallOptimizationTest, CallCodeObject2) { ...@@ -77,7 +77,7 @@ TEST_F(TailCallOptimizationTest, CallCodeObject2) {
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0, new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
Operator::kNoProperties, 0, CallDescriptor::kSupportsTailCalls); Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
Node* p0 = Parameter(0); Node* p0 = Parameter(0);
Node* p1 = Parameter(1); Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1, Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
...@@ -99,7 +99,7 @@ TEST_F(TailCallOptimizationTest, CallJSFunction0) { ...@@ -99,7 +99,7 @@ TEST_F(TailCallOptimizationTest, CallJSFunction0) {
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0, new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
Operator::kNoProperties, 0, CallDescriptor::kNoFlags); Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
Node* p0 = Parameter(0); Node* p0 = Parameter(0);
Node* p1 = Parameter(1); Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1, Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
...@@ -119,7 +119,7 @@ TEST_F(TailCallOptimizationTest, CallJSFunction1) { ...@@ -119,7 +119,7 @@ TEST_F(TailCallOptimizationTest, CallJSFunction1) {
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0, new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
Operator::kNoProperties, 0, CallDescriptor::kSupportsTailCalls); Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
Node* p0 = Parameter(0); Node* p0 = Parameter(0);
Node* p1 = Parameter(1); Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1, Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
...@@ -143,7 +143,7 @@ TEST_F(TailCallOptimizationTest, CallJSFunction2) { ...@@ -143,7 +143,7 @@ TEST_F(TailCallOptimizationTest, CallJSFunction2) {
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) MachineSignature(1, 1, kMachineSignature),
new (zone()) LocationSignature(1, 1, kLocationSignature), 0, new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
Operator::kNoProperties, 0, CallDescriptor::kSupportsTailCalls); Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
Node* p0 = Parameter(0); Node* p0 = Parameter(0);
Node* p1 = Parameter(1); Node* p1 = Parameter(1);
Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1, Node* call = graph()->NewNode(common()->Call(kCallDescriptor), p0, p1,
......
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