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/ia32/assembler-ia32.h" | 10 #include "src/ia32/assembler-ia32.h" |
11 #include "src/ia32/macro-assembler-ia32.h" | 11 #include "src/ia32/macro-assembler-ia32.h" |
12 #include "src/scopes.h" | 12 #include "src/scopes.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 #define __ masm()-> | 18 #define __ masm()-> |
19 | 19 |
20 | 20 |
21 // Adds IA-32 specific methods for decoding operands. | 21 // Adds IA-32 specific methods for decoding operands. |
22 class IA32OperandConverter : public InstructionOperandConverter { | 22 class IA32OperandConverter : public InstructionOperandConverter { |
23 public: | 23 public: |
24 IA32OperandConverter(CodeGenerator* gen, Instruction* instr) | 24 IA32OperandConverter(CodeGenerator* gen, Instruction* instr) |
25 : InstructionOperandConverter(gen, instr) {} | 25 : InstructionOperandConverter(gen, instr) {} |
26 | 26 |
27 Operand InputOperand(int index) { return ToOperand(instr_->InputAt(index)); } | 27 Operand InputOperand(size_t index) { |
| 28 return ToOperand(instr_->InputAt(index)); |
| 29 } |
28 | 30 |
29 Immediate InputImmediate(int index) { | 31 Immediate InputImmediate(size_t index) { |
30 return ToImmediate(instr_->InputAt(index)); | 32 return ToImmediate(instr_->InputAt(index)); |
31 } | 33 } |
32 | 34 |
33 Operand OutputOperand() { return ToOperand(instr_->Output()); } | 35 Operand OutputOperand() { return ToOperand(instr_->Output()); } |
34 | 36 |
35 Operand ToOperand(InstructionOperand* op, int extra = 0) { | 37 Operand ToOperand(InstructionOperand* op, int extra = 0) { |
36 if (op->IsRegister()) { | 38 if (op->IsRegister()) { |
37 DCHECK(extra == 0); | 39 DCHECK(extra == 0); |
38 return Operand(ToRegister(op)); | 40 return Operand(ToRegister(op)); |
39 } else if (op->IsDoubleRegister()) { | 41 } else if (op->IsDoubleRegister()) { |
(...skipping 28 matching lines...) Expand all Loading... |
68 return Immediate(constant.ToHeapObject()); | 70 return Immediate(constant.ToHeapObject()); |
69 case Constant::kInt64: | 71 case Constant::kInt64: |
70 break; | 72 break; |
71 case Constant::kRpoNumber: | 73 case Constant::kRpoNumber: |
72 return Immediate::CodeRelativeOffset(ToLabel(operand)); | 74 return Immediate::CodeRelativeOffset(ToLabel(operand)); |
73 } | 75 } |
74 UNREACHABLE(); | 76 UNREACHABLE(); |
75 return Immediate(-1); | 77 return Immediate(-1); |
76 } | 78 } |
77 | 79 |
78 static int NextOffset(int* offset) { | 80 static size_t NextOffset(size_t* offset) { |
79 int i = *offset; | 81 size_t i = *offset; |
80 (*offset)++; | 82 (*offset)++; |
81 return i; | 83 return i; |
82 } | 84 } |
83 | 85 |
84 static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) { | 86 static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) { |
85 STATIC_ASSERT(0 == static_cast<int>(times_1)); | 87 STATIC_ASSERT(0 == static_cast<int>(times_1)); |
86 STATIC_ASSERT(1 == static_cast<int>(times_2)); | 88 STATIC_ASSERT(1 == static_cast<int>(times_2)); |
87 STATIC_ASSERT(2 == static_cast<int>(times_4)); | 89 STATIC_ASSERT(2 == static_cast<int>(times_4)); |
88 STATIC_ASSERT(3 == static_cast<int>(times_8)); | 90 STATIC_ASSERT(3 == static_cast<int>(times_8)); |
89 int scale = static_cast<int>(mode - one); | 91 int scale = static_cast<int>(mode - one); |
90 DCHECK(scale >= 0 && scale < 4); | 92 DCHECK(scale >= 0 && scale < 4); |
91 return static_cast<ScaleFactor>(scale); | 93 return static_cast<ScaleFactor>(scale); |
92 } | 94 } |
93 | 95 |
94 Operand MemoryOperand(int* offset) { | 96 Operand MemoryOperand(size_t* offset) { |
95 AddressingMode mode = AddressingModeField::decode(instr_->opcode()); | 97 AddressingMode mode = AddressingModeField::decode(instr_->opcode()); |
96 switch (mode) { | 98 switch (mode) { |
97 case kMode_MR: { | 99 case kMode_MR: { |
98 Register base = InputRegister(NextOffset(offset)); | 100 Register base = InputRegister(NextOffset(offset)); |
99 int32_t disp = 0; | 101 int32_t disp = 0; |
100 return Operand(base, disp); | 102 return Operand(base, disp); |
101 } | 103 } |
102 case kMode_MRI: { | 104 case kMode_MRI: { |
103 Register base = InputRegister(NextOffset(offset)); | 105 Register base = InputRegister(NextOffset(offset)); |
104 int32_t disp = InputInt32(NextOffset(offset)); | 106 int32_t disp = InputInt32(NextOffset(offset)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 return Operand(Immediate(disp)); | 149 return Operand(Immediate(disp)); |
148 } | 150 } |
149 case kMode_None: | 151 case kMode_None: |
150 UNREACHABLE(); | 152 UNREACHABLE(); |
151 return Operand(no_reg, 0); | 153 return Operand(no_reg, 0); |
152 } | 154 } |
153 UNREACHABLE(); | 155 UNREACHABLE(); |
154 return Operand(no_reg, 0); | 156 return Operand(no_reg, 0); |
155 } | 157 } |
156 | 158 |
157 Operand MemoryOperand(int first_input = 0) { | 159 Operand MemoryOperand(size_t first_input = 0) { |
158 return MemoryOperand(&first_input); | 160 return MemoryOperand(&first_input); |
159 } | 161 } |
160 }; | 162 }; |
161 | 163 |
162 | 164 |
163 namespace { | 165 namespace { |
164 | 166 |
165 bool HasImmediateInput(Instruction* instr, int index) { | 167 bool HasImmediateInput(Instruction* instr, size_t index) { |
166 return instr->InputAt(index)->IsImmediate(); | 168 return instr->InputAt(index)->IsImmediate(); |
167 } | 169 } |
168 | 170 |
169 | 171 |
170 class OutOfLineLoadInteger FINAL : public OutOfLineCode { | 172 class OutOfLineLoadInteger FINAL : public OutOfLineCode { |
171 public: | 173 public: |
172 OutOfLineLoadInteger(CodeGenerator* gen, Register result) | 174 OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
173 : OutOfLineCode(gen), result_(result) {} | 175 : OutOfLineCode(gen), result_(result) {} |
174 | 176 |
175 void Generate() FINAL { __ xor_(result_, result_); } | 177 void Generate() FINAL { __ xor_(result_, result_); } |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 i.InputOperand(1)); | 549 i.InputOperand(1)); |
548 break; | 550 break; |
549 } | 551 } |
550 case kIA32Movsxbl: | 552 case kIA32Movsxbl: |
551 __ movsx_b(i.OutputRegister(), i.MemoryOperand()); | 553 __ movsx_b(i.OutputRegister(), i.MemoryOperand()); |
552 break; | 554 break; |
553 case kIA32Movzxbl: | 555 case kIA32Movzxbl: |
554 __ movzx_b(i.OutputRegister(), i.MemoryOperand()); | 556 __ movzx_b(i.OutputRegister(), i.MemoryOperand()); |
555 break; | 557 break; |
556 case kIA32Movb: { | 558 case kIA32Movb: { |
557 int index = 0; | 559 size_t index = 0; |
558 Operand operand = i.MemoryOperand(&index); | 560 Operand operand = i.MemoryOperand(&index); |
559 if (HasImmediateInput(instr, index)) { | 561 if (HasImmediateInput(instr, index)) { |
560 __ mov_b(operand, i.InputInt8(index)); | 562 __ mov_b(operand, i.InputInt8(index)); |
561 } else { | 563 } else { |
562 __ mov_b(operand, i.InputRegister(index)); | 564 __ mov_b(operand, i.InputRegister(index)); |
563 } | 565 } |
564 break; | 566 break; |
565 } | 567 } |
566 case kIA32Movsxwl: | 568 case kIA32Movsxwl: |
567 __ movsx_w(i.OutputRegister(), i.MemoryOperand()); | 569 __ movsx_w(i.OutputRegister(), i.MemoryOperand()); |
568 break; | 570 break; |
569 case kIA32Movzxwl: | 571 case kIA32Movzxwl: |
570 __ movzx_w(i.OutputRegister(), i.MemoryOperand()); | 572 __ movzx_w(i.OutputRegister(), i.MemoryOperand()); |
571 break; | 573 break; |
572 case kIA32Movw: { | 574 case kIA32Movw: { |
573 int index = 0; | 575 size_t index = 0; |
574 Operand operand = i.MemoryOperand(&index); | 576 Operand operand = i.MemoryOperand(&index); |
575 if (HasImmediateInput(instr, index)) { | 577 if (HasImmediateInput(instr, index)) { |
576 __ mov_w(operand, i.InputInt16(index)); | 578 __ mov_w(operand, i.InputInt16(index)); |
577 } else { | 579 } else { |
578 __ mov_w(operand, i.InputRegister(index)); | 580 __ mov_w(operand, i.InputRegister(index)); |
579 } | 581 } |
580 break; | 582 break; |
581 } | 583 } |
582 case kIA32Movl: | 584 case kIA32Movl: |
583 if (instr->HasOutput()) { | 585 if (instr->HasOutput()) { |
584 __ mov(i.OutputRegister(), i.MemoryOperand()); | 586 __ mov(i.OutputRegister(), i.MemoryOperand()); |
585 } else { | 587 } else { |
586 int index = 0; | 588 size_t index = 0; |
587 Operand operand = i.MemoryOperand(&index); | 589 Operand operand = i.MemoryOperand(&index); |
588 if (HasImmediateInput(instr, index)) { | 590 if (HasImmediateInput(instr, index)) { |
589 __ mov(operand, i.InputImmediate(index)); | 591 __ mov(operand, i.InputImmediate(index)); |
590 } else { | 592 } else { |
591 __ mov(operand, i.InputRegister(index)); | 593 __ mov(operand, i.InputRegister(index)); |
592 } | 594 } |
593 } | 595 } |
594 break; | 596 break; |
595 case kIA32Movsd: | 597 case kIA32Movsd: |
596 if (instr->HasOutput()) { | 598 if (instr->HasOutput()) { |
597 __ movsd(i.OutputDoubleRegister(), i.MemoryOperand()); | 599 __ movsd(i.OutputDoubleRegister(), i.MemoryOperand()); |
598 } else { | 600 } else { |
599 int index = 0; | 601 size_t index = 0; |
600 Operand operand = i.MemoryOperand(&index); | 602 Operand operand = i.MemoryOperand(&index); |
601 __ movsd(operand, i.InputDoubleRegister(index)); | 603 __ movsd(operand, i.InputDoubleRegister(index)); |
602 } | 604 } |
603 break; | 605 break; |
604 case kIA32Movss: | 606 case kIA32Movss: |
605 if (instr->HasOutput()) { | 607 if (instr->HasOutput()) { |
606 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); | 608 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); |
607 } else { | 609 } else { |
608 int index = 0; | 610 size_t index = 0; |
609 Operand operand = i.MemoryOperand(&index); | 611 Operand operand = i.MemoryOperand(&index); |
610 __ movss(operand, i.InputDoubleRegister(index)); | 612 __ movss(operand, i.InputDoubleRegister(index)); |
611 } | 613 } |
612 break; | 614 break; |
613 case kIA32Lea: { | 615 case kIA32Lea: { |
614 AddressingMode mode = AddressingModeField::decode(instr->opcode()); | 616 AddressingMode mode = AddressingModeField::decode(instr->opcode()); |
615 // Shorten "leal" to "addl", "subl" or "shll" if the register allocation | 617 // Shorten "leal" to "addl", "subl" or "shll" if the register allocation |
616 // and addressing mode just happens to work out. The "addl"/"subl" forms | 618 // and addressing mode just happens to work out. The "addl"/"subl" forms |
617 // in these cases are faster based on measurements. | 619 // in these cases are faster based on measurements. |
618 if (mode == kMode_MI) { | 620 if (mode == kMode_MI) { |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1270 } | 1272 } |
1271 } | 1273 } |
1272 MarkLazyDeoptSite(); | 1274 MarkLazyDeoptSite(); |
1273 } | 1275 } |
1274 | 1276 |
1275 #undef __ | 1277 #undef __ |
1276 | 1278 |
1277 } // namespace compiler | 1279 } // namespace compiler |
1278 } // namespace internal | 1280 } // namespace internal |
1279 } // namespace v8 | 1281 } // namespace v8 |
OLD | NEW |