]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/plr/server/src/asmjit/Compiler.cc
update
[l4.git] / l4 / pkg / plr / server / src / asmjit / Compiler.cc
1 // AsmJit - Complete JIT Assembler for C++ Language.
2
3 // Copyright (c) 2008-2010, Petr Kobalicek <kobalicek.petr@gmail.com>
4 //
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
12 // conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 // OTHER DEALINGS IN THE SOFTWARE.
25
26 // We are using sprintf() here.
27 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
28 #define _CRT_SECURE_NO_WARNINGS
29 #endif // _MSC_VER
30
31 // [Dependencies]
32 #include "Assembler.h"
33 #include "Compiler.h"
34 #include "CpuInfo.h"
35 #include "Logger.h"
36 #include "Util.h"
37
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41
42 // [Api-Begin]
43 #include "ApiBegin.h"
44
45 namespace AsmJit {
46
47 // ============================================================================
48 // [AsmJit::Emittable]
49 // ============================================================================
50
51 Emittable::Emittable(Compiler* c, uint32_t type) ASMJIT_NOTHROW :
52   _compiler(c),
53   _next(NULL),
54   _prev(NULL),
55   _comment(NULL),
56   _type((uint8_t)type),
57   _translated(false),
58   _reserved0(0),
59   _reserved1(0),
60   _offset(INVALID_VALUE)
61 {
62 }
63
64 Emittable::~Emittable() ASMJIT_NOTHROW
65 {
66 }
67
68 void Emittable::prepare(CompilerContext& cc) ASMJIT_NOTHROW
69 {
70   _offset = cc._currentOffset;
71 }
72
73 Emittable* Emittable::translate(CompilerContext& cc) ASMJIT_NOTHROW
74 {
75   return translated();
76 }
77
78 void Emittable::emit(Assembler& a) ASMJIT_NOTHROW
79 {
80 }
81
82 void Emittable::post(Assembler& a) ASMJIT_NOTHROW
83 {
84 }
85
86 int Emittable::getMaxSize() const ASMJIT_NOTHROW
87 {
88   // Default maximum size is -1 which means that it's not known.
89   return -1;
90 }
91
92 bool Emittable::_tryUnuseVar(VarData* v) ASMJIT_NOTHROW
93 {
94   return false;
95 }
96
97 void Emittable::setComment(const char* str) ASMJIT_NOTHROW
98 {
99   _comment = _compiler->getZone().zstrdup(str);
100 }
101
102 void Emittable::setCommentF(const char* fmt, ...) ASMJIT_NOTHROW
103 {
104   // I'm really not expecting larger inline comments:)
105   char buf[256];
106
107   va_list ap;
108   va_start(ap, fmt);
109   vsnprintf(buf, 255, fmt, ap);
110   va_end(ap);
111
112   // I don't know if vsnprintf can produce non-null terminated string, in case
113   // it can, we terminate it here.
114   buf[255] = '\0';
115
116   setComment(buf);
117 }
118
119 // ============================================================================
120 // [AsmJit::EDummy]
121 // ============================================================================
122
123 EDummy::EDummy(Compiler* c) ASMJIT_NOTHROW :
124   Emittable(c, EMITTABLE_DUMMY)
125 {
126 }
127
128 EDummy::~EDummy() ASMJIT_NOTHROW
129 {
130 }
131
132 int EDummy::getMaxSize() const ASMJIT_NOTHROW
133 {
134   return 0;
135 }
136
137 // ============================================================================
138 // [AsmJit::EFunctionEnd]
139 // ============================================================================
140
141 EFunctionEnd::EFunctionEnd(Compiler* c) ASMJIT_NOTHROW :
142   EDummy(c)
143 {
144   _type = EMITTABLE_FUNCTION_END;
145 }
146
147 EFunctionEnd::~EFunctionEnd() ASMJIT_NOTHROW
148 {
149 }
150
151 Emittable* EFunctionEnd::translate(CompilerContext& cc) ASMJIT_NOTHROW
152 {
153   _translated = true;
154   return NULL;
155 }
156
157 // ============================================================================
158 // [AsmJit::EComment]
159 // ============================================================================
160
161 EComment::EComment(Compiler* c, const char* str) ASMJIT_NOTHROW :
162   Emittable(c, EMITTABLE_COMMENT)
163 {
164   setComment(str);
165 }
166
167 EComment::~EComment() ASMJIT_NOTHROW
168 {
169 }
170
171 void EComment::emit(Assembler& a) ASMJIT_NOTHROW
172 {
173   if (a.getLogger())
174   {
175     a.getLogger()->logString(getComment());
176   }
177 }
178
179 int EComment::getMaxSize() const ASMJIT_NOTHROW
180 {
181   return 0;
182 }
183
184 // ============================================================================
185 // [AsmJit::EData]
186 // ============================================================================
187
188 EData::EData(Compiler* c, const void* data, sysuint_t length) ASMJIT_NOTHROW :
189   Emittable(c, EMITTABLE_EMBEDDED_DATA)
190 {
191   _length = length;
192   memcpy(_data, data, length);
193 }
194
195 EData::~EData() ASMJIT_NOTHROW
196 {
197 }
198
199 void EData::emit(Assembler& a) ASMJIT_NOTHROW
200 {
201   a.embed(_data, _length);
202 }
203
204 int EData::getMaxSize() const ASMJIT_NOTHROW
205 {
206   return (int)_length;;
207 }
208
209 // ============================================================================
210 // [AsmJit::EAlign]
211 // ============================================================================
212
213 EAlign::EAlign(Compiler* c, uint32_t size) ASMJIT_NOTHROW :
214   Emittable(c, EMITTABLE_ALIGN), _size(size)
215 {
216 }
217
218 EAlign::~EAlign() ASMJIT_NOTHROW
219 {
220 }
221
222 void EAlign::emit(Assembler& a) ASMJIT_NOTHROW
223 {
224   a.align(_size);
225 }
226
227 int EAlign::getMaxSize() const ASMJIT_NOTHROW
228 {
229   return (_size > 0) ? (int)_size - 1 : 0;
230 }
231
232 // ============================================================================
233 // [AsmJit::ETarget]
234 // ============================================================================
235
236 ETarget::ETarget(Compiler* c, const Label& label) ASMJIT_NOTHROW :
237   Emittable(c, EMITTABLE_TARGET),
238   _label(label),
239   _from(NULL),
240   _state(NULL),
241   _jumpsCount(0)
242 {
243 }
244
245 ETarget::~ETarget() ASMJIT_NOTHROW
246 {
247 }
248
249 void ETarget::prepare(CompilerContext& cc) ASMJIT_NOTHROW
250 {
251   _offset = cc._currentOffset++;
252 }
253
254 Emittable* ETarget::translate(CompilerContext& cc) ASMJIT_NOTHROW
255 {
256   // If this ETarget was already translated, it's needed to change the current
257   // state and return NULL to tell CompilerContext to process next untranslated
258   // emittable.
259   if (_translated)
260   {
261     cc._restoreState(_state);
262     return NULL;
263   }
264
265   if (cc._unrecheable)
266   {
267     cc._unrecheable = 0;
268
269     // Assign state to the compiler context. 
270     ASMJIT_ASSERT(_state != NULL);
271     cc._assignState(_state);
272   }
273   else
274   {
275     _state = cc._saveState();
276   }
277
278   return translated();
279 }
280
281 void ETarget::emit(Assembler& a) ASMJIT_NOTHROW
282 {
283   a.bind(_label);
284 }
285
286 int ETarget::getMaxSize() const ASMJIT_NOTHROW
287 {
288   return 0;
289 }
290
291 } // AsmJit namespace