Mercurial > hg > truffle
comparison src/share/vm/asm/assembler.hpp @ 7199:cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
Reviewed-by: kvn
author | twisti |
---|---|
date | Fri, 30 Nov 2012 15:23:16 -0800 |
parents | 6ab62ad83507 |
children | f0c2369fda5a |
comparison
equal
deleted
inserted
replaced
7198:6ab62ad83507 | 7199:cd3d6a6b95d9 |
---|---|
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 |
202 protected: | 203 protected: |
203 CodeSection* _code_section; // section within the code buffer | 204 CodeSection* _code_section; // section within the code buffer |
204 OopRecorder* _oop_recorder; // support for relocInfo::oop_type | 205 OopRecorder* _oop_recorder; // support for relocInfo::oop_type |
205 | 206 |
206 // Code emission & accessing | 207 // Code emission & accessing |
207 inline address addr_at(int pos) const; | 208 address addr_at(int pos) const { return code_section()->start() + pos; } |
209 | |
208 | 210 |
209 // 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. |
210 // 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. |
211 address target(Label& L); // return _code_section->target(L) | 213 address target(Label& L) { return code_section()->target(L, pc()); } |
212 | 214 |
213 bool is8bit(int x) const { return -0x80 <= x && x < 0x80; } | 215 bool is8bit(int x) const { return -0x80 <= x && x < 0x80; } |
214 bool isByte(int x) const { return 0 <= x && x < 0x100; } | 216 bool isByte(int x) const { return 0 <= x && x < 0x100; } |
215 bool isShiftCount(int x) const { return 0 <= x && x < 32; } | 217 bool isShiftCount(int x) const { return 0 <= x && x < 32; } |
216 | 218 |
219 void emit_int8( int8_t x) { code_section()->emit_int8( x); } | |
220 void emit_int16( int16_t x) { code_section()->emit_int16( x); } | |
221 void emit_int32( int32_t x) { code_section()->emit_int32( x); } | |
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 | |
217 void emit_byte(int x) { emit_int8 (x); } // deprecated | 228 void emit_byte(int x) { emit_int8 (x); } // deprecated |
218 void emit_word(int x) { emit_int16(x); } // deprecated | 229 void emit_word(int x) { emit_int16(x); } // deprecated |
219 void emit_long(jint x) { emit_int32(x); } // deprecated | 230 void emit_long(jint x) { emit_int32(x); } // deprecated |
220 | |
221 inline void emit_int8( int8_t x); | |
222 inline void emit_int16( int16_t x); | |
223 inline void emit_int32( int32_t x); | |
224 inline void emit_int64( int64_t x); | |
225 | |
226 inline void emit_float( jfloat x); | |
227 inline void emit_double(jdouble x); | |
228 inline void emit_address(address x); | |
229 | 231 |
230 // Instruction boundaries (required when emitting relocatable values). | 232 // Instruction boundaries (required when emitting relocatable values). |
231 class InstructionMark: public StackObj { | 233 class InstructionMark: public StackObj { |
232 private: | 234 private: |
233 AbstractAssembler* _assm; | 235 AbstractAssembler* _assm; |
240 ~InstructionMark() { | 242 ~InstructionMark() { |
241 _assm->clear_inst_mark(); | 243 _assm->clear_inst_mark(); |
242 } | 244 } |
243 }; | 245 }; |
244 friend class InstructionMark; | 246 friend class InstructionMark; |
245 #ifdef ASSERT | 247 #ifdef ASSERT |
246 // Make it return true on platforms which need to verify | 248 // Make it return true on platforms which need to verify |
247 // instruction boundaries for some operations. | 249 // instruction boundaries for some operations. |
248 inline static bool pd_check_instruction_mark(); | 250 inline static bool pd_check_instruction_mark(); |
249 | 251 |
250 // 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. |
265 } | 267 } |
266 ~ShortBranchVerifier() { | 268 ~ShortBranchVerifier() { |
267 _assm->clear_short_branch_delta(); | 269 _assm->clear_short_branch_delta(); |
268 } | 270 } |
269 }; | 271 }; |
270 #else | 272 #else |
271 // Dummy in product. | 273 // Dummy in product. |
272 class ShortBranchVerifier: public StackObj { | 274 class ShortBranchVerifier: public StackObj { |
273 public: | 275 public: |
274 ShortBranchVerifier(AbstractAssembler* assm) {} | 276 ShortBranchVerifier(AbstractAssembler* assm) {} |
275 }; | 277 }; |
276 #endif | 278 #endif |
277 | 279 |
278 // Label functions | 280 // Label functions |
279 void print(Label& L); | 281 void print(Label& L); |
280 | 282 |
281 public: | 283 public: |
309 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); } |
310 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); } |
311 | 313 |
312 // Accessors | 314 // Accessors |
313 CodeSection* code_section() const { return _code_section; } | 315 CodeSection* code_section() const { return _code_section; } |
314 inline CodeBuffer* code() const; | 316 CodeBuffer* code() const { return code_section()->outer(); } |
315 inline int sect() const; | 317 int sect() const { return code_section()->index(); } |
316 inline address pc() const; | 318 address pc() const { return code_section()->end(); } |
317 inline int offset() const; | 319 int offset() const { return code_section()->size(); } |
318 inline int locator() const; // CodeBuffer::locator(offset(), sect()) | 320 int locator() const { return CodeBuffer::locator(offset(), sect()); } |
319 | 321 |
320 OopRecorder* oop_recorder() const { return _oop_recorder; } | 322 OopRecorder* oop_recorder() const { return _oop_recorder; } |
321 void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; } | 323 void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; } |
322 | 324 |
323 address inst_mark() const; | 325 address inst_mark() const { return code_section()->mark(); } |
324 void set_inst_mark(); | 326 void set_inst_mark() { code_section()->set_mark(); } |
325 void clear_inst_mark(); | 327 void clear_inst_mark() { code_section()->clear_mark(); } |
326 | 328 |
327 // Constants in code | 329 // Constants in code |
328 void a_byte(int x); | 330 void a_byte(int x); |
329 void a_long(jint x); | 331 void a_long(jint x); |
330 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 } | |
331 void relocate( relocInfo::relocType rtype, int format = 0) { | 338 void relocate( relocInfo::relocType rtype, int format = 0) { |
332 if (rtype != relocInfo::none) | 339 code_section()->relocate(code_section()->end(), rtype, format); |
333 relocate(Relocation::spec_simple(rtype), format); | |
334 } | 340 } |
335 | 341 |
336 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 |
337 | 343 |
338 // Associate a comment with the current offset. It will be printed | 344 // Associate a comment with the current offset. It will be printed |