22 * questions. |
22 * questions. |
23 * |
23 * |
24 */ |
24 */ |
25 |
25 |
26 #include "precompiled.hpp" |
26 #include "precompiled.hpp" |
27 #include "assembler_ppc.inline.hpp" |
27 #include "asm/assembler.inline.hpp" |
|
28 #include "asm/macroAssembler.inline.hpp" |
28 #include "compiler/disassembler.hpp" |
29 #include "compiler/disassembler.hpp" |
29 #include "memory/resourceArea.hpp" |
30 #include "memory/resourceArea.hpp" |
30 #include "runtime/java.hpp" |
31 #include "runtime/java.hpp" |
31 #include "runtime/stubCodeGenerator.hpp" |
32 #include "runtime/stubCodeGenerator.hpp" |
32 #include "utilities/defaultStream.hpp" |
33 #include "utilities/defaultStream.hpp" |
166 CodeBuffer cb("detect_section_size", code_size, 0); |
167 CodeBuffer cb("detect_section_size", code_size, 0); |
167 MacroAssembler* a = new MacroAssembler(&cb); |
168 MacroAssembler* a = new MacroAssembler(&cb); |
168 |
169 |
169 uint32_t *code = (uint32_t *)a->pc(); |
170 uint32_t *code = (uint32_t *)a->pc(); |
170 // Emit code. |
171 // Emit code. |
171 void (*test1)() = (void(*)())(void *)a->emit_fd(); |
172 void (*test1)() = (void(*)())(void *)a->function_entry(); |
172 |
173 |
173 Label l1; |
174 Label l1; |
174 |
175 |
175 a->li(R4, 1); |
176 a->li(R4, 1); |
176 a->sldi(R4, R4, 28); |
177 a->sldi(R4, R4, 28); |
240 a->cmpdi(CCR0, R4, unroll); // 33 |
241 a->cmpdi(CCR0, R4, unroll); // 33 |
241 a->bge(CCR0, l1); // 34 |
242 a->bge(CCR0, l1); // 34 |
242 a->blr(); |
243 a->blr(); |
243 |
244 |
244 // Emit code. |
245 // Emit code. |
245 void (*test2)() = (void(*)())(void *)a->emit_fd(); |
246 void (*test2)() = (void(*)())(void *)a->function_entry(); |
246 // uint32_t *code = (uint32_t *)a->pc(); |
247 // uint32_t *code = (uint32_t *)a->pc(); |
247 |
248 |
248 Label l2; |
249 Label l2; |
249 |
250 |
250 a->li(R4, 1); |
251 a->li(R4, 1); |
381 if (UsePower6SchedulerPPC64) Unimplemented(); |
382 if (UsePower6SchedulerPPC64) Unimplemented(); |
382 } |
383 } |
383 #endif // COMPILER2 |
384 #endif // COMPILER2 |
384 |
385 |
385 void VM_Version::determine_features() { |
386 void VM_Version::determine_features() { |
|
387 #if defined(ABI_ELFv2) |
|
388 const int code_size = (num_features+1+2*7)*BytesPerInstWord; // TODO(asmundak): calculation is incorrect. |
|
389 #else |
386 // 7 InstWords for each call (function descriptor + blr instruction). |
390 // 7 InstWords for each call (function descriptor + blr instruction). |
387 const int code_size = (num_features+1+2*7)*BytesPerInstWord; |
391 const int code_size = (num_features+1+2*7)*BytesPerInstWord; |
|
392 #endif |
388 int features = 0; |
393 int features = 0; |
389 |
394 |
390 // create test area |
395 // create test area |
391 enum { BUFFER_SIZE = 2*4*K }; // Needs to be >=2* max cache line size (cache line size can't exceed min page size). |
396 enum { BUFFER_SIZE = 2*4*K }; // Needs to be >=2* max cache line size (cache line size can't exceed min page size). |
392 char test_area[BUFFER_SIZE]; |
397 char test_area[BUFFER_SIZE]; |
396 ResourceMark rm; |
401 ResourceMark rm; |
397 CodeBuffer cb("detect_cpu_features", code_size, 0); |
402 CodeBuffer cb("detect_cpu_features", code_size, 0); |
398 MacroAssembler* a = new MacroAssembler(&cb); |
403 MacroAssembler* a = new MacroAssembler(&cb); |
399 |
404 |
400 // Emit code. |
405 // Emit code. |
401 void (*test)(address addr, uint64_t offset)=(void(*)(address addr, uint64_t offset))(void *)a->emit_fd(); |
406 void (*test)(address addr, uint64_t offset)=(void(*)(address addr, uint64_t offset))(void *)a->function_entry(); |
402 uint32_t *code = (uint32_t *)a->pc(); |
407 uint32_t *code = (uint32_t *)a->pc(); |
403 // Don't use R0 in ldarx. |
408 // Don't use R0 in ldarx. |
404 // Keep R3_ARG1 unmodified, it contains &field (see below). |
409 // Keep R3_ARG1 unmodified, it contains &field (see below). |
405 // Keep R4_ARG2 unmodified, it contains offset = 0 (see below). |
410 // Keep R4_ARG2 unmodified, it contains offset = 0 (see below). |
406 a->fsqrt(F3, F4); // code[0] -> fsqrt_m |
411 a->fsqrt(F3, F4); // code[0] -> fsqrt_m |
413 a->fcfids(F3, F4); // code[7] -> fcfids |
418 a->fcfids(F3, F4); // code[7] -> fcfids |
414 a->vand(VR0, VR0, VR0); // code[8] -> vand |
419 a->vand(VR0, VR0, VR0); // code[8] -> vand |
415 a->blr(); |
420 a->blr(); |
416 |
421 |
417 // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. |
422 // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. |
418 void (*zero_cacheline_func_ptr)(char*) = (void(*)(char*))(void *)a->emit_fd(); |
423 void (*zero_cacheline_func_ptr)(char*) = (void(*)(char*))(void *)a->function_entry(); |
419 a->dcbz(R3_ARG1); // R3_ARG1 = addr |
424 a->dcbz(R3_ARG1); // R3_ARG1 = addr |
420 a->blr(); |
425 a->blr(); |
421 |
426 |
422 uint32_t *code_end = (uint32_t *)a->pc(); |
427 uint32_t *code_end = (uint32_t *)a->pc(); |
423 a->flush(); |
428 a->flush(); |