CACAO
X86_64ModRMOperand.hpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/x86_64/X86_64ModRMOperand.hpp - X86_64ModRMOperand
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_64MODRMOPERAND
26 #define _JIT_COMPILER2_X86_64MODRMOPERAND
27 
32 
33 #include "toolbox/logging.hpp"
34 
36 
37 namespace cacao {
38 namespace jit {
39 namespace compiler2 {
40 namespace x86_64 {
41 
42 struct IndexOp {
44  explicit IndexOp(MachineOperand *op) : op(op) {}
45 };
46 
47 struct BaseOp {
49  explicit BaseOp(MachineOperand *op) : op(op) {}
50 };
51 
52 class X86_64ModRMOperand;
53 
54 class NativeAddress : public MachineAddress {
55 public:
56 
57  /// Construct a NativeAddress.
58  ///
59  /// @param type The type of the data referenced by this NativeAddress.
61 
62  virtual NativeAddress *to_NativeAddress();
64 };
65 
67 public:
68  enum ScaleFactor {
69  Scale1 = 0,
70  Scale2 = 1,
71  Scale4 = 2,
72  Scale8 = 3
73  };
74 
76  : NativeAddress(type)
77  ,disp(0)
78  ,scale(Scale1)
79  ,base86_64(NULL)
80  ,index86_64(NULL) {
82  }
84  : NativeAddress(type)
85  ,disp(disp)
86  ,scale(Scale1)
87  ,base86_64(NULL)
88  ,index86_64(NULL) {
90  }
92  : NativeAddress(type)
93  ,disp(disp)
94  ,scale(scale)
95  ,base86_64(NULL)
96  ,index86_64(NULL) {
98  if (index.op != NULL)
100  }
102  : NativeAddress(type)
103  ,disp(disp)
104  ,scale(get_scale(scale_type))
105  ,base86_64(NULL)
106  ,index86_64(NULL) {
108  if (index.op != NULL)
109  embedded_operands.push_back(EmbeddedMachineOperand(index.op));
110  }
112  : NativeAddress(type)
113  ,disp(disp)
114  ,scale(Scale1)
115  ,base86_64(NULL)
116  ,index86_64(NULL) {
118  if (index.op != NULL)
119  embedded_operands.push_back(EmbeddedMachineOperand(index.op));
120  }
121 
122  virtual const char* get_name() const {
123  return "ModRMOperand";
124  }
126  virtual OStream& print(OStream &OS) const {
127  if (disp)
128  OS << disp;
129  OS << '(';
130  if (embedded_operands[base].real && embedded_operands[base].real->op)
131  OS << embedded_operands[base].real->op;
132  else if (embedded_operands[base].dummy)
133  OS << embedded_operands[base].dummy;
134  OS << ',';
135  if (op_size() > index) {
136  if (embedded_operands[index].real && embedded_operands[index].real->op)
137  OS << embedded_operands[index].real->op;
138  else if (embedded_operands[index].dummy)
139  OS << embedded_operands[index].dummy;
140  }
141  OS << ',';
142  OS << (1 << scale);
143  OS << ')';
144  return OS;
145  }
146 
147 
148  void prepareEmit();
149  u1 getRex(const X86_64Register &reg, bool opsiz64);
150  bool useSIB();
151  u1 getModRM(const X86_64Register &reg);
152  u1 getSIB(const X86_64Register &reg);
153  bool useDisp8();
154  bool useDisp32();
155  s1 getDisp8();
156  s1 getDisp32_1();
157  s1 getDisp32_2();
158  s1 getDisp32_3();
159  s1 getDisp32_4();
161  static ScaleFactor get_scale(int32_t scale);
163  if (embedded_operands[base].real->op)
165  else
166  return &RBP;
167  }
168 
170  if (op_size() > index)
172  else
173  return NULL;
174  }
175 
176  inline s4 getDisp() {
177  return disp;
178  }
179 
180  inline u1 getScale() {
181  return scale;
182  }
183 
184 private:
185  const static unsigned base = 0;
186  const static unsigned index = 1;
191 };
192 
193 template <>
195  Address *addr = op->to_Address();
196  assert(addr);
197  MachineAddress *maddr = addr->to_MachineAddress();
198  assert(maddr);
199  NativeAddress *naddr = maddr->to_NativeAddress();
200  assert(naddr);
201  X86_64ModRMOperand *modrm = naddr->to_X86_64ModRMOperand();
202  assert(modrm);
203  return modrm;
204 }
205 
206 } // end namespace x86_64
207 } // end namespace compiler2
208 } // end namespace jit
209 } // end namespace cacao
210 
211 #endif /* _JIT_COMPILER2_X86_64MODRMOPERAND */
212 
213 
214 /*
215  * These are local overrides for various environment variables in Emacs.
216  * Please do not remove this and leave it at the end of the file, where
217  * Emacs will automagically detect them.
218  * ---------------------------------------------------------------------
219  * Local variables:
220  * mode: c++
221  * indent-tabs-mode: t
222  * c-basic-offset: 4
223  * tab-width: 4
224  * End:
225  * vim:noexpandtab:sw=4:ts=4:
226  */
virtual NativeAddress * to_NativeAddress()=0
u1 getRex(const X86_64Register &reg, bool opsiz64)
X86_64Register * cast_to< X86_64Register >(Register *reg)
X86_64ModRMOperand(Type::TypeID type, const BaseOp &base)
virtual OStream & print(OStream &OS) const
X86_64ModRMOperand(Type::TypeID type, const BaseOp &base, s4 disp)
u2 op
Definition: disass.cpp:129
uint8_t u1
Definition: types.hpp:40
virtual X86_64ModRMOperand * to_X86_64ModRMOperand()=0
GPRegister RBP("RBP", 0x5, false, 0x5 *8, 8)
X86_64ModRMOperand * cast_to< X86_64ModRMOperand >(MachineOperand *op)
X86_64ModRMOperand(Type::TypeID type, const BaseOp &base, const IndexOp &index, ScaleFactor scale, s4 disp=0)
Simple stream class for formatted output.
Definition: OStream.hpp:141
X86_64ModRMOperand(Type::TypeID type, const BaseOp &base, const IndexOp &index, Type::TypeID scale_type, s4 disp=0)
static ScaleFactor get_scale(Type::TypeID type)
int32_t s4
Definition: types.hpp:45
NativeAddress(Type::TypeID type)
Construct a NativeAddress.
OStream & OS
virtual MachineAddress * to_MachineAddress()=0
Operands that can be directly used by the machine (register, memory, stackslot)
int8_t s1
Definition: types.hpp:39
embedded_operand_list embedded_operands
TODO describe.
X86_64ModRMOperand(Type::TypeID type, const BaseOp &base, const IndexOp &index, s4 disp)