CACAO
X86_64EmitHelper.hpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/X86_64EmitHelper.hpp - X86_64EmitHelper
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 
25 #ifndef _JIT_COMPILER2_X86_64EMITHELPER
26 #define _JIT_COMPILER2_X86_64EMITHELPER
27 
31 #include "vm/types.hpp"
32 #include "toolbox/logging.hpp"
33 
34 #define DEBUG_NAME "compiler2/x86_64 Emit"
35 
36 namespace cacao {
37 namespace jit {
38 namespace compiler2 {
39 namespace x86_64 {
40 
41 /**
42  * Opcode ref field.
43  */
44 struct OpReg {
46  OpReg(X86_64Register *reg) : reg(reg) {}
48  return reg;
49  }
51  return reg;
52  }
53 };
54 
55 /**
56  * REX Prefix Builder.
57  */
58 struct REX {
59  enum Field {
60  W = 3, ///< 0 = Operand size determined by CS.D
61  ///< 1 = 64 Bit Operand Size
62  R = 2, ///< Extension of the ModR/M reg field
63  X = 1, ///< Extension of the SIB index field
64  B = 0 ///< Extension of the ModR/M r/m field, SIB base field, or Opcode reg field
65  };
67 
68  REX() : rex(0x4 << 4) {}
69 
70  /// convert to u1
71  operator u1() {
72  return rex;
73  }
74  /**
75  * @note (binary) operator+ is evaluated left to right
76  */
78  rex |= 1 << f;
79  return *this;
80  }
81  /**
82  * @note (binary) operator- is evaluated left to right
83  */
85  rex &= ~(1 << f);
86  return *this;
87  }
89  if (reg->extented)
90  rex |= 1 << B;
91  return *this;
92  }
93 };
94 
95 inline u1 get_rex(X86_64Register *reg, X86_64Register *rm = NULL,
96  bool opsiz64 = true) {
97  const unsigned rex_w = 3;
98  const unsigned rex_r = 2;
99  //const unsigned rex_x = 1;
100  const unsigned rex_b = 0;
101 
102  u1 rex = 0x40;
103 
104  // 64-bit operand size
105  if (opsiz64) {
106  rex |= (1 << rex_w);
107  }
108 
109  if (reg && reg->extented) {
110  rex |= (1 << rex_r);
111  }
112  if (rm && rm->extented) {
113  rex |= (1 << rex_b);
114  }
115  return rex;
116 }
117 
118 inline u1 get_rex(const X86_64Register *reg1, X86_64Register *reg2 = NULL,
120  X86_64Register *reg3 = NULL) {
121  const unsigned rex_w = 3;
122  const unsigned rex_r = 2;
123  const unsigned rex_x = 1;
124  const unsigned rex_b = 0;
125 
126  u1 rex = 0x40;
127 
128  // 64-bit operand size
129  if (op_size == GPInstruction::OS_64) {
130  rex |= (1 << rex_w);
131  }
132  if (reg1 && reg1->extented) {
133  rex |= (1 << rex_r);
134  }
135  if (reg2 && reg2->extented) {
136  rex |= (1 << rex_b);
137  }
138  if (reg3 && reg3->extented) {
139  rex |= (1 << rex_x);
140  }
141  return rex;
142 
143 }
144 
146  return index || base == &RSP || base == &R12;
147 }
148 
149 inline u1 get_modrm(u1 reg, u1 base, s4 disp, bool use_sib = false) {
150  u1 modrm_mod = 6;
151  u1 modrm_reg = 3;
152  u1 modrm_rm = 0;
153 
154  u1 mod = 0;
155  u1 rm = 0;
156  u1 modrm = 0;
157 
158  if (disp == 0 || base == 0x05 /* RBP */) {
159  // no disp
160  mod = 0x00; //0b00
161  }
162  else if (fits_into<s1>(disp)) {
163  // disp8
164  mod = 0x01; // 0b01
165  } else if (fits_into<s4>(disp)) {
166  // disp32
167  mod = 0x02; // 0b10
168  }
169  else {
170  ABORT_MSG("Illegal displacement", "Displacement: "<<disp);
171  }
172 
173  if (use_sib) {
174  rm = 0x04; // 0b100
175  }
176  else {
177  rm = base;
178  }
179 
180  modrm = mod << modrm_mod;
181  modrm |= reg << modrm_reg;
182  modrm |= rm << modrm_rm;
183 
184  return modrm;
185 }
186 
187 inline u1 get_modrm (X86_64Register *reg, X86_64Register *base, s4 disp, bool use_sib = false) {
188  return get_modrm((reg != NULL) ? reg->get_index() : 0, (base != NULL) ? base->get_index() : 0, disp, use_sib);
189 }
190 
191 inline u1 get_sib(X86_64Register *base, X86_64Register *index = NULL, u1 scale = 1) {
192  u1 sib_scale = 6;
193  u1 sib_index = 3;
194  u1 sib_base = 0;
195 
196  u1 sib = 0;
197 
198  sib = scale << sib_scale;
199  if (index) {
200  sib |= index->get_index() << sib_index;
201  }
202  else {
203  sib |= RSP.get_index() << sib_index;
204  }
205 
206  sib |= base->get_index() << sib_base;
207 
208  return sib;
209 }
210 
211 
212 inline u1 get_modrm_u1(u1 mod, u1 reg, u1 rm) {
213  const unsigned modrm_mod = 6;
214  const unsigned modrm_reg = 3;
215  const unsigned modrm_rm = 0;
216 
217  u1 modrm = (0x3 & mod) << modrm_mod;
218  modrm |= (0x7 & reg) << modrm_reg;
219  modrm |= (0x7 & rm) << modrm_rm;
220 
221  return modrm;
222 }
224  return get_modrm_u1(mod,reg->get_index(), rm->get_index());
225 }
227  return get_modrm(0x3,reg,rm);
228 }
229 inline u1 get_modrm_1reg(u1 reg, X86_64Register *rm) {
230  return get_modrm_u1(0x3,reg,rm->get_index());
231 }
232 
234 private:
236 public:
237  typedef Container::iterator iterator;
238  typedef Container::const_iterator const_iterator;
239  typedef Container::value_type value_type;
240 
241  void push_front(u1 d) { data.push_front(d); }
242  void push_back(u1 d) { data.push_back(d); }
244  push_back(d);
245  return *this;
246  }
247  u1& operator[](std::size_t i) {
248  if (i >= size()) {
249  data.resize(i+1,0);
250  }
251  return data[i];
252  }
253  u1 operator[](std::size_t i) const {
254  assert(i < size());
255  return data[i];
256  }
257  std::size_t size() const { return data.size(); }
258  const_iterator begin() const { return data.begin(); }
259  const_iterator end() const { return data.end(); }
260  iterator begin() { return data.begin(); }
261  iterator end() { return data.end(); }
262 private:
264 };
265 
267  CodeFragment CF = CM->get_CodeFragment(CSB.size());
268  for (std::size_t i = 0, e = CSB.size(); i < e; ++i) {
269  CF[i] = CSB[i];
270  }
271 }
272 
273 template <>
275  switch (op->get_OperandID()) {
277  {
278  ManagedStackSlot *mslot = op->to_ManagedStackSlot();
279  assert(mslot);
280  StackSlot *slot = mslot->to_StackSlot();
281  assert(slot);
282  return slot;
283  }
285  {
286  StackSlot *slot = op->to_StackSlot();
287  assert(slot);
288  return slot;
289  }
290  default: break;
291  }
292  assert(0 && "Not a stackslot");
293  return NULL;
294 }
295 
296 template <>
298  Immediate* imm = op->to_Immediate();
299  assert(imm);
300  return imm;
301 }
302 
304  template <class T>
305  static void reg2reg(CodeMemory *CM, T opcode,
306  X86_64Register *reg, X86_64Register *rm) {
307  CodeFragment code = CM->get_CodeFragment(2 + sizeof(T));
308 
309  code[0] = get_rex(reg,rm);
310 
311  for (int i = 0, e = sizeof(T) ; i < e ; ++i) {
312  code[i + 1] = (u1) 0xff & (opcode >> (8 * (e - i - 1)));
313  }
314 
315  code[1 + sizeof(T)] = get_modrm_reg2reg(reg,rm);
316  }
317  template <class T>
318  static void reg2rbp_disp8(CodeMemory *CM, T opcode,
319  X86_64Register *reg, s1 disp) {
320  CodeFragment code = CM->get_CodeFragment(3 + sizeof(T));
321 
322  code[0] = get_rex(reg);
323 
324  for (int i = 0, e = sizeof(T) ; i < e ; ++i) {
325  code[i + 1] = (u1) 0xff & (opcode >> (8 * (e - i - 1)));
326  }
327 
328  code[1 + sizeof(T)] = get_modrm(0x1,reg,&RBP);
329  code[2 + sizeof(T)] = u1(disp);
330  }
331  template <class T>
332  static void reg2rbp_disp32(CodeMemory *CM, T opcode,
333  X86_64Register *reg, s4 disp) {
334  CodeFragment code = CM->get_CodeFragment(6 + sizeof(T));
335 
336  code[0] = get_rex(reg);
337 
338  for (int i = 0, e = sizeof(T) ; i < e ; ++i) {
339  code[i + 1] = (u1) 0xff & (opcode >> (8 * (e - i - 1)));
340  }
341 
342  code[1 + sizeof(T)] = get_modrm(0x2,reg,&RBP);
343  code[2 + sizeof(T)] = u1( 0xff & (disp >> (0 * 8)));
344  code[3 + sizeof(T)] = u1( 0xff & (disp >> (1 * 8)));
345  code[4 + sizeof(T)] = u1( 0xff & (disp >> (2 * 8)));
346  code[5 + sizeof(T)] = u1( 0xff & (disp >> (3 * 8)));
347  }
348  template <class O,class I>
349  static void reg2imm(CodeMemory *CM, O opcode,
350  X86_64Register *reg, I imm) {
351  CodeFragment code = CM->get_CodeFragment(1 + sizeof(O) + sizeof(I));
352 
353  code[0] = get_rex(reg);
354 
355  for (int i = 0, e = sizeof(O) ; i < e ; ++i) {
356  code[i + 1] = (u1) 0xff & (opcode >> (8 * (e - i - 1)));
357  }
358  for (int i = 0, e = sizeof(I) ; i < e ; ++i) {
359  code[i + sizeof(O) + 1] = (u1) 0xff & (imm >> (8 * i));
360  }
361 
362  }
363  template <class O,class I>
364  static void reg2imm_modrm(CodeMemory *CM, O opcode,
365  X86_64Register* reg, X86_64Register *rm, I imm) {
366  CodeFragment code = CM->get_CodeFragment(2 + sizeof(O) + sizeof(I));
367 
368  code[0] = get_rex(reg, rm);
369 
370  for (int i = 0, e = sizeof(O) ; i < e ; ++i) {
371  code[i + 1] = (u1) 0xff & (opcode >> (8 * (e - i - 1)));
372  }
373  code[1 + sizeof(O)] = get_modrm_1reg(reg->get_index(),rm);
374  for (int i = 0, e = sizeof(I) ; i < e ; ++i) {
375  code[i + sizeof(O) + 2] = (u1) 0xff & (imm >> (8 * i));
376  }
377 
378  }
379  template <class O,class I>
380  static void imm_op(CodeMemory *CM, O opcode, I imm) {
381  CodeFragment code = CM->get_CodeFragment(sizeof(O) + sizeof(I));
382 
383  for (int i = 0, e = sizeof(O) ; i < e ; ++i) {
384  code[i] = (u1) 0xff & (opcode >> (8 * (e - i - 1)));
385  }
386  for (int i = 0, e = sizeof(I) ; i < e ; ++i) {
387  code[i + sizeof(O)] = (u1) 0xff & (imm >> (8 * i));
388  }
389 
390  }
391  template <class O,class I>
392  static void imm_op(CodeFragment &code, O opcode, I imm) {
393  assert(code.size() == (sizeof(O) + sizeof(I)));
394 
395  for (int i = 0, e = sizeof(O) ; i < e ; ++i) {
396  code[i] = (u1) 0xff & (opcode >> (8 * (e - i - 1)));
397  }
398  for (int i = 0, e = sizeof(I) ; i < e ; ++i) {
399  code[i + sizeof(O)] = (u1) 0xff & (imm >> (8 * i));
400  }
401 
402  }
403  template <class I,class Seg>
404  static void imm(Seg seg,I imm) {
405  assert(seg.size() == sizeof(I));
406 
407  for (int i = 0, e = sizeof(I) ; i < e ; ++i) {
408  seg[i] = (u1) 0xff & *(reinterpret_cast<u1*>(&imm) + i);
409  }
410 
411  }
412 
413  static void emit (CodeMemory* CM, u1 primary_opcode, GPInstruction::OperandSize op_size, MachineOperand *src, MachineOperand *dst, u1 secondary_opcode = 0, u1 op_reg = 0, u1 prefix = 0, bool prefix_0f = false, bool encode_dst = true, bool imm_sign_extended = false) {
414  CodeSegmentBuilder code;
415  if (dst->is_Register()) {
416  X86_64Register *dst_reg = cast_to<X86_64Register>(dst);
417  if (src->is_Register()) {
418  X86_64Register *src_reg = cast_to<X86_64Register>(src);
419  u1 rex = get_rex(dst_reg,src_reg,op_size == GPInstruction::OS_64);
420  if (rex != 0x40)
421  code += rex;
422  if (prefix)
423  code += prefix;
424  if (prefix_0f)
425  code += 0x0F;
426  code += primary_opcode;
427  if (secondary_opcode != 0x00) {
428  code += secondary_opcode;
429  }
430  code += get_modrm_reg2reg (dst_reg,src_reg);
431  }
432  else if (src->is_Immediate()) {
433  Immediate *src_imm = cast_to<Immediate>(src);
434  u1 rex = get_rex(NULL,dst_reg,op_size == GPInstruction::OS_64);
435  if (rex != 0x40)
436  code += rex;
437  if (prefix)
438  code += prefix;
439  if (prefix_0f)
440  code += 0x0F;
441  if (!encode_dst)
442  primary_opcode += dst_reg->get_index();
443  code += primary_opcode;
444  if (secondary_opcode != 0x00) {
445  code += secondary_opcode;
446  }
447  if (encode_dst) {
448  code += get_modrm_1reg(op_reg,dst_reg);
449  }
450  if (!imm_sign_extended) {
451  switch(op_size) {
452  case GPInstruction::OS_8:
453  {
454  s1 immval = src_imm->get_value<s1>();
455  code += (u1) 0xff & (immval >> 0x00);
456  break;
457  }
459  {
460  s2 immval = src_imm->get_value<s2>();
461  code += (u1) 0xff & (immval >> 0x00);
462  code += (u1) 0xff & (immval >> 0x08);
463  break;
464  }
466  {
467  s4 immval = src_imm->get_value<s4>();
468  code += (u1) 0xff & (immval >> 0x00);
469  code += (u1) 0xff & (immval >> 0x08);
470  code += (u1) 0xff & (immval >> 0x10);
471  code += (u1) 0xff & (immval >> 0x18);
472  break;
473  }
475  {
476  s8 immval = src_imm->get_value<s8>();
477  code += (u1) 0xff & (immval >> 0x00);
478  code += (u1) 0xff & (immval >> 0x08);
479  code += (u1) 0xff & (immval >> 0x10);
480  code += (u1) 0xff & (immval >> 0x18);
481  code += (u1) 0xff & (immval >> 0x20);
482  code += (u1) 0xff & (immval >> 0x28);
483  code += (u1) 0xff & (immval >> 0x30);
484  code += (u1) 0xff & (immval >> 0x38);
485  break;
486  }
488  ABORT_MSG("Invalid Immediate Size",
489  "dst: " << dst_reg << " src: " << src_imm << " op_code: " << primary_opcode);
490  break;
491  }
492  }
493  else {
494  if (fits_into<s1>(src_imm->get_value<s8>())) {
495  s1 immval = src_imm->get_value<s1>();
496  code += (u1) 0xff & (immval >> 0x00);
497  }
498  else if (fits_into<s2>(src_imm->get_value<s8>())) {
499  s2 immval = src_imm->get_value<s2>();
500  code += (u1) 0xff & (immval >> 0x00);
501  code += (u1) 0xff & (immval >> 0x08);
502  }
503  else if (fits_into<s4>(src_imm->get_value<s8>())) {
504  s4 immval = src_imm->get_value<s4>();
505  code += (u1) 0xff & (immval >> 0x00);
506  code += (u1) 0xff & (immval >> 0x08);
507  code += (u1) 0xff & (immval >> 0x10);
508  code += (u1) 0xff & (immval >> 0x18);
509  }
510  else {
511  s8 immval = src_imm->get_value<s8>();
512  code += (u1) 0xff & (immval >> 0x00);
513  code += (u1) 0xff & (immval >> 0x08);
514  code += (u1) 0xff & (immval >> 0x10);
515  code += (u1) 0xff & (immval >> 0x18);
516  code += (u1) 0xff & (immval >> 0x20);
517  code += (u1) 0xff & (immval >> 0x28);
518  code += (u1) 0xff & (immval >> 0x30);
519  code += (u1) 0xff & (immval >> 0x38);
520  }
521  }
522  }
523  else if (src->is_stackslot()) {
524  StackSlot *src_slot = cast_to<StackSlot>(src);
525  s4 index = src_slot->get_index() * 8;
526  u1 rex = get_rex(dst_reg,NULL,op_size == GPInstruction::OS_64);
527  if (rex != 0x40)
528  code += rex;
529  if (prefix)
530  code += prefix;
531  if (prefix_0f)
532  code += 0x0F;
533  code += primary_opcode;
534  if (secondary_opcode != 0x00) {
535  code += secondary_opcode;
536  }
537  if (fits_into<s1>(index)) {
538  // Shouldn't mod be 0x0 for RIP relative addressing? needs test
539  code += get_modrm(0x1,dst_reg,&RBP);
540  code += index;
541  } else {
542  code += get_modrm(0x2,dst_reg,&RBP);
543  code += (u1) 0xff & (index >> 0x00);
544  code += (u1) 0xff & (index >> 0x08);
545  code += (u1) 0xff & (index >> 0x10);
546  code += (u1) 0xff & (index >> 0x18);
547  }
548  }
549  else if (src->is_Address()) {
551  X86_64Register *base = src_mod->getBase();
552  X86_64Register *index = src_mod->getIndex();
553  s4 disp = src_mod->getDisp();
554  u1 scale = src_mod->getScale();
555  u1 rex = get_rex(dst_reg, base, op_size, index);
556  if (rex != 0x40)
557  code += rex;
558  if (prefix)
559  code += prefix;
560  if (prefix_0f)
561  code += 0x0F;
562  code += primary_opcode;
563  if (secondary_opcode != 0x00) {
564  code += secondary_opcode;
565  }
566  bool sib = use_sib(base, index);
567  code += get_modrm(dst_reg,base,disp,sib);
568  if (sib) {
569  code += get_sib(base,index,scale);
570  }
571  if (disp != 0) {
572  if (fits_into<s1>(disp) && base != &RBP) {
573  code += (s1)disp;
574  }
575  else {
576  code += (u1) 0xff & (disp >> 0x00);
577  code += (u1) 0xff & (disp >> 0x08);
578  code += (u1) 0xff & (disp >> 0x10);
579  code += (u1) 0xff & (disp >> 0x18);
580  }
581  }
582  }
583  else {
584  ABORT_MSG("Operand(s) not supported",
585  "dst_reg: " << dst_reg << " src: " << src << " op_code: " << primary_opcode);
586  }
587  }
588  else if (dst->is_stackslot()) {
589  StackSlot *dst_slot = cast_to<StackSlot>(dst);
590  s4 index = dst_slot->get_index() * 8;
591  if (src->is_Register()) {
592  X86_64Register *src_reg = cast_to<X86_64Register>(src);
593  u1 rex = get_rex(src_reg,NULL,op_size == GPInstruction::OS_64);
594  if (rex != 0x40)
595  code += rex;
596  if (prefix)
597  code += prefix;
598  if (prefix_0f)
599  code += 0x0F;
600  code += primary_opcode;
601  if (secondary_opcode != 0x00) {
602  code += secondary_opcode;
603  }
604  if (fits_into<s1>(index)) {
605  // Shouldn't mod be 0x0 for RIP relative addressing? needs test
606  code += get_modrm(0x1,src_reg,&RBP);
607  code += index;
608  } else {
609  code += get_modrm(0x2,src_reg,&RBP);
610  code += (u1) 0xff & (index >> 0x00);
611  code += (u1) 0xff & (index >> 0x08);
612  code += (u1) 0xff & (index >> 0x10);
613  code += (u1) 0xff & (index >> 0x18);
614  }
615  }
616  else {
617  ABORT_MSG("Operand(s) not supported",
618  "dst: " << dst_slot << " src: " << src << " op_code: " << primary_opcode);
619  }
620  }
621  else if (dst->is_Address()) {
623  X86_64Register *base = dst_mod->getBase();
624  X86_64Register *index = dst_mod->getIndex();
625  s4 disp = dst_mod->getDisp();
626  u1 scale = dst_mod->getScale();
627  if (src->is_Register()) {
628  X86_64Register *src_reg = cast_to<X86_64Register>(src);
629  u1 rex = get_rex(src_reg, base, op_size, index);
630  if (rex != 0x40)
631  code += rex;
632  if (prefix)
633  code += prefix;
634  if (prefix_0f)
635  code += 0x0F;
636  code += primary_opcode;
637  if (secondary_opcode != 0x00) {
638  code += secondary_opcode;
639  }
640  bool sib = use_sib(base, index);
641  code += get_modrm(src_reg,base,disp,sib);
642  if (sib) {
643  code += get_sib(base,index,scale);
644  }
645  if (disp != 0) {
646  if (fits_into<s1>(disp) && base != &RBP) {
647  code += (s1)disp;
648  }
649  else {
650  code += (u1) 0xff & (disp >> 0x00);
651  code += (u1) 0xff & (disp >> 0x08);
652  code += (u1) 0xff & (disp >> 0x10);
653  code += (u1) 0xff & (disp >> 0x18);
654  }
655  }
656  }
657  else if (src->is_Immediate()) {
658  Immediate *src_imm = cast_to<Immediate>(src);
659  u1 rex = get_rex(NULL, base, op_size, index);
660  if (rex != 0x40)
661  code += rex;
662  if (prefix)
663  code += prefix;
664  if (prefix_0f)
665  code += 0x0F;
666  code += primary_opcode;
667  if (secondary_opcode != 0x00) {
668  code += secondary_opcode;
669  }
670  bool sib = use_sib(base, index);
671  code += get_modrm(op_reg,base->get_index(),disp,sib);
672  if (sib) {
673  code += get_sib(base,index,scale);
674  }
675  if (disp != 0) {
676  if (fits_into<s1>(disp) && base != &RBP) {
677  code += (s1)disp;
678  }
679  else {
680  code += (u1) 0xff & (disp >> 0x00);
681  code += (u1) 0xff & (disp >> 0x08);
682  code += (u1) 0xff & (disp >> 0x10);
683  code += (u1) 0xff & (disp >> 0x18);
684  }
685  }
686  switch(op_size) {
687  case GPInstruction::OS_8:
688  {
689  s1 immval = src_imm->get_value<s1>();
690  code += (u1) 0xff & (immval >> 0x00);
691  break;
692  }
694  {
695  s2 immval = src_imm->get_value<s2>();
696  code += (u1) 0xff & (immval >> 0x00);
697  code += (u1) 0xff & (immval >> 0x08);
698  break;
699  }
701  {
702  s4 immval = src_imm->get_value<s4>();
703  code += (u1) 0xff & (immval >> 0x00);
704  code += (u1) 0xff & (immval >> 0x08);
705  code += (u1) 0xff & (immval >> 0x10);
706  code += (u1) 0xff & (immval >> 0x18);
707  break;
708  }
710  {
711  if (disp != 0) {
712  ABORT_MSG("Invalid Immediate Size (imm64 with disp not allowed)",
713  "dst: " << dst_mod << " src: " << src_imm << " op_code: " << primary_opcode);
714  }
715  s8 immval = src_imm->get_value<s8>();
716  code += (u1) 0xff & (immval >> 0x00);
717  code += (u1) 0xff & (immval >> 0x08);
718  code += (u1) 0xff & (immval >> 0x10);
719  code += (u1) 0xff & (immval >> 0x18);
720  code += (u1) 0xff & (immval >> 0x20);
721  code += (u1) 0xff & (immval >> 0x28);
722  code += (u1) 0xff & (immval >> 0x30);
723  code += (u1) 0xff & (immval >> 0x38);
724  break;
725  }
727  ABORT_MSG("Invalid Immediate Size",
728  "dst: " << dst_mod << " src: " << src_imm << " op_code: " << primary_opcode);
729  break;
730  }
731  }
732  else {
733  ABORT_MSG("Operand(s) not supported",
734  "dst: " << dst_mod << " src: " << src << " op_code: " << primary_opcode);
735  }
736  }
737  else {
738  ABORT_MSG("Operand(s) not supported!",
739  "dst: " << dst << " src: " << src << " op_code: " << primary_opcode);
740  }
741 
742 
743  add_CodeSegmentBuilder(CM,code);
744  }
745 
746 };
747 #if 0
748 template <>
749 static void InstructionEncoding::reg2reg<u1>(
750  CodeMemory *CM, u1 opcode,
751  X86_64Register *src, X86_64Register *dst) {
752  CodeFragment code = CM->get_CodeFragment(3);
753  code[0] = get_rex(src,dst);
754  code[1] = opcode;
755  code[2] = get_modrm_reg2reg(src,dst);
756 }
757 #endif
758 
759 } // end namespace x86_64
760 } // end namespace compiler2
761 } // end namespace jit
762 } // end namespace cacao
763 
764 #endif /* _JIT_COMPILER2_X86_64EMITHELPER */
765 
766 
767 /*
768  * These are local overrides for various environment variables in Emacs.
769  * Please do not remove this and leave it at the end of the file, where
770  * Emacs will automagically detect them.
771  * ---------------------------------------------------------------------
772  * Local variables:
773  * mode: c++
774  * indent-tabs-mode: t
775  * c-basic-offset: 4
776  * tab-width: 4
777  * End:
778  * vim:noexpandtab:sw=4:ts=4:
779  */
jlong jlong jlong jlong jint jmethodID jint slot
Definition: jvmti.h:497
std::size_t index
X86_64Register * cast_to< X86_64Register >(Register *reg)
CodeFragment get_CodeFragment(std::size_t size)
get a code fragment
Definition: CodeMemory.cpp:79
u1 get_modrm(u1 reg, u1 base, s4 disp, bool use_sib=false)
static void reg2rbp_disp8(CodeMemory *CM, T opcode, X86_64Register *reg, s1 disp)
virtual StackSlot * to_StackSlot()
FIXME this should be managed.
u1 get_modrm_reg2reg(X86_64Register *reg, X86_64Register *rm)
static void reg2reg(CodeMemory *CM, T opcode, X86_64Register *reg, X86_64Register *rm)
u2 op
Definition: disass.cpp:129
alloc::set< EdgeType >::type mod
u1 get_modrm_1reg(u1 reg, X86_64Register *rm)
std::deque< T, Allocator< T > > type
Definition: deque.hpp:38
static void imm_op(CodeMemory *CM, O opcode, I imm)
void add_CodeSegmentBuilder(CodeMemory *CM, const CodeSegmentBuilder &CSB)
X86_64Register * operator*() const
uint8_t u1
Definition: types.hpp:40
u1 get_sib(X86_64Register *base, X86_64Register *index=NULL, u1 scale=1)
Extension of the ModR/M reg field.
int64_t s8
Definition: types.hpp:48
bool use_sib(X86_64Register *base, X86_64Register *index)
GPRegister R12("R12", 0x4, true, 0xc *8, 8)
u1 get_rex(X86_64Register *reg, X86_64Register *rm=NULL, bool opsiz64=true)
Extension of the SIB index field.
static void reg2imm(CodeMemory *CM, O opcode, X86_64Register *reg, I imm)
GPRegister RBP("RBP", 0x5, false, 0x5 *8, 8)
0 = Operand size determined by CS.D 1 = 64 Bit Operand Size
X86_64ModRMOperand * cast_to< X86_64ModRMOperand >(MachineOperand *op)
StackSlot * cast_to< StackSlot >(MachineOperand *op)
std::size_t size() const
size of the reference
Definition: Segment.hpp:392
X86_64Register * operator->() const
MIIterator i
int32_t s4
Definition: types.hpp:45
Immediate * cast_to< Immediate >(MachineOperand *op)
static void emit(CodeMemory *CM, u1 primary_opcode, GPInstruction::OperandSize op_size, MachineOperand *src, MachineOperand *dst, u1 secondary_opcode=0, u1 op_reg=0, u1 prefix=0, bool prefix_0f=false, bool encode_dst=true, bool imm_sign_extended=false)
static void reg2imm_modrm(CodeMemory *CM, O opcode, X86_64Register *reg, X86_64Register *rm, I imm)
MIIterator e
u1 get_modrm_u1(u1 mod, u1 reg, u1 rm)
#define I(value)
Definition: codegen.c:279
Operands that can be directly used by the machine (register, memory, stackslot)
int8_t s1
Definition: types.hpp:39
int16_t s2
Definition: types.hpp:42
Extension of the ModR/M r/m field, SIB base field, or Opcode reg field.
Segment reference.
Definition: Segment.hpp:44
static void imm_op(CodeFragment &code, O opcode, I imm)
static void reg2rbp_disp32(CodeMemory *CM, T opcode, X86_64Register *reg, s4 disp)
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:133
GPRegister RSP("RSP", 0x4, false, 0x4 *8, 8)