1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "gc/shared/barrierSetAssembler.hpp" 27 28 #define __ masm-> 29 30 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, 31 Register dst, Address src, Register tmp1, Register tmp2, Register tmp3) { 32 bool in_heap = (decorators & IN_HEAP) != 0; 33 bool in_native = (decorators & IN_NATIVE) != 0; 34 switch (type) { 35 case T_OBJECT: 36 case T_ARRAY: { 37 if (in_heap) { 38 #ifdef AARCH64 39 if (UseCompressedOops) { 40 __ ldr_w(dst, src); 41 __ decode_heap_oop(dst); 42 } else 43 #endif // AARCH64 44 { 45 __ ldr(dst, src); 46 } 47 } else { 48 assert(in_native, "why else?"); 49 __ ldr(dst, src); 50 } 51 break; 52 } 53 case T_BOOLEAN: __ ldrb (dst, src); break; 54 case T_BYTE: __ ldrsb (dst, src); break; 55 case T_CHAR: __ ldrh (dst, src); break; 56 case T_SHORT: __ ldrsh (dst, src); break; 57 case T_INT: __ ldr_s32 (dst, src); break; 58 case T_ADDRESS: __ ldr (dst, src); break; 59 case T_LONG: 60 #ifdef AARCH64 61 __ ldr (dst, src); break; 62 #else 63 assert(dst == noreg, "only to ltos"); 64 __ add (src.index(), src.index(), src.base()); 65 __ ldmia (src.index(), RegisterSet(R0_tos_lo) | RegisterSet(R1_tos_hi)); 66 #endif // AARCH64 67 break; 68 #ifdef __SOFTFP__ 69 case T_FLOAT: 70 assert(dst == noreg, "only to ftos"); 71 __ ldr (R0_tos, src); 72 break; 73 case T_DOUBLE: 74 assert(dst == noreg, "only to dtos"); 75 __ add (src.index(), src.index(), src.base()); 76 __ ldmia (src.index(), RegisterSet(R0_tos_lo) | RegisterSet(R1_tos_hi)); 77 break; 78 #else 79 case T_FLOAT: 80 assert(dst == noreg, "only to ftos"); 81 __ add(src.index(), src.index(), src.base()); 82 __ ldr_float (S0_tos, src.index()); 83 break; 84 case T_DOUBLE: 85 assert(dst == noreg, "only to dtos"); 86 __ add (src.index(), src.index(), src.base()); 87 __ ldr_double (D0_tos, src.index()); 88 break; 89 #endif 90 default: Unimplemented(); 91 } 92 93 } 94 95 void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, 96 Address obj, Register val, Register tmp1, Register tmp2, Register tmp3, bool is_null) { 97 bool in_heap = (decorators & IN_HEAP) != 0; 98 bool in_native = (decorators & IN_NATIVE) != 0; 99 switch (type) { 100 case T_OBJECT: 101 case T_ARRAY: { 102 if (in_heap) { 103 #ifdef AARCH64 104 if (UseCompressedOops) { 105 assert(!dst.uses(src), "not enough registers"); 106 if (!is_null) { 107 __ encode_heap_oop(src); 108 } 109 __ str_w(val, obj); 110 } else 111 #endif // AARCH64 112 { 113 __ str(val, obj); 114 } 115 } else { 116 assert(in_native, "why else?"); 117 __ str(val, obj); 118 } 119 break; 120 } 121 case T_BOOLEAN: 122 __ and_32(val, val, 1); 123 __ strb(val, obj); 124 break; 125 case T_BYTE: __ strb (val, obj); break; 126 case T_CHAR: __ strh (val, obj); break; 127 case T_SHORT: __ strh (val, obj); break; 128 case T_INT: __ str (val, obj); break; 129 case T_ADDRESS: __ str (val, obj); break; 130 case T_LONG: 131 #ifdef AARCH64 132 __ str (val, obj); break; 133 #else // AARCH64 134 assert(val == noreg, "only tos"); 135 __ add (obj.index(), obj.index(), obj.base()); 136 __ stmia (obj.index(), RegisterSet(R0_tos_lo) | RegisterSet(R1_tos_hi)); 137 #endif // AARCH64 138 break; 139 #ifdef __SOFTFP__ 140 case T_FLOAT: 141 assert(val == noreg, "only tos"); 142 __ str (R0_tos, obj); 143 break; 144 case T_DOUBLE: 145 assert(val == noreg, "only tos"); 146 __ add (obj.index(), obj.index(), obj.base()); 147 __ stmia (obj.index(), RegisterSet(R0_tos_lo) | RegisterSet(R1_tos_hi)); 148 break; 149 #else 150 case T_FLOAT: 151 assert(val == noreg, "only tos"); 152 __ add (obj.index(), obj.index(), obj.base()); 153 __ str_float (S0_tos, obj.index()); 154 break; 155 case T_DOUBLE: 156 assert(val == noreg, "only tos"); 157 __ add (obj.index(), obj.index(), obj.base()); 158 __ str_double (D0_tos, obj.index()); 159 break; 160 #endif 161 default: Unimplemented(); 162 } 163 } 164 165 void BarrierSetAssembler::obj_equals(MacroAssembler* masm, 166 Register obj1, Register obj2) { 167 __ cmp(obj1, obj2); 168 }