CACAO
X86_64Register.hpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/X86_64Register.hpp - X86_64Register
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_64REGISTER
26 #define _JIT_COMPILER2_X86_64REGISTER
27 
30 
31 #include "toolbox/logging.hpp"
32 
34 
35 namespace cacao {
36 namespace jit {
37 namespace compiler2 {
38 namespace x86_64 {
39 
40 /**
41  * x86_64 Register
42  */
43 
45 public:
46  const unsigned index;
47  const bool extented;
48  const char* name;
51 
52  X86_64Register(const char* name,unsigned index,bool extented,
55  : index(index), extented(extented), name(name), offset(offset),
56  size(size) {}
57  unsigned get_index() const {
58  return index;
59  }
60  virtual MachineOperand::IdentifyTy id_base() const = 0;
62  virtual MachineOperand::IdentifySizeTy id_size() const { return size; }
63 };
64 
66 public:
67  const unsigned index;
68 
69  FPUStackRegister(unsigned index) : index(index) {}
70 };
71 
72 /**
73  * This represents a machine register usage.
74  *
75  * It consists of a reference to the physical register and a type. This
76  * abstraction is needed because registers can be used several times
77  * with different types, e.g. DH vs. eDX vs. EDX vs. RDX.
78  */
80 private:
82 public:
85  return this;
86  }
88  return reg;
89  }
90  virtual IdentifyTy id_base() const { return reg->id_base(); }
91  virtual IdentifyOffsetTy id_offset() const { return reg->id_offset(); }
92  virtual IdentifySizeTy id_size() const { return reg->id_size(); }
93 };
94 
95 inline OStream& operator<<(OStream &OS, const X86_64Register& reg) {
96  return OS << reg.name;
97 }
98 
99 class GPRegister : public X86_64Register {
100 private:
101  static const uint8_t base;
102 public:
103  GPRegister(const char* name,unsigned index,bool extented_gpr,
106  : X86_64Register(name,index,extented_gpr, offset, size) {}
107  virtual MachineOperand::IdentifyTy id_base() const { return static_cast<const void*>(&base); }
108 };
109 
110 class SSERegister : public X86_64Register {
111 private:
112  static const uint8_t base;
113 public:
114  SSERegister(const char* name,unsigned index,bool extented_gpr,
117  : X86_64Register(name,index,extented_gpr, offset, size) {}
118  virtual MachineOperand::IdentifyTy id_base() const { return static_cast<const void*>(&base); }
119 };
120 
121 template <>
123  Register *reg = op->to_Register();
124  assert(reg);
125  return reg;
126 }
127 
128 template <>
130  MachineRegister *mreg = reg->to_MachineRegister();
131  assert(mreg);
132  NativeRegister *nreg = mreg->to_NativeRegister();
133  assert(nreg);
134  X86_64Register *xreg = nreg->get_X86_64Register();
135  assert(xreg);
136  return xreg;
137 }
138 
139 template <>
141  Register *reg = op->to_Register();
142  assert(reg);
143  MachineRegister *mreg = reg->to_MachineRegister();
144  assert(mreg);
145  NativeRegister *nreg = mreg->to_NativeRegister();
146  assert(nreg);
147  X86_64Register *xreg = nreg->get_X86_64Register();
148  assert(xreg);
149  return xreg;
150 }
151 
152 template <>
154  assert(reg);
155  return reg;
156 }
157 
166 extern GPRegister R8;
167 extern GPRegister R9;
174 
175 const unsigned IntegerArgumentRegisterSize = 6;
177 
194 
195 
204 
205 
206 const unsigned FloatArgumentRegisterSize = 8;
208 #if 0
209 class RegisterFile : public compiler2::RegisterFile {
210 public:
211  RegisterFile(Type::TypeID type) {
212  switch (type) {
213  case Type::ByteTypeID:
214  case Type::IntTypeID:
215  case Type::LongTypeID:
217  #if 1
218  for(unsigned i = 0; i < IntegerArgumentRegisterSize ; ++i) {
219  regs.push_back(IntegerArgumentRegisters[i]);
220  }
221  assert(regs.size() == IntegerArgumentRegisterSize);
222  #else
223  regs.push_back(&RDI);
224  regs.push_back(&RSI);
225  regs.push_back(&RDX);
226  #if 0
227  regs.push_back(&RCX);
228  regs.push_back(&R8);
229  regs.push_back(&R9);
230  #endif
231  #endif
232  return;
233  case Type::DoubleTypeID:
234  #if 1
235  for(unsigned i = 0; i < FloatArgumentRegisterSize ; ++i) {
236  regs.push_back(FloatArgumentRegisters[i]);
237  }
238  assert(regs.size() == FloatArgumentRegisterSize);
239  #else
240  regs.push_back(&XMM0);
241  regs.push_back(&XMM1);
242  regs.push_back(&XMM2);
243  #endif
244  return;
245  default: break;
246  }
247  ABORT_MSG("X86_64 Register File Type Not supported!",
248  "Type: " << type);
249  }
250 };
251 #endif
252 } // end namespace x86_64
253 } // end namespace compiler2
254 } // end namespace jit
255 } // end namespace cacao
256 
257 #endif /* _JIT_COMPILER2_X86_64REGISTER */
258 
259 
260 /*
261  * These are local overrides for various environment variables in Emacs.
262  * Please do not remove this and leave it at the end of the file, where
263  * Emacs will automagically detect them.
264  * ---------------------------------------------------------------------
265  * Local variables:
266  * mode: c++
267  * indent-tabs-mode: t
268  * c-basic-offset: 4
269  * tab-width: 4
270  * End:
271  * vim:noexpandtab:sw=4:ts=4:
272  */
GPRegister RDX("RDX", 0x2, false, 0x2 *8, 8)
virtual MachineOperand::IdentifyTy id_base() const =0
const MachineOperand::IdentifySizeTy size
GPRegister R9("R9", 0x1, true, 0x9 *8, 8)
X86_64Register * cast_to< X86_64Register >(Register *reg)
const unsigned IntegerArgumentRegisterSize
char * regs[]
Definition: disass.c:51
This represents a machine register usage.
Register * cast_to< Register >(MachineOperand *op)
GPRegister(const char *name, unsigned index, bool extented_gpr, MachineOperand::IdentifyOffsetTy offset, MachineOperand::IdentifySizeTy size)
SSERegister XMM6("XMM6", 0x6, false, 0x6 *16, 16)
GPRegister R11("R11", 0x3, true, 0xb *8, 8)
u2 op
Definition: disass.cpp:129
SSERegister XMM9("XMM9", 0x1, true, 0x9 *16, 16)
SSERegister * FloatArgumentRegisters[]
SSERegister XMM1("XMM1", 0x1, false, 0x1 *16, 16)
SSERegister XMM4("XMM4", 0x4, false, 0x4 *16, 16)
SSERegister XMM12("XMM12", 0x4, true, 0xc *16, 16)
virtual MachineOperand::IdentifyTy id_base() const
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
GPRegister R12("R12", 0x4, true, 0xc *8, 8)
X86_64Register(const char *name, unsigned index, bool extented, MachineOperand::IdentifyOffsetTy offset, MachineOperand::IdentifySizeTy size)
GPRegister R14("R14", 0x6, true, 0xe *8, 8)
GPRegister RSI("RSI", 0x6, false, 0x6 *8, 8)
SSERegister XMM10("XMM10", 0x2, true, 0xa *16, 16)
SSERegister XMM2("XMM2", 0x2, false, 0x2 *16, 16)
virtual MachineOperand::IdentifyOffsetTy id_offset() const
OStream & operator<<(OStream &OS, const ModRMOperandDesc &modrm)
GPRegister RBP("RBP", 0x5, false, 0x5 *8, 8)
virtual MachineOperand::IdentifySizeTy id_size() const
SSERegister(const char *name, unsigned index, bool extented_gpr, MachineOperand::IdentifyOffsetTy offset, MachineOperand::IdentifySizeTy size)
Simple stream class for formatted output.
Definition: OStream.hpp:141
MIIterator i
virtual MachineRegister * to_MachineRegister()
virtual IdentifySizeTy id_size() const
const unsigned FloatArgumentRegisterSize
GPRegister * IntegerArgumentRegisters[]
GPRegister R15("R15", 0x7, true, 0xf *8, 8)
OStream & OS
SSERegister XMM5("XMM5", 0x5, false, 0x5 *16, 16)
GPRegister R13("R13", 0x5, true, 0xd *8, 8)
SSERegister XMM13("XMM13", 0x5, true, 0xd *16, 16)
NativeRegister(Type::TypeID type, X86_64Register *reg)
GPRegister RDI("RDI", 0x7, false, 0x7 *8, 8)
GPRegister RCX("RCX", 0x1, false, 0x1 *8, 8)
virtual NativeRegister * to_NativeRegister()=0
virtual MachineRegister * to_MachineRegister()
Operands that can be directly used by the machine (register, memory, stackslot)
GPRegister R10("R10", 0x2, true, 0xa *8, 8)
virtual MachineOperand::IdentifyTy id_base() const
SSERegister XMM7("XMM7", 0x7, false, 0x7 *16, 16)
GPRegister RAX("RAX", 0x0, false, 0x0 *8, 8)
SSERegister XMM8("XMM8", 0x0, true, 0x8 *16, 16)
SSERegister XMM3("XMM3", 0x3, false, 0x3 *16, 16)
SSERegister XMM0("XMM0", 0x0, false, 0x0 *16, 16)
virtual IdentifyOffsetTy id_offset() const
SSERegister XMM14("XMM14", 0x6, true, 0xe *16, 16)
SSERegister XMM11("XMM11", 0x3, true, 0xb *16, 16)
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:133
GPRegister R8("R8", 0x0, true, 0x8 *8, 8)
GPRegister RBX("RBX", 0x3, false, 0x3 *8, 8)
const MachineOperand::IdentifyOffsetTy offset
GPRegister RSP("RSP", 0x4, false, 0x4 *8, 8)
SSERegister XMM15("XMM15", 0x7, true, 0xf *16, 16)