1234 __ lea(scratch, cardtable);
1235 } else {
1236 ExternalAddress cardtable((address)disp);
1237 __ lea(scratch, cardtable);
1238 }
1239
1240 const Register count = end; // 'end' register contains bytes count now
1241 __ addptr(start, scratch);
1242 __ BIND(L_loop);
1243 __ movb(Address(start, count, Address::times_1), 0);
1244 __ decrement(count);
1245 __ jcc(Assembler::greaterEqual, L_loop);
1246 }
1247 break;
1248 default:
1249 ShouldNotReachHere();
1250
1251 }
1252 }
1253
1254 // Copy big chunks forward
1255 //
1256 // Inputs:
1257 // end_from - source arrays end address
1258 // end_to - destination array end address
1259 // qword_count - 64-bits element count, negative
1260 // to - scratch
1261 // L_copy_32_bytes - entry label
1262 // L_copy_8_bytes - exit label
1263 //
1264 void copy_32_bytes_forward(Register end_from, Register end_to,
1265 Register qword_count, Register to,
1266 Label& L_copy_32_bytes, Label& L_copy_8_bytes) {
1267 DEBUG_ONLY(__ stop("enter at entry label, not here"));
1268 Label L_loop;
1269 __ align(16);
1270 __ BIND(L_loop);
1271 __ movq(to, Address(end_from, qword_count, Address::times_8, -24));
1272 __ movq(Address(end_to, qword_count, Address::times_8, -24), to);
1273 __ movq(to, Address(end_from, qword_count, Address::times_8, -16));
1274 __ movq(Address(end_to, qword_count, Address::times_8, -16), to);
1275 __ movq(to, Address(end_from, qword_count, Address::times_8, - 8));
1276 __ movq(Address(end_to, qword_count, Address::times_8, - 8), to);
1277 __ movq(to, Address(end_from, qword_count, Address::times_8, - 0));
1278 __ movq(Address(end_to, qword_count, Address::times_8, - 0), to);
1279 __ BIND(L_copy_32_bytes);
1280 __ addptr(qword_count, 4);
1281 __ jcc(Assembler::lessEqual, L_loop);
1282 __ subptr(qword_count, 4);
1283 __ jcc(Assembler::less, L_copy_8_bytes); // Copy trailing qwords
1284 }
1285
1286
1287 // Copy big chunks backward
1288 //
1289 // Inputs:
1290 // from - source arrays address
1291 // dest - destination array address
1292 // qword_count - 64-bits element count
1293 // to - scratch
1294 // L_copy_32_bytes - entry label
1295 // L_copy_8_bytes - exit label
1296 //
1297 void copy_32_bytes_backward(Register from, Register dest,
1298 Register qword_count, Register to,
1299 Label& L_copy_32_bytes, Label& L_copy_8_bytes) {
1300 DEBUG_ONLY(__ stop("enter at entry label, not here"));
1301 Label L_loop;
1302 __ align(16);
1303 __ BIND(L_loop);
1304 __ movq(to, Address(from, qword_count, Address::times_8, 24));
1305 __ movq(Address(dest, qword_count, Address::times_8, 24), to);
1306 __ movq(to, Address(from, qword_count, Address::times_8, 16));
1307 __ movq(Address(dest, qword_count, Address::times_8, 16), to);
1308 __ movq(to, Address(from, qword_count, Address::times_8, 8));
1309 __ movq(Address(dest, qword_count, Address::times_8, 8), to);
1310 __ movq(to, Address(from, qword_count, Address::times_8, 0));
1311 __ movq(Address(dest, qword_count, Address::times_8, 0), to);
1312 __ BIND(L_copy_32_bytes);
1313 __ subptr(qword_count, 4);
1314 __ jcc(Assembler::greaterEqual, L_loop);
1315 __ addptr(qword_count, 4);
1316 __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords
1317 }
1318
1319
1320 // Arguments:
1321 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
1322 // ignored
1323 // name - stub name string
1324 //
1325 // Inputs:
1326 // c_rarg0 - source array address
1327 // c_rarg1 - destination array address
1328 // c_rarg2 - element count, treated as ssize_t, can be zero
1329 //
1330 // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries,
1331 // we let the hardware handle it. The one to eight bytes within words,
|
1234 __ lea(scratch, cardtable);
1235 } else {
1236 ExternalAddress cardtable((address)disp);
1237 __ lea(scratch, cardtable);
1238 }
1239
1240 const Register count = end; // 'end' register contains bytes count now
1241 __ addptr(start, scratch);
1242 __ BIND(L_loop);
1243 __ movb(Address(start, count, Address::times_1), 0);
1244 __ decrement(count);
1245 __ jcc(Assembler::greaterEqual, L_loop);
1246 }
1247 break;
1248 default:
1249 ShouldNotReachHere();
1250
1251 }
1252 }
1253
1254
1255 // Copy big chunks forward
1256 //
1257 // Inputs:
1258 // end_from - source arrays end address
1259 // end_to - destination array end address
1260 // qword_count - 64-bits element count, negative
1261 // to - scratch
1262 // L_copy_32_bytes - entry label
1263 // L_copy_8_bytes - exit label
1264 //
1265 void copy_32_bytes_forward(Register end_from, Register end_to,
1266 Register qword_count, Register to,
1267 Label& L_copy_32_bytes, Label& L_copy_8_bytes) {
1268 DEBUG_ONLY(__ stop("enter at entry label, not here"));
1269 Label L_loop;
1270 __ align(16);
1271 __ BIND(L_loop);
1272 if(UseUnalignedLoadStores) {
1273 __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24));
1274 __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0);
1275 __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, - 8));
1276 __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm1);
1277
1278 } else {
1279 __ movq(to, Address(end_from, qword_count, Address::times_8, -24));
1280 __ movq(Address(end_to, qword_count, Address::times_8, -24), to);
1281 __ movq(to, Address(end_from, qword_count, Address::times_8, -16));
1282 __ movq(Address(end_to, qword_count, Address::times_8, -16), to);
1283 __ movq(to, Address(end_from, qword_count, Address::times_8, - 8));
1284 __ movq(Address(end_to, qword_count, Address::times_8, - 8), to);
1285 __ movq(to, Address(end_from, qword_count, Address::times_8, - 0));
1286 __ movq(Address(end_to, qword_count, Address::times_8, - 0), to);
1287
1288 }
1289 __ BIND(L_copy_32_bytes);
1290 __ addptr(qword_count, 4);
1291 __ jcc(Assembler::lessEqual, L_loop);
1292 __ subptr(qword_count, 4);
1293 __ jcc(Assembler::less, L_copy_8_bytes); // Copy trailing qwords
1294 }
1295
1296
1297 // Copy big chunks backward
1298 //
1299 // Inputs:
1300 // from - source arrays address
1301 // dest - destination array address
1302 // qword_count - 64-bits element count
1303 // to - scratch
1304 // L_copy_32_bytes - entry label
1305 // L_copy_8_bytes - exit label
1306 //
1307 void copy_32_bytes_backward(Register from, Register dest,
1308 Register qword_count, Register to,
1309 Label& L_copy_32_bytes, Label& L_copy_8_bytes) {
1310 DEBUG_ONLY(__ stop("enter at entry label, not here"));
1311 Label L_loop;
1312 __ align(16);
1313 __ BIND(L_loop);
1314 if(UseUnalignedLoadStores) {
1315 __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 16));
1316 __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm0);
1317 __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 0));
1318 __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm1);
1319
1320 } else {
1321 __ movq(to, Address(from, qword_count, Address::times_8, 24));
1322 __ movq(Address(dest, qword_count, Address::times_8, 24), to);
1323 __ movq(to, Address(from, qword_count, Address::times_8, 16));
1324 __ movq(Address(dest, qword_count, Address::times_8, 16), to);
1325 __ movq(to, Address(from, qword_count, Address::times_8, 8));
1326 __ movq(Address(dest, qword_count, Address::times_8, 8), to);
1327 __ movq(to, Address(from, qword_count, Address::times_8, 0));
1328 __ movq(Address(dest, qword_count, Address::times_8, 0), to);
1329
1330 }
1331 __ BIND(L_copy_32_bytes);
1332 __ subptr(qword_count, 4);
1333 __ jcc(Assembler::greaterEqual, L_loop);
1334 __ addptr(qword_count, 4);
1335 __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords
1336 }
1337
1338
1339 // Arguments:
1340 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
1341 // ignored
1342 // name - stub name string
1343 //
1344 // Inputs:
1345 // c_rarg0 - source array address
1346 // c_rarg1 - destination array address
1347 // c_rarg2 - element count, treated as ssize_t, can be zero
1348 //
1349 // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries,
1350 // we let the hardware handle it. The one to eight bytes within words,
|