Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / compiler / ia32 / code-generator-ia32.cc
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
3 // found in the LICENSE file.
4
5 #include "src/compiler/code-generator.h"
6
7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/node-properties-inl.h"
11 #include "src/ia32/assembler-ia32.h"
12 #include "src/ia32/macro-assembler-ia32.h"
13 #include "src/scopes.h"
14
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18
19 #define __ masm()->
20
21
22 // Adds IA-32 specific methods for decoding operands.
23 class IA32OperandConverter : public InstructionOperandConverter {
24  public:
25   IA32OperandConverter(CodeGenerator* gen, Instruction* instr)
26       : InstructionOperandConverter(gen, instr) {}
27
28   Operand InputOperand(int index) { return ToOperand(instr_->InputAt(index)); }
29
30   Immediate InputImmediate(int index) {
31     return ToImmediate(instr_->InputAt(index));
32   }
33
34   Operand OutputOperand() { return ToOperand(instr_->Output()); }
35
36   Operand ToOperand(InstructionOperand* op, int extra = 0) {
37     if (op->IsRegister()) {
38       DCHECK(extra == 0);
39       return Operand(ToRegister(op));
40     } else if (op->IsDoubleRegister()) {
41       DCHECK(extra == 0);
42       return Operand(ToDoubleRegister(op));
43     }
44     DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
45     // The linkage computes where all spill slots are located.
46     FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra);
47     return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset());
48   }
49
50   Operand HighOperand(InstructionOperand* op) {
51     DCHECK(op->IsDoubleStackSlot());
52     return ToOperand(op, kPointerSize);
53   }
54
55   Immediate ToImmediate(InstructionOperand* operand) {
56     Constant constant = ToConstant(operand);
57     switch (constant.type()) {
58       case Constant::kInt32:
59         return Immediate(constant.ToInt32());
60       case Constant::kFloat32:
61         return Immediate(
62             isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
63       case Constant::kFloat64:
64         return Immediate(
65             isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
66       case Constant::kExternalReference:
67         return Immediate(constant.ToExternalReference());
68       case Constant::kHeapObject:
69         return Immediate(constant.ToHeapObject());
70       case Constant::kInt64:
71         break;
72     }
73     UNREACHABLE();
74     return Immediate(-1);
75   }
76
77   static int NextOffset(int* offset) {
78     int i = *offset;
79     (*offset)++;
80     return i;
81   }
82
83   static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) {
84     STATIC_ASSERT(0 == static_cast<int>(times_1));
85     STATIC_ASSERT(1 == static_cast<int>(times_2));
86     STATIC_ASSERT(2 == static_cast<int>(times_4));
87     STATIC_ASSERT(3 == static_cast<int>(times_8));
88     int scale = static_cast<int>(mode - one);
89     DCHECK(scale >= 0 && scale < 4);
90     return static_cast<ScaleFactor>(scale);
91   }
92
93   Operand MemoryOperand(int* offset) {
94     AddressingMode mode = AddressingModeField::decode(instr_->opcode());
95     switch (mode) {
96       case kMode_MR: {
97         Register base = InputRegister(NextOffset(offset));
98         int32_t disp = 0;
99         return Operand(base, disp);
100       }
101       case kMode_MRI: {
102         Register base = InputRegister(NextOffset(offset));
103         int32_t disp = InputInt32(NextOffset(offset));
104         return Operand(base, disp);
105       }
106       case kMode_MR1:
107       case kMode_MR2:
108       case kMode_MR4:
109       case kMode_MR8: {
110         Register base = InputRegister(NextOffset(offset));
111         Register index = InputRegister(NextOffset(offset));
112         ScaleFactor scale = ScaleFor(kMode_MR1, mode);
113         int32_t disp = 0;
114         return Operand(base, index, scale, disp);
115       }
116       case kMode_MR1I:
117       case kMode_MR2I:
118       case kMode_MR4I:
119       case kMode_MR8I: {
120         Register base = InputRegister(NextOffset(offset));
121         Register index = InputRegister(NextOffset(offset));
122         ScaleFactor scale = ScaleFor(kMode_MR1I, mode);
123         int32_t disp = InputInt32(NextOffset(offset));
124         return Operand(base, index, scale, disp);
125       }
126       case kMode_M1:
127       case kMode_M2:
128       case kMode_M4:
129       case kMode_M8: {
130         Register index = InputRegister(NextOffset(offset));
131         ScaleFactor scale = ScaleFor(kMode_M1, mode);
132         int32_t disp = 0;
133         return Operand(index, scale, disp);
134       }
135       case kMode_M1I:
136       case kMode_M2I:
137       case kMode_M4I:
138       case kMode_M8I: {
139         Register index = InputRegister(NextOffset(offset));
140         ScaleFactor scale = ScaleFor(kMode_M1I, mode);
141         int32_t disp = InputInt32(NextOffset(offset));
142         return Operand(index, scale, disp);
143       }
144       case kMode_MI: {
145         int32_t disp = InputInt32(NextOffset(offset));
146         return Operand(Immediate(disp));
147       }
148       case kMode_None:
149         UNREACHABLE();
150         return Operand(no_reg, 0);
151     }
152     UNREACHABLE();
153     return Operand(no_reg, 0);
154   }
155
156   Operand MemoryOperand() {
157     int first_input = 0;
158     return MemoryOperand(&first_input);
159   }
160 };
161
162
163 static bool HasImmediateInput(Instruction* instr, int index) {
164   return instr->InputAt(index)->IsImmediate();
165 }
166
167
168 // Assembles an instruction after register allocation, producing machine code.
169 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
170   IA32OperandConverter i(this, instr);
171
172   switch (ArchOpcodeField::decode(instr->opcode())) {
173     case kArchCallCodeObject: {
174       EnsureSpaceForLazyDeopt();
175       if (HasImmediateInput(instr, 0)) {
176         Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
177         __ call(code, RelocInfo::CODE_TARGET);
178       } else {
179         Register reg = i.InputRegister(0);
180         __ call(Operand(reg, Code::kHeaderSize - kHeapObjectTag));
181       }
182       AddSafepointAndDeopt(instr);
183       break;
184     }
185     case kArchCallJSFunction: {
186       EnsureSpaceForLazyDeopt();
187       Register func = i.InputRegister(0);
188       if (FLAG_debug_code) {
189         // Check the function's context matches the context argument.
190         __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
191         __ Assert(equal, kWrongFunctionContext);
192       }
193       __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
194       AddSafepointAndDeopt(instr);
195       break;
196     }
197     case kArchJmp:
198       __ jmp(code()->GetLabel(i.InputRpo(0)));
199       break;
200     case kArchNop:
201       // don't emit code for nops.
202       break;
203     case kArchRet:
204       AssembleReturn();
205       break;
206     case kArchStackPointer:
207       __ mov(i.OutputRegister(), esp);
208       break;
209     case kArchTruncateDoubleToI:
210       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
211       break;
212     case kIA32Add:
213       if (HasImmediateInput(instr, 1)) {
214         __ add(i.InputOperand(0), i.InputImmediate(1));
215       } else {
216         __ add(i.InputRegister(0), i.InputOperand(1));
217       }
218       break;
219     case kIA32And:
220       if (HasImmediateInput(instr, 1)) {
221         __ and_(i.InputOperand(0), i.InputImmediate(1));
222       } else {
223         __ and_(i.InputRegister(0), i.InputOperand(1));
224       }
225       break;
226     case kIA32Cmp:
227       if (HasImmediateInput(instr, 1)) {
228         __ cmp(i.InputOperand(0), i.InputImmediate(1));
229       } else {
230         __ cmp(i.InputRegister(0), i.InputOperand(1));
231       }
232       break;
233     case kIA32Test:
234       if (HasImmediateInput(instr, 1)) {
235         __ test(i.InputOperand(0), i.InputImmediate(1));
236       } else {
237         __ test(i.InputRegister(0), i.InputOperand(1));
238       }
239       break;
240     case kIA32Imul:
241       if (HasImmediateInput(instr, 1)) {
242         __ imul(i.OutputRegister(), i.InputOperand(0), i.InputInt32(1));
243       } else {
244         __ imul(i.OutputRegister(), i.InputOperand(1));
245       }
246       break;
247     case kIA32ImulHigh:
248       __ imul(i.InputRegister(1));
249       break;
250     case kIA32UmulHigh:
251       __ mul(i.InputRegister(1));
252       break;
253     case kIA32Idiv:
254       __ cdq();
255       __ idiv(i.InputOperand(1));
256       break;
257     case kIA32Udiv:
258       __ Move(edx, Immediate(0));
259       __ div(i.InputOperand(1));
260       break;
261     case kIA32Not:
262       __ not_(i.OutputOperand());
263       break;
264     case kIA32Neg:
265       __ neg(i.OutputOperand());
266       break;
267     case kIA32Or:
268       if (HasImmediateInput(instr, 1)) {
269         __ or_(i.InputOperand(0), i.InputImmediate(1));
270       } else {
271         __ or_(i.InputRegister(0), i.InputOperand(1));
272       }
273       break;
274     case kIA32Xor:
275       if (HasImmediateInput(instr, 1)) {
276         __ xor_(i.InputOperand(0), i.InputImmediate(1));
277       } else {
278         __ xor_(i.InputRegister(0), i.InputOperand(1));
279       }
280       break;
281     case kIA32Sub:
282       if (HasImmediateInput(instr, 1)) {
283         __ sub(i.InputOperand(0), i.InputImmediate(1));
284       } else {
285         __ sub(i.InputRegister(0), i.InputOperand(1));
286       }
287       break;
288     case kIA32Shl:
289       if (HasImmediateInput(instr, 1)) {
290         __ shl(i.OutputOperand(), i.InputInt5(1));
291       } else {
292         __ shl_cl(i.OutputOperand());
293       }
294       break;
295     case kIA32Shr:
296       if (HasImmediateInput(instr, 1)) {
297         __ shr(i.OutputOperand(), i.InputInt5(1));
298       } else {
299         __ shr_cl(i.OutputOperand());
300       }
301       break;
302     case kIA32Sar:
303       if (HasImmediateInput(instr, 1)) {
304         __ sar(i.OutputOperand(), i.InputInt5(1));
305       } else {
306         __ sar_cl(i.OutputOperand());
307       }
308       break;
309     case kIA32Ror:
310       if (HasImmediateInput(instr, 1)) {
311         __ ror(i.OutputOperand(), i.InputInt5(1));
312       } else {
313         __ ror_cl(i.OutputOperand());
314       }
315       break;
316     case kSSEFloat64Cmp:
317       __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
318       break;
319     case kSSEFloat64Add:
320       __ addsd(i.InputDoubleRegister(0), i.InputOperand(1));
321       break;
322     case kSSEFloat64Sub:
323       __ subsd(i.InputDoubleRegister(0), i.InputOperand(1));
324       break;
325     case kSSEFloat64Mul:
326       __ mulsd(i.InputDoubleRegister(0), i.InputOperand(1));
327       break;
328     case kSSEFloat64Div:
329       __ divsd(i.InputDoubleRegister(0), i.InputOperand(1));
330       break;
331     case kSSEFloat64Mod: {
332       // TODO(dcarney): alignment is wrong.
333       __ sub(esp, Immediate(kDoubleSize));
334       // Move values to st(0) and st(1).
335       __ movsd(Operand(esp, 0), i.InputDoubleRegister(1));
336       __ fld_d(Operand(esp, 0));
337       __ movsd(Operand(esp, 0), i.InputDoubleRegister(0));
338       __ fld_d(Operand(esp, 0));
339       // Loop while fprem isn't done.
340       Label mod_loop;
341       __ bind(&mod_loop);
342       // This instructions traps on all kinds inputs, but we are assuming the
343       // floating point control word is set to ignore them all.
344       __ fprem();
345       // The following 2 instruction implicitly use eax.
346       __ fnstsw_ax();
347       __ sahf();
348       __ j(parity_even, &mod_loop);
349       // Move output to stack and clean up.
350       __ fstp(1);
351       __ fstp_d(Operand(esp, 0));
352       __ movsd(i.OutputDoubleRegister(), Operand(esp, 0));
353       __ add(esp, Immediate(kDoubleSize));
354       break;
355     }
356     case kSSEFloat64Sqrt:
357       __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0));
358       break;
359     case kSSEFloat64Floor: {
360       CpuFeatureScope sse_scope(masm(), SSE4_1);
361       __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
362                  v8::internal::Assembler::kRoundDown);
363       break;
364     }
365     case kSSEFloat64Ceil: {
366       CpuFeatureScope sse_scope(masm(), SSE4_1);
367       __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
368                  v8::internal::Assembler::kRoundUp);
369       break;
370     }
371     case kSSEFloat64RoundTruncate: {
372       CpuFeatureScope sse_scope(masm(), SSE4_1);
373       __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
374                  v8::internal::Assembler::kRoundToZero);
375       break;
376     }
377     case kSSECvtss2sd:
378       __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0));
379       break;
380     case kSSECvtsd2ss:
381       __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0));
382       break;
383     case kSSEFloat64ToInt32:
384       __ cvttsd2si(i.OutputRegister(), i.InputOperand(0));
385       break;
386     case kSSEFloat64ToUint32: {
387       XMMRegister scratch = xmm0;
388       __ Move(scratch, -2147483648.0);
389       __ addsd(scratch, i.InputOperand(0));
390       __ cvttsd2si(i.OutputRegister(), scratch);
391       __ add(i.OutputRegister(), Immediate(0x80000000));
392       break;
393     }
394     case kSSEInt32ToFloat64:
395       __ cvtsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
396       break;
397     case kSSEUint32ToFloat64:
398       __ LoadUint32(i.OutputDoubleRegister(), i.InputOperand(0));
399       break;
400     case kIA32Movsxbl:
401       __ movsx_b(i.OutputRegister(), i.MemoryOperand());
402       break;
403     case kIA32Movzxbl:
404       __ movzx_b(i.OutputRegister(), i.MemoryOperand());
405       break;
406     case kIA32Movb: {
407       int index = 0;
408       Operand operand = i.MemoryOperand(&index);
409       if (HasImmediateInput(instr, index)) {
410         __ mov_b(operand, i.InputInt8(index));
411       } else {
412         __ mov_b(operand, i.InputRegister(index));
413       }
414       break;
415     }
416     case kIA32Movsxwl:
417       __ movsx_w(i.OutputRegister(), i.MemoryOperand());
418       break;
419     case kIA32Movzxwl:
420       __ movzx_w(i.OutputRegister(), i.MemoryOperand());
421       break;
422     case kIA32Movw: {
423       int index = 0;
424       Operand operand = i.MemoryOperand(&index);
425       if (HasImmediateInput(instr, index)) {
426         __ mov_w(operand, i.InputInt16(index));
427       } else {
428         __ mov_w(operand, i.InputRegister(index));
429       }
430       break;
431     }
432     case kIA32Movl:
433       if (instr->HasOutput()) {
434         __ mov(i.OutputRegister(), i.MemoryOperand());
435       } else {
436         int index = 0;
437         Operand operand = i.MemoryOperand(&index);
438         if (HasImmediateInput(instr, index)) {
439           __ mov(operand, i.InputImmediate(index));
440         } else {
441           __ mov(operand, i.InputRegister(index));
442         }
443       }
444       break;
445     case kIA32Movsd:
446       if (instr->HasOutput()) {
447         __ movsd(i.OutputDoubleRegister(), i.MemoryOperand());
448       } else {
449         int index = 0;
450         Operand operand = i.MemoryOperand(&index);
451         __ movsd(operand, i.InputDoubleRegister(index));
452       }
453       break;
454     case kIA32Movss:
455       if (instr->HasOutput()) {
456         __ movss(i.OutputDoubleRegister(), i.MemoryOperand());
457       } else {
458         int index = 0;
459         Operand operand = i.MemoryOperand(&index);
460         __ movss(operand, i.InputDoubleRegister(index));
461       }
462       break;
463     case kIA32Lea:
464       __ lea(i.OutputRegister(), i.MemoryOperand());
465       break;
466     case kIA32Push:
467       if (HasImmediateInput(instr, 0)) {
468         __ push(i.InputImmediate(0));
469       } else {
470         __ push(i.InputOperand(0));
471       }
472       break;
473     case kIA32StoreWriteBarrier: {
474       Register object = i.InputRegister(0);
475       Register index = i.InputRegister(1);
476       Register value = i.InputRegister(2);
477       __ mov(Operand(object, index, times_1, 0), value);
478       __ lea(index, Operand(object, index, times_1, 0));
479       SaveFPRegsMode mode =
480           frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
481       __ RecordWrite(object, index, value, mode);
482       break;
483     }
484   }
485 }
486
487
488 // Assembles branches after an instruction.
489 void CodeGenerator::AssembleArchBranch(Instruction* instr,
490                                        FlagsCondition condition) {
491   IA32OperandConverter i(this, instr);
492   Label done;
493
494   // Emit a branch. The true and false targets are always the last two inputs
495   // to the instruction.
496   BasicBlock::RpoNumber tblock =
497       i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
498   BasicBlock::RpoNumber fblock =
499       i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
500   bool fallthru = IsNextInAssemblyOrder(fblock);
501   Label* tlabel = code()->GetLabel(tblock);
502   Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
503   Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar;
504   switch (condition) {
505     case kUnorderedEqual:
506       __ j(parity_even, flabel, flabel_distance);
507     // Fall through.
508     case kEqual:
509       __ j(equal, tlabel);
510       break;
511     case kUnorderedNotEqual:
512       __ j(parity_even, tlabel);
513     // Fall through.
514     case kNotEqual:
515       __ j(not_equal, tlabel);
516       break;
517     case kSignedLessThan:
518       __ j(less, tlabel);
519       break;
520     case kSignedGreaterThanOrEqual:
521       __ j(greater_equal, tlabel);
522       break;
523     case kSignedLessThanOrEqual:
524       __ j(less_equal, tlabel);
525       break;
526     case kSignedGreaterThan:
527       __ j(greater, tlabel);
528       break;
529     case kUnorderedLessThan:
530       __ j(parity_even, flabel, flabel_distance);
531     // Fall through.
532     case kUnsignedLessThan:
533       __ j(below, tlabel);
534       break;
535     case kUnorderedGreaterThanOrEqual:
536       __ j(parity_even, tlabel);
537     // Fall through.
538     case kUnsignedGreaterThanOrEqual:
539       __ j(above_equal, tlabel);
540       break;
541     case kUnorderedLessThanOrEqual:
542       __ j(parity_even, flabel, flabel_distance);
543     // Fall through.
544     case kUnsignedLessThanOrEqual:
545       __ j(below_equal, tlabel);
546       break;
547     case kUnorderedGreaterThan:
548       __ j(parity_even, tlabel);
549     // Fall through.
550     case kUnsignedGreaterThan:
551       __ j(above, tlabel);
552       break;
553     case kOverflow:
554       __ j(overflow, tlabel);
555       break;
556     case kNotOverflow:
557       __ j(no_overflow, tlabel);
558       break;
559   }
560   if (!fallthru) __ jmp(flabel, flabel_distance);  // no fallthru to flabel.
561   __ bind(&done);
562 }
563
564
565 // Assembles boolean materializations after an instruction.
566 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
567                                         FlagsCondition condition) {
568   IA32OperandConverter i(this, instr);
569   Label done;
570
571   // Materialize a full 32-bit 1 or 0 value. The result register is always the
572   // last output of the instruction.
573   Label check;
574   DCHECK_NE(0, instr->OutputCount());
575   Register reg = i.OutputRegister(instr->OutputCount() - 1);
576   Condition cc = no_condition;
577   switch (condition) {
578     case kUnorderedEqual:
579       __ j(parity_odd, &check, Label::kNear);
580       __ Move(reg, Immediate(0));
581       __ jmp(&done, Label::kNear);
582     // Fall through.
583     case kEqual:
584       cc = equal;
585       break;
586     case kUnorderedNotEqual:
587       __ j(parity_odd, &check, Label::kNear);
588       __ mov(reg, Immediate(1));
589       __ jmp(&done, Label::kNear);
590     // Fall through.
591     case kNotEqual:
592       cc = not_equal;
593       break;
594     case kSignedLessThan:
595       cc = less;
596       break;
597     case kSignedGreaterThanOrEqual:
598       cc = greater_equal;
599       break;
600     case kSignedLessThanOrEqual:
601       cc = less_equal;
602       break;
603     case kSignedGreaterThan:
604       cc = greater;
605       break;
606     case kUnorderedLessThan:
607       __ j(parity_odd, &check, Label::kNear);
608       __ Move(reg, Immediate(0));
609       __ jmp(&done, Label::kNear);
610     // Fall through.
611     case kUnsignedLessThan:
612       cc = below;
613       break;
614     case kUnorderedGreaterThanOrEqual:
615       __ j(parity_odd, &check, Label::kNear);
616       __ mov(reg, Immediate(1));
617       __ jmp(&done, Label::kNear);
618     // Fall through.
619     case kUnsignedGreaterThanOrEqual:
620       cc = above_equal;
621       break;
622     case kUnorderedLessThanOrEqual:
623       __ j(parity_odd, &check, Label::kNear);
624       __ Move(reg, Immediate(0));
625       __ jmp(&done, Label::kNear);
626     // Fall through.
627     case kUnsignedLessThanOrEqual:
628       cc = below_equal;
629       break;
630     case kUnorderedGreaterThan:
631       __ j(parity_odd, &check, Label::kNear);
632       __ mov(reg, Immediate(1));
633       __ jmp(&done, Label::kNear);
634     // Fall through.
635     case kUnsignedGreaterThan:
636       cc = above;
637       break;
638     case kOverflow:
639       cc = overflow;
640       break;
641     case kNotOverflow:
642       cc = no_overflow;
643       break;
644   }
645   __ bind(&check);
646   if (reg.is_byte_register()) {
647     // setcc for byte registers (al, bl, cl, dl).
648     __ setcc(cc, reg);
649     __ movzx_b(reg, reg);
650   } else {
651     // Emit a branch to set a register to either 1 or 0.
652     Label set;
653     __ j(cc, &set, Label::kNear);
654     __ Move(reg, Immediate(0));
655     __ jmp(&done, Label::kNear);
656     __ bind(&set);
657     __ mov(reg, Immediate(1));
658   }
659   __ bind(&done);
660 }
661
662
663 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
664   Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
665       isolate(), deoptimization_id, Deoptimizer::LAZY);
666   __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
667 }
668
669
670 // The calling convention for JSFunctions on IA32 passes arguments on the
671 // stack and the JSFunction and context in EDI and ESI, respectively, thus
672 // the steps of the call look as follows:
673
674 // --{ before the call instruction }--------------------------------------------
675 //                                                         |  caller frame |
676 //                                                         ^ esp           ^ ebp
677
678 // --{ push arguments and setup ESI, EDI }--------------------------------------
679 //                                       | args + receiver |  caller frame |
680 //                                       ^ esp                             ^ ebp
681 //                 [edi = JSFunction, esi = context]
682
683 // --{ call [edi + kCodeEntryOffset] }------------------------------------------
684 //                                 | RET | args + receiver |  caller frame |
685 //                                 ^ esp                                   ^ ebp
686
687 // =={ prologue of called function }============================================
688 // --{ push ebp }---------------------------------------------------------------
689 //                            | FP | RET | args + receiver |  caller frame |
690 //                            ^ esp                                        ^ ebp
691
692 // --{ mov ebp, esp }-----------------------------------------------------------
693 //                            | FP | RET | args + receiver |  caller frame |
694 //                            ^ ebp,esp
695
696 // --{ push esi }---------------------------------------------------------------
697 //                      | CTX | FP | RET | args + receiver |  caller frame |
698 //                      ^esp  ^ ebp
699
700 // --{ push edi }---------------------------------------------------------------
701 //                | FNC | CTX | FP | RET | args + receiver |  caller frame |
702 //                ^esp        ^ ebp
703
704 // --{ subi esp, #N }-----------------------------------------------------------
705 // | callee frame | FNC | CTX | FP | RET | args + receiver |  caller frame |
706 // ^esp                       ^ ebp
707
708 // =={ body of called function }================================================
709
710 // =={ epilogue of called function }============================================
711 // --{ mov esp, ebp }-----------------------------------------------------------
712 //                            | FP | RET | args + receiver |  caller frame |
713 //                            ^ esp,ebp
714
715 // --{ pop ebp }-----------------------------------------------------------
716 // |                               | RET | args + receiver |  caller frame |
717 //                                 ^ esp                                   ^ ebp
718
719 // --{ ret #A+1 }-----------------------------------------------------------
720 // |                                                       |  caller frame |
721 //                                                         ^ esp           ^ ebp
722
723
724 // Runtime function calls are accomplished by doing a stub call to the
725 // CEntryStub (a real code object). On IA32 passes arguments on the
726 // stack, the number of arguments in EAX, the address of the runtime function
727 // in EBX, and the context in ESI.
728
729 // --{ before the call instruction }--------------------------------------------
730 //                                                         |  caller frame |
731 //                                                         ^ esp           ^ ebp
732
733 // --{ push arguments and setup EAX, EBX, and ESI }-----------------------------
734 //                                       | args + receiver |  caller frame |
735 //                                       ^ esp                             ^ ebp
736 //              [eax = #args, ebx = runtime function, esi = context]
737
738 // --{ call #CEntryStub }-------------------------------------------------------
739 //                                 | RET | args + receiver |  caller frame |
740 //                                 ^ esp                                   ^ ebp
741
742 // =={ body of runtime function }===============================================
743
744 // --{ runtime returns }--------------------------------------------------------
745 //                                                         |  caller frame |
746 //                                                         ^ esp           ^ ebp
747
748 // Other custom linkages (e.g. for calling directly into and out of C++) may
749 // need to save callee-saved registers on the stack, which is done in the
750 // function prologue of generated code.
751
752 // --{ before the call instruction }--------------------------------------------
753 //                                                         |  caller frame |
754 //                                                         ^ esp           ^ ebp
755
756 // --{ set up arguments in registers on stack }---------------------------------
757 //                                                  | args |  caller frame |
758 //                                                  ^ esp                  ^ ebp
759 //                  [r0 = arg0, r1 = arg1, ...]
760
761 // --{ call code }--------------------------------------------------------------
762 //                                            | RET | args |  caller frame |
763 //                                            ^ esp                        ^ ebp
764
765 // =={ prologue of called function }============================================
766 // --{ push ebp }---------------------------------------------------------------
767 //                                       | FP | RET | args |  caller frame |
768 //                                       ^ esp                             ^ ebp
769
770 // --{ mov ebp, esp }-----------------------------------------------------------
771 //                                       | FP | RET | args |  caller frame |
772 //                                       ^ ebp,esp
773
774 // --{ save registers }---------------------------------------------------------
775 //                                | regs | FP | RET | args |  caller frame |
776 //                                ^ esp  ^ ebp
777
778 // --{ subi esp, #N }-----------------------------------------------------------
779 //                 | callee frame | regs | FP | RET | args |  caller frame |
780 //                 ^esp                  ^ ebp
781
782 // =={ body of called function }================================================
783
784 // =={ epilogue of called function }============================================
785 // --{ restore registers }------------------------------------------------------
786 //                                | regs | FP | RET | args |  caller frame |
787 //                                ^ esp  ^ ebp
788
789 // --{ mov esp, ebp }-----------------------------------------------------------
790 //                                       | FP | RET | args |  caller frame |
791 //                                       ^ esp,ebp
792
793 // --{ pop ebp }----------------------------------------------------------------
794 //                                            | RET | args |  caller frame |
795 //                                            ^ esp                        ^ ebp
796
797
798 void CodeGenerator::AssemblePrologue() {
799   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
800   Frame* frame = this->frame();
801   int stack_slots = frame->GetSpillSlotCount();
802   if (descriptor->kind() == CallDescriptor::kCallAddress) {
803     // Assemble a prologue similar the to cdecl calling convention.
804     __ push(ebp);
805     __ mov(ebp, esp);
806     const RegList saves = descriptor->CalleeSavedRegisters();
807     if (saves != 0) {  // Save callee-saved registers.
808       int register_save_area_size = 0;
809       for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
810         if (!((1 << i) & saves)) continue;
811         __ push(Register::from_code(i));
812         register_save_area_size += kPointerSize;
813       }
814       frame->SetRegisterSaveAreaSize(register_save_area_size);
815     }
816   } else if (descriptor->IsJSFunctionCall()) {
817     CompilationInfo* info = this->info();
818     __ Prologue(info->IsCodePreAgingActive());
819     frame->SetRegisterSaveAreaSize(
820         StandardFrameConstants::kFixedFrameSizeFromFp);
821
822     // Sloppy mode functions and builtins need to replace the receiver with the
823     // global proxy when called as functions (without an explicit receiver
824     // object).
825     // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
826     if (info->strict_mode() == SLOPPY && !info->is_native()) {
827       Label ok;
828       // +2 for return address and saved frame pointer.
829       int receiver_slot = info->scope()->num_parameters() + 2;
830       __ mov(ecx, Operand(ebp, receiver_slot * kPointerSize));
831       __ cmp(ecx, isolate()->factory()->undefined_value());
832       __ j(not_equal, &ok, Label::kNear);
833       __ mov(ecx, GlobalObjectOperand());
834       __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalProxyOffset));
835       __ mov(Operand(ebp, receiver_slot * kPointerSize), ecx);
836       __ bind(&ok);
837     }
838
839   } else {
840     __ StubPrologue();
841     frame->SetRegisterSaveAreaSize(
842         StandardFrameConstants::kFixedFrameSizeFromFp);
843   }
844   if (stack_slots > 0) {
845     __ sub(esp, Immediate(stack_slots * kPointerSize));
846   }
847 }
848
849
850 void CodeGenerator::AssembleReturn() {
851   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
852   if (descriptor->kind() == CallDescriptor::kCallAddress) {
853     const RegList saves = descriptor->CalleeSavedRegisters();
854     if (frame()->GetRegisterSaveAreaSize() > 0) {
855       // Remove this frame's spill slots first.
856       int stack_slots = frame()->GetSpillSlotCount();
857       if (stack_slots > 0) {
858         __ add(esp, Immediate(stack_slots * kPointerSize));
859       }
860       // Restore registers.
861       if (saves != 0) {
862         for (int i = 0; i < Register::kNumRegisters; i++) {
863           if (!((1 << i) & saves)) continue;
864           __ pop(Register::from_code(i));
865         }
866       }
867       __ pop(ebp);  // Pop caller's frame pointer.
868       __ ret(0);
869     } else {
870       // No saved registers.
871       __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
872       __ pop(ebp);       // Pop caller's frame pointer.
873       __ ret(0);
874     }
875   } else {
876     __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
877     __ pop(ebp);       // Pop caller's frame pointer.
878     int pop_count = descriptor->IsJSFunctionCall()
879                         ? static_cast<int>(descriptor->JSParameterCount())
880                         : 0;
881     __ ret(pop_count * kPointerSize);
882   }
883 }
884
885
886 void CodeGenerator::AssembleMove(InstructionOperand* source,
887                                  InstructionOperand* destination) {
888   IA32OperandConverter g(this, NULL);
889   // Dispatch on the source and destination operand kinds.  Not all
890   // combinations are possible.
891   if (source->IsRegister()) {
892     DCHECK(destination->IsRegister() || destination->IsStackSlot());
893     Register src = g.ToRegister(source);
894     Operand dst = g.ToOperand(destination);
895     __ mov(dst, src);
896   } else if (source->IsStackSlot()) {
897     DCHECK(destination->IsRegister() || destination->IsStackSlot());
898     Operand src = g.ToOperand(source);
899     if (destination->IsRegister()) {
900       Register dst = g.ToRegister(destination);
901       __ mov(dst, src);
902     } else {
903       Operand dst = g.ToOperand(destination);
904       __ push(src);
905       __ pop(dst);
906     }
907   } else if (source->IsConstant()) {
908     Constant src_constant = g.ToConstant(source);
909     if (src_constant.type() == Constant::kHeapObject) {
910       Handle<HeapObject> src = src_constant.ToHeapObject();
911       if (destination->IsRegister()) {
912         Register dst = g.ToRegister(destination);
913         __ LoadHeapObject(dst, src);
914       } else {
915         DCHECK(destination->IsStackSlot());
916         Operand dst = g.ToOperand(destination);
917         AllowDeferredHandleDereference embedding_raw_address;
918         if (isolate()->heap()->InNewSpace(*src)) {
919           __ PushHeapObject(src);
920           __ pop(dst);
921         } else {
922           __ mov(dst, src);
923         }
924       }
925     } else if (destination->IsRegister()) {
926       Register dst = g.ToRegister(destination);
927       __ Move(dst, g.ToImmediate(source));
928     } else if (destination->IsStackSlot()) {
929       Operand dst = g.ToOperand(destination);
930       __ Move(dst, g.ToImmediate(source));
931     } else if (src_constant.type() == Constant::kFloat32) {
932       // TODO(turbofan): Can we do better here?
933       uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32());
934       if (destination->IsDoubleRegister()) {
935         XMMRegister dst = g.ToDoubleRegister(destination);
936         __ Move(dst, src);
937       } else {
938         DCHECK(destination->IsDoubleStackSlot());
939         Operand dst = g.ToOperand(destination);
940         __ Move(dst, Immediate(src));
941       }
942     } else {
943       DCHECK_EQ(Constant::kFloat64, src_constant.type());
944       uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64());
945       uint32_t lower = static_cast<uint32_t>(src);
946       uint32_t upper = static_cast<uint32_t>(src >> 32);
947       if (destination->IsDoubleRegister()) {
948         XMMRegister dst = g.ToDoubleRegister(destination);
949         __ Move(dst, src);
950       } else {
951         DCHECK(destination->IsDoubleStackSlot());
952         Operand dst0 = g.ToOperand(destination);
953         Operand dst1 = g.HighOperand(destination);
954         __ Move(dst0, Immediate(lower));
955         __ Move(dst1, Immediate(upper));
956       }
957     }
958   } else if (source->IsDoubleRegister()) {
959     XMMRegister src = g.ToDoubleRegister(source);
960     if (destination->IsDoubleRegister()) {
961       XMMRegister dst = g.ToDoubleRegister(destination);
962       __ movaps(dst, src);
963     } else {
964       DCHECK(destination->IsDoubleStackSlot());
965       Operand dst = g.ToOperand(destination);
966       __ movsd(dst, src);
967     }
968   } else if (source->IsDoubleStackSlot()) {
969     DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
970     Operand src = g.ToOperand(source);
971     if (destination->IsDoubleRegister()) {
972       XMMRegister dst = g.ToDoubleRegister(destination);
973       __ movsd(dst, src);
974     } else {
975       // We rely on having xmm0 available as a fixed scratch register.
976       Operand dst = g.ToOperand(destination);
977       __ movsd(xmm0, src);
978       __ movsd(dst, xmm0);
979     }
980   } else {
981     UNREACHABLE();
982   }
983 }
984
985
986 void CodeGenerator::AssembleSwap(InstructionOperand* source,
987                                  InstructionOperand* destination) {
988   IA32OperandConverter g(this, NULL);
989   // Dispatch on the source and destination operand kinds.  Not all
990   // combinations are possible.
991   if (source->IsRegister() && destination->IsRegister()) {
992     // Register-register.
993     Register src = g.ToRegister(source);
994     Register dst = g.ToRegister(destination);
995     __ xchg(dst, src);
996   } else if (source->IsRegister() && destination->IsStackSlot()) {
997     // Register-memory.
998     __ xchg(g.ToRegister(source), g.ToOperand(destination));
999   } else if (source->IsStackSlot() && destination->IsStackSlot()) {
1000     // Memory-memory.
1001     Operand src = g.ToOperand(source);
1002     Operand dst = g.ToOperand(destination);
1003     __ push(dst);
1004     __ push(src);
1005     __ pop(dst);
1006     __ pop(src);
1007   } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) {
1008     // XMM register-register swap. We rely on having xmm0
1009     // available as a fixed scratch register.
1010     XMMRegister src = g.ToDoubleRegister(source);
1011     XMMRegister dst = g.ToDoubleRegister(destination);
1012     __ movaps(xmm0, src);
1013     __ movaps(src, dst);
1014     __ movaps(dst, xmm0);
1015   } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
1016     // XMM register-memory swap.  We rely on having xmm0
1017     // available as a fixed scratch register.
1018     XMMRegister reg = g.ToDoubleRegister(source);
1019     Operand other = g.ToOperand(destination);
1020     __ movsd(xmm0, other);
1021     __ movsd(other, reg);
1022     __ movaps(reg, xmm0);
1023   } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) {
1024     // Double-width memory-to-memory.
1025     Operand src0 = g.ToOperand(source);
1026     Operand src1 = g.HighOperand(source);
1027     Operand dst0 = g.ToOperand(destination);
1028     Operand dst1 = g.HighOperand(destination);
1029     __ movsd(xmm0, dst0);  // Save destination in xmm0.
1030     __ push(src0);         // Then use stack to copy source to destination.
1031     __ pop(dst0);
1032     __ push(src1);
1033     __ pop(dst1);
1034     __ movsd(src0, xmm0);
1035   } else {
1036     // No other combinations are possible.
1037     UNREACHABLE();
1038   }
1039 }
1040
1041
1042 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); }
1043
1044
1045 void CodeGenerator::EnsureSpaceForLazyDeopt() {
1046   int space_needed = Deoptimizer::patch_size();
1047   if (!info()->IsStub()) {
1048     // Ensure that we have enough space after the previous lazy-bailout
1049     // instruction for patching the code here.
1050     int current_pc = masm()->pc_offset();
1051     if (current_pc < last_lazy_deopt_pc_ + space_needed) {
1052       int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
1053       __ Nop(padding_size);
1054     }
1055   }
1056   MarkLazyDeoptSite();
1057 }
1058
1059 #undef __
1060
1061 }  // namespace compiler
1062 }  // namespace internal
1063 }  // namespace v8