Commit 1d03493d authored by yangguo@chromium.org's avatar yangguo@chromium.org

Simplify some code related to x64 calling convention.

R=mvstanton@chromium.org
BUG=

Review URL: https://chromiumcodereview.appspot.com/13940014

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14409 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cc846ab7
......@@ -200,6 +200,19 @@ const Register r14 = { kRegister_r14_Code };
const Register r15 = { kRegister_r15_Code };
const Register no_reg = { kRegister_no_reg_Code };
#ifdef _WIN64
// Windows calling convention
const Register arg_reg_1 = rcx;
const Register arg_reg_2 = rdx;
const Register arg_reg_3 = r8;
const Register arg_reg_4 = r9;
#else
// AMD64 calling convention
const Register arg_reg_1 = rdi;
const Register arg_reg_2 = rsi;
const Register arg_reg_3 = rdx;
const Register arg_reg_4 = rcx;
#endif // _WIN64
struct XMMRegister {
static const int kMaxNumRegisters = 16;
......
......@@ -648,11 +648,7 @@ static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// the stub returns.
__ subq(Operand(rsp, 0), Immediate(5));
__ Pushad();
#ifdef _WIN64
__ movq(rcx, Operand(rsp, kNumSafepointRegisters * kPointerSize));
#else
__ movq(rdi, Operand(rsp, kNumSafepointRegisters * kPointerSize));
#endif
__ movq(arg_reg_1, Operand(rsp, kNumSafepointRegisters * kPointerSize));
{ // NOLINT
FrameScope scope(masm, StackFrame::MANUAL);
__ PrepareCallCFunction(1);
......
......@@ -538,11 +538,8 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
__ PushCallerSaved(save_doubles_);
const int argument_count = 1;
__ PrepareCallCFunction(argument_count);
#ifdef _WIN64
__ LoadAddress(rcx, ExternalReference::isolate_address(masm->isolate()));
#else
__ LoadAddress(rdi, ExternalReference::isolate_address(masm->isolate()));
#endif
__ LoadAddress(arg_reg_1,
ExternalReference::isolate_address(masm->isolate()));
AllowExternalCallThatCantCauseGC scope(masm);
__ CallCFunction(
......@@ -2012,12 +2009,7 @@ void FloatingPointHelper::NumbersToSmis(MacroAssembler* masm,
void MathPowStub::Generate(MacroAssembler* masm) {
// Choose register conforming to calling convention (when bailing out).
#ifdef _WIN64
const Register exponent = rdx;
#else
const Register exponent = rdi;
#endif
const Register base = rax;
const Register scratch = rcx;
const XMMRegister double_result = xmm3;
......@@ -3026,20 +3018,6 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ movq(Operand(rsp, (argument_slots_on_stack - 5) * kPointerSize), r8);
#endif
// First four arguments are passed in registers on both Linux and Windows.
#ifdef _WIN64
Register arg4 = r9;
Register arg3 = r8;
Register arg2 = rdx;
Register arg1 = rcx;
#else
Register arg4 = rcx;
Register arg3 = rdx;
Register arg2 = rsi;
Register arg1 = rdi;
#endif
// Keep track on aliasing between argX defined above and the registers used.
// rdi: subject string
// rbx: previous index
// rcx: encoding of subject string (1 if ASCII 0 if two_byte);
......@@ -3048,7 +3026,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// r15: original subject string
// Argument 2: Previous index.
__ movq(arg2, rbx);
__ movq(arg_reg_2, rbx);
// Argument 4: End of string data
// Argument 3: Start of string data
......@@ -3056,20 +3034,24 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Prepare start and end index of the input.
// Load the length from the original sliced string if that is the case.
__ addq(rbx, r14);
__ SmiToInteger32(arg3, FieldOperand(r15, String::kLengthOffset));
__ addq(r14, arg3); // Using arg3 as scratch.
__ SmiToInteger32(arg_reg_3, FieldOperand(r15, String::kLengthOffset));
__ addq(r14, arg_reg_3); // Using arg3 as scratch.
// rbx: start index of the input
// r14: end index of the input
// r15: original subject string
__ testb(rcx, rcx); // Last use of rcx as encoding of subject string.
__ j(zero, &setup_two_byte, Label::kNear);
__ lea(arg4, FieldOperand(rdi, r14, times_1, SeqOneByteString::kHeaderSize));
__ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqOneByteString::kHeaderSize));
__ lea(arg_reg_4,
FieldOperand(rdi, r14, times_1, SeqOneByteString::kHeaderSize));
__ lea(arg_reg_3,
FieldOperand(rdi, rbx, times_1, SeqOneByteString::kHeaderSize));
__ jmp(&setup_rest, Label::kNear);
__ bind(&setup_two_byte);
__ lea(arg4, FieldOperand(rdi, r14, times_2, SeqTwoByteString::kHeaderSize));
__ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize));
__ lea(arg_reg_4,
FieldOperand(rdi, r14, times_2, SeqTwoByteString::kHeaderSize));
__ lea(arg_reg_3,
FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize));
__ bind(&setup_rest);
// Argument 1: Original subject string.
......@@ -3077,7 +3059,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// use rbp, which points exactly to one pointer size below the previous rsp.
// (Because creating a new stack frame pushes the previous rbp onto the stack
// and thereby moves up rsp by one kPointerSize.)
__ movq(arg1, r15);
__ movq(arg_reg_1, r15);
// Locate the code entry and call it.
__ addq(r11, Immediate(Code::kHeaderSize - kHeapObjectTag));
......@@ -4102,11 +4084,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// PerformGC. No need to use PrepareCallCFunction/CallCFunction here as the
// stack is known to be aligned. This function takes one argument which is
// passed in register.
#ifdef _WIN64
__ movq(rcx, rax);
#else // _WIN64
__ movq(rdi, rax);
#endif
__ movq(arg_reg_1, rax);
__ movq(kScratchRegister,
ExternalReference::perform_gc_function(masm->isolate()));
__ call(kScratchRegister);
......@@ -6494,24 +6472,16 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) {
void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm, Mode mode) {
regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
#ifdef _WIN64
Register arg3 = r8;
Register arg2 = rdx;
Register arg1 = rcx;
#else
Register arg3 = rdx;
Register arg2 = rsi;
Register arg1 = rdi;
#endif
Register address =
arg1.is(regs_.address()) ? kScratchRegister : regs_.address();
arg_reg_1.is(regs_.address()) ? kScratchRegister : regs_.address();
ASSERT(!address.is(regs_.object()));
ASSERT(!address.is(arg1));
ASSERT(!address.is(arg_reg_1));
__ Move(address, regs_.address());
__ Move(arg1, regs_.object());
__ Move(arg_reg_1, regs_.object());
// TODO(gc) Can we just set address arg2 in the beginning?
__ Move(arg2, address);
__ LoadAddress(arg3, ExternalReference::isolate_address(masm->isolate()));
__ Move(arg_reg_2, address);
__ LoadAddress(arg_reg_3,
ExternalReference::isolate_address(masm->isolate()));
int argument_count = 3;
AllowExternalCallThatCantCauseGC scope(masm);
......
......@@ -609,37 +609,22 @@ void Deoptimizer::EntryGenerator::Generate() {
const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize +
kDoubleRegsSize;
// When calling new_deoptimizer_function we need to pass the last argument
// on the stack on windows and in r8 on linux. The remaining arguments are
// all passed in registers (different ones on linux and windows though).
#ifdef _WIN64
Register arg4 = r9;
Register arg3 = r8;
Register arg2 = rdx;
Register arg1 = rcx;
#else
Register arg4 = rcx;
Register arg3 = rdx;
Register arg2 = rsi;
Register arg1 = rdi;
#endif
// We use this to keep the value of the fifth argument temporarily.
// Unfortunately we can't store it directly in r8 (used for passing
// this on linux), since it is another parameter passing register on windows.
Register arg5 = r11;
// Get the bailout id from the stack.
__ movq(arg3, Operand(rsp, kSavedRegistersAreaSize));
__ movq(arg_reg_3, Operand(rsp, kSavedRegistersAreaSize));
// Get the address of the location in the code object if possible
// and compute the fp-to-sp delta in register arg5.
if (type() == EAGER) {
__ Set(arg4, 0);
__ Set(arg_reg_4, 0);
__ lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize));
} else {
__ movq(arg4, Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize));
__ movq(arg_reg_4,
Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize));
__ lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 2 * kPointerSize));
}
......@@ -649,8 +634,8 @@ void Deoptimizer::EntryGenerator::Generate() {
// Allocate a new deoptimizer object.
__ PrepareCallCFunction(6);
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ movq(arg1, rax);
__ Set(arg2, type());
__ movq(arg_reg_1, rax);
__ Set(arg_reg_2, type());
// Args 3 and 4 are already in the right registers.
// On windows put the arguments on the stack (PrepareCallCFunction
......@@ -713,8 +698,8 @@ void Deoptimizer::EntryGenerator::Generate() {
// Compute the output frame in the deoptimizer.
__ push(rax);
__ PrepareCallCFunction(2);
__ movq(arg1, rax);
__ LoadAddress(arg2, ExternalReference::isolate_address(isolate()));
__ movq(arg_reg_1, rax);
__ LoadAddress(arg_reg_2, ExternalReference::isolate_address(isolate()));
{
AllowExternalCallThatCantCauseGC scope(masm());
__ CallCFunction(
......
......@@ -3001,16 +3001,10 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) {
// Return a random uint32 number in rax.
// The fresh HeapNumber is in rbx, which is callee-save on both x64 ABIs.
__ PrepareCallCFunction(1);
#ifdef _WIN64
__ movq(rcx,
__ movq(arg_reg_1,
ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX));
__ movq(rcx, FieldOperand(rcx, GlobalObject::kNativeContextOffset));
#else
__ movq(rdi,
ContextOperand(context_register(), Context::GLOBAL_OBJECT_INDEX));
__ movq(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
#endif
__ movq(arg_reg_1,
FieldOperand(arg_reg_1, GlobalObject::kNativeContextOffset));
__ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
// Convert 32 random bits in rax to 0.(32 random bits) in a double
......@@ -3108,13 +3102,8 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
}
__ bind(&runtime);
__ PrepareCallCFunction(2);
#ifdef _WIN64
__ movq(rcx, object);
__ movq(rdx, index, RelocInfo::NONE64);
#else
__ movq(rdi, object);
__ movq(rsi, index, RelocInfo::NONE64);
#endif
__ movq(arg_reg_1, object);
__ movq(arg_reg_2, index, RelocInfo::NONE64);
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
__ jmp(&done);
......
......@@ -1644,13 +1644,8 @@ void LCodeGen::DoDateField(LDateField* instr) {
}
__ bind(&runtime);
__ PrepareCallCFunction(2);
#ifdef _WIN64
__ movq(rcx, object);
__ movq(rdx, index, RelocInfo::NONE64);
#else
__ movq(rdi, object);
__ movq(rsi, index, RelocInfo::NONE64);
#endif
__ movq(arg_reg_1, object);
__ movq(arg_reg_2, index, RelocInfo::NONE64);
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
__ bind(&done);
......@@ -3646,12 +3641,7 @@ void LCodeGen::DoPower(LPower* instr) {
// Having marked this as a call, we can use any registers.
// Just make sure that the input/output registers are the expected ones.
// Choose register conforming to calling convention (when bailing out).
#ifdef _WIN64
Register exponent = rdx;
#else
Register exponent = rdi;
#endif
ASSERT(!instr->right()->IsRegister() ||
ToRegister(instr->right()).is(exponent));
ASSERT(!instr->right()->IsDoubleRegister() ||
......
......@@ -1556,12 +1556,7 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
ASSERT(instr->left()->representation().IsDouble());
LOperand* left = UseFixedDouble(instr->left(), xmm2);
LOperand* right = exponent_type.IsDouble() ?
UseFixedDouble(instr->right(), xmm1) :
#ifdef _WIN64
UseFixed(instr->right(), rdx);
#else
UseFixed(instr->right(), rdi);
#endif
UseFixedDouble(instr->right(), xmm1) : UseFixed(instr->right(), rdx);
LPower* result = new(zone()) LPower(left, right);
return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
CAN_DEOPTIMIZE_EAGERLY);
......@@ -1571,11 +1566,7 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->global_object()->representation().IsTagged());
#ifdef _WIN64
LOperand* global_object = UseFixed(instr->global_object(), rcx);
#else
LOperand* global_object = UseFixed(instr->global_object(), rdi);
#endif
LOperand* global_object = UseFixed(instr->global_object(), arg_reg_1);
LRandom* result = new(zone()) LRandom(global_object);
return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
}
......
......@@ -817,11 +817,7 @@ void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
bind(&delete_allocated_handles);
movq(Operand(base_reg, kLimitOffset), prev_limit_reg);
movq(prev_limit_reg, rax);
#ifdef _WIN64
LoadAddress(rcx, ExternalReference::isolate_address(isolate()));
#else
LoadAddress(rdi, ExternalReference::isolate_address(isolate()));
#endif
LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate()));
LoadAddress(rax,
ExternalReference::delete_handle_scope_extensions(isolate()));
call(rax);
......
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