Mercurial > hg > graal-jvmci-8
comparison src/cpu/ppc/vm/vm_version_ppc.cpp @ 17803:31e80afe3fed
8035647: PPC64: Support for elf v2 abi.
Summary: ELFv2 ABI used by the little endian PowerPC64 on Linux.
Reviewed-by: kvn
Contributed-by: asmundak@google.com
author | goetz |
---|---|
date | Thu, 06 Mar 2014 10:55:28 -0800 |
parents | 67fa91961822 |
children | 92aa6797d639 71a71b0bc844 |
comparison
equal
deleted
inserted
replaced
17802:7c462558a08a | 17803:31e80afe3fed |
---|---|
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(); |