Mercurial > hg > graal-compiler
diff src/cpu/ppc/vm/sharedRuntime_ppc.cpp @ 14445:67fa91961822
8029940: PPC64 (part 122): C2 compiler port
Reviewed-by: kvn
author | goetz |
---|---|
date | Wed, 11 Dec 2013 00:06:11 +0100 |
parents | b0133e4187d3 |
children | e5e8aa897002 |
line wrap: on
line diff
--- a/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Tue Dec 10 14:29:43 2013 +0100 +++ b/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Wed Dec 11 00:06:11 2013 +0100 @@ -687,17 +687,9 @@ F13->as_VMReg() }; - const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); - const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); - - // The first 8 arguments are not passed on the stack. - const int num_args_in_regs = 8; -#define put_arg_in_reg(arg) ((arg) < num_args_in_regs) - // Check calling conventions consistency. - assert(num_iarg_registers == num_args_in_regs - && num_iarg_registers == 8 - && num_farg_registers == 13, + assert(sizeof(iarg_reg) / sizeof(iarg_reg[0]) == Argument::n_int_register_parameters_c && + sizeof(farg_reg) / sizeof(farg_reg[0]) == Argument::n_float_register_parameters_c, "consistency"); // `Stk' counts stack slots. Due to alignment, 32 bit values occupy @@ -705,8 +697,6 @@ const int inc_stk_for_intfloat = 2; // 2 slots for ints and floats const int inc_stk_for_longdouble = 2; // 2 slots for longs and doubles - int ill_i = 0; - int ill_t = 0; int i; VMReg reg; // Leave room for C-compatible ABI_112. @@ -726,6 +716,11 @@ if (regs2 != NULL) regs2[i].set_bad(); switch(sig_bt[i]) { + + // + // If arguments 0-7 are integers, they are passed in integer registers. + // Argument i is placed in iarg_reg[i]. + // case T_BOOLEAN: case T_CHAR: case T_BYTE: @@ -754,7 +749,7 @@ case T_ADDRESS: case T_METADATA: // Oops are already boxed if required (JNI). - if (put_arg_in_reg(arg)) { + if (arg < Argument::n_int_register_parameters_c) { reg = iarg_reg[arg]; } else { reg = VMRegImpl::stack2reg(stk); @@ -762,57 +757,66 @@ } regs[i].set2(reg); break; + + // + // Floats are treated differently from int regs: The first 13 float arguments + // are passed in registers (not the float args among the first 13 args). + // Thus argument i is NOT passed in farg_reg[i] if it is float. It is passed + // in farg_reg[j] if argument i is the j-th float argument of this call. + // case T_FLOAT: - if (put_arg_in_reg(arg)) { + if (freg < Argument::n_float_register_parameters_c) { + // Put float in register ... reg = farg_reg[freg]; + ++freg; + + // Argument i for i > 8 is placed on the stack even if it's + // placed in a register (if it's a float arg). Aix disassembly + // shows that xlC places these float args on the stack AND in + // a register. This is not documented, but we follow this + // convention, too. + if (arg >= Argument::n_regs_not_on_stack_c) { + // ... and on the stack. + guarantee(regs2 != NULL, "must pass float in register and stack slot"); + VMReg reg2 = VMRegImpl::stack2reg(stk LINUX_ONLY(+1)); + regs2[i].set1(reg2); + stk += inc_stk_for_intfloat; + } + } else { - // Put float on stack -# if defined(LINUX) - reg = VMRegImpl::stack2reg(stk+1); -# elif defined(AIX) - reg = VMRegImpl::stack2reg(stk); -# else -# error "unknown OS" -# endif + // Put float on stack. + reg = VMRegImpl::stack2reg(stk LINUX_ONLY(+1)); stk += inc_stk_for_intfloat; } - - if (freg < num_farg_registers) { - // There are still some float argument registers left. Put the - // float in a register if not already done. - if (reg != farg_reg[freg]) { - guarantee(regs2 != NULL, "must pass float in register and stack slot"); - VMReg reg2 = farg_reg[freg]; - regs2[i].set1(reg2); - } - ++freg; - } - regs[i].set1(reg); break; case T_DOUBLE: assert(sig_bt[i+1] == T_VOID, "expecting half"); - if (put_arg_in_reg(arg)) { + if (freg < Argument::n_float_register_parameters_c) { + // Put double in register ... reg = farg_reg[freg]; + ++freg; + + // Argument i for i > 8 is placed on the stack even if it's + // placed in a register (if it's a double arg). Aix disassembly + // shows that xlC places these float args on the stack AND in + // a register. This is not documented, but we follow this + // convention, too. + if (arg >= Argument::n_regs_not_on_stack_c) { + // ... and on the stack. + guarantee(regs2 != NULL, "must pass float in register and stack slot"); + VMReg reg2 = VMRegImpl::stack2reg(stk); + regs2[i].set2(reg2); + stk += inc_stk_for_longdouble; + } } else { // Put double on stack. reg = VMRegImpl::stack2reg(stk); stk += inc_stk_for_longdouble; } - - if (freg < num_farg_registers) { - // There are still some float argument registers left. Put the - // float in a register if not already done. - if (reg != farg_reg[freg]) { - guarantee(regs2 != NULL, "must pass float in register and stack slot"); - VMReg reg2 = farg_reg[freg]; - regs2[i].set2(reg2); - } - ++freg; - } - regs[i].set2(reg); break; + case T_VOID: // Do not count halves. regs[i].set_bad(); @@ -877,7 +881,7 @@ __ mtlr(return_pc); - // call the interpreter + // Call the interpreter. __ BIND(call_interpreter); __ mtctr(ientry); @@ -947,8 +951,12 @@ // Jump to the interpreter just as if interpreter was doing it. +#ifdef CC_INTERP + const Register tos = R17_tos; +#endif + // load TOS - __ addi(R17_tos, R1_SP, st_off); + __ addi(tos, R1_SP, st_off); // Frame_manager expects initial_caller_sp (= SP without resize by c2i) in R21_tmp1. assert(sender_SP == R21_sender_SP, "passing initial caller's SP in wrong register"); @@ -982,7 +990,9 @@ // save code can segv when fxsave instructions find improperly // aligned stack pointer. +#ifdef CC_INTERP const Register ld_ptr = R17_tos; +#endif const Register value_regs[] = { R22_tmp2, R23_tmp3, R24_tmp4, R25_tmp5, R26_tmp6 }; const int num_value_regs = sizeof(value_regs) / sizeof(Register); int value_regs_index = 0; @@ -1137,7 +1147,7 @@ __ bne_predict_taken(CCR0, valid); // We have a null argument, branch to ic_miss_stub. __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), - relocInfo::runtime_call_type); + relocInfo::runtime_call_type); __ BIND(valid); } } @@ -1154,7 +1164,7 @@ __ beq_predict_taken(CCR0, valid); // We have an unexpected klass, branch to ic_miss_stub. __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), - relocInfo::runtime_call_type); + relocInfo::runtime_call_type); __ BIND(valid); } @@ -1170,8 +1180,7 @@ __ beq_predict_taken(CCR0, call_interpreter); // Branch to ic_miss_stub. - __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), - relocInfo::runtime_call_type); + __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type); // entry: c2i @@ -2594,7 +2603,11 @@ __ ld(frame_size_reg, 0, frame_sizes_reg); __ std(pc_reg, _abi(lr), R1_SP); __ push_frame(frame_size_reg, R0/*tmp*/); +#ifdef CC_INTERP __ std(R1_SP, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); +#else + Unimplemented(); +#endif __ addi(number_of_frames_reg, number_of_frames_reg, -1); __ addi(frame_sizes_reg, frame_sizes_reg, wordSize); __ addi(pcs_reg, pcs_reg, wordSize); @@ -2693,7 +2706,9 @@ // Store it in the top interpreter frame. __ std(R0, _abi(lr), R1_SP); // Initialize frame_manager_lr of interpreter top frame. +#ifdef CC_INTERP __ std(R0, _top_ijava_frame_abi(frame_manager_lr), R1_SP); +#endif } #endif @@ -2886,8 +2901,7 @@ // Initialize R14_state. __ ld(R14_state, 0, R1_SP); - __ addi(R14_state, R14_state, - -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); + __ addi(R14_state, R14_state, -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); // Also inititialize R15_prev_state. __ restore_prev_state(); @@ -3010,8 +3024,7 @@ // Initialize R14_state, ... __ ld(R11_scratch1, 0, R1_SP); - __ addi(R14_state, R11_scratch1, - -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); + __ addi(R14_state, R11_scratch1, -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); // also initialize R15_prev_state. __ restore_prev_state(); // Return to the interpreter entry point.