< prev index next >

src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp

Print this page
rev 12409 : 8171244: PPC64: Make interpreter's math entries consistent with C1 and C2 and support FMA
Reviewed-by: kvn, goetz


1117     __ std(R12_scratch2, _ijava_state_neg(monitors), R1_SP);
1118     __ std(R12_scratch2, _ijava_state_neg(bcp), R1_SP);
1119     __ std(R12_scratch2, _ijava_state_neg(mdx), R1_SP);
1120   }
1121   __ std(R11_scratch1, _ijava_state_neg(ijava_reserved), R1_SP);
1122   __ std(R12_scratch2, _ijava_state_neg(esp), R1_SP);
1123   __ std(R12_scratch2, _ijava_state_neg(lresult), R1_SP);
1124   __ std(R12_scratch2, _ijava_state_neg(fresult), R1_SP);
1125 #endif
1126   __ subf(R12_scratch2, top_frame_size, R1_SP);
1127   __ std(R0, _ijava_state_neg(oop_tmp), R1_SP);
1128   __ std(R12_scratch2, _ijava_state_neg(top_frame_sp), R1_SP);
1129 
1130   // Push top frame.
1131   __ push_frame(top_frame_size, R11_scratch1);
1132 }
1133 
1134 // End of helpers
1135 
1136 address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
1137   if (!Interpreter::math_entry_available(kind)) {
1138     NOT_PRODUCT(__ should_not_reach_here();)
1139     return NULL;


























1140   }
1141 



1142   address entry = __ pc();
1143 
1144   __ lfd(F1_RET, Interpreter::stackElementSize, R15_esp);














1145 
1146   // Pop c2i arguments (if any) off when we return.
1147 #ifdef ASSERT
1148   __ ld(R9_ARG7, 0, R1_SP);
1149   __ ld(R10_ARG8, 0, R21_sender_SP);
1150   __ cmpd(CCR0, R9_ARG7, R10_ARG8);
1151   __ asm_assert_eq("backlink", 0x545);
1152 #endif // ASSERT
1153   __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
1154 
1155   if (kind == Interpreter::java_lang_math_sqrt) {
1156     __ fsqrt(F1_RET, F1_RET);
1157   } else if (kind == Interpreter::java_lang_math_abs) {
1158     __ fabs(F1_RET, F1_RET);




1159   } else {
1160     ShouldNotReachHere();












1161   }
1162 
1163   // And we're done.
1164   __ blr();
1165 
1166   __ flush();
1167 
1168   return entry;
1169 }
1170 
1171 void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
1172   // Quick & dirty stack overflow checking: bang the stack & handle trap.
1173   // Note that we do the banging after the frame is setup, since the exception
1174   // handling code expects to find a valid interpreter frame on the stack.
1175   // Doing the banging earlier fails if the caller frame is not an interpreter
1176   // frame.
1177   // (Also, the exception throwing code expects to unlock any synchronized
1178   // method receiever, so do the banging after locking the receiver.)
1179 
1180   // Bang each page in the shadow zone. We can't assume it's been done for
1181   // an interpreter frame with greater than a page of locals, so each page
1182   // needs to be checked.  Only true for non-native.
1183   if (UseStackBanging) {




1117     __ std(R12_scratch2, _ijava_state_neg(monitors), R1_SP);
1118     __ std(R12_scratch2, _ijava_state_neg(bcp), R1_SP);
1119     __ std(R12_scratch2, _ijava_state_neg(mdx), R1_SP);
1120   }
1121   __ std(R11_scratch1, _ijava_state_neg(ijava_reserved), R1_SP);
1122   __ std(R12_scratch2, _ijava_state_neg(esp), R1_SP);
1123   __ std(R12_scratch2, _ijava_state_neg(lresult), R1_SP);
1124   __ std(R12_scratch2, _ijava_state_neg(fresult), R1_SP);
1125 #endif
1126   __ subf(R12_scratch2, top_frame_size, R1_SP);
1127   __ std(R0, _ijava_state_neg(oop_tmp), R1_SP);
1128   __ std(R12_scratch2, _ijava_state_neg(top_frame_sp), R1_SP);
1129 
1130   // Push top frame.
1131   __ push_frame(top_frame_size, R11_scratch1);
1132 }
1133 
1134 // End of helpers
1135 
1136 address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
1137 
1138   // Decide what to do: Use same platform specific instructions and runtime calls as compilers.
1139   bool use_instruction = false;
1140   address runtime_entry = NULL;
1141   int num_args = 1;
1142   bool double_precision = true;
1143 
1144   // PPC64 specific:
1145   switch (kind) {
1146     case Interpreter::java_lang_math_sqrt: use_instruction = VM_Version::has_fsqrt(); break;
1147     case Interpreter::java_lang_math_abs:  use_instruction = true; break;
1148     case Interpreter::java_lang_math_fmaF:
1149     case Interpreter::java_lang_math_fmaD: use_instruction = UseFMA; break;
1150     default: break; // Fall back to runtime call.
1151   }
1152 
1153   switch (kind) {
1154     case Interpreter::java_lang_math_sin  : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);   break;
1155     case Interpreter::java_lang_math_cos  : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);   break;
1156     case Interpreter::java_lang_math_tan  : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);   break;
1157     case Interpreter::java_lang_math_abs  : /* run interpreted */ break;
1158     case Interpreter::java_lang_math_sqrt : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt);  break;
1159     case Interpreter::java_lang_math_log  : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);   break;
1160     case Interpreter::java_lang_math_log10: runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10); break;
1161     case Interpreter::java_lang_math_pow  : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow); num_args = 2; break;
1162     case Interpreter::java_lang_math_exp  : runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);   break;
1163     case Interpreter::java_lang_math_fmaF : /* run interpreted */ num_args = 3; double_precision = false; break;
1164     case Interpreter::java_lang_math_fmaD : /* run interpreted */ num_args = 3; break;
1165     default: ShouldNotReachHere();
1166   }
1167 
1168   // Use normal entry if neither instruction nor runtime call is used.
1169   if (!use_instruction && runtime_entry == NULL) return NULL;
1170 
1171   address entry = __ pc();
1172 
1173   // Load arguments
1174   assert(num_args <= 13, "passed in registers");
1175   if (double_precision) {
1176     int offset = (2 * num_args - 1) * Interpreter::stackElementSize;
1177     for (int i = 0; i < num_args; ++i) {
1178       __ lfd(as_FloatRegister(F1_ARG1->encoding() + i), offset, R15_esp);
1179       offset -= 2 * Interpreter::stackElementSize;
1180     }
1181   } else {
1182     int offset = num_args * Interpreter::stackElementSize;
1183     for (int i = 0; i < num_args; ++i) {
1184       __ lfs(as_FloatRegister(F1_ARG1->encoding() + i), offset, R15_esp);
1185       offset -= Interpreter::stackElementSize;
1186     }
1187   }
1188 
1189   // Pop c2i arguments (if any) off when we return.
1190 #ifdef ASSERT
1191   __ ld(R9_ARG7, 0, R1_SP);
1192   __ ld(R10_ARG8, 0, R21_sender_SP);
1193   __ cmpd(CCR0, R9_ARG7, R10_ARG8);
1194   __ asm_assert_eq("backlink", 0x545);
1195 #endif // ASSERT
1196   __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
1197 
1198   if (use_instruction) {
1199     switch (kind) {
1200       case Interpreter::java_lang_math_sqrt: __ fsqrt(F1_RET, F1);          break;
1201       case Interpreter::java_lang_math_abs:  __ fabs(F1_RET, F1);           break;
1202       case Interpreter::java_lang_math_fmaF: __ fmadds(F1_RET, F1, F2, F3); break;
1203       case Interpreter::java_lang_math_fmaD: __ fmadd(F1_RET, F1, F2, F3);  break;
1204       default: ShouldNotReachHere();
1205     }
1206   } else {
1207     // Comment: Can use tail call if the unextended frame is always C ABI compliant:
1208     //__ load_const_optimized(R12_scratch2, runtime_entry, R0);
1209     //__ call_c_and_return_to_caller(R12_scratch2);
1210 
1211     // Push a new C frame and save LR.
1212     __ save_LR_CR(R0);
1213     __ push_frame_reg_args(0, R11_scratch1);
1214 
1215     __ call_VM_leaf(runtime_entry);
1216 
1217     // Pop the C frame and restore LR.
1218     __ pop_frame();
1219     __ restore_LR_CR(R0);
1220   }
1221 

1222   __ blr();
1223 
1224   __ flush();
1225 
1226   return entry;
1227 }
1228 
1229 void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
1230   // Quick & dirty stack overflow checking: bang the stack & handle trap.
1231   // Note that we do the banging after the frame is setup, since the exception
1232   // handling code expects to find a valid interpreter frame on the stack.
1233   // Doing the banging earlier fails if the caller frame is not an interpreter
1234   // frame.
1235   // (Also, the exception throwing code expects to unlock any synchronized
1236   // method receiever, so do the banging after locking the receiver.)
1237 
1238   // Bang each page in the shadow zone. We can't assume it's been done for
1239   // an interpreter frame with greater than a page of locals, so each page
1240   // needs to be checked.  Only true for non-native.
1241   if (UseStackBanging) {


< prev index next >