Mercurial > hg > graal-compiler
comparison src/share/vm/asm/assembler.hpp @ 7206:d2f8c38e543d
Merge
author | roland |
---|---|
date | Fri, 07 Dec 2012 01:09:03 -0800 |
parents | f0c2369fda5a |
children | 18d56ca3e901 |
comparison
equal
deleted
inserted
replaced
7191:816b7e5bf2ed | 7206:d2f8c38e543d |
---|---|
23 */ | 23 */ |
24 | 24 |
25 #ifndef SHARE_VM_ASM_ASSEMBLER_HPP | 25 #ifndef SHARE_VM_ASM_ASSEMBLER_HPP |
26 #define SHARE_VM_ASM_ASSEMBLER_HPP | 26 #define SHARE_VM_ASM_ASSEMBLER_HPP |
27 | 27 |
28 #include "asm/codeBuffer.hpp" | |
28 #include "code/oopRecorder.hpp" | 29 #include "code/oopRecorder.hpp" |
29 #include "code/relocInfo.hpp" | 30 #include "code/relocInfo.hpp" |
30 #include "memory/allocation.hpp" | 31 #include "memory/allocation.hpp" |
31 #include "utilities/debug.hpp" | 32 #include "utilities/debug.hpp" |
32 #include "utilities/growableArray.hpp" | 33 #include "utilities/growableArray.hpp" |
33 #include "utilities/top.hpp" | 34 #include "utilities/top.hpp" |
35 | |
34 #ifdef TARGET_ARCH_x86 | 36 #ifdef TARGET_ARCH_x86 |
35 # include "register_x86.hpp" | 37 # include "register_x86.hpp" |
36 # include "vm_version_x86.hpp" | 38 # include "vm_version_x86.hpp" |
37 #endif | 39 #endif |
38 #ifdef TARGET_ARCH_sparc | 40 #ifdef TARGET_ARCH_sparc |
52 # include "vm_version_ppc.hpp" | 54 # include "vm_version_ppc.hpp" |
53 #endif | 55 #endif |
54 | 56 |
55 // This file contains platform-independent assembler declarations. | 57 // This file contains platform-independent assembler declarations. |
56 | 58 |
57 class CodeBuffer; | |
58 class MacroAssembler; | 59 class MacroAssembler; |
59 class AbstractAssembler; | 60 class AbstractAssembler; |
60 class Label; | 61 class Label; |
61 | 62 |
62 /** | 63 /** |
120 void bind_loc(int loc) { | 121 void bind_loc(int loc) { |
121 assert(loc >= 0, "illegal locator"); | 122 assert(loc >= 0, "illegal locator"); |
122 assert(_loc == -1, "already bound"); | 123 assert(_loc == -1, "already bound"); |
123 _loc = loc; | 124 _loc = loc; |
124 } | 125 } |
125 void bind_loc(int pos, int sect); // = bind_loc(locator(pos, sect)) | 126 void bind_loc(int pos, int sect) { bind_loc(CodeBuffer::locator(pos, sect)); } |
126 | 127 |
127 #ifndef PRODUCT | 128 #ifndef PRODUCT |
128 // Iterates over all unresolved instructions for printing | 129 // Iterates over all unresolved instructions for printing |
129 void print_instructions(MacroAssembler* masm) const; | 130 void print_instructions(MacroAssembler* masm) const; |
130 #endif // PRODUCT | 131 #endif // PRODUCT |
135 */ | 136 */ |
136 int loc() const { | 137 int loc() const { |
137 assert(_loc >= 0, "unbound label"); | 138 assert(_loc >= 0, "unbound label"); |
138 return _loc; | 139 return _loc; |
139 } | 140 } |
140 int loc_pos() const; // == locator_pos(loc()) | 141 int loc_pos() const { return CodeBuffer::locator_pos(loc()); } |
141 int loc_sect() const; // == locator_sect(loc()) | 142 int loc_sect() const { return CodeBuffer::locator_sect(loc()); } |
142 | 143 |
143 bool is_bound() const { return _loc >= 0; } | 144 bool is_bound() const { return _loc >= 0; } |
144 bool is_unbound() const { return _loc == -1 && _patch_index > 0; } | 145 bool is_unbound() const { return _loc == -1 && _patch_index > 0; } |
145 bool is_unused() const { return _loc == -1 && _patch_index == 0; } | 146 bool is_unused() const { return _loc == -1 && _patch_index == 0; } |
146 | 147 |
199 class AbstractAssembler : public ResourceObj { | 200 class AbstractAssembler : public ResourceObj { |
200 friend class Label; | 201 friend class Label; |
201 | 202 |
202 protected: | 203 protected: |
203 CodeSection* _code_section; // section within the code buffer | 204 CodeSection* _code_section; // section within the code buffer |
204 address _code_begin; // first byte of code buffer | |
205 address _code_limit; // first byte after code buffer | |
206 address _code_pos; // current code generation position | |
207 OopRecorder* _oop_recorder; // support for relocInfo::oop_type | 205 OopRecorder* _oop_recorder; // support for relocInfo::oop_type |
208 | 206 |
209 // Code emission & accessing | 207 // Code emission & accessing |
210 address addr_at(int pos) const { return _code_begin + pos; } | 208 address addr_at(int pos) const { return code_section()->start() + pos; } |
209 | |
211 | 210 |
212 // This routine is called with a label is used for an address. | 211 // This routine is called with a label is used for an address. |
213 // Labels and displacements truck in offsets, but target must return a PC. | 212 // Labels and displacements truck in offsets, but target must return a PC. |
214 address target(Label& L); // return _code_section->target(L) | 213 address target(Label& L) { return code_section()->target(L, pc()); } |
215 | 214 |
216 bool is8bit(int x) const { return -0x80 <= x && x < 0x80; } | 215 bool is8bit(int x) const { return -0x80 <= x && x < 0x80; } |
217 bool isByte(int x) const { return 0 <= x && x < 0x100; } | 216 bool isByte(int x) const { return 0 <= x && x < 0x100; } |
218 bool isShiftCount(int x) const { return 0 <= x && x < 32; } | 217 bool isShiftCount(int x) const { return 0 <= x && x < 32; } |
219 | 218 |
220 void emit_byte(int x); // emit a single byte | 219 void emit_int8( int8_t x) { code_section()->emit_int8( x); } |
221 void emit_word(int x); // emit a 16-bit word (not a wordSize word!) | 220 void emit_int16( int16_t x) { code_section()->emit_int16( x); } |
222 void emit_long(jint x); // emit a 32-bit word (not a longSize word!) | 221 void emit_int32( int32_t x) { code_section()->emit_int32( x); } |
223 void emit_address(address x); // emit an address (not a longSize word!) | 222 void emit_int64( int64_t x) { code_section()->emit_int64( x); } |
223 | |
224 void emit_float( jfloat x) { code_section()->emit_float( x); } | |
225 void emit_double( jdouble x) { code_section()->emit_double( x); } | |
226 void emit_address(address x) { code_section()->emit_address(x); } | |
227 | |
228 void emit_byte(int x) { emit_int8 (x); } // deprecated | |
229 void emit_word(int x) { emit_int16(x); } // deprecated | |
230 void emit_long(jint x) { emit_int32(x); } // deprecated | |
224 | 231 |
225 // Instruction boundaries (required when emitting relocatable values). | 232 // Instruction boundaries (required when emitting relocatable values). |
226 class InstructionMark: public StackObj { | 233 class InstructionMark: public StackObj { |
227 private: | 234 private: |
228 AbstractAssembler* _assm; | 235 AbstractAssembler* _assm; |
235 ~InstructionMark() { | 242 ~InstructionMark() { |
236 _assm->clear_inst_mark(); | 243 _assm->clear_inst_mark(); |
237 } | 244 } |
238 }; | 245 }; |
239 friend class InstructionMark; | 246 friend class InstructionMark; |
240 #ifdef ASSERT | 247 #ifdef ASSERT |
241 // Make it return true on platforms which need to verify | 248 // Make it return true on platforms which need to verify |
242 // instruction boundaries for some operations. | 249 // instruction boundaries for some operations. |
243 inline static bool pd_check_instruction_mark(); | 250 static bool pd_check_instruction_mark(); |
244 | 251 |
245 // Add delta to short branch distance to verify that it still fit into imm8. | 252 // Add delta to short branch distance to verify that it still fit into imm8. |
246 int _short_branch_delta; | 253 int _short_branch_delta; |
247 | 254 |
248 int short_branch_delta() const { return _short_branch_delta; } | 255 int short_branch_delta() const { return _short_branch_delta; } |
260 } | 267 } |
261 ~ShortBranchVerifier() { | 268 ~ShortBranchVerifier() { |
262 _assm->clear_short_branch_delta(); | 269 _assm->clear_short_branch_delta(); |
263 } | 270 } |
264 }; | 271 }; |
265 #else | 272 #else |
266 // Dummy in product. | 273 // Dummy in product. |
267 class ShortBranchVerifier: public StackObj { | 274 class ShortBranchVerifier: public StackObj { |
268 public: | 275 public: |
269 ShortBranchVerifier(AbstractAssembler* assm) {} | 276 ShortBranchVerifier(AbstractAssembler* assm) {} |
270 }; | 277 }; |
271 #endif | 278 #endif |
272 | 279 |
273 // Label functions | 280 // Label functions |
274 void print(Label& L); | 281 void print(Label& L); |
275 | 282 |
276 public: | 283 public: |
277 | 284 |
278 // Creation | 285 // Creation |
279 AbstractAssembler(CodeBuffer* code); | 286 AbstractAssembler(CodeBuffer* code); |
280 | |
281 // save end pointer back to code buf. | |
282 void sync(); | |
283 | 287 |
284 // ensure buf contains all code (call this before using/copying the code) | 288 // ensure buf contains all code (call this before using/copying the code) |
285 void flush(); | 289 void flush(); |
286 | 290 |
287 // min and max values for signed immediate ranges | 291 // min and max values for signed immediate ranges |
306 static bool is_simm16(intptr_t x) { return is_simm(x, 16); } | 310 static bool is_simm16(intptr_t x) { return is_simm(x, 16); } |
307 static bool is_simm26(intptr_t x) { return is_simm(x, 26); } | 311 static bool is_simm26(intptr_t x) { return is_simm(x, 26); } |
308 static bool is_simm32(intptr_t x) { return is_simm(x, 32); } | 312 static bool is_simm32(intptr_t x) { return is_simm(x, 32); } |
309 | 313 |
310 // Accessors | 314 // Accessors |
311 CodeBuffer* code() const; // _code_section->outer() | |
312 CodeSection* code_section() const { return _code_section; } | 315 CodeSection* code_section() const { return _code_section; } |
313 int sect() const; // return _code_section->index() | 316 CodeBuffer* code() const { return code_section()->outer(); } |
314 address pc() const { return _code_pos; } | 317 int sect() const { return code_section()->index(); } |
315 int offset() const { return _code_pos - _code_begin; } | 318 address pc() const { return code_section()->end(); } |
316 int locator() const; // CodeBuffer::locator(offset(), sect()) | 319 int offset() const { return code_section()->size(); } |
320 int locator() const { return CodeBuffer::locator(offset(), sect()); } | |
321 | |
317 OopRecorder* oop_recorder() const { return _oop_recorder; } | 322 OopRecorder* oop_recorder() const { return _oop_recorder; } |
318 void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; } | 323 void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; } |
319 | 324 |
320 address inst_mark() const; | 325 address inst_mark() const { return code_section()->mark(); } |
321 void set_inst_mark(); | 326 void set_inst_mark() { code_section()->set_mark(); } |
322 void clear_inst_mark(); | 327 void clear_inst_mark() { code_section()->clear_mark(); } |
323 | 328 |
324 // Constants in code | 329 // Constants in code |
325 void a_byte(int x); | 330 void a_byte(int x); |
326 void a_long(jint x); | 331 void a_long(jint x); |
327 void relocate(RelocationHolder const& rspec, int format = 0); | 332 void relocate(RelocationHolder const& rspec, int format = 0) { |
333 assert(!pd_check_instruction_mark() | |
334 || inst_mark() == NULL || inst_mark() == code_section()->end(), | |
335 "call relocate() between instructions"); | |
336 code_section()->relocate(code_section()->end(), rspec, format); | |
337 } | |
328 void relocate( relocInfo::relocType rtype, int format = 0) { | 338 void relocate( relocInfo::relocType rtype, int format = 0) { |
329 if (rtype != relocInfo::none) | 339 code_section()->relocate(code_section()->end(), rtype, format); |
330 relocate(Relocation::spec_simple(rtype), format); | |
331 } | 340 } |
332 | 341 |
333 static int code_fill_byte(); // used to pad out odd-sized code buffers | 342 static int code_fill_byte(); // used to pad out odd-sized code buffers |
334 | 343 |
335 // Associate a comment with the current offset. It will be printed | 344 // Associate a comment with the current offset. It will be printed |
346 // Inform assembler when generating stub code and relocation info | 355 // Inform assembler when generating stub code and relocation info |
347 address start_a_stub(int required_space); | 356 address start_a_stub(int required_space); |
348 void end_a_stub(); | 357 void end_a_stub(); |
349 // Ditto for constants. | 358 // Ditto for constants. |
350 address start_a_const(int required_space, int required_align = sizeof(double)); | 359 address start_a_const(int required_space, int required_align = sizeof(double)); |
351 void end_a_const(); | 360 void end_a_const(CodeSection* cs); // Pass the codesection to continue in (insts or stubs?). |
352 | 361 |
353 // constants support | 362 // constants support |
363 // | |
364 // We must remember the code section (insts or stubs) in c1 | |
365 // so we can reset to the proper section in end_a_const(). | |
354 address long_constant(jlong c) { | 366 address long_constant(jlong c) { |
367 CodeSection* c1 = _code_section; | |
355 address ptr = start_a_const(sizeof(c), sizeof(c)); | 368 address ptr = start_a_const(sizeof(c), sizeof(c)); |
356 if (ptr != NULL) { | 369 if (ptr != NULL) { |
357 *(jlong*)ptr = c; | 370 emit_int64(c); |
358 _code_pos = ptr + sizeof(c); | 371 end_a_const(c1); |
359 end_a_const(); | |
360 } | 372 } |
361 return ptr; | 373 return ptr; |
362 } | 374 } |
363 address double_constant(jdouble c) { | 375 address double_constant(jdouble c) { |
376 CodeSection* c1 = _code_section; | |
364 address ptr = start_a_const(sizeof(c), sizeof(c)); | 377 address ptr = start_a_const(sizeof(c), sizeof(c)); |
365 if (ptr != NULL) { | 378 if (ptr != NULL) { |
366 *(jdouble*)ptr = c; | 379 emit_double(c); |
367 _code_pos = ptr + sizeof(c); | 380 end_a_const(c1); |
368 end_a_const(); | |
369 } | 381 } |
370 return ptr; | 382 return ptr; |
371 } | 383 } |
372 address float_constant(jfloat c) { | 384 address float_constant(jfloat c) { |
385 CodeSection* c1 = _code_section; | |
373 address ptr = start_a_const(sizeof(c), sizeof(c)); | 386 address ptr = start_a_const(sizeof(c), sizeof(c)); |
374 if (ptr != NULL) { | 387 if (ptr != NULL) { |
375 *(jfloat*)ptr = c; | 388 emit_float(c); |
376 _code_pos = ptr + sizeof(c); | 389 end_a_const(c1); |
377 end_a_const(); | |
378 } | 390 } |
379 return ptr; | 391 return ptr; |
380 } | 392 } |
381 address address_constant(address c) { | 393 address address_constant(address c) { |
394 CodeSection* c1 = _code_section; | |
382 address ptr = start_a_const(sizeof(c), sizeof(c)); | 395 address ptr = start_a_const(sizeof(c), sizeof(c)); |
383 if (ptr != NULL) { | 396 if (ptr != NULL) { |
384 *(address*)ptr = c; | 397 emit_address(c); |
385 _code_pos = ptr + sizeof(c); | 398 end_a_const(c1); |
386 end_a_const(); | |
387 } | 399 } |
388 return ptr; | 400 return ptr; |
389 } | 401 } |
390 address address_constant(address c, RelocationHolder const& rspec) { | 402 address address_constant(address c, RelocationHolder const& rspec) { |
403 CodeSection* c1 = _code_section; | |
391 address ptr = start_a_const(sizeof(c), sizeof(c)); | 404 address ptr = start_a_const(sizeof(c), sizeof(c)); |
392 if (ptr != NULL) { | 405 if (ptr != NULL) { |
393 relocate(rspec); | 406 relocate(rspec); |
394 *(address*)ptr = c; | 407 emit_address(c); |
395 _code_pos = ptr + sizeof(c); | 408 end_a_const(c1); |
396 end_a_const(); | |
397 } | 409 } |
398 return ptr; | 410 return ptr; |
399 } | 411 } |
400 | 412 |
401 // Bootstrapping aid to cope with delayed determination of constants. | 413 // Bootstrapping aid to cope with delayed determination of constants. |