1 /*
2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2012, 2014 SAP AG. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
316 // In disjoint mode decoding can save a cycle if src != dst.
317 Register narrowOop = (tmp != noreg && Universe::narrow_oop_base_disjoint()) ? tmp : d;
318 lwz(narrowOop, offs, s1);
319 // Attention: no null check here!
320 Register res = decode_heap_oop_not_null(d, narrowOop);
321 assert(res == d, "caller will not consume loaded value");
322 } else {
323 ld(d, offs, s1);
324 }
325 }
326
327 inline void MacroAssembler::store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, Register tmp) {
328 if (UseCompressedOops) {
329 Register compressedOop = encode_heap_oop_not_null((tmp != noreg) ? tmp : d, d);
330 stw(compressedOop, offs, s1);
331 } else {
332 std(d, offs, s1);
333 }
334 }
335
336 inline void MacroAssembler::load_heap_oop(Register d, RegisterOrConstant offs, Register s1) {
337 if (UseCompressedOops) {
338 lwz(d, offs, s1);
339 decode_heap_oop(d);
340 } else {
341 ld(d, offs, s1);
342 }
343 }
344
345 inline Register MacroAssembler::encode_heap_oop_not_null(Register d, Register src) {
346 Register current = (src != noreg) ? src : d; // Oop to be compressed is in d if no src provided.
347 if (Universe::narrow_oop_base_overlaps()) {
348 sub(d, current, R30);
349 current = d;
350 }
351 if (Universe::narrow_oop_shift() != 0) {
352 rldicl(d, current, 64-Universe::narrow_oop_shift(), 32); // Clears the upper bits.
353 current = d;
354 }
355 return current; // Encoded oop is in this register.
356 }
357
358 inline Register MacroAssembler::decode_heap_oop_not_null(Register d, Register src) {
359 if (Universe::narrow_oop_base_disjoint() && src != noreg && src != d &&
360 Universe::narrow_oop_shift() != 0) {
361 mr(d, R30);
362 rldimi(d, src, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
363 return d;
364 }
365
366 Register current = (src != noreg) ? src : d; // Compressed oop is in d if no src provided.
367 if (Universe::narrow_oop_shift() != 0) {
368 sldi(d, current, Universe::narrow_oop_shift());
369 current = d;
370 }
371 if (Universe::narrow_oop_base() != NULL) {
372 add(d, current, R30);
373 current = d;
374 }
375 return current; // Decoded oop is in this register.
376 }
377
378 inline void MacroAssembler::decode_heap_oop(Register d) {
379 Label isNull;
380 if (Universe::narrow_oop_base() != NULL) {
381 cmpwi(CCR0, d, 0);
382 beq(CCR0, isNull);
383 }
384 decode_heap_oop_not_null(d);
385 bind(isNull);
386 }
387
388 // SIGTRAP-based range checks for arrays.
389 inline void MacroAssembler::trap_range_check_l(Register a, Register b) {
390 tw (traptoLessThanUnsigned, a/*reg a*/, b/*reg b*/);
391 }
392 inline void MacroAssembler::trap_range_check_l(Register a, int si16) {
393 twi(traptoLessThanUnsigned, a/*reg a*/, si16);
394 }
395 inline void MacroAssembler::trap_range_check_le(Register a, int si16) {
396 twi(traptoEqual | traptoLessThanUnsigned, a/*reg a*/, si16);
397 }
398 inline void MacroAssembler::trap_range_check_g(Register a, int si16) {
399 twi(traptoGreaterThanUnsigned, a/*reg a*/, si16);
400 }
401 inline void MacroAssembler::trap_range_check_ge(Register a, Register b) {
402 tw (traptoEqual | traptoGreaterThanUnsigned, a/*reg a*/, b/*reg b*/);
403 }
404 inline void MacroAssembler::trap_range_check_ge(Register a, int si16) {
|
1 /*
2 * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2012, 2015 SAP AG. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
316 // In disjoint mode decoding can save a cycle if src != dst.
317 Register narrowOop = (tmp != noreg && Universe::narrow_oop_base_disjoint()) ? tmp : d;
318 lwz(narrowOop, offs, s1);
319 // Attention: no null check here!
320 Register res = decode_heap_oop_not_null(d, narrowOop);
321 assert(res == d, "caller will not consume loaded value");
322 } else {
323 ld(d, offs, s1);
324 }
325 }
326
327 inline void MacroAssembler::store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, Register tmp) {
328 if (UseCompressedOops) {
329 Register compressedOop = encode_heap_oop_not_null((tmp != noreg) ? tmp : d, d);
330 stw(compressedOop, offs, s1);
331 } else {
332 std(d, offs, s1);
333 }
334 }
335
336 inline void MacroAssembler::load_heap_oop(Register d, RegisterOrConstant offs, Register s1, Label *is_null) {
337 if (UseCompressedOops) {
338 lwz(d, offs, s1);
339 if (is_null != NULL) {
340 cmpwi(CCR0, d, 0);
341 beq(CCR0, *is_null);
342 decode_heap_oop_not_null(d);
343 } else {
344 decode_heap_oop(d);
345 }
346 } else {
347 ld(d, offs, s1);
348 if (is_null != NULL) {
349 cmpdi(CCR0, d, 0);
350 beq(CCR0, *is_null);
351 }
352 }
353 }
354
355 inline Register MacroAssembler::encode_heap_oop_not_null(Register d, Register src) {
356 Register current = (src != noreg) ? src : d; // Oop to be compressed is in d if no src provided.
357 if (Universe::narrow_oop_base_overlaps()) {
358 sub_const_optimized(d, current, Universe::narrow_oop_base(), R0);
359 current = d;
360 }
361 if (Universe::narrow_oop_shift() != 0) {
362 rldicl(d, current, 64-Universe::narrow_oop_shift(), 32); // Clears the upper bits.
363 current = d;
364 }
365 return current; // Encoded oop is in this register.
366 }
367
368 inline Register MacroAssembler::decode_heap_oop_not_null(Register d, Register src) {
369 if (Universe::narrow_oop_base_disjoint() && src != noreg && src != d &&
370 Universe::narrow_oop_shift() != 0) {
371 load_const_optimized(d, Universe::narrow_oop_base(), R0);
372 rldimi(d, src, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
373 return d;
374 }
375
376 Register current = (src != noreg) ? src : d; // Compressed oop is in d if no src provided.
377 if (Universe::narrow_oop_shift() != 0) {
378 sldi(d, current, Universe::narrow_oop_shift());
379 current = d;
380 }
381 if (Universe::narrow_oop_base() != NULL) {
382 add_const_optimized(d, current, Universe::narrow_oop_base(), R0);
383 current = d;
384 }
385 return current; // Decoded oop is in this register.
386 }
387
388 inline void MacroAssembler::decode_heap_oop(Register d) {
389 Label isNull;
390 bool use_isel = false;
391 if (Universe::narrow_oop_base() != NULL) {
392 cmpwi(CCR0, d, 0);
393 if (VM_Version::has_isel()) {
394 use_isel = true;
395 } else {
396 beq(CCR0, isNull);
397 }
398 }
399 decode_heap_oop_not_null(d);
400 if (use_isel) {
401 isel_0(d, CCR0, Assembler::equal);
402 }
403 bind(isNull);
404 }
405
406 // SIGTRAP-based range checks for arrays.
407 inline void MacroAssembler::trap_range_check_l(Register a, Register b) {
408 tw (traptoLessThanUnsigned, a/*reg a*/, b/*reg b*/);
409 }
410 inline void MacroAssembler::trap_range_check_l(Register a, int si16) {
411 twi(traptoLessThanUnsigned, a/*reg a*/, si16);
412 }
413 inline void MacroAssembler::trap_range_check_le(Register a, int si16) {
414 twi(traptoEqual | traptoLessThanUnsigned, a/*reg a*/, si16);
415 }
416 inline void MacroAssembler::trap_range_check_g(Register a, int si16) {
417 twi(traptoGreaterThanUnsigned, a/*reg a*/, si16);
418 }
419 inline void MacroAssembler::trap_range_check_ge(Register a, Register b) {
420 tw (traptoEqual | traptoGreaterThanUnsigned, a/*reg a*/, b/*reg b*/);
421 }
422 inline void MacroAssembler::trap_range_check_ge(Register a, int si16) {
|