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 |
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. |
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 |