| OLD | NEW | 
|     1 // Copyright 2013 the V8 project authors. All rights reserved. |     1 // Copyright 2013 the V8 project authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #include "src/compiler/code-generator.h" |     5 #include "src/compiler/code-generator.h" | 
|     6  |     6  | 
|     7 #include "src/compiler/code-generator-impl.h" |     7 #include "src/compiler/code-generator-impl.h" | 
|     8 #include "src/compiler/gap-resolver.h" |     8 #include "src/compiler/gap-resolver.h" | 
|     9 #include "src/compiler/node-matchers.h" |     9 #include "src/compiler/node-matchers.h" | 
|    10 #include "src/compiler/node-properties-inl.h" |    10 #include "src/compiler/node-properties-inl.h" | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   197       __ asm_instr##_cl(i.OutputRegister());                             \ |   197       __ asm_instr##_cl(i.OutputRegister());                             \ | 
|   198     }                                                                    \ |   198     }                                                                    \ | 
|   199   } while (0) |   199   } while (0) | 
|   200  |   200  | 
|   201  |   201  | 
|   202 // Assembles an instruction after register allocation, producing machine code. |   202 // Assembles an instruction after register allocation, producing machine code. | 
|   203 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |   203 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 
|   204   X64OperandConverter i(this, instr); |   204   X64OperandConverter i(this, instr); | 
|   205  |   205  | 
|   206   switch (ArchOpcodeField::decode(instr->opcode())) { |   206   switch (ArchOpcodeField::decode(instr->opcode())) { | 
 |   207     case kArchCallCodeObject: { | 
 |   208       if (HasImmediateInput(instr, 0)) { | 
 |   209         Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 
 |   210         __ Call(code, RelocInfo::CODE_TARGET); | 
 |   211       } else { | 
 |   212         Register reg = i.InputRegister(0); | 
 |   213         int entry = Code::kHeaderSize - kHeapObjectTag; | 
 |   214         __ Call(Operand(reg, entry)); | 
 |   215       } | 
 |   216       AddSafepointAndDeopt(instr); | 
 |   217       AddNopForSmiCodeInlining(); | 
 |   218       break; | 
 |   219     } | 
 |   220     case kArchCallAddress: | 
 |   221       if (HasImmediateInput(instr, 0)) { | 
 |   222         Immediate64 imm = i.InputImmediate64(0); | 
 |   223         DCHECK_EQ(kImm64Value, imm.type); | 
 |   224         __ Call(reinterpret_cast<byte*>(imm.value), RelocInfo::NONE64); | 
 |   225       } else { | 
 |   226         __ call(i.InputRegister(0)); | 
 |   227       } | 
 |   228       break; | 
 |   229     case kArchCallJSFunction: { | 
 |   230       // TODO(jarin) The load of the context should be separated from the call. | 
 |   231       Register func = i.InputRegister(0); | 
 |   232       __ movp(rsi, FieldOperand(func, JSFunction::kContextOffset)); | 
 |   233       __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); | 
 |   234       AddSafepointAndDeopt(instr); | 
 |   235       break; | 
 |   236     } | 
 |   237     case kArchDeoptimize: { | 
 |   238       int deoptimization_id = MiscField::decode(instr->opcode()); | 
 |   239       BuildTranslation(instr, 0, deoptimization_id); | 
 |   240       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 
 |   241           isolate(), deoptimization_id, Deoptimizer::LAZY); | 
 |   242       __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 
 |   243       break; | 
 |   244     } | 
 |   245     case kArchDrop: { | 
 |   246       int words = MiscField::decode(instr->opcode()); | 
 |   247       __ addq(rsp, Immediate(kPointerSize * words)); | 
 |   248       break; | 
 |   249     } | 
|   207     case kArchJmp: |   250     case kArchJmp: | 
|   208       __ jmp(code_->GetLabel(i.InputBlock(0))); |   251       __ jmp(code_->GetLabel(i.InputBlock(0))); | 
|   209       break; |   252       break; | 
|   210     case kArchNop: |   253     case kArchNop: | 
|   211       // don't emit code for nops. |   254       // don't emit code for nops. | 
|   212       break; |   255       break; | 
|   213     case kArchRet: |   256     case kArchRet: | 
|   214       AssembleReturn(); |   257       AssembleReturn(); | 
|   215       break; |   258       break; | 
|   216     case kArchDeoptimize: { |  | 
|   217       int deoptimization_id = MiscField::decode(instr->opcode()); |  | 
|   218       BuildTranslation(instr, 0, deoptimization_id); |  | 
|   219  |  | 
|   220       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |  | 
|   221           isolate(), deoptimization_id, Deoptimizer::LAZY); |  | 
|   222       __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |  | 
|   223       break; |  | 
|   224     } |  | 
|   225     case kArchTruncateDoubleToI: |   259     case kArchTruncateDoubleToI: | 
|   226       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); |   260       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0)); | 
|   227       break; |   261       break; | 
|   228     case kX64Add32: |   262     case kX64Add32: | 
|   229       ASSEMBLE_BINOP(addl); |   263       ASSEMBLE_BINOP(addl); | 
|   230       break; |   264       break; | 
|   231     case kX64Add: |   265     case kX64Add: | 
|   232       ASSEMBLE_BINOP(addq); |   266       ASSEMBLE_BINOP(addq); | 
|   233       break; |   267       break; | 
|   234     case kX64Sub32: |   268     case kX64Sub32: | 
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   372       break; |   406       break; | 
|   373     case kX64Sar: |   407     case kX64Sar: | 
|   374       ASSEMBLE_SHIFT(sarq, 6); |   408       ASSEMBLE_SHIFT(sarq, 6); | 
|   375       break; |   409       break; | 
|   376     case kX64Ror32: |   410     case kX64Ror32: | 
|   377       ASSEMBLE_SHIFT(rorl, 5); |   411       ASSEMBLE_SHIFT(rorl, 5); | 
|   378       break; |   412       break; | 
|   379     case kX64Ror: |   413     case kX64Ror: | 
|   380       ASSEMBLE_SHIFT(rorq, 6); |   414       ASSEMBLE_SHIFT(rorq, 6); | 
|   381       break; |   415       break; | 
|   382     case kX64Push: { |  | 
|   383       RegisterOrOperand input = i.InputRegisterOrOperand(0); |  | 
|   384       if (input.type == kRegister) { |  | 
|   385         __ pushq(input.reg); |  | 
|   386       } else { |  | 
|   387         __ pushq(input.operand); |  | 
|   388       } |  | 
|   389       break; |  | 
|   390     } |  | 
|   391     case kX64PushI: |  | 
|   392       __ pushq(i.InputImmediate(0)); |  | 
|   393       break; |  | 
|   394     case kX64CallCodeObject: { |  | 
|   395       if (HasImmediateInput(instr, 0)) { |  | 
|   396         Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |  | 
|   397         __ Call(code, RelocInfo::CODE_TARGET); |  | 
|   398       } else { |  | 
|   399         Register reg = i.InputRegister(0); |  | 
|   400         int entry = Code::kHeaderSize - kHeapObjectTag; |  | 
|   401         __ Call(Operand(reg, entry)); |  | 
|   402       } |  | 
|   403  |  | 
|   404       AddSafepointAndDeopt(instr); |  | 
|   405  |  | 
|   406       AddNopForSmiCodeInlining(); |  | 
|   407       break; |  | 
|   408     } |  | 
|   409     case kX64CallAddress: |  | 
|   410       if (HasImmediateInput(instr, 0)) { |  | 
|   411         Immediate64 imm = i.InputImmediate64(0); |  | 
|   412         DCHECK_EQ(kImm64Value, imm.type); |  | 
|   413         __ Call(reinterpret_cast<byte*>(imm.value), RelocInfo::NONE64); |  | 
|   414       } else { |  | 
|   415         __ call(i.InputRegister(0)); |  | 
|   416       } |  | 
|   417       break; |  | 
|   418     case kPopStack: { |  | 
|   419       int words = MiscField::decode(instr->opcode()); |  | 
|   420       __ addq(rsp, Immediate(kPointerSize * words)); |  | 
|   421       break; |  | 
|   422     } |  | 
|   423     case kX64CallJSFunction: { |  | 
|   424       Register func = i.InputRegister(0); |  | 
|   425  |  | 
|   426       // TODO(jarin) The load of the context should be separated from the call. |  | 
|   427       __ movp(rsi, FieldOperand(func, JSFunction::kContextOffset)); |  | 
|   428       __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); |  | 
|   429  |  | 
|   430       AddSafepointAndDeopt(instr); |  | 
|   431       break; |  | 
|   432     } |  | 
|   433     case kSSEFloat64Cmp: { |   416     case kSSEFloat64Cmp: { | 
|   434       RegisterOrOperand input = i.InputRegisterOrOperand(1); |   417       RegisterOrOperand input = i.InputRegisterOrOperand(1); | 
|   435       if (input.type == kDoubleRegister) { |   418       if (input.type == kDoubleRegister) { | 
|   436         __ ucomisd(i.InputDoubleRegister(0), input.double_reg); |   419         __ ucomisd(i.InputDoubleRegister(0), input.double_reg); | 
|   437       } else { |   420       } else { | 
|   438         __ ucomisd(i.InputDoubleRegister(0), input.operand); |   421         __ ucomisd(i.InputDoubleRegister(0), input.operand); | 
|   439       } |   422       } | 
|   440       break; |   423       break; | 
|   441     } |   424     } | 
|   442     case kSSEFloat64Add: |   425     case kSSEFloat64Add: | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   506       } else { |   489       } else { | 
|   507         __ cvtlsi2sd(i.OutputDoubleRegister(), input.operand); |   490         __ cvtlsi2sd(i.OutputDoubleRegister(), input.operand); | 
|   508       } |   491       } | 
|   509       break; |   492       break; | 
|   510     } |   493     } | 
|   511     case kSSEUint32ToFloat64: { |   494     case kSSEUint32ToFloat64: { | 
|   512       // TODO(turbofan): X64 SSE cvtqsi2sd should support operands. |   495       // TODO(turbofan): X64 SSE cvtqsi2sd should support operands. | 
|   513       __ cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0)); |   496       __ cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0)); | 
|   514       break; |   497       break; | 
|   515     } |   498     } | 
|   516  |  | 
|   517     case kX64Movsxbl: |   499     case kX64Movsxbl: | 
|   518       __ movsxbl(i.OutputRegister(), i.MemoryOperand()); |   500       __ movsxbl(i.OutputRegister(), i.MemoryOperand()); | 
|   519       break; |   501       break; | 
|   520     case kX64Movzxbl: |   502     case kX64Movzxbl: | 
|   521       __ movzxbl(i.OutputRegister(), i.MemoryOperand()); |   503       __ movzxbl(i.OutputRegister(), i.MemoryOperand()); | 
|   522       break; |   504       break; | 
|   523     case kX64Movb: { |   505     case kX64Movb: { | 
|   524       int index = 0; |   506       int index = 0; | 
|   525       Operand operand = i.MemoryOperand(&index); |   507       Operand operand = i.MemoryOperand(&index); | 
|   526       if (HasImmediateInput(instr, index)) { |   508       if (HasImmediateInput(instr, index)) { | 
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   603       break; |   585       break; | 
|   604     case kX64Movsd: |   586     case kX64Movsd: | 
|   605       if (instr->HasOutput()) { |   587       if (instr->HasOutput()) { | 
|   606         __ movsd(i.OutputDoubleRegister(), i.MemoryOperand()); |   588         __ movsd(i.OutputDoubleRegister(), i.MemoryOperand()); | 
|   607       } else { |   589       } else { | 
|   608         int index = 0; |   590         int index = 0; | 
|   609         Operand operand = i.MemoryOperand(&index); |   591         Operand operand = i.MemoryOperand(&index); | 
|   610         __ movsd(operand, i.InputDoubleRegister(index)); |   592         __ movsd(operand, i.InputDoubleRegister(index)); | 
|   611       } |   593       } | 
|   612       break; |   594       break; | 
 |   595     case kX64Push: | 
 |   596       if (HasImmediateInput(instr, 0)) { | 
 |   597         __ pushq(i.InputImmediate(0)); | 
 |   598       } else { | 
 |   599         RegisterOrOperand input = i.InputRegisterOrOperand(0); | 
 |   600         if (input.type == kRegister) { | 
 |   601           __ pushq(input.reg); | 
 |   602         } else { | 
 |   603           __ pushq(input.operand); | 
 |   604         } | 
 |   605       } | 
 |   606       break; | 
|   613     case kX64StoreWriteBarrier: { |   607     case kX64StoreWriteBarrier: { | 
|   614       Register object = i.InputRegister(0); |   608       Register object = i.InputRegister(0); | 
|   615       Register index = i.InputRegister(1); |   609       Register index = i.InputRegister(1); | 
|   616       Register value = i.InputRegister(2); |   610       Register value = i.InputRegister(2); | 
|   617       __ movsxlq(index, index); |   611       __ movsxlq(index, index); | 
|   618       __ movq(Operand(object, index, times_1, 0), value); |   612       __ movq(Operand(object, index, times_1, 0), value); | 
|   619       __ leaq(index, Operand(object, index, times_1, 0)); |   613       __ leaq(index, Operand(object, index, times_1, 0)); | 
|   620       SaveFPRegsMode mode = code_->frame()->DidAllocateDoubleRegisters() |   614       SaveFPRegsMode mode = code_->frame()->DidAllocateDoubleRegisters() | 
|   621                                 ? kSaveFPRegs |   615                                 ? kSaveFPRegs | 
|   622                                 : kDontSaveFPRegs; |   616                                 : kDontSaveFPRegs; | 
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1003 } |   997 } | 
|  1004  |   998  | 
|  1005  |   999  | 
|  1006 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } |  1000 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); } | 
|  1007  |  1001  | 
|  1008 #undef __ |  1002 #undef __ | 
|  1009  |  1003  | 
|  1010 }  // namespace internal |  1004 }  // namespace internal | 
|  1011 }  // namespace compiler |  1005 }  // namespace compiler | 
|  1012 }  // namespace v8 |  1006 }  // namespace v8 | 
| OLD | NEW |