# HG changeset patch # User simonis # Date 1433785175 0 # Mon Jun 08 17:39:35 2015 +0000 # Node ID eaad02bf09153d8ab96f44f1e601fd0d8d923127 # Parent 5657d2f881800edced2eac3d1a368c506011729f 8080684: PPC64: Fix little-endian build after "8077838: Recent developments for ppc" Summary: Also fix the Power8 detection which was broken because we issued an illegal 'lqarx' instruction Reviewed-by: kvn, asmundak diff --git a/src/cpu/ppc/vm/vm_version_ppc.cpp b/src/cpu/ppc/vm/vm_version_ppc.cpp --- a/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -505,7 +505,8 @@ void VM_Version::determine_features() { #if defined(ABI_ELFv2) - const int code_size = (num_features+1+2*7)*BytesPerInstWord; // TODO(asmundak): calculation is incorrect. + // 1 InstWord per call for the blr instruction. + const int code_size = (num_features+1+2*1)*BytesPerInstWord; #else // 7 InstWords for each call (function descriptor + blr instruction). const int code_size = (num_features+1+2*7)*BytesPerInstWord; @@ -540,7 +541,8 @@ a->popcntw(R7, R5); // code[6] -> popcntw a->fcfids(F3, F4); // code[7] -> fcfids a->vand(VR0, VR0, VR0); // code[8] -> vand - a->lqarx_unchecked(R7, R3_ARG1, R4_ARG2, 1); // code[9] -> lqarx_m + // arg0 of lqarx must be an even register, (arg1 + arg2) must be a multiple of 16 + a->lqarx_unchecked(R6, R3_ARG1, R4_ARG2, 1); // code[9] -> lqarx_m a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb a->tcheck(0); // code[12] -> tcheck @@ -572,7 +574,8 @@ // Execute code. Illegal instructions will be replaced by 0 in the signal handler. VM_Version::_is_determine_features_test_running = true; - (*test)((address)mid_of_test_area, (uint64_t)0); + // We must align the first argument to 16 bytes because of the lqarx check. + (*test)((address)align_size_up((intptr_t)mid_of_test_area, 16), (uint64_t)0); VM_Version::_is_determine_features_test_running = false; // determine which instructions are legal. @@ -614,12 +617,12 @@ MacroAssembler* a = new MacroAssembler(&cb); // Emit code. - uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->emit_fd(); + uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->function_entry(); uint32_t *code = (uint32_t *)a->pc(); a->mfdscr(R3); a->blr(); - void (*set_dscr)(long) = (void(*)(long))(void *)a->emit_fd(); + void (*set_dscr)(long) = (void(*)(long))(void *)a->function_entry(); a->mtdscr(R3); a->blr();