CACAO
X86_64Backend.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/X86_64Backend.hpp - X86_64Backend
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
37 #include "vm/jit/PatcherNew.hpp"
38 #include "vm/jit/jit.hpp"
39 #include "vm/jit/code.hpp"
40 #include "vm/class.hpp"
41 #include "vm/field.hpp"
42 
43 #include "md-trap.hpp"
44 
45 #include "toolbox/OStream.hpp"
46 #include "toolbox/logging.hpp"
47 
48 #define DEBUG_NAME "compiler2/x86_64"
49 
50 // code.hpp fix
51 #undef RAX
52 #undef XMM0
53 
54 namespace cacao {
55 namespace jit {
56 namespace compiler2 {
57 
58 // BackendBase must be specialized in namespace compiler2!
59 using namespace x86_64;
60 
61 template<>
62 const char* BackendBase<X86_64>::get_name() const {
63  return "x86_64";
64 }
65 
66 template<>
68  MachineOperand* dst) const {
69  Type::TypeID type = dst->get_type();
70  assert(type == src->get_type());
71  assert(!(src->is_stackslot() && dst->is_stackslot()));
72  switch (type) {
73  case Type::CharTypeID:
74  case Type::ByteTypeID:
75  case Type::ShortTypeID:
76  case Type::IntTypeID:
77  case Type::LongTypeID:
79  {
80  return new MovInst(
81  SrcOp(src),
82  DstOp(dst),
84  }
85  case Type::DoubleTypeID:
86  {
87  switch (src->get_OperandID()) {
89  return new MovImmSDInst(
90  SrcOp(src),
91  DstOp(dst));
92  default:
93  return new MovSDInst(
94  SrcOp(src),
95  DstOp(dst));
96  }
97  break;
98  }
99  case Type::FloatTypeID:
100  {
101  switch (src->get_OperandID()) {
103  return new MovImmSSInst(
104  SrcOp(src),
105  DstOp(dst));
106  default:
107  return new MovSSInst(
108  SrcOp(src),
109  DstOp(dst));
110  }
111  break;
112  }
113  default:
114  break;
115  }
116  ABORT_MSG("x86_64: Move not supported",
117  "Inst: " << src << " -> " << dst << " type: " << type);
118  return NULL;
119 }
120 
121 template<>
123  return new JumpInst(target);
124 }
125 
126 namespace {
127 
128 template <unsigned size, class T>
129 inline T align_to(T val) {
130  T rem =(val % size);
131  return val + ( rem == 0 ? 0 : size - rem);
132 }
133 
134 } // end anonymous namespace
135 
136 template<>
138  EnterInst enter(align_to<16>(SSM->get_frame_size()));
139  enter.emit(CM);
140  // fix alignment
142  emit_nop(CF,CF.size());
143 }
144 
145 void X86_64LoweringVisitor::visit(LOADInst *I, bool copyOperands) {
146  assert(I);
147  //MachineInstruction *minst = loadParameter(I->get_index(), I->get_type());
149  //FIXME inefficient
150  const MachineMethodDescriptor MMD(MD);
151  Type::TypeID type = I->get_type();
152  VirtualRegister *dst = new VirtualRegister(type);
153  MachineInstruction *move = NULL;
154  switch (type) {
155  case Type::ByteTypeID:
156  case Type::ShortTypeID:
157  case Type::IntTypeID:
158  case Type::LongTypeID:
160  move = new MovInst(
161  SrcOp(MMD[I->get_index()]),
162  DstOp(dst),
164  break;
165  case Type::FloatTypeID:
166  move = new MovSSInst(
167  SrcOp(MMD[I->get_index()]),
168  DstOp(dst));
169  break;
170  case Type::DoubleTypeID:
171  move = new MovSDInst(
172  SrcOp(MMD[I->get_index()]),
173  DstOp(dst));
174  break;
175  default:
176  ABORT_MSG("x86_64 type not supported: ",
177  I << " type: " << type);
178  }
179  get_current()->push_back(move);
180  set_op(I,move->get_result().op);
181 }
182 
183 void X86_64LoweringVisitor::visit(CMPInst *I, bool copyOperands) {
184  assert(I);
185  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
186  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
187  Type::TypeID type = I->get_operand(0)->get_type();
188  assert(type == I->get_operand(1)->get_type());
189  switch (type) {
190  case Type::FloatTypeID:
191  case Type::DoubleTypeID:
192  {
193 
199  // unordered 0
200  MBB->push_back(new MovInst(
201  SrcOp(new Immediate(0,Type::IntType())),
202  DstOp(dst),
203  op_size
204  ));
205  // less then (1)
206  MBB->push_back(new MovInst(
207  SrcOp(new Immediate(1,Type::IntType())),
208  DstOp(less),
209  op_size
210  ));
211  // greater then (-1)
212  MBB->push_back(new MovInst(
213  SrcOp(new Immediate(-1,Type::IntType())),
214  DstOp(greater),
215  op_size
216  ));
217  // compare
218  switch (type) {
219  case Type::FloatTypeID:
220  MBB->push_back(new UCOMISSInst(Src2Op(src_op1), Src1Op(src_op2)));
221  break;
222  case Type::DoubleTypeID:
223  MBB->push_back(new UCOMISDInst(Src2Op(src_op1), Src1Op(src_op2)));
224  break;
225  default: assert(0);
226  break;
227  }
228  // cmov less
229  MBB->push_back(new CMovInst(
230  Cond::B,
231  DstSrc1Op(dst),
232  Src2Op(less),
233  op_size
234  ));
235  // cmov greater
236  MBB->push_back(new CMovInst(
237  Cond::A,
238  DstSrc1Op(dst),
239  Src2Op(greater),
240  op_size
241  ));
242  switch (I->get_FloatHandling()) {
243  case CMPInst::L:
244  // treat unordered as GT
245  MBB->push_back(new CMovInst(
246  Cond::P,
247  DstSrc1Op(dst),
248  Src2Op(greater),
249  op_size
250  ));
251  break;
252 
253  case CMPInst::G:
254  // treat unordered as LT
255  MBB->push_back(new CMovInst(
256  Cond::P,
257  DstSrc1Op(dst),
258  Src2Op(less),
259  op_size
260  ));
261  break;
262  default: assert(0);
263  break;
264  }
265  set_op(I,dst);
266  return;
267  }
268  default: break;
269  }
270  ABORT_MSG("x86_64: Lowering not supported",
271  "Inst: " << I << " type: " << type);
272 }
273 
274 void X86_64LoweringVisitor::visit(IFInst *I, bool copyOperands) {
275  assert(I);
276  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
277  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
278  Type::TypeID type = I->get_type();
279  switch (type) {
280  case Type::ByteTypeID:
281  case Type::IntTypeID:
282  case Type::LongTypeID:
283  {
284  // Integer types
285  CmpInst *cmp = new CmpInst(
286  Src2Op(src_op2),
287  Src1Op(src_op1),
289 
290  MachineInstruction *cjmp = NULL;
291  BeginInstRef &then = I->get_then_target();
292  BeginInstRef &els = I->get_else_target();
293 
294  switch (I->get_condition()) {
295  case Conditional::EQ:
296  cjmp = new CondJumpInst(Cond::E, get(then.get()),get(els.get()));
297  break;
298  case Conditional::LT:
299  cjmp = new CondJumpInst(Cond::L, get(then.get()),get(els.get()));
300  break;
301  case Conditional::LE:
302  cjmp = new CondJumpInst(Cond::LE, get(then.get()),get(els.get()));
303  break;
304  case Conditional::GE:
305  cjmp = new CondJumpInst(Cond::GE, get(then.get()),get(els.get()));
306  break;
307  case Conditional::GT:
308  cjmp = new CondJumpInst(Cond::G, get(then.get()),get(els.get()));
309  break;
310  case Conditional::NE:
311  cjmp = new CondJumpInst(Cond::NE, get(then.get()),get(els.get()));
312  break;
313  default:
314  ABORT_MSG("x86_64 Conditional not supported: ",
315  I << " cond: " << I->get_condition());
316  }
317  //MachineInstruction *jmp = new JumpInst(get(els.get()));
318  get_current()->push_back(cmp);
319  get_current()->push_back(cjmp);
320  //get_current()->push_back(jmp);
321 
322  set_op(I,cjmp->get_result().op);
323  return;
324  }
325  default: break;
326  }
327  ABORT_MSG("x86_64: Lowering not supported",
328  "Inst: " << I << " type: " << type);
329 }
330 
331 void X86_64LoweringVisitor::visit(NEGInst *I, bool copyOperands) {
332  assert(I);
334  Type::TypeID type = I->get_type();
336  //GPInstruction::OperandSize op_size = get_OperandSize_from_Type(type);
337 
338  VirtualRegister *dst = new VirtualRegister(type);
339 
340  switch (type) {
341  case Type::FloatTypeID:
342  MBB->push_back(new MovImmSSInst(
343  SrcOp(new Immediate(0x80000000,Type::IntType())),
344  DstOp(dst)
345  ));
346  MBB->push_back(new XORPSInst(
347  Src2Op(src),
348  DstSrc1Op(dst)
349  ));
350  break;
351  case Type::DoubleTypeID:
352  MBB->push_back(new MovImmSDInst(
353  SrcOp(new Immediate(0x8000000000000000L,Type::LongType())),
354  DstOp(dst)
355  ));
356  MBB->push_back(new XORPDInst(
357  Src2Op(src),
358  DstSrc1Op(dst)
359  ));
360  break;
361  case Type::IntTypeID:
362  case Type::LongTypeID:
363  MBB->push_back(get_Backend()->create_Move(src,dst));
365  break;
366  default:
367  ABORT_MSG("x86_64: Lowering not supported",
368  "Inst: " << I << " type: " << type);
369  }
370  set_op(I,dst);
371 }
372 
373 void X86_64LoweringVisitor::visit(ADDInst *I, bool copyOperands) {
374  assert(I);
375  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
376  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
377  Type::TypeID type = I->get_type();
378  VirtualRegister *dst = NULL;
379 
380  setupSrcDst(src_op1, src_op2, dst, type, copyOperands, I->is_commutable());
381 
382  MachineInstruction *alu = NULL;
383 
384  switch (type) {
385  case Type::ByteTypeID:
386  case Type::IntTypeID:
387  case Type::LongTypeID:
388  alu = new AddInst(
389  Src2Op(src_op2),
390  DstSrc1Op(dst),
392  break;
393  case Type::DoubleTypeID:
394  alu = new AddSDInst(
395  Src2Op(src_op2),
396  DstSrc1Op(dst));
397  break;
398  case Type::FloatTypeID:
399  alu = new AddSSInst(
400  Src2Op(src_op2),
401  DstSrc1Op(dst));
402  break;
403  default:
404  ABORT_MSG("x86_64: Lowering not supported",
405  "Inst: " << I << " type: " << type);
406  }
407  get_current()->push_back(alu);
408  set_op(I,alu->get_result().op);
409 }
410 
411 void X86_64LoweringVisitor::visit(ANDInst *I, bool copyOperands) {
412  assert(I);
413  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
414  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
415  Type::TypeID type = I->get_type();
416  VirtualRegister *dst = NULL;
417 
418  setupSrcDst(src_op1, src_op2, dst, type, copyOperands, I->is_commutable());
419 
420  MachineInstruction *alu = NULL;
421 
422  switch (type) {
423  case Type::ByteTypeID:
424  case Type::IntTypeID:
425  case Type::LongTypeID:
426  alu = new AndInst(
427  Src2Op(src_op2),
428  DstSrc1Op(dst),
430  break;
431  default:
432  ABORT_MSG("x86_64: Lowering not supported",
433  "Inst: " << I << " type: " << type);
434  }
435  get_current()->push_back(alu);
436  set_op(I,alu->get_result().op);
437 }
438 
439 void X86_64LoweringVisitor::visit(ORInst *I, bool copyOperands) {
440  assert(I);
441  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
442  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
443  Type::TypeID type = I->get_type();
444  VirtualRegister *dst = NULL;
445 
446  setupSrcDst(src_op1, src_op2, dst, type, copyOperands, I->is_commutable());
447 
448  MachineInstruction *alu = NULL;
449 
450  switch (type) {
451  case Type::ByteTypeID:
452  case Type::IntTypeID:
453  case Type::LongTypeID:
454  alu = new OrInst(
455  Src2Op(src_op2),
456  DstSrc1Op(dst),
458  break;
459  default:
460  ABORT_MSG("x86_64: Lowering not supported",
461  "Inst: " << I << " type: " << type);
462  }
463  get_current()->push_back(alu);
464  set_op(I,alu->get_result().op);
465 }
466 
467 void X86_64LoweringVisitor::visit(XORInst *I, bool copyOperands) {
468  assert(I);
469  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
470  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
471  Type::TypeID type = I->get_type();
472  VirtualRegister *dst = NULL;
473 
474  setupSrcDst(src_op1, src_op2, dst, type, copyOperands, I->is_commutable());
475 
476  MachineInstruction *alu = NULL;
477 
478  switch (type) {
479  case Type::ByteTypeID:
480  case Type::IntTypeID:
481  case Type::LongTypeID:
482  alu = new XorInst(
483  Src2Op(src_op2),
484  DstSrc1Op(dst),
486  break;
487  default:
488  ABORT_MSG("x86_64: Lowering not supported",
489  "Inst: " << I << " type: " << type);
490  }
491  get_current()->push_back(alu);
492  set_op(I,alu->get_result().op);
493 }
494 
495 void X86_64LoweringVisitor::visit(SUBInst *I, bool copyOperands) {
496  assert(I);
497  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
498  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
499  Type::TypeID type = I->get_type();
500  VirtualRegister *dst = NULL;
501 
502  setupSrcDst(src_op1, src_op2, dst, type, copyOperands, I->is_commutable());
503 
504  MachineInstruction *alu = NULL;
505 
506  switch (type) {
507  case Type::ByteTypeID:
508  case Type::IntTypeID:
509  case Type::LongTypeID:
510  alu = new SubInst(
511  Src2Op(src_op2),
512  DstSrc1Op(dst),
514  break;
515  case Type::DoubleTypeID:
516  alu = new SubSDInst(
517  Src2Op(src_op2),
518  DstSrc1Op(dst));
519  break;
520  case Type::FloatTypeID:
521  alu = new SubSSInst(
522  Src2Op(src_op2),
523  DstSrc1Op(dst));
524  break;
525  default:
526  ABORT_MSG("x86_64: Lowering not supported",
527  "Inst: " << I << " type: " << type);
528  }
529  get_current()->push_back(alu);
530  set_op(I,alu->get_result().op);
531 }
532 
533 void X86_64LoweringVisitor::visit(MULInst *I, bool copyOperands) {
534  assert(I);
535  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
536  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
537  Type::TypeID type = I->get_type();
538  VirtualRegister *dst = NULL;
539 
540  setupSrcDst(src_op1, src_op2, dst, type, copyOperands, I->is_commutable());
541 
542  MachineInstruction *alu = NULL;
543 
544  switch (type) {
545  case Type::ByteTypeID:
546  case Type::IntTypeID:
547  case Type::LongTypeID:
548  alu = new IMulInst(
549  Src2Op(src_op2),
550  DstSrc1Op(dst),
552  break;
553  case Type::DoubleTypeID:
554  alu = new MulSDInst(
555  Src2Op(src_op2),
556  DstSrc1Op(dst));
557  break;
558  case Type::FloatTypeID:
559  alu = new MulSSInst(
560  Src2Op(src_op2),
561  DstSrc1Op(dst));
562  break;
563  default:
564  ABORT_MSG("x86_64: Lowering not supported",
565  "Inst: " << I << " type: " << type);
566  }
567  get_current()->push_back(alu);
568  set_op(I,alu->get_result().op);
569 }
570 
571 void X86_64LoweringVisitor::visit(DIVInst *I, bool copyOperands) {
572  assert(I);
573  MachineOperand* src_op1 = get_op(I->get_operand(0)->to_Instruction());
574  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
575  Type::TypeID type = I->get_type();
577 
578  MachineInstruction *alu = NULL;
579 
580  switch (type) {
581  case Type::IntTypeID:
582  case Type::LongTypeID:
583  {
584  // 1. move the dividend to RAX
585  // 2. extend the dividend to RDX:RAX
586  // 3. perform the division
587  MachineOperand *dividendUpper = new NativeRegister(type, &RDX);
588  MachineOperand *result = new NativeRegister(type, &RAX);
589  MachineInstruction *convertToQuadword = new CDQInst(DstSrc1Op(dividendUpper), DstSrc2Op(result), opsize);
590  get_current()->push_back(get_Backend()->create_Move(src_op1, result));
591  get_current()->push_back(convertToQuadword);
592  alu = new IDivInst(Src2Op(src_op2), DstSrc1Op(result), DstSrc2Op(dividendUpper), opsize);
593  break;
594  }
595  case Type::DoubleTypeID:
596  {
597  VirtualRegister *dst = new VirtualRegister(type);
598  MachineInstruction *mov = get_Backend()->create_Move(src_op1, dst);
599  get_current()->push_back(mov);
600  alu = new DivSDInst(
601  Src2Op(src_op2),
602  DstSrc1Op(dst));
603  break;
604  }
605  case Type::FloatTypeID:
606  {
607  VirtualRegister *dst = new VirtualRegister(type);
608  MachineInstruction *mov = get_Backend()->create_Move(src_op1, dst);
609  get_current()->push_back(mov);
610  alu = new DivSSInst(
611  Src2Op(src_op2),
612  DstSrc1Op(dst));
613  break;
614  }
615  default:
616  ABORT_MSG("x86_64: Lowering not supported",
617  "Inst: " << I << " type: " << type);
618  }
619 
620  get_current()->push_back(alu);
621  set_op(I,alu->get_result().op);
622 }
623 
624 void X86_64LoweringVisitor::visit(REMInst *I, bool copyOperands) {
625  assert(I);
626 
627  MachineOperand* dividendLower;
628  MachineOperand* src_op2 = get_op(I->get_operand(1)->to_Instruction());
629  Type::TypeID type = I->get_type();
631  MachineOperand *dividend = get_op(I->get_operand(0)->to_Instruction());;
632 
633  MachineInstruction *resultInst = NULL;
634  MachineOperand *resultOperand;
635  MachineInstruction *convertToQuadword;
636 
637  StackSlotManager *ssm;
638  ManagedStackSlot *src;
639  ManagedStackSlot *dst;
640  ManagedStackSlot *resultSlot;
641 
642  switch (type) {
643  case Type::IntTypeID:
644  case Type::LongTypeID:
645 
646  // 1. move the dividend to RAX
647  // 2. extend the dividend to RDX:RAX
648  // 3. perform the division
649  resultOperand = new NativeRegister(type, &RDX);
650  dividendLower = new NativeRegister(type, &RAX);
651  convertToQuadword = new CDQInst(DstSrc1Op(dividendLower), DstSrc2Op(resultOperand), opsize);
652  get_current()->push_back(get_Backend()->create_Move(dividend, dividendLower));
653  get_current()->push_back(convertToQuadword);
654  resultInst = new IDivInst(Src2Op(src_op2), DstSrc1Op(resultOperand), DstSrc2Op(dividendLower), opsize);
655  get_current()->push_back(resultInst);
656  break;
657  case Type::FloatTypeID:
658  case Type::DoubleTypeID:
660  src = ssm->create_ManagedStackSlot(type);
661  dst = ssm->create_ManagedStackSlot(type);
662  resultSlot = ssm->create_ManagedStackSlot(type);
663 
664  // operands of the FP stack can only be loaded from memory
665  get_current()->push_back(get_Backend()->create_Move(dividend, src));
666  get_current()->push_back(get_Backend()->create_Move(src_op2, dst));
667 
668  // initialize the FP stack
669  get_current()->push_back(new FLDInst(SrcMemOp(dst), opsize));
670  get_current()->push_back(new FLDInst(SrcMemOp(src), opsize));
671 
672  get_current()->push_back(new FPRemInst(opsize));
673  resultInst = new FSTPInst(DstMemOp(resultSlot), opsize);
674  get_current()->push_back(resultInst);
675 
676  // clean the FP stack
679  break;
680  default:
681  ABORT_MSG("x86_64: Lowering not supported",
682  "Inst: " << I << " type: " << type);
683  }
684 
685  set_op(I,resultInst->get_result().op);
686 }
687 
688 void X86_64LoweringVisitor::visit(AREFInst *I, bool copyOperands) {
689  // Only emit Instructions if Pattern Matching is used. If not ASTOREInst/ALOADInst will handle everything
690 #if 0
691 //#ifdef PATTERN_MATCHING // won't currently work because if base or index are modified, AREF should be modified instead/aswell.
692  assert(I);
693  MachineOperand* src_ref = get_op(I->get_operand(0)->to_Instruction());
694  MachineOperand* src_index = get_op(I->get_operand(1)->to_Instruction());
695  assert(src_ref->get_type() == Type::ReferenceTypeID);
696  assert(src_index->get_type() == Type::IntTypeID);
697 
698  Type::TypeID type = I->get_type();
699 
701 
702  s4 offset;
703  switch (type) {
704  case Type::ByteTypeID:
705  offset = OFFSET(java_bytearray_t, data[0]);
706  break;
707  case Type::ShortTypeID:
708  offset = OFFSET(java_shortarray_t, data[0]);
709  break;
710  case Type::IntTypeID:
711  offset = OFFSET(java_intarray_t, data[0]);
712  break;
713  case Type::LongTypeID:
714  offset = OFFSET(java_longarray_t, data[0]);
715  break;
716  case Type::FloatTypeID:
717  offset = OFFSET(java_floatarray_t, data[0]);
718  break;
719  case Type::DoubleTypeID:
720  offset = OFFSET(java_doublearray_t, data[0]);
721  break;
723  offset = OFFSET(java_objectarray_t, data[0]);
724  break;
725  default:
726  ABORT_MSG("x86_64 Lowering not supported",
727  "Inst: " << I << " type: " << type);
728  offset = 0;
729  }
730 
731  // create modrm source operand
732  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(src_ref),IndexOp(src_index),type,offset);
734  get_current()->push_back(lea);
735  set_op(I,lea->get_result().op);
736 #endif
737 }
738 
739 void X86_64LoweringVisitor::visit(ALOADInst *I, bool copyOperands) {
740  assert(I);
741  Type::TypeID type = I->get_type();
742  Instruction* ref_inst = I->get_operand(0)->to_Instruction();
743  MachineOperand *vreg = new VirtualRegister(type);
744  MachineOperand *modrm = NULL;
745 
746  // if Pattern Matching is used, src op is Register with Effective Address , otherwise src op is AREFInst
747 #if 0
748 //#ifdef PATTERN_MATCHING // won't currently work because if base or index are modified, AREF should be modified instead/aswell.
749  MachineOperand* src_ref = get_op(ref_inst);
750  assert(src_ref->get_type() == Type::ReferenceTypeID);
751 
752  modrm = new X86_64ModRMOperand(BaseOp(src_ref));
753 #else
754  MachineOperand* src_base = get_op(ref_inst->get_operand(0)->to_Instruction());
755  assert(src_base->get_type() == Type::ReferenceTypeID);
756  MachineOperand* src_index = get_op(ref_inst->get_operand(1)->to_Instruction());
757  assert(src_index->get_type() == Type::IntTypeID);
758 
759  s4 offset;
760  switch (type) {
761  case Type::ByteTypeID:
762  offset = OFFSET(java_bytearray_t, data[0]);
763  break;
764  case Type::ShortTypeID:
765  offset = OFFSET(java_shortarray_t, data[0]);
766  break;
767  case Type::IntTypeID:
768  offset = OFFSET(java_intarray_t, data[0]);
769  break;
770  case Type::LongTypeID:
771  offset = OFFSET(java_longarray_t, data[0]);
772  break;
773  case Type::FloatTypeID:
774  offset = OFFSET(java_floatarray_t, data[0]);
775  break;
776  case Type::DoubleTypeID:
777  offset = OFFSET(java_doublearray_t, data[0]);
778  break;
780  offset = OFFSET(java_objectarray_t, data[0]);
781  break;
782  default:
783  ABORT_MSG("x86_64 Lowering not supported",
784  "Inst: " << I << " type: " << type);
785  offset = 0;
786  }
787 
788  modrm = new X86_64ModRMOperand(BaseOp(src_base),IndexOp(src_index),type,offset);
789 #endif
790  MachineInstruction *move = NULL;
791 
792  switch (type) {
793  case Type::CharTypeID:
794  case Type::ByteTypeID:
795  case Type::ShortTypeID:
796  case Type::IntTypeID:
797  case Type::LongTypeID:
799  move = new MovInst(SrcOp(modrm),DstOp(vreg),get_OperandSize_from_Type(type));
800  break;
801  case Type::FloatTypeID:
802  move = new MovSSInst(SrcOp(modrm),DstOp(vreg));
803  break;
804  case Type::DoubleTypeID:
805  move = new MovSDInst(SrcOp(modrm),DstOp(vreg));
806  break;
807  default:
808  ABORT_MSG("x86_64 Lowering not supported",
809  "Inst: " << I << " type: " << type);
810  }
811 
812  get_current()->push_back(move);
813  set_op(I,move->get_result().op);
814 }
815 
816 void X86_64LoweringVisitor::visit(ASTOREInst *I, bool copyOperands) {
817  assert(I);
818  Instruction* ref_inst = I->get_operand(0)->to_Instruction();
819  MachineOperand* src_value = get_op(I->get_operand(1)->to_Instruction());
820  Type::TypeID type = src_value->get_type();
821  MachineOperand *modrm = NULL;
822  MachineInstruction *move = NULL;
823 
824  // if Pattern Matching is used, src op is Register with Effective Address , otherwise src op is AREFInst
825 #if 0
826 //#ifdef PATTERN_MATCHING // won't currently work because if base or index are modified, AREF should be modified instead/aswell.
827  MachineOperand* src_ref = get_op(ref_inst);
828  assert(src_ref->get_type() == Type::ReferenceTypeID);
829 
830  modrm = new X86_64ModRMOperand(BaseOp(src_ref));
831 #else
832  MachineOperand* src_base = get_op(ref_inst->get_operand(0)->to_Instruction());
833  assert(src_base->get_type() == Type::ReferenceTypeID);
834  MachineOperand* src_index = get_op(ref_inst->get_operand(1)->to_Instruction());
835  assert(src_index->get_type() == Type::IntTypeID);
836 
837  s4 offset;
838  switch (type) {
839  case Type::ByteTypeID:
840  offset = OFFSET(java_bytearray_t, data[0]);
841  break;
842  case Type::ShortTypeID:
843  offset = OFFSET(java_shortarray_t, data[0]);
844  break;
845  case Type::IntTypeID:
846  offset = OFFSET(java_intarray_t, data[0]);
847  break;
848  case Type::LongTypeID:
849  offset = OFFSET(java_longarray_t, data[0]);
850  break;
851  case Type::FloatTypeID:
852  offset = OFFSET(java_floatarray_t, data[0]);
853  break;
854  case Type::DoubleTypeID:
855  offset = OFFSET(java_doublearray_t, data[0]);
856  break;
858  offset = OFFSET(java_objectarray_t, data[0]);
859  break;
860  default:
861  ABORT_MSG("x86_64 Lowering not supported",
862  "Inst: " << I << " type: " << type);
863  offset = 0;
864  }
865 
866  modrm = new X86_64ModRMOperand(BaseOp(src_base),IndexOp(src_index),type,offset);
867 #endif
868  switch (type) {
869  case Type::CharTypeID:
870  case Type::ByteTypeID:
871  case Type::ShortTypeID:
872  case Type::IntTypeID:
873  case Type::LongTypeID:
875  move = new MovInst(SrcOp(src_value),DstOp(modrm),get_OperandSize_from_Type(type));
876  break;
877  case Type::FloatTypeID:
878  move = new MovSSInst(SrcOp(src_value),DstOp(modrm));
879  break;
880  case Type::DoubleTypeID:
881  move = new MovSDInst(SrcOp(src_value),DstOp(modrm));
882  break;
883  default:
884  ABORT_MSG("x86_64 Lowering not supported",
885  "Inst: " << I << " type: " << type);
886  }
887  get_current()->push_back(move);
888  set_op(I,move->get_result().op);
889 }
890 
891 void X86_64LoweringVisitor::visit(ARRAYLENGTHInst *I, bool copyOperands) {
892  assert(I);
893  MachineOperand* src_op = get_op(I->get_operand(0)->to_Instruction());
894  assert(I->get_type() == Type::IntTypeID);
895  assert(src_op->get_type() == Type::ReferenceTypeID);
897  // create modrm source operand
899  MachineInstruction *move = new MovInst(SrcOp(modrm)
900  ,DstOp(vreg)
902  );
903  get_current()->push_back(move);
904  set_op(I,move->get_result().op);
905 }
906 
908  assert(I);
909  MachineOperand* src_ref = get_op(I->get_operand(0)->to_Instruction());
910  MachineOperand* src_index = get_op(I->get_operand(1)->to_Instruction());
911  assert(src_ref->get_type() == Type::ReferenceTypeID);
912  assert(src_index->get_type() == Type::IntTypeID);
913 
914  // load array length
917  MachineInstruction *move = new MovInst(SrcOp(modrm)
918  ,DstOp(len)
920  );
921  get_current()->push_back(move);
922  // compare with index
923  CmpInst *cmp = new CmpInst(
924  Src2Op(len),
925  Src1Op(src_index),
927  get_current()->push_back(cmp);
928  // throw exception
930  get_current()->push_back(trap);
931 }
932 
933 void X86_64LoweringVisitor::visit(RETURNInst *I, bool copyOperands) {
934  assert(I);
935  Type::TypeID type = I->get_type();
936  MachineOperand* src_op = (type == Type::VoidTypeID ? 0 : get_op(I->get_operand(0)->to_Instruction()));
937  switch (type) {
938  case Type::CharTypeID:
939  case Type::ByteTypeID:
940  case Type::ShortTypeID:
941  case Type::IntTypeID:
942  case Type::LongTypeID:
943  {
944  MachineOperand *ret_reg = new NativeRegister(type,&RAX);
945  MachineInstruction *reg = new MovInst(
946  SrcOp(src_op),
947  DstOp(ret_reg),
949  LeaveInst *leave = new LeaveInst();
950  RetInst *ret = new RetInst(get_OperandSize_from_Type(type),SrcOp(ret_reg));
951  get_current()->push_back(reg);
952  get_current()->push_back(leave);
953  get_current()->push_back(ret);
954  set_op(I,ret->get_result().op);
955  return;
956  }
957  case Type::FloatTypeID:
958  {
959  MachineOperand *ret_reg = new NativeRegister(type,&XMM0);
960  MachineInstruction *reg = new MovSSInst(
961  SrcOp(src_op),
962  DstOp(ret_reg));
963  LeaveInst *leave = new LeaveInst();
964  RetInst *ret = new RetInst(get_OperandSize_from_Type(type),SrcOp(ret_reg));
965  get_current()->push_back(reg);
966  get_current()->push_back(leave);
967  get_current()->push_back(ret);
968  set_op(I,ret->get_result().op);
969  return;
970  }
971  case Type::DoubleTypeID:
972  {
973  MachineOperand *ret_reg = new NativeRegister(type,&XMM0);
974  MachineInstruction *reg = new MovSDInst(
975  SrcOp(src_op),
976  DstOp(ret_reg));
977  LeaveInst *leave = new LeaveInst();
978  RetInst *ret = new RetInst(get_OperandSize_from_Type(type),SrcOp(ret_reg));
979  get_current()->push_back(reg);
980  get_current()->push_back(leave);
981  get_current()->push_back(ret);
982  set_op(I,ret->get_result().op);
983  return;
984  }
985  case Type::VoidTypeID:
986  {
987  LeaveInst *leave = new LeaveInst();
988  RetInst *ret = new RetInst();
989  get_current()->push_back(leave);
990  get_current()->push_back(ret);
991  set_op(I,ret->get_result().op);
992  return;
993  }
994 
996  // TODO: implement
997  default: break;
998  }
999  ABORT_MSG("x86_64 Lowering not supported",
1000  "Inst: " << I << " type: " << type);
1001 }
1002 
1003 void X86_64LoweringVisitor::visit(CASTInst *I, bool copyOperands) {
1004  assert(I);
1005  MachineOperand* src_op = get_op(I->get_operand(0)->to_Instruction());
1007  Type::TypeID to = I->get_type();
1008 
1009  switch (from) {
1010  case Type::IntTypeID:
1011  {
1012  switch (to) {
1013  case Type::ByteTypeID:
1014  {
1015  MachineInstruction *mov = new MovSXInst(SrcOp(src_op), DstOp(new VirtualRegister(to)),
1017  get_current()->push_back(mov);
1018  set_op(I, mov->get_result().op);
1019  return;
1020  }
1021  case Type::CharTypeID:
1022  case Type::ShortTypeID:
1023  {
1024  MachineInstruction *mov = new MovSXInst(SrcOp(src_op), DstOp(new VirtualRegister(to)),
1026  get_current()->push_back(mov);
1027  set_op(I, mov->get_result().op);
1028  return;
1029  }
1030  case Type::LongTypeID:
1031  {
1032  MachineInstruction *mov = new MovSXInst(
1033  SrcOp(src_op),
1034  DstOp(new VirtualRegister(to)),
1036  get_current()->push_back(mov);
1037  set_op(I,mov->get_result().op);
1038  return;
1039  }
1040  case Type::DoubleTypeID:
1041  {
1043  MachineInstruction *clearResult = new MovImmSDInst(SrcOp(new Immediate(0, Type::DoubleType())), DstOp(result));
1044  MachineInstruction *conversion = new CVTSI2SDInst(
1045  SrcOp(src_op),
1046  DstOp(result),
1048  get_current()->push_back(clearResult);
1049  get_current()->push_back(conversion);
1050  set_op(I,conversion->get_result().op);
1051  return;
1052  }
1053  case Type::FloatTypeID:
1054  {
1055  MachineInstruction *mov = new CVTSI2SSInst(
1056  SrcOp(src_op),
1057  DstOp(new VirtualRegister(to)),
1059  get_current()->push_back(mov);
1060  set_op(I,mov->get_result().op);
1061  return;
1062  }
1063  default:
1064  break;
1065  }
1066  break;
1067  }
1068  case Type::LongTypeID:
1069  {
1070  switch (to) {
1071  case Type::IntTypeID:
1072  {
1073  // force a 32bit move to cut the upper byte
1075  get_current()->push_back(mov);
1076  set_op(I, mov->get_result().op);
1077  return;
1078  }
1079  case Type::DoubleTypeID:
1080  {
1081  MachineInstruction *mov = new CVTSI2SDInst(
1082  SrcOp(src_op),
1083  DstOp(new VirtualRegister(to)),
1085  get_current()->push_back(mov);
1086  set_op(I,mov->get_result().op);
1087  return;
1088  }
1089  case Type::FloatTypeID:
1090  {
1091  MachineInstruction *mov = new CVTSI2SSInst(
1092  SrcOp(src_op),
1093  DstOp(new VirtualRegister(to)),
1095  get_current()->push_back(mov);
1096  set_op(I,mov->get_result().op);
1097  return;
1098  }
1099  default:
1100  break;
1101  }
1102 
1103  break;
1104  }
1105 
1106  case Type::DoubleTypeID:
1107  {
1108  switch (to) {
1109 
1110  case Type::IntTypeID:
1111  {
1112  // TODO: currently this is replaced by the stackanalysis pass with ICMD_BUILTIN and therefore implemented
1113  // in a builtin function
1114  }
1115  case Type::LongTypeID:
1116  {
1117  // TODO: currently this is replaced by the stackanalysis pass with ICMD_BUILTIN and therefore implemented
1118  // in a builtin function
1119  }
1120  case Type::FloatTypeID:
1121  {
1122  MachineInstruction *mov = new CVTSD2SSInst(
1123  SrcOp(src_op),
1124  DstOp(new VirtualRegister(to)),
1126  get_current()->push_back(mov);
1127  set_op(I,mov->get_result().op);
1128  return;
1129  }
1130  default:
1131  break;
1132  }
1133  break;
1134  }
1135  case Type::FloatTypeID:
1136  {
1137  switch(to) {
1138 
1139  case Type::IntTypeID:
1140  {
1141  // TODO: currently this is replaced by the stackanalysis pass with ICMD_BUILTIN and therefore implemented
1142  // in a builtin function
1143  }
1144  case Type::LongTypeID:
1145  {
1146  // TODO: currently this is replaced by the stackanalysis pass with ICMD_BUILTIN and therefore implemented
1147  // in a builtin function
1148  }
1149  case Type::DoubleTypeID:
1150  {
1151  MachineInstruction *mov = new CVTSS2SDInst(
1152  SrcOp(src_op),
1153  DstOp(new VirtualRegister(to)),
1155  get_current()->push_back(mov);
1156  set_op(I,mov->get_result().op);
1157  return;
1158  }
1159  default:
1160  break;
1161  }
1162  break;
1163  }
1164  default:
1165  break;
1166  }
1167 
1168  ABORT_MSG("x86_64 Cast not supported!", "From " << from << " to " << to );
1169 }
1170 
1172  assert(I);
1173  Type::TypeID type = I->get_type();
1175  MachineMethodDescriptor MMD(MD);
1176 
1177  // operands for the call
1179  MachineOperand *result = &NoOperand;
1180 
1181  // get return value
1182  switch (type) {
1183  case Type::IntTypeID:
1184  case Type::LongTypeID:
1185  result = new NativeRegister(type,&RAX);
1186  break;
1187  default:
1188  ABORT_MSG("x86_64 Lowering not supported",
1189  "Inst: " << I << " type: " << type);
1190  }
1191 
1192  // create call
1193  MachineInstruction* call = new CallInst(SrcOp(addr),DstOp(result),I->op_size());
1194  // move values to parameters
1195  for (std::size_t i = 0; i < I->op_size(); ++i ) {
1197  new UnassignedReg(MD[i]),
1198  MMD[i]
1199  );
1200  get_current()->push_back(mov);
1201  // set call operand
1202  call->set_operand(i+1,MMD[i]);
1203  }
1204  // spill caller saved
1205 
1206  // load address
1208  DataSegment::IdxTy idx = DS.get_index(DSFMIRef(I->get_fmiref()));
1209  if (DataSegment::is_invalid(idx)) {
1210  DataFragment data = DS.get_Ref(sizeof(void*));
1211  idx = DS.insert_tag(DSFMIRef(I->get_fmiref()),data);
1212  }
1213  if (I->is_resolved()) {
1214  LOG2("INVOKESTATICInst: is resolved" << nl);
1215  // write stubroutine
1216  //methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
1217  //lm = I->get_fmiref()->p.method;
1218  //lm->stubroutine;
1219  } else {
1220  LOG2("INVOKESTATICInst: is notresolved" << nl);
1221  }
1222  MovDSEGInst *dmov = new MovDSEGInst(DstOp(addr),idx);
1223  get_current()->push_back(dmov);
1224 
1225  // add call
1226  get_current()->push_back(call);
1227  // get result
1228  if (result != &NoOperand) {
1229  MachineInstruction *reg = new MovInst(
1230  SrcOp(result),
1231  DstOp(new VirtualRegister(type)),
1233  get_current()->push_back(reg);
1234  set_op(I,reg->get_result().op);
1235  }
1236  #if 0
1237  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1238  unresolved_method* um;
1239  um = iptr->sx.s23.s3.um;
1240  disp = dseg_add_unique_address(cd, um);
1241 
1243  um, disp);
1244  }
1245  else {
1246  methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
1247  lm = iptr->sx.s23.s3.fmiref->p.method;
1248  disp = dseg_add_functionptr(cd, lm->stubroutine);
1249  }
1250  #endif
1251 }
1252 namespace {
1253 
1254 template <class I,class Seg>
1255 static void write_data(Seg seg, I data) {
1256  assert(seg.size() == sizeof(I));
1257 
1258  for (int i = 0, e = sizeof(I) ; i < e ; ++i) {
1259  seg[i] = (u1) 0xff & *(reinterpret_cast<u1*>(&data) + i);
1260  }
1261 
1262 }
1263 } // end anonymous namespace
1264 
1265 void X86_64LoweringVisitor::visit(GETSTATICInst *I, bool copyOperands) {
1266  assert(I);
1268  constant_FMIref* fmiref = I->get_fmiref();
1269  DataSegment::IdxTy idx = DS.get_index(DSFMIRef(fmiref));
1270  size_t size = sizeof(void*);
1271  if (DataSegment::is_invalid(idx)) {
1272  DataFragment datafrag = DS.get_Ref(size);
1273  idx = DS.insert_tag(DSFMIRef(fmiref), datafrag);
1274  }
1275 
1276  if (I->is_resolved()) {
1277  fieldinfo* fi = I->get_fmiref()->p.field;
1278 
1280  //PROFILE_CYCLE_STOP;
1281  Patcher *patcher = new InitializeClassPatcher(fi->clazz);
1282  PatcherPtrTy ptr(patcher);
1283  get_Backend()->get_JITData()->get_jitdata()->code->patchers->push_back(ptr);
1284  MachineInstruction *pi = new PatchInst(patcher);
1285  get_current()->push_back(pi);
1286  //PROFILE_CYCLE_START;
1287  }
1288  DataFragment datafrag = DS.get_Ref(idx, size);
1289  // write data
1290  write_data<void*>(datafrag, fmiref->p.field->value);
1291  } else {
1292  assert(0 && "Not yet implemented");
1293  #if 0
1294  unresolved_field* uf = iptr->sx.s23.s3.uf;
1295  fieldtype = uf->fieldref->parseddesc.fd->type;
1296  disp = dseg_add_unique_address(cd, 0);
1297 
1298  pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1299 
1300  fi = NULL; /* Silence compiler warning */
1301  #endif
1302  }
1304  MovDSEGInst *dmov = new MovDSEGInst(DstOp(addr),idx);
1305  MachineOperand *vreg = new VirtualRegister(I->get_type());
1306  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(addr));
1307  MachineInstruction *mov;
1308  switch (I->get_type()) {
1309  case Type::CharTypeID:
1310  case Type::ByteTypeID:
1311  case Type::ShortTypeID:
1312  case Type::IntTypeID:
1313  case Type::LongTypeID:
1314  case Type::ReferenceTypeID:
1315  mov = new MovInst(SrcOp(modrm),DstOp(vreg),get_OperandSize_from_Type(I->get_type()));
1316  break;
1317  case Type::FloatTypeID:
1318  mov = new MovSSInst(SrcOp(modrm),DstOp(vreg));
1319  break;
1320  case Type::DoubleTypeID:
1321  mov = new MovSDInst(SrcOp(modrm),DstOp(vreg));
1322  break;
1323  default:
1324  ABORT_MSG("x86_64 Lowering not supported",
1325  "Inst: " << I << " type: " << I->get_type());
1326  }
1327  get_current()->push_back(dmov);
1328  get_current()->push_back(mov);
1329  set_op(I,mov->get_result().op);
1330 }
1331 
1333  assert(I);
1334  MachineOperand* src_op = get_op(I->get_operand(0)->to_Instruction());
1335  Type::TypeID type = I->get_type();
1336 
1339  e = I->match_end(); i != e; ++i) {
1340  // create compare
1341  CmpInst *cmp = new CmpInst(
1342  Src2Op(new Immediate(*i,Type::IntType())),
1343  Src1Op(src_op),
1345  get_current()->push_back(cmp);
1346  // create new block
1347  MachineBasicBlock *then_block = get(s->get());
1348  MachineBasicBlock *else_block = new_block();
1349  assert(else_block);
1350  else_block->insert_pred(get_current());
1351  else_block->push_front(new MachineLabelInst());
1352  // create cond jump
1353  MachineInstruction *cjmp = new CondJumpInst(Cond::E, then_block, else_block);
1354  get_current()->push_back(cjmp);
1355  // set current
1356  set_current(else_block);
1357  ++s;
1358  }
1359 
1360  // default
1361  MachineInstruction *jmp = new JumpInst(get(s->get()));
1362  get_current()->push_back(jmp);
1363  assert(++s == I->succ_end());
1364 
1365  set_op(I,jmp->get_result().op);
1366 }
1367 
1369  assert_msg(0 , "Fix CondJump");
1370  assert(I);
1371  MachineOperand* src_op = get_op(I->get_operand(0)->to_Instruction());
1372  Type::TypeID type = I->get_type();
1373  VirtualRegister *src = new VirtualRegister(type);
1374  MachineInstruction *mov = get_Backend()->create_Move(src_op, src);
1375  get_current()->push_back(mov);
1376 
1377  s4 low = I->get_low();
1378  s4 high = I->get_high();
1379 
1380  // adjust offset
1381  if (low != 0) {
1382  SubInst *sub = new SubInst(
1383  Src2Op(new Immediate(low,Type::IntType())),
1384  DstSrc1Op(src),
1386  );
1387  get_current()->push_back(sub);
1388  high -= low;
1389  }
1390  // check range
1391  CmpInst *cmp = new CmpInst(
1392  Src2Op(new Immediate(high,Type::IntType())),
1393  Src1Op(src),
1395  MachineInstruction *cjmp = new CondJumpInst(Cond::G, get(I->succ_front().get()),get((++I->succ_begin())->get()));
1396  get_current()->push_back(cmp);
1397  get_current()->push_back(cjmp);
1398 
1399  // TODO load data segment and jump
1400  // load address
1402  DataFragment data = DS.get_Ref(sizeof(void*) * (high - low + 1));
1403  DataSegment::IdxTy idx = data.get_begin();
1405  WARNING_MSG("TODO","add offset");
1406  MovDSEGInst *dmov = new MovDSEGInst(DstOp(addr),idx);
1407  get_current()->push_back(dmov);
1408  IndirectJumpInst *jmp = new IndirectJumpInst(SrcOp(addr));
1409  // adding targets
1411  e = I->succ_end(); i != e; ++i) {
1412  jmp->add_target(get(i->get()));
1413  }
1414  get_current()->push_back(jmp);
1415  // assert(0 && "load data segment and jump"));
1416  // load table entry
1417  set_op(I,cjmp->get_result().op);
1418 }
1419 
1421 
1422  switch(ruleId){
1423  case AddImmImm:
1424  {
1425  assert(I);
1426  Type::TypeID type = I->get_type();
1427  CONSTInst* const_left = I->get_operand(0)->to_Instruction()->to_CONSTInst();
1428  CONSTInst* const_right = I->get_operand(1)->to_Instruction()->to_CONSTInst();
1429 
1430  Immediate *imm = NULL;
1431  switch (type) {
1432  case Type::IntTypeID:
1433  {
1434  s4 val = const_left->get_Int() + const_right->get_Int();
1435  imm = new Immediate(val, Type::IntType());
1436  break;
1437  }
1438  case Type::LongTypeID:
1439  {
1440  s8 val = const_left->get_Long() + const_right->get_Long();
1441  imm = new Immediate(val, Type::LongType());
1442  break;
1443  }
1444  case Type::FloatTypeID:
1445  {
1446  float val = const_left->get_Float() + const_right->get_Float();
1447  imm = new Immediate(val, Type::FloatType());
1448  break;
1449  }
1450  case Type::DoubleTypeID:
1451  {
1452  double val = const_left->get_Double() + const_right->get_Double();
1453  imm = new Immediate(val, Type::DoubleType());
1454  break;
1455  }
1456  default:
1457  assert(0);
1458  break;
1459  }
1460 
1461  VirtualRegister *reg = new VirtualRegister(I->get_type());
1462  MachineInstruction *move = get_Backend()->create_Move(imm,reg);
1463  get_current()->push_back(move);
1464  set_op(I,move->get_result().op);
1465  break;
1466  }
1467  // all immediates should be second operand, see ssa construction pass
1468  case AddRegImm:
1469  { // todo: copyOperands?!?
1470  // todo: extend pattern to not rely on data type, instead check if const fits into imm encoding
1471  assert(I);
1472  Type::TypeID type = I->get_type();
1473 
1474  MachineOperand* src_op = get_op(I->get_operand(0)->to_Instruction());
1475  Immediate* const_op = new Immediate(I->get_operand(1)->to_Instruction()->to_CONSTInst());
1476 
1477  VirtualRegister *dst = new VirtualRegister(type);
1478  MachineInstruction *mov = get_Backend()->create_Move(src_op,dst);
1479 
1480  MachineInstruction *alu = NULL;
1481 
1482  switch (type) {
1483  case Type::ByteTypeID:
1484  case Type::IntTypeID:
1485  case Type::LongTypeID:
1486  alu = new AddInst(
1487  Src2Op(const_op),
1488  DstSrc1Op(dst),
1490  break;
1491  default:
1492  ABORT_MSG("x86_64: AddImm Lowering not supported",
1493  "Inst: " << I << " type: " << type);
1494  }
1495  get_current()->push_back(mov);
1496  get_current()->push_back(alu);
1497  set_op(I,alu->get_result().op);
1498 
1499  break;
1500 
1501  }
1502  case SubRegImm:
1503  {
1504  assert(I);
1505  Type::TypeID type = I->get_type();
1506 
1507  MachineOperand* src_op = get_op(I->get_operand(0)->to_Instruction());
1508  Immediate* const_op = new Immediate(I->get_operand(1)->to_Instruction()->to_CONSTInst());
1509 
1510  VirtualRegister *dst = new VirtualRegister(type);
1511  MachineInstruction *mov = get_Backend()->create_Move(src_op,dst);
1512  MachineInstruction *alu = NULL;
1513 
1514  switch (type) {
1515  case Type::ByteTypeID:
1516  case Type::IntTypeID:
1517  case Type::LongTypeID:
1518  alu = new SubInst(
1519  Src2Op(const_op),
1520  DstSrc1Op(dst),
1522  break;
1523  default:
1524  ABORT_MSG("x86_64: SubRegImm Lowering not supported",
1525  "Inst: " << I << " type: " << type);
1526  }
1527  get_current()->push_back(mov);
1528  get_current()->push_back(alu);
1529  set_op(I,alu->get_result().op);
1530  break;
1531  }
1532  case MulRegImm:
1533  {
1534  // todo: copyOperands?!?
1535  // todo: 3operand version!
1536  assert(I);
1537  Type::TypeID type = I->get_type();
1538 
1539  MachineOperand* src_op = get_op(I->get_operand(0)->to_Instruction());
1540  Immediate* const_op = new Immediate(I->get_operand(1)->to_Instruction()->to_CONSTInst());
1541 
1542  VirtualRegister *dst = new VirtualRegister(type);
1543 
1544  MachineInstruction *alu = NULL;
1545 
1546  switch (type) {
1547  case Type::ByteTypeID:
1548  case Type::IntTypeID:
1549  case Type::LongTypeID:
1550  alu = new IMulImmInst(
1551  Src1Op(src_op),
1552  Src2Op(const_op),
1553  DstOp(dst),
1555  break;
1556  default:
1557  ABORT_MSG("x86_64: MulImm Lowering not supported",
1558  "Inst: " << I << " type: " << type);
1559  }
1560  get_current()->push_back(alu);
1561  set_op(I,alu->get_result().op);
1562 
1563  break;
1564  }
1565  // LEA
1566  case BaseIndexDisplacement:
1567  {
1568  /*
1569  ADDInstID
1570  ADDInstID
1571  stm, // base
1572  stm // index
1573  CONSTInstID // disp
1574  */
1575  assert(I);
1576  Type::TypeID type = I->get_type();
1577 
1578  Instruction* nested_add = I->get_operand(0)->to_Instruction();
1579  MachineOperand* base = get_op(nested_add->get_operand(0)->to_Instruction());
1580  MachineOperand* index = get_op(nested_add->get_operand(1)->to_Instruction());
1581 
1582  CONSTInst* displacement = I->get_operand(1)->to_Instruction()->to_CONSTInst();
1583  VirtualRegister *dst = new VirtualRegister(type);
1584 
1585  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(base),IndexOp(index),displacement->get_value());
1586  MachineInstruction* lea = new LEAInst(DstOp(dst), get_OperandSize_from_Type(type), SrcOp(modrm));
1587 
1588  get_current()->push_back(lea);
1589  set_op(I,lea->get_result().op);
1590  break;
1591  }
1592  case BaseIndexDisplacement2:
1593  {
1594  /*
1595  ADDInstID
1596  stm
1597  ADDInstID
1598  stm
1599  CONSTInstID
1600  */
1601  assert(I);
1602  Type::TypeID type = I->get_type();
1603  MachineOperand* base = get_op(I->get_operand(0)->to_Instruction());
1604 
1605  Instruction* nested_add = I->get_operand(1)->to_Instruction();
1606  MachineOperand* index = get_op(nested_add->get_operand(0)->to_Instruction());
1607 
1608  CONSTInst* displacement = nested_add->get_operand(1)->to_Instruction()->to_CONSTInst();
1609  VirtualRegister *dst = new VirtualRegister(type);
1610 
1611  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(base),IndexOp(index),displacement->get_value());
1612  MachineInstruction* lea = new LEAInst(DstOp(dst), get_OperandSize_from_Type(type), SrcOp(modrm));
1613 
1614  get_current()->push_back(lea);
1615  set_op(I,lea->get_result().op);
1616  break;
1617  }
1618  case BaseIndexMultiplier:
1619  {
1620  /*
1621  ADDInstID
1622  stm, // base
1623  MULInstID
1624  stm, // index
1625  CONSTInstID // multiplier
1626  */
1627  assert(I);
1628  Type::TypeID type = I->get_type();
1629 
1630  MachineOperand* base = get_op(I->get_operand(0)->to_Instruction());
1631 
1632  Instruction* nested_mul = I->get_operand(1)->to_Instruction();
1633  MachineOperand* index = get_op(nested_mul->get_operand(0)->to_Instruction());
1634  CONSTInst* multiplier = nested_mul->get_operand(1)->to_Instruction()->to_CONSTInst();
1635 
1636  VirtualRegister *dst = new VirtualRegister(type);
1637  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(base)
1638  ,IndexOp(index)
1639  ,X86_64ModRMOperand::get_scale(multiplier->get_Int())
1640  );
1641  MachineInstruction* lea = new LEAInst(DstOp(dst), get_OperandSize_from_Type(type), SrcOp(modrm));
1642 
1643  get_current()->push_back(lea);
1644  set_op(I,lea->get_result().op);
1645  break;
1646  }
1647  case BaseIndexMultiplier2:
1648  {
1649  /*
1650  ADDInstID
1651  MULInstID
1652  stm, // index
1653  CONSTInstID // multiplier
1654  stm // base
1655  */
1656  assert(I);
1657  Type::TypeID type = I->get_type();
1658 
1659  MachineOperand* base = get_op(I->get_operand(1)->to_Instruction());
1660 
1661  Instruction* nested_mul = I->get_operand(0)->to_Instruction();
1662  MachineOperand* index = get_op(nested_mul->get_operand(0)->to_Instruction());
1663  CONSTInst* multiplier = nested_mul->get_operand(1)->to_Instruction()->to_CONSTInst();
1664 
1665  VirtualRegister *dst = new VirtualRegister(type);
1666  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(base)
1667  ,IndexOp(index)
1668  ,X86_64ModRMOperand::get_scale(multiplier->get_Int())
1669  );
1670  MachineInstruction* lea = new LEAInst(DstOp(dst), get_OperandSize_from_Type(type), SrcOp(modrm));
1671 
1672  get_current()->push_back(lea);
1673  set_op(I,lea->get_result().op);
1674  break;
1675  }
1676  case BaseIndexMultiplierDisplacement:
1677  {
1678  /*
1679  ADDInstID
1680  ADDInstID
1681  stm, // base
1682  MULInstID
1683  stm, // index
1684  CONSTInstID // multiplier
1685  CONSTInstID // displacement
1686  */
1687  assert(I);
1688  Type::TypeID type = I->get_type();
1689 
1690  Instruction* bim_root = I->get_operand(0)->to_Instruction();
1691  MachineOperand* base = get_op(bim_root->get_operand(0)->to_Instruction());
1692 
1693  Instruction* nested_mul = bim_root->get_operand(1)->to_Instruction();
1694  MachineOperand* index = get_op(nested_mul->get_operand(0)->to_Instruction());
1695  CONSTInst* multiplier = nested_mul->get_operand(1)->to_Instruction()->to_CONSTInst();
1696 
1697  CONSTInst* displacement = I->get_operand(1)->to_Instruction()->to_CONSTInst();
1698 
1699  VirtualRegister *dst = new VirtualRegister(type);
1700  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(base)
1701  ,IndexOp(index)
1702  ,X86_64ModRMOperand::get_scale(multiplier->get_Int())
1703  ,displacement->get_value()
1704  );
1705  MachineInstruction* lea = new LEAInst(DstOp(dst), get_OperandSize_from_Type(type), SrcOp(modrm));
1706 
1707  get_current()->push_back(lea);
1708  set_op(I,lea->get_result().op);
1709  break;
1710  }
1711  case BaseIndexMultiplierDisplacement2:
1712  {
1713  /*
1714  ADDInstID
1715  stm, // base
1716  ADDInstID
1717  MULInstID
1718  stm, // index
1719  CONSTInstID // multiplier
1720  CONSTInstID // displacement
1721  */
1722  assert(I);
1723  Type::TypeID type = I->get_type();
1724 
1725  MachineOperand* base = get_op(I->get_operand(0)->to_Instruction());
1726 
1727  Instruction* mul_add = I->get_operand(1)->to_Instruction();
1728  MachineOperand* index = get_op(mul_add->get_operand(0)->to_Instruction()->get_operand(0)->to_Instruction());
1729  CONSTInst* multiplier = mul_add->get_operand(0)->to_Instruction()->get_operand(1)->to_Instruction()->to_CONSTInst();
1730 
1731  CONSTInst* displacement = mul_add->get_operand(1)->to_Instruction()->to_CONSTInst();
1732 
1733  VirtualRegister *dst = new VirtualRegister(type);
1734  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(base)
1735  ,IndexOp(index)
1736  ,X86_64ModRMOperand::get_scale(multiplier->get_Int())
1737  ,displacement->get_value()
1738  );
1739  MachineInstruction* lea = new LEAInst(DstOp(dst), get_OperandSize_from_Type(type), SrcOp(modrm));
1740 
1741  get_current()->push_back(lea);
1742  set_op(I,lea->get_result().op);
1743  break;
1744  }
1745  case ALoad:
1746  {
1747  /*
1748  ALOADInstID
1749  AREFInstID
1750  stm,
1751  stm
1752  */
1753 
1754  assert(I);
1755  Instruction *ref = I->get_operand(0)->to_Instruction();
1756  assert(ref);
1757  MachineOperand* src_ref = get_op(ref->get_operand(0)->to_Instruction());
1758  MachineOperand* src_index = get_op(ref->get_operand(1)->to_Instruction());
1759  assert(src_ref->get_type() == Type::ReferenceTypeID);
1760  assert(src_index->get_type() == Type::IntTypeID);
1761 
1762  Type::TypeID type = ref->get_type();
1763 
1764  VirtualRegister *dst = new VirtualRegister(type);
1765 
1766  s4 offset;
1767  switch (type) {
1768  case Type::ByteTypeID:
1769  offset = OFFSET(java_bytearray_t, data[0]);
1770  break;
1771  case Type::ShortTypeID:
1772  offset = OFFSET(java_shortarray_t, data[0]);
1773  break;
1774  case Type::IntTypeID:
1775  offset = OFFSET(java_intarray_t, data[0]);
1776  break;
1777  case Type::LongTypeID:
1778  offset = OFFSET(java_longarray_t, data[0]);
1779  break;
1780  case Type::FloatTypeID:
1781  offset = OFFSET(java_floatarray_t, data[0]);
1782  break;
1783  case Type::DoubleTypeID:
1784  offset = OFFSET(java_doublearray_t, data[0]);
1785  break;
1786  case Type::ReferenceTypeID:
1787  offset = OFFSET(java_objectarray_t, data[0]);
1788  break;
1789  default:
1790  ABORT_MSG("x86_64 Lowering not supported",
1791  "Inst: " << I << " type: " << type);
1792  offset = 0;
1793  }
1794 
1795  // create modrm source operand
1796  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(src_ref),IndexOp(src_index),type,offset);
1797  MachineInstruction *move = NULL;
1798  switch (type) {
1799  case Type::CharTypeID:
1800  case Type::ByteTypeID:
1801  case Type::ShortTypeID:
1802  case Type::IntTypeID:
1803  case Type::LongTypeID:
1804  case Type::ReferenceTypeID:
1805  move = new MovInst(SrcOp(modrm),DstOp(dst),get_OperandSize_from_Type(type));
1806  break;
1807  case Type::FloatTypeID:
1808  move = new MovSSInst(SrcOp(modrm),DstOp(dst));
1809  break;
1810  case Type::DoubleTypeID:
1811  move = new MovSDInst(SrcOp(modrm),DstOp(dst));
1812  break;
1813  default:
1814  ABORT_MSG("x86_64 Lowering not supported",
1815  "Inst: " << I << " type: " << type);
1816  }
1817  get_current()->push_back(move);
1818  set_op(I,move->get_result().op);
1819  break;
1820  }
1821  case AStore:
1822  {
1823  /*
1824  ASTOREInstID
1825  AREFInstID,
1826  stm,
1827  stm
1828  stm
1829  */
1830 
1831  assert(I);
1832  Instruction *ref = I->get_operand(0)->to_Instruction();
1833  assert(ref);
1834  MachineOperand* dst_ref = get_op(ref->get_operand(0)->to_Instruction());
1835  MachineOperand* dst_index = get_op(ref->get_operand(1)->to_Instruction());
1836  assert(dst_ref->get_type() == Type::ReferenceTypeID);
1837  assert(dst_index->get_type() == Type::IntTypeID);
1839 
1840  Type::TypeID type = ref->get_type();
1841 
1842  s4 offset;
1843  switch (type) {
1844  case Type::ByteTypeID:
1845  offset = OFFSET(java_bytearray_t, data[0]);
1846  break;
1847  case Type::ShortTypeID:
1848  offset = OFFSET(java_shortarray_t, data[0]);
1849  break;
1850  case Type::IntTypeID:
1851  offset = OFFSET(java_intarray_t, data[0]);
1852  break;
1853  case Type::LongTypeID:
1854  offset = OFFSET(java_longarray_t, data[0]);
1855  break;
1856  case Type::FloatTypeID:
1857  offset = OFFSET(java_floatarray_t, data[0]);
1858  break;
1859  case Type::DoubleTypeID:
1860  offset = OFFSET(java_doublearray_t, data[0]);
1861  break;
1862  case Type::ReferenceTypeID:
1863  // TODO: implement me
1864  default:
1865  ABORT_MSG("x86_64 Lowering not supported",
1866  "Inst: " << I << " type: " << type);
1867  offset = 0;
1868  }
1869 
1870  // create modrm source operand
1871  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(dst_ref),IndexOp(dst_index),type,offset);
1872  MachineInstruction *move = NULL;
1873  switch (type) {
1874  case Type::CharTypeID:
1875  case Type::ByteTypeID:
1876  case Type::ShortTypeID:
1877  case Type::IntTypeID:
1878  case Type::LongTypeID:
1879  case Type::ReferenceTypeID:
1880  move = new MovInst(SrcOp(src),DstOp(modrm),get_OperandSize_from_Type(type));
1881  break;
1882  case Type::FloatTypeID:
1883  move = new MovSSInst(SrcOp(src),DstOp(modrm));
1884  break;
1885  case Type::DoubleTypeID:
1886  move = new MovSDInst(SrcOp(src),DstOp(modrm));
1887  break;
1888  default:
1889  ABORT_MSG("x86_64 Lowering not supported",
1890  "Inst: " << I << " type: " << type);
1891  }
1892  get_current()->push_back(move);
1893  set_op(I,move->get_result().op);
1894  break;
1895  }
1896  case AStoreImm:
1897  {
1898  /*
1899  ASTOREInstID
1900  AREFInstID,
1901  stm,
1902  stm
1903  CONSTInstID
1904  */
1905 
1906  assert(I);
1907  Instruction *ref = I->get_operand(0)->to_Instruction();
1908  assert(ref);
1909  MachineOperand* dst_ref = get_op(ref->get_operand(0)->to_Instruction());
1910  MachineOperand* dst_index = get_op(ref->get_operand(1)->to_Instruction());
1911  assert(dst_ref->get_type() == Type::ReferenceTypeID);
1912  assert(dst_index->get_type() == Type::IntTypeID);
1913  Immediate* imm = new Immediate(I->get_operand(1)->to_Instruction()->to_CONSTInst());
1914 
1915  Type::TypeID type = ref->get_type();
1916 
1917  s4 offset;
1918  switch (type) {
1919  case Type::ByteTypeID:
1920  offset = OFFSET(java_bytearray_t, data[0]);
1921  break;
1922  case Type::ShortTypeID:
1923  offset = OFFSET(java_shortarray_t, data[0]);
1924  break;
1925  case Type::IntTypeID:
1926  offset = OFFSET(java_intarray_t, data[0]);
1927  break;
1928  case Type::LongTypeID:
1929  offset = OFFSET(java_longarray_t, data[0]);
1930  break;
1931  case Type::FloatTypeID:
1932  offset = OFFSET(java_floatarray_t, data[0]);
1933  break;
1934  case Type::DoubleTypeID:
1935  offset = OFFSET(java_doublearray_t, data[0]);
1936  break;
1937  case Type::ReferenceTypeID:
1938  // TODO: implement me
1939  default:
1940  ABORT_MSG("x86_64 Lowering not supported",
1941  "Inst: " << I << " type: " << type);
1942  offset = 0;
1943  }
1944 
1945  // create modrm source operand
1946  MachineOperand *modrm = new X86_64ModRMOperand(BaseOp(dst_ref),IndexOp(dst_index),type,offset);
1947  MachineInstruction *move = NULL;
1948  switch (type) {
1949  case Type::CharTypeID:
1950  case Type::ByteTypeID:
1951  case Type::ShortTypeID:
1952  case Type::IntTypeID:
1953  case Type::LongTypeID:
1954  case Type::ReferenceTypeID:
1955  move = new MovInst(SrcOp(imm),DstOp(modrm),get_OperandSize_from_Type(type));
1956  break;
1957  case Type::FloatTypeID:
1958  move = new MovSSInst(SrcOp(imm),DstOp(modrm));
1959  break;
1960  case Type::DoubleTypeID:
1961  move = new MovSDInst(SrcOp(imm),DstOp(modrm));
1962  break;
1963  default:
1964  ABORT_MSG("x86_64 Lowering not supported",
1965  "Inst: " << I << " type: " << type);
1966  }
1967  get_current()->push_back(move);
1968  set_op(I,move->get_result().op);
1969  break;
1970  }
1971  default:
1972  ABORT_MSG("Rule not supported", "Rule " << ruleId << " is not supported by method lowerComplex!");
1973 
1974  }
1975 }
1976 
1978  Type::TypeID type, bool copyOperands, bool isCommutable) {
1979 
1980  if (!copyOperands){
1981  if (src_op1->is_Register()){
1982  dst = src_op1->to_Register()->to_VirtualRegister();
1983  return;
1984  } else if (src_op2->is_Register() && isCommutable){
1985  dst = src_op2->to_Register()->to_VirtualRegister();
1986  src_op2 = src_op1;
1987  return;
1988  }
1989  }
1990  dst = new VirtualRegister(type);
1991  MachineInstruction *mov = get_Backend()->create_Move(src_op1,dst);
1992  get_current()->push_back(mov);
1993 }
1994 
1995 
1996 #if 0
1997 template<>
1998 compiler2::RegisterFile*
2000  return new x86_64::RegisterFile(type);
2001 }
2002 #endif
2003 
2004 
2005 } // end namespace compiler2
2006 } // end namespace jit
2007 } // end namespace cacao
2008 
2009 
2010 /*
2011  * These are local overrides for various environment variables in Emacs.
2012  * Please do not remove this and leave it at the end of the file, where
2013  * Emacs will automagically detect them.
2014  * ---------------------------------------------------------------------
2015  * Local variables:
2016  * mode: c++
2017  * indent-tabs-mode: t
2018  * c-basic-offset: 4
2019  * tab-width: 4
2020  * End:
2021  * vim:noexpandtab:sw=4:ts=4:
2022  */
static const COND B
below (CF = 1)
Definition: X86_64Cond.hpp:81
void set_op(Instruction *I, MachineOperand *op) const
Definition: Backend.hpp:106
BeginInstRef & get_else_target()
GPRegister RDX("RDX", 0x2, false, 0x2 *8, 8)
std::size_t index
void set_current(MachineBasicBlock *MBB)
Definition: Backend.hpp:122
static const COND E
equal (ZF = 1)
Definition: X86_64Cond.hpp:88
virtual MachineInstruction * create_Move(MachineOperand *src, MachineOperand *dst) const =0
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
Subtract Scalar Double-Precision Floating-Point Values.
virtual Instruction * to_Instruction()
Definition: Value.hpp:88
CodeFragment get_aligned_CodeFragment(std::size_t size)
get an aligned code fragment
Definition: CodeMemory.cpp:83
Simple wrapper for second operand of an x86_64 instruction.
GPInstruction::OperandSize get_OperandSize_from_Type(const Type::TypeID type)
#define WARNING_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:96
Simple wrapper for first operand of an x86_64 instruction.
virtual MachineInstruction * create_Jump(MachineBasicBlock *target) const
PointerTag< DataSegmentType, constant_FMIref, FMIRefID > DSFMIRef
Definition: DataSegment.hpp:49
s4 dseg_add_unique_address(codegendata *cd, void *value)
Definition: dseg.cpp:525
const MethodDescriptor & get_MethodDescriptor() const
Get the MethodDescriptor.
Definition: MethodC2.hpp:164
argument_type from
Type::TypeID get_type() const
get the value type of the instruction
Definition: Value.hpp:68
virtual CONSTInst * to_CONSTInst()
Definition: Instruction.hpp:53
u4 get_frame_size() const
get the size of the stack frame in bytes
static const COND G
greater (ZF = 0 and SF = OF)
Definition: X86_64Cond.hpp:108
Multiply Scalar Double-Precision Floating-Point Values.
codeinfo * code
Definition: jit.hpp:128
A basic block of (scheduled) machine instructions.
virtual void create_frame(CodeMemory *CM, StackSlotManager *SSM) const
#define dseg_add_functionptr(cd, value)
Definition: dseg.hpp:39
virtual void lowerComplex(Instruction *I, int ruleId)
union constant_FMIref::@26 p
StackSlotManager * get_StackSlotManager()
Definition: JITData.hpp:56
Convert Dword Integer to Scalar Single-Precision FP Value.
Add Scalar Single-Precision Floating-Point Values.
patchref_t * patcher_add_patch_ref(jitdata *jd, functionptr patcher, void *ref, s4 disp)
uint8_t u1
Definition: types.hpp:40
void set_operand(std::size_t i, MachineOperand *op)
Divide Scalar Single-Precision Floating-Point Values.
int64_t s8
Definition: types.hpp:48
constant_FMIref * get_fmiref() const
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
Simple wrapper for first operand of an x86_64 instruction which is also used for the result...
#define PATCHER_get_putstatic
jitdata * get_jitdata() const
Definition: JITData.hpp:51
this stores a reference to a begin instruction
Subtract Scalar Single-Precision Floating-Point Values.
ManagedStackSlot * create_ManagedStackSlot(Type::TypeID type)
create a new managed stack slot
GPInstruction::OperandSize get_operand_size_from_Type(Type::TypeID type)
SuccessorListTy::const_iterator succ_end() const
virtual void visit(LOADInst *I, bool copyOperands)
u1 * stubroutine
Definition: method.hpp:102
void push_back(MachineInstruction *value)
Appends the given element value to the end of the container.
constant_FMIref * fieldref
Definition: resolve.hpp:88
Simple wrapper for the operand of an single operand x86_64 instruction.
Conditional::CondID get_condition() const
CodeMemory * get_CodeMemory()
Definition: JITData.hpp:57
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
void emit_nop(CodeFragment code, int length)
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
Multiply Scalar Single-Precision Floating-Point Values.
imm_union * value
Definition: field.hpp:67
Convert Dword Integer to Scalar Double-Precision FP Value.
void push_front(MachineInstruction *value)
inserts value to the beginning
virtual VirtualRegister * to_VirtualRegister()
Instruction super class.
Definition: Instruction.hpp:73
std::size_t size() const
size of the reference
Definition: Segment.hpp:392
typedesc * fd
Definition: references.hpp:74
MIIterator i
Fieldref, Methodref and InterfaceMethodref.
Definition: references.hpp:86
static ScaleFactor get_scale(Type::TypeID type)
#define LOG2(STMT)
Definition: logging.hpp:93
int32_t s4
Definition: types.hpp:45
static const COND L
less (SF &lt;&gt; OF)
Definition: X86_64Cond.hpp:101
IdxTy insert_tag(SegmentTag< Tag > *tag, IdxTy o)
insert tag
Definition: Segment.hpp:123
SuccessorListTy::const_iterator succ_begin() const
cacao::shared_ptr< cacao::Patcher > PatcherPtrTy
Definition: code.hpp:60
classinfo * clazz
Definition: field.hpp:55
virtual const char * get_name() const
static const COND GE
greater or equal (SF = OF)
Definition: X86_64Cond.hpp:104
IdxTy get_index(Tag2 tag) const
get the index of a tag
Definition: Segment.hpp:254
constant_FMIref * get_fmiref() const
virtual MachineInstruction * create_Move(MachineOperand *src, MachineOperand *dst) const
Simple wrapper for first operand of an x86_64 instruction which is also used for the result...
SuccessorListTy::const_iterator succ_const_iterator
MIIterator e
#define PATCHER_invokestatic_special
void setupSrcDst(MachineOperand *&src_op1, MachineOperand *&src_op2, VirtualRegister *&dst, Type::TypeID type, bool copyOperands, bool isCommutable)
Simple wrapper for destination of an x86_64 instruction.
Proxy to encode explicit and implicit successors.
virtual void emit(CodeMemory *CM) const
emit machine code
MachineBasicBlock * get_current() const
Definition: Backend.hpp:121
#define I(value)
Definition: codegen.c:279
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
PatcherListTy * patchers
Definition: code.hpp:98
Operands that can be directly used by the machine (register, memory, stackslot)
static const COND NE
not equal (ZF = 0)
Definition: X86_64Cond.hpp:90
GPRegister RAX("RAX", 0x0, false, 0x0 *8, 8)
const MachineOperandDesc & get_result() const
static bool class_is_or_almost_initialized(classinfo *c)
Definition: class.hpp:433
x86_64::NativeRegister NativeRegister
Definition: Target.hpp:46
#define INSTRUCTION_IS_UNRESOLVED(iptr)
Segment reference.
Definition: Segment.hpp:44
static const COND A
above (CF = 0 and ZF = 0)
Definition: X86_64Cond.hpp:94
#define assert_msg(COND, EXPR)
Definition: logging.hpp:107
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
static const COND P
parity (PF = 1)
Definition: X86_64Cond.hpp:97
SSERegister XMM0("XMM0", 0x0, false, 0x0 *16, 16)
virtual bool is_commutable() const
True if the operands of the instruction are commutable.
const parseddesc_t parseddesc
Definition: references.hpp:105
BeginInst * target
void insert_pred(MachineBasicBlock *value)
Appends the given element value to the list of predecessors.
MachineBasicBlock * new_block() const
Definition: Backend.cpp:70
IdxTy get_begin() const
Get the index of the first element.
Definition: Segment.hpp:343
MachineOperand * get_op(Instruction *I) const
Definition: Backend.hpp:100
fieldinfo * field
Definition: references.hpp:100
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:133
BeginInstRef & get_then_target()
Nl nl
Definition: OStream.cpp:56
JITData * get_JITData() const
Definition: Backend.hpp:52
Add Scalar Double-Precision Floating-Point Values.
#define OFFSET(s, el)
Definition: memory.hpp:90
Ref get_Ref(std::size_t t)
get a new reference to the segment
Definition: Segment.hpp:208
Patcher super class.
Definition: PatcherNew.hpp:49
static const COND LE
less or equal (ZF = 1 or SF &lt;&gt; OF)
Definition: X86_64Cond.hpp:105
const DataSegment & get_DataSegment() const
get DataSegment
Definition: CodeMemory.hpp:69
Divide Scalar Double-Precision Floating-Point Values.
FloatHandling get_FloatHandling() const
MethodDescriptor TODO: more info.