3188 * R3_ARG1 - int crc
3189 * R4_ARG2 - byte* buf
3190 * R5_ARG3 - int length (of buffer)
3191 *
3192 * scratch:
3193 * R2, R6-R12
3194 *
3195 * Ouput:
3196 * R3_RET - int crc result
3197 */
3198 // Compute CRC32 function.
3199 address generate_CRC32_updateBytes(const char* name) {
3200 __ align(CodeEntryAlignment);
3201 StubCodeMark mark(this, "StubRoutines", name);
3202 address start = __ function_entry(); // Remember stub start address (is rtn value).
3203
3204 // arguments to kernel_crc32:
3205 const Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call.
3206 const Register data = R4_ARG2; // source byte array
3207 const Register dataLen = R5_ARG3; // #bytes to process
3208 const Register table = R6_ARG4; // crc table address
3209
3210 const Register t0 = R2;
3211 const Register t1 = R7;
3212 const Register t2 = R8;
3213 const Register t3 = R9;
3214 const Register tc0 = R10;
3215 const Register tc1 = R11;
3216 const Register tc2 = R12;
3217
3218 BLOCK_COMMENT("Stub body {");
3219 assert_different_registers(crc, data, dataLen, table);
3220
3221 StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
3222
3223 __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table);
3224
3225 BLOCK_COMMENT("return");
3226 __ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
3227 __ blr();
3228
3229 BLOCK_COMMENT("} Stub body");
3230 return start;
3231 }
3232
3233 // Initialization
3234 void generate_initial() {
3235 // Generates all stubs and initializes the entry points
3236
3237 // Entry points that exist in all platforms.
3238 // Note: This is code that could be shared among different platforms - however the
3239 // benefit seems to be smaller than the disadvantage of having a
3240 // much more complicated generator structure. See also comment in
3241 // stubRoutines.hpp.
3242
3243 StubRoutines::_forward_exception_entry = generate_forward_exception();
3244 StubRoutines::_call_stub_entry = generate_call_stub(StubRoutines::_call_stub_return_address);
3245 StubRoutines::_catch_exception_entry = generate_catch_exception();
3246
3247 // Build this early so it's available for the interpreter.
3248 StubRoutines::_throw_StackOverflowError_entry =
3249 generate_throw_exception("StackOverflowError throw_exception",
|
3188 * R3_ARG1 - int crc
3189 * R4_ARG2 - byte* buf
3190 * R5_ARG3 - int length (of buffer)
3191 *
3192 * scratch:
3193 * R2, R6-R12
3194 *
3195 * Ouput:
3196 * R3_RET - int crc result
3197 */
3198 // Compute CRC32 function.
3199 address generate_CRC32_updateBytes(const char* name) {
3200 __ align(CodeEntryAlignment);
3201 StubCodeMark mark(this, "StubRoutines", name);
3202 address start = __ function_entry(); // Remember stub start address (is rtn value).
3203
3204 // arguments to kernel_crc32:
3205 const Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call.
3206 const Register data = R4_ARG2; // source byte array
3207 const Register dataLen = R5_ARG3; // #bytes to process
3208
3209 const Register table = R6; // crc table address
3210
3211 #ifdef VM_LITTLE_ENDIAN
3212 if (VM_Version::has_vpmsumb()) {
3213 const Register constants = R2; // constants address
3214 const Register bconstants = R8; // barret table address
3215
3216 const Register t0 = R9;
3217 const Register t1 = R10;
3218 const Register t2 = R11;
3219 const Register t3 = R12;
3220 const Register t4 = R7;
3221
3222 BLOCK_COMMENT("Stub body {");
3223 assert_different_registers(crc, data, dataLen, table);
3224
3225 StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
3226 StubRoutines::ppc64::generate_load_crc_constants_addr(_masm, constants);
3227 StubRoutines::ppc64::generate_load_crc_barret_constants_addr(_masm, bconstants);
3228
3229 __ kernel_crc32_1word_vpmsumd(crc, data, dataLen, table, constants, bconstants, t0, t1, t2, t3, t4);
3230
3231 BLOCK_COMMENT("return");
3232 __ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
3233 __ blr();
3234
3235 BLOCK_COMMENT("} Stub body");
3236 } else
3237 #endif
3238 {
3239 const Register t0 = R2;
3240 const Register t1 = R7;
3241 const Register t2 = R8;
3242 const Register t3 = R9;
3243 const Register tc0 = R10;
3244 const Register tc1 = R11;
3245 const Register tc2 = R12;
3246
3247 BLOCK_COMMENT("Stub body {");
3248 assert_different_registers(crc, data, dataLen, table);
3249
3250 StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
3251
3252 __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table);
3253
3254 BLOCK_COMMENT("return");
3255 __ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).
3256 __ blr();
3257
3258 BLOCK_COMMENT("} Stub body");
3259 }
3260
3261 return start;
3262 }
3263
3264 // Initialization
3265 void generate_initial() {
3266 // Generates all stubs and initializes the entry points
3267
3268 // Entry points that exist in all platforms.
3269 // Note: This is code that could be shared among different platforms - however the
3270 // benefit seems to be smaller than the disadvantage of having a
3271 // much more complicated generator structure. See also comment in
3272 // stubRoutines.hpp.
3273
3274 StubRoutines::_forward_exception_entry = generate_forward_exception();
3275 StubRoutines::_call_stub_entry = generate_call_stub(StubRoutines::_call_stub_return_address);
3276 StubRoutines::_catch_exception_entry = generate_catch_exception();
3277
3278 // Build this early so it's available for the interpreter.
3279 StubRoutines::_throw_StackOverflowError_entry =
3280 generate_throw_exception("StackOverflowError throw_exception",
|