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:
57  virtual NativeAddress *to_NativeAddress();
59 };
60 
62 public:
63  enum ScaleFactor {
64  Scale1 = 0,
65  Scale2 = 1,
66  Scale4 = 2,
67  Scale8 = 3
68  };
69 
71  : disp(0)
72  ,scale(Scale1)
73  ,base86_64(NULL)
74  ,index86_64(NULL) {
76  }
78  : disp(disp)
79  ,scale(Scale1)
80  ,base86_64(NULL)
81  ,index86_64(NULL) {
83  }
85  : disp(disp)
86  ,scale(scale)
87  ,base86_64(NULL)
88  ,index86_64(NULL) {
90  if (index.op != NULL)
92  }
94  : disp(disp)
95  ,scale(get_scale(type))
96  ,base86_64(NULL)
97  ,index86_64(NULL) {
99  if (index.op != NULL)
100  embedded_operands.push_back(EmbeddedMachineOperand(index.op));
101  }
103  : disp(disp)
104  ,scale(Scale1)
105  ,base86_64(NULL)
106  ,index86_64(NULL) {
107  embedded_operands.push_back(EmbeddedMachineOperand(base.op));
108  if (index.op != NULL)
109  embedded_operands.push_back(EmbeddedMachineOperand(index.op));
110  }
111 
112  virtual const char* get_name() const {
113  return "ModRMOperand";
114  }
116  virtual OStream& print(OStream &OS) const {
117  if (disp)
118  OS << disp;
119  OS << '(';
120  if (embedded_operands[base].real && embedded_operands[base].real->op)
121  OS << embedded_operands[base].real->op;
122  else if (embedded_operands[base].dummy)
123  OS << embedded_operands[base].dummy;
124  OS << ',';
125  if (op_size() > index) {
126  if (embedded_operands[index].real && embedded_operands[index].real->op)
127  OS << embedded_operands[index].real->op;
128  else if (embedded_operands[index].dummy)
129  OS << embedded_operands[index].dummy;
130  }
131  OS << ',';
132  OS << (1 << scale);
133  OS << ')';
134  return OS;
135  }
136 
137 
138  void prepareEmit();
139  u1 getRex(const X86_64Register &reg, bool opsiz64);
140  bool useSIB();
141  u1 getModRM(const X86_64Register &reg);
142  u1 getSIB(const X86_64Register &reg);
143  bool useDisp8();
144  bool useDisp32();
145  s1 getDisp8();
146  s1 getDisp32_1();
147  s1 getDisp32_2();
148  s1 getDisp32_3();
149  s1 getDisp32_4();
151  static ScaleFactor get_scale(int32_t scale);
153  if (embedded_operands[base].real->op)
155  else
156  return &RBP;
157  }
158 
160  if (op_size() > index)
162  else
163  return NULL;
164  }
165 
166  inline s4 getDisp() {
167  return disp;
168  }
169 
170  inline u1 getScale() {
171  return scale;
172  }
173 
174 private:
175  const static unsigned base = 0;
176  const static unsigned index = 1;
181 };
182 
183 template <>
185  Address *addr = op->to_Address();
186  assert(addr);
187  MachineAddress *maddr = addr->to_MachineAddress();
188  assert(maddr);
189  NativeAddress *naddr = maddr->to_NativeAddress();
190  assert(naddr);
191  X86_64ModRMOperand *modrm = naddr->to_X86_64ModRMOperand();
192  assert(modrm);
193  return modrm;
194 }
195 
196 } // end namespace x86_64
197 } // end namespace compiler2
198 } // end namespace jit
199 } // end namespace cacao
200 
201 #endif /* _JIT_COMPILER2_X86_64MODRMOPERAND */
202 
203 
204 /*
205  * These are local overrides for various environment variables in Emacs.
206  * Please do not remove this and leave it at the end of the file, where
207  * Emacs will automagically detect them.
208  * ---------------------------------------------------------------------
209  * Local variables:
210  * mode: c++
211  * indent-tabs-mode: t
212  * c-basic-offset: 4
213  * tab-width: 4
214  * End:
215  * vim:noexpandtab:sw=4:ts=4:
216  */
virtual NativeAddress * to_NativeAddress()=0
u1 getRex(const X86_64Register &reg, bool opsiz64)
X86_64Register * cast_to< X86_64Register >(Register *reg)
virtual OStream & print(OStream &OS) const
u2 op
Definition: disass.cpp:129
uint8_t u1
Definition: types.hpp:40
X86_64ModRMOperand(const BaseOp &base, const IndexOp &index, Type::TypeID type, s4 disp=0)
virtual X86_64ModRMOperand * to_X86_64ModRMOperand()=0
GPRegister RBP("RBP", 0x5, false, 0x5 *8, 8)
X86_64ModRMOperand * cast_to< X86_64ModRMOperand >(MachineOperand *op)
Simple stream class for formatted output.
Definition: OStream.hpp:141
static ScaleFactor get_scale(Type::TypeID type)
int32_t s4
Definition: types.hpp:45
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
X86_64ModRMOperand(const BaseOp &base, const IndexOp &index, ScaleFactor scale, s4 disp=0)
embedded_operand_list embedded_operands
TODO describe.
X86_64ModRMOperand(const BaseOp &base, const IndexOp &index, s4 disp)