Commit c0aa591b authored by lrn@chromium.org's avatar lrn@chromium.org

X64: Tweak code generation slightly.

Uses a shorter opcode for movl and movb with immediates.
Make movl preferable to movq in Set(register, int64_t) and use Set in more places.

Review URL: http://codereview.chromium.org/6824074

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7589 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 250b2054
......@@ -99,7 +99,7 @@ void CpuFeatures::Probe() {
// ecx:edx. Temporarily enable CPUID support because we know it's
// safe here.
__ bind(&cpuid);
__ movq(rax, Immediate(1));
__ movl(rax, Immediate(1));
supported_ = kDefaultCpuFeatures | (1 << CPUID);
{ Scope fscope(CPUID);
__ cpuid();
......@@ -1398,7 +1398,12 @@ void Assembler::leave() {
void Assembler::movb(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
emit_rex_32(dst, src);
if (dst.code() > 3) {
// Register is not one of al, bl, cl, dl. Its encoding needs REX.
emit_rex_32(dst, src);
} else {
emit_optional_rex_32(dst, src);
}
emit(0x8A);
emit_operand(dst, src);
}
......@@ -1406,16 +1411,21 @@ void Assembler::movb(Register dst, const Operand& src) {
void Assembler::movb(Register dst, Immediate imm) {
EnsureSpace ensure_space(this);
emit_rex_32(dst);
emit(0xC6);
emit_modrm(0x0, dst);
if (dst.code() > 3) {
emit_rex_32(dst);
}
emit(0xB0 + dst.low_bits());
emit(imm.value_);
}
void Assembler::movb(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
emit_rex_32(src, dst);
if (src.code() > 3) {
emit_rex_32(src, dst);
} else {
emit_optional_rex_32(src, dst);
}
emit(0x88);
emit_operand(src, dst);
}
......@@ -1465,16 +1475,15 @@ void Assembler::movl(const Operand& dst, Immediate value) {
emit_optional_rex_32(dst);
emit(0xC7);
emit_operand(0x0, dst);
emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
emit(value);
}
void Assembler::movl(Register dst, Immediate value) {
EnsureSpace ensure_space(this);
emit_optional_rex_32(dst);
emit(0xC7);
emit_modrm(0x0, dst);
emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
emit(0xB8 + dst.low_bits());
emit(value);
}
......
......@@ -96,7 +96,7 @@ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
// rax: number of arguments
__ bind(&non_function_call);
// Set expected number of arguments to zero (not changing rax).
__ movq(rbx, Immediate(0));
__ Set(rbx, 0);
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
......@@ -1372,7 +1372,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// Copy receiver and all expected arguments.
const int offset = StandardFrameConstants::kCallerSPOffset;
__ lea(rax, Operand(rbp, rax, times_pointer_size, offset));
__ movq(rcx, Immediate(-1)); // account for receiver
__ Set(rcx, -1); // account for receiver
Label copy;
__ bind(&copy);
......@@ -1391,7 +1391,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
// Copy receiver and all actual arguments.
const int offset = StandardFrameConstants::kCallerSPOffset;
__ lea(rdi, Operand(rbp, rax, times_pointer_size, offset));
__ movq(rcx, Immediate(-1)); // account for receiver
__ Set(rcx, -1); // account for receiver
Label copy;
__ bind(&copy);
......
......@@ -273,7 +273,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
// Return 1/0 for true/false in rax.
__ bind(&true_result);
__ movq(rax, Immediate(1));
__ Set(rax, 1);
__ ret(1 * kPointerSize);
__ bind(&false_result);
__ Set(rax, 0);
......@@ -1281,7 +1281,7 @@ void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
__ bind(&check_undefined_arg1);
__ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
__ j(not_equal, conversion_failure);
__ movl(r8, Immediate(0));
__ Set(r8, 0);
__ jmp(&load_arg2);
__ bind(&arg1_is_object);
......@@ -1301,7 +1301,7 @@ void FloatingPointHelper::LoadAsIntegers(MacroAssembler* masm,
__ bind(&check_undefined_arg2);
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
__ j(not_equal, conversion_failure);
__ movl(rcx, Immediate(0));
__ Set(rcx, 0);
__ jmp(&done);
__ bind(&arg2_is_object);
......@@ -1458,7 +1458,7 @@ void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
__ j(not_equal, &slow);
// Operand is a float, negate its value by flipping sign bit.
__ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
__ movq(kScratchRegister, Immediate(0x01));
__ Set(kScratchRegister, 0x01);
__ shl(kScratchRegister, Immediate(63));
__ xor_(rdx, kScratchRegister); // Flip sign.
// rdx is value to store.
......@@ -1530,7 +1530,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movq(rax, Operand(rsp, 1 * kPointerSize));
// Save 1 in xmm3 - we need this several times later on.
__ movl(rcx, Immediate(1));
__ Set(rcx, 1);
__ cvtlsi2sd(xmm3, rcx);
Label exponent_nonsmi;
......@@ -3253,7 +3253,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
__ Assert(equal, "InstanceofStub unexpected call site cache (mov).");
}
__ xorl(rax, rax);
__ Set(rax, 0);
}
__ ret(2 * kPointerSize + extra_stack_space);
......@@ -4112,7 +4112,7 @@ void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
// if (hash == 0) hash = 27;
Label hash_not_zero;
__ j(not_zero, &hash_not_zero);
__ movl(hash, Immediate(27));
__ Set(hash, 27);
__ bind(&hash_not_zero);
}
......@@ -4308,7 +4308,7 @@ void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
// Use scratch3 as loop index, min_length as limit and scratch2
// for computation.
const Register index = scratch3;
__ movl(index, Immediate(0)); // Index into strings.
__ Set(index, 0); // Index into strings.
__ bind(&loop);
// Compare characters.
// TODO(lrn): Could we load more than one character at a time?
......
......@@ -665,7 +665,7 @@ void Deoptimizer::EntryGenerator::Generate() {
__ PrepareCallCFunction(6);
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ movq(arg1, rax);
__ movq(arg2, Immediate(type()));
__ Set(arg2, type());
// Args 3 and 4 are already in the right registers.
// On windows put the arguments on the stack (PrepareCallCFunction
......
......@@ -652,6 +652,9 @@ int DisassemblerX64::PrintImmediateOp(byte* data) {
case 2:
mnem = "adc";
break;
case 3:
mnem = "sbb";
break;
case 4:
mnem = "and";
break;
......@@ -1502,7 +1505,39 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
data++;
}
break;
case 0xB0:
case 0xB1:
case 0xB2:
case 0xB3:
case 0xB4:
case 0xB5:
case 0xB6:
case 0xB7:
case 0xB8:
case 0xB9:
case 0xBA:
case 0xBB:
case 0xBC:
case 0xBD:
case 0xBE:
case 0xBF: {
// mov reg8,imm8 or mov reg32,imm32
byte opcode = *data;
data++;
bool is_32bit = (opcode >= 0xB8);
int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
if (is_32bit) {
AppendToBuffer("mov%c %s, ",
operand_size_code(),
NameOfCPURegister(reg));
data += PrintImmediate(data, DOUBLEWORD_SIZE);
} else {
AppendToBuffer("movb %s, ",
NameOfByteCPURegister(reg));
data += PrintImmediate(data, BYTE_SIZE);
}
break;
}
case 0xFE: {
data++;
int mod, regop, rm;
......@@ -1513,9 +1548,8 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
} else {
UnimplementedInstruction();
}
}
break;
}
case 0x68:
AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1));
data += 5;
......
......@@ -1010,7 +1010,7 @@ static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
// Call the entry.
CEntryStub stub(1);
__ movq(rax, Immediate(2));
__ Set(rax, 2);
__ LoadAddress(rbx, ExternalReference(IC_Utility(id), masm->isolate()));
__ CallStub(&stub);
......
......@@ -149,7 +149,7 @@ bool LCodeGen::GeneratePrologue() {
int slots = StackSlotCount();
if (slots > 0) {
if (FLAG_debug_code) {
__ movl(rax, Immediate(slots));
__ Set(rax, slots);
__ movq(kScratchRegister, kSlotsZapValue, RelocInfo::NONE);
Label loop;
__ bind(&loop);
......@@ -1099,7 +1099,7 @@ void LCodeGen::DoSubI(LSubI* instr) {
void LCodeGen::DoConstantI(LConstantI* instr) {
ASSERT(instr->result()->IsRegister());
__ movl(ToRegister(instr->result()), Immediate(instr->value()));
__ Set(ToRegister(instr->result()), instr->value());
}
......@@ -1514,10 +1514,11 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
__ CompareRoot(reg, Heap::kNullValueRootIndex);
if (instr->is_strict()) {
ASSERT(Heap::kTrueValueRootIndex >= 0);
__ movl(result, Immediate(Heap::kTrueValueRootIndex));
NearLabel load;
__ j(equal, &load);
__ movl(result, Immediate(Heap::kFalseValueRootIndex));
__ Set(result, Heap::kFalseValueRootIndex);
__ bind(&load);
__ LoadRootIndexed(result, result, 0);
} else {
......@@ -1976,11 +1977,11 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
__ Push(instr->function());
Register temp = ToRegister(instr->TempAt(0));
static const int kAdditionalDelta = 13;
static const int kAdditionalDelta = 10;
int delta =
masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
__ movq(temp, Immediate(delta));
__ push(temp);
ASSERT(delta >= 0);
__ push_imm32(delta);
// We are pushing three values on the stack but recording a
// safepoint with two arguments because stub is going to
......@@ -1992,6 +1993,8 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
RECORD_SAFEPOINT_WITH_REGISTERS,
2);
ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check));
// Move result to a register that survives the end of the
// PushSafepointRegisterScope.
__ movq(kScratchRegister, rax);
}
__ testq(kScratchRegister, kScratchRegister);
......@@ -2426,14 +2429,14 @@ void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
} else {
__ cmpq(rbp, ToOperand(instr->InputAt(0)));
}
__ movq(result, Immediate(scope()->num_parameters()));
__ movl(result, Immediate(scope()->num_parameters()));
__ j(equal, &done);
// Arguments adaptor frame present. Get argument length from there.
__ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
__ movq(result, Operand(result,
ArgumentsAdaptorFrameConstants::kLengthOffset));
__ SmiToInteger32(result, result);
__ SmiToInteger32(result,
Operand(result,
ArgumentsAdaptorFrameConstants::kLengthOffset));
// Argument length is in result register.
__ bind(&done);
......@@ -3415,7 +3418,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
// conversions.
__ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
DeoptimizeIf(not_equal, instr->environment());
__ movl(input_reg, Immediate(0));
__ Set(input_reg, 0);
__ jmp(&done);
__ bind(&heap_number);
......
......@@ -788,10 +788,10 @@ void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
void MacroAssembler::Set(Register dst, int64_t x) {
if (x == 0) {
xorl(dst, dst);
} else if (is_int32(x)) {
movq(dst, Immediate(static_cast<int32_t>(x)));
} else if (is_uint32(x)) {
movl(dst, Immediate(static_cast<uint32_t>(x)));
} else if (is_int32(x)) {
movq(dst, Immediate(static_cast<int32_t>(x)));
} else {
movq(dst, x, RelocInfo::NONE);
}
......@@ -801,7 +801,7 @@ void MacroAssembler::Set(const Operand& dst, int64_t x) {
if (is_int32(x)) {
movq(dst, Immediate(static_cast<int32_t>(x)));
} else {
movq(kScratchRegister, x, RelocInfo::NONE);
Set(kScratchRegister, x);
movq(dst, kScratchRegister);
}
}
......@@ -1814,7 +1814,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
// Set external caught exception to false.
ExternalReference external_caught(
Isolate::k_external_caught_exception_address, isolate());
movq(rax, Immediate(false));
Set(rax, static_cast<int64_t>(false));
Store(external_caught, rax);
// Set pending exception and rax to out of memory exception.
......@@ -2002,7 +2002,7 @@ void MacroAssembler::TryGetFunctionPrototype(Register function,
void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
if (FLAG_native_code_counters && counter->Enabled()) {
Operand counter_operand = ExternalOperand(ExternalReference(counter));
movq(counter_operand, Immediate(value));
movl(counter_operand, Immediate(value));
}
}
......@@ -2220,8 +2220,8 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
const int kFrameAlignment = OS::ActivationFrameAlignment();
if (kFrameAlignment > 0) {
ASSERT(IsPowerOf2(kFrameAlignment));
movq(kScratchRegister, Immediate(-kFrameAlignment));
and_(rsp, kScratchRegister);
ASSERT(is_int8(kFrameAlignment));
and_(rsp, Immediate(-kFrameAlignment));
}
// Patch the saved entry sp.
......
......@@ -762,7 +762,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ j(above_equal, &stack_ok);
// Exit with OutOfMemory exception. There is not enough space on the stack
// for our working registers.
__ movq(rax, Immediate(EXCEPTION));
__ Set(rax, EXCEPTION);
__ jmp(&exit_label_);
__ bind(&stack_limit_hit);
......@@ -799,7 +799,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
// Fill saved registers with initial value = start offset - 1
// Fill in stack push order, to avoid accessing across an unwritten
// page (a problem on Windows).
__ movq(rcx, Immediate(kRegisterZero));
__ Set(rcx, kRegisterZero);
Label init_loop;
__ bind(&init_loop);
__ movq(Operand(rbp, rcx, times_1, 0), rax);
......@@ -829,7 +829,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
__ jmp(&start_label_);
__ bind(&at_start);
__ movq(current_character(), Immediate('\n'));
__ Set(current_character(), '\n');
__ jmp(&start_label_);
......@@ -857,7 +857,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ movl(Operand(rbx, i * kIntSize), rax);
}
}
__ movq(rax, Immediate(SUCCESS));
__ Set(rax, SUCCESS);
}
// Exit and return rax
......@@ -959,7 +959,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
// If any of the code above needed to exit with an exception.
__ bind(&exit_with_exception);
// Exit with Result EXCEPTION(-1) to signal thrown exception.
__ movq(rax, Immediate(EXCEPTION));
__ Set(rax, EXCEPTION);
__ jmp(&exit_label_);
}
......
......@@ -399,7 +399,7 @@ static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
masm->isolate());
__ movq(rax, Immediate(5));
__ Set(rax, 5);
__ LoadAddress(rbx, ref);
CEntryStub stub(1);
......
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