1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 import java.lang.invoke.MethodHandles; 17 import java.lang.invoke.VarHandle; 18 19 public class Main { main(String[] args)20 public static void main(String[] args) { 21 // Since the tests will share a value, we have the condition that the value starts 22 // and ends as 0 before and after each test. 23 24 // Int tests 25 $noinline$testGetAndAdd_Int(); 26 $noinline$testGetAndSet_Int(); 27 $noinline$testGetAndBitwiseAnd_Int(); 28 $noinline$testGetAndBitwiseOr_Int(); 29 $noinline$testGetAndBitwiseXor_Int(); 30 31 // Long tests 32 $noinline$testGetAndAdd_Long(); 33 $noinline$testGetAndSet_Long(); 34 $noinline$testGetAndBitwiseAnd_Long(); 35 $noinline$testGetAndBitwiseOr_Long(); 36 $noinline$testGetAndBitwiseXor_Long(); 37 38 // Float tests 39 $noinline$testGetAndAdd_Float(); 40 $noinline$testGetAndSet_Float(); 41 42 // Double tests 43 $noinline$testGetAndAdd_Double(); 44 $noinline$testGetAndSet_Double(); 45 } 46 $noinline$testGetAndAdd_Int()47 private static void $noinline$testGetAndAdd_Int() { 48 Main m = new Main(); 49 // 0 + 100 = 100 50 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 51 m.$noinline$getAndAdd_Int(100); 52 $noinline$assertIntEquals(100, (int) INT_VALUE.get(m)); 53 54 // 100 - 100 = 0 55 m.$noinline$getAndAdd_Int(-100); 56 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 57 } 58 $noinline$testGetAndSet_Int()59 private static void $noinline$testGetAndSet_Int() { 60 Main m = new Main(); 61 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 62 m.$noinline$getAndSet_Int(100); 63 $noinline$assertIntEquals(100, (int) INT_VALUE.get(m)); 64 65 m.$noinline$getAndSet_Int(-100); 66 $noinline$assertIntEquals(-100, (int) INT_VALUE.get(m)); 67 68 m.$noinline$getAndSet_Int(0); 69 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 70 } 71 $noinline$testGetAndBitwiseAnd_Int()72 private static void $noinline$testGetAndBitwiseAnd_Int() { 73 Main m = new Main(); 74 // 0 AND X = 0 75 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 76 m.$noinline$getAndBitwiseAnd_Int(100); 77 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 78 79 // 10101010 AND 80 // 11001100 = 81 // 10001000 82 m.$noinline$getAndSet_Int(0b10101010); 83 m.$noinline$getAndBitwiseAnd_Int(0b11001100); 84 $noinline$assertIntEquals(0b10001000, (int) INT_VALUE.get(m)); 85 86 // 10001000 AND 87 // 11111111 = 88 // 10001000 89 m.$noinline$getAndBitwiseAnd_Int(0b11111111); 90 $noinline$assertIntEquals(0b10001000, (int) INT_VALUE.get(m)); 91 92 // 10001000 AND 93 // 01110111 = 94 // 0 95 m.$noinline$getAndBitwiseAnd_Int(0b01110111); 96 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 97 } 98 $noinline$testGetAndBitwiseOr_Int()99 private static void $noinline$testGetAndBitwiseOr_Int() { 100 Main m = new Main(); 101 102 // 0 OR X = X 103 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 104 m.$noinline$getAndBitwiseOr_Int(0b10101010); 105 $noinline$assertIntEquals(0b10101010, (int) INT_VALUE.get(m)); 106 107 // 10101010 OR 108 // 01010101 = 109 // 11111111 110 m.$noinline$getAndBitwiseOr_Int(0b01010101); 111 $noinline$assertIntEquals(0b11111111, (int) INT_VALUE.get(m)); 112 113 // 11111111 OR 114 // 0 = 115 // 11111111 116 m.$noinline$getAndBitwiseOr_Int(0); 117 $noinline$assertIntEquals(0b11111111, (int) INT_VALUE.get(m)); 118 119 // Set to 0 due to precondition. See comment in main. 120 m.$noinline$getAndSet_Int(0); 121 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 122 } 123 $noinline$testGetAndBitwiseXor_Int()124 private static void $noinline$testGetAndBitwiseXor_Int() { 125 Main m = new Main(); 126 127 // 0 XOR X = X 128 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 129 m.$noinline$getAndBitwiseXor_Int(0b10101010); 130 $noinline$assertIntEquals(0b10101010, (int) INT_VALUE.get(m)); 131 132 // 10101010 XOR 133 // 01010101 = 134 // 11111111 135 m.$noinline$getAndBitwiseXor_Int(0b01010101); 136 $noinline$assertIntEquals(0b11111111, (int) INT_VALUE.get(m)); 137 138 // 11111111 XOR 139 // 01010101 = 140 // 10101010 141 m.$noinline$getAndBitwiseXor_Int(0b01010101); 142 $noinline$assertIntEquals(0b10101010, (int) INT_VALUE.get(m)); 143 144 // X XOR X = 0 145 m.$noinline$getAndBitwiseXor_Int(0b10101010); 146 $noinline$assertIntEquals(0, (int) INT_VALUE.get(m)); 147 } 148 $noinline$testGetAndAdd_Long()149 private static void $noinline$testGetAndAdd_Long() { 150 Main m = new Main(); 151 // 0 + 100 = 100 152 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 153 m.$noinline$getAndAdd_Long(100); 154 $noinline$assertLongEquals(100L, (long) LONG_VALUE.get(m)); 155 156 // 100 - 100 = 0 157 m.$noinline$getAndAdd_Long(-100); 158 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 159 } 160 $noinline$testGetAndSet_Long()161 private static void $noinline$testGetAndSet_Long() { 162 Main m = new Main(); 163 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 164 m.$noinline$getAndSet_Long(100); 165 $noinline$assertLongEquals(100L, (long) LONG_VALUE.get(m)); 166 167 m.$noinline$getAndSet_Long(-100); 168 $noinline$assertLongEquals(-100L, (long) LONG_VALUE.get(m)); 169 170 m.$noinline$getAndSet_Long(0); 171 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 172 } 173 $noinline$testGetAndBitwiseAnd_Long()174 private static void $noinline$testGetAndBitwiseAnd_Long() { 175 Main m = new Main(); 176 // 0 AND X = 0 177 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 178 m.$noinline$getAndBitwiseAnd_Long(100); 179 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 180 181 // 10101010 AND 182 // 11001100 = 183 // 10001000 184 m.$noinline$getAndSet_Long(0b10101010); 185 m.$noinline$getAndBitwiseAnd_Long(0b11001100); 186 $noinline$assertLongEquals(0b10001000L, (long) LONG_VALUE.get(m)); 187 188 // 10001000 AND 189 // 11111111 = 190 // 10001000 191 m.$noinline$getAndBitwiseAnd_Long(0b11111111); 192 $noinline$assertLongEquals(0b10001000L, (long) LONG_VALUE.get(m)); 193 194 // 10001000 AND 195 // 01110111 = 196 // 0 197 m.$noinline$getAndBitwiseAnd_Long(0b01110111); 198 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 199 } 200 $noinline$testGetAndBitwiseOr_Long()201 private static void $noinline$testGetAndBitwiseOr_Long() { 202 Main m = new Main(); 203 204 // 0 OR X = X 205 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 206 m.$noinline$getAndBitwiseOr_Long(0b10101010); 207 $noinline$assertLongEquals(0b10101010L, (long) LONG_VALUE.get(m)); 208 209 // 10101010 OR 210 // 01010101 = 211 // 11111111 212 m.$noinline$getAndBitwiseOr_Long(0b01010101); 213 $noinline$assertLongEquals(0b11111111L, (long) LONG_VALUE.get(m)); 214 215 // 11111111 OR 216 // 0 = 217 // 11111111 218 m.$noinline$getAndBitwiseOr_Long(0); 219 $noinline$assertLongEquals(0b11111111L, (long) LONG_VALUE.get(m)); 220 221 // Set to 0 due to precondition. See comment in main. 222 m.$noinline$getAndSet_Long(0); 223 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 224 } 225 $noinline$testGetAndBitwiseXor_Long()226 private static void $noinline$testGetAndBitwiseXor_Long() { 227 Main m = new Main(); 228 229 // 0 XOR X = X 230 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 231 m.$noinline$getAndBitwiseXor_Long(0b10101010); 232 $noinline$assertLongEquals(0b10101010L, (long) LONG_VALUE.get(m)); 233 234 // 10101010 XOR 235 // 01010101 = 236 // 11111111 237 m.$noinline$getAndBitwiseXor_Long(0b01010101); 238 $noinline$assertLongEquals(0b11111111L, (long) LONG_VALUE.get(m)); 239 240 // 11111111 XOR 241 // 01010101 = 242 // 10101010 243 m.$noinline$getAndBitwiseXor_Long(0b01010101); 244 $noinline$assertLongEquals(0b10101010L, (long) LONG_VALUE.get(m)); 245 246 // X XOR X = 0 247 m.$noinline$getAndBitwiseXor_Long(0b10101010); 248 $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m)); 249 } 250 $noinline$testGetAndAdd_Float()251 private static void $noinline$testGetAndAdd_Float() { 252 Main m = new Main(); 253 // 0 + 100 = 100 254 $noinline$assertFloatEquals(0.0f, (float) FLOAT_VALUE.get(m)); 255 m.$noinline$getAndAdd_Float(100.0f); 256 $noinline$assertFloatEquals(100.0f, (float) FLOAT_VALUE.get(m)); 257 258 // 100 - 100 = 0 259 m.$noinline$getAndAdd_Float(-100.0f); 260 $noinline$assertFloatEquals(0.0f, (float) FLOAT_VALUE.get(m)); 261 } 262 $noinline$testGetAndSet_Float()263 private static void $noinline$testGetAndSet_Float() { 264 Main m = new Main(); 265 $noinline$assertFloatEquals(0.0f, (float) FLOAT_VALUE.get(m)); 266 m.$noinline$getAndSet_Float(100.0f); 267 $noinline$assertFloatEquals(100.0f, (float) FLOAT_VALUE.get(m)); 268 269 m.$noinline$getAndSet_Float(-100.0f); 270 $noinline$assertFloatEquals(-100.0f, (float) FLOAT_VALUE.get(m)); 271 272 m.$noinline$getAndSet_Float(0.0f); 273 $noinline$assertFloatEquals(0.0f, (float) FLOAT_VALUE.get(m)); 274 } 275 $noinline$testGetAndAdd_Double()276 private static void $noinline$testGetAndAdd_Double() { 277 Main m = new Main(); 278 // 0 + 100 = 100 279 $noinline$assertDoubleEquals(0.0d, (double) DOUBLE_VALUE.get(m)); 280 m.$noinline$getAndAdd_Double(100.0d); 281 $noinline$assertDoubleEquals(100.0d, (double) DOUBLE_VALUE.get(m)); 282 283 // 100 - 100 = 0 284 m.$noinline$getAndAdd_Double(-100.0d); 285 $noinline$assertDoubleEquals(0.0d, (double) DOUBLE_VALUE.get(m)); 286 } 287 $noinline$testGetAndSet_Double()288 private static void $noinline$testGetAndSet_Double() { 289 Main m = new Main(); 290 $noinline$assertDoubleEquals(0.0d, (double) DOUBLE_VALUE.get(m)); 291 m.$noinline$getAndSet_Double(100.0d); 292 $noinline$assertDoubleEquals(100.0d, (double) DOUBLE_VALUE.get(m)); 293 294 m.$noinline$getAndSet_Double(-100.0d); 295 $noinline$assertDoubleEquals(-100.0d, (double) DOUBLE_VALUE.get(m)); 296 297 m.$noinline$getAndSet_Double(0.0d); 298 $noinline$assertDoubleEquals(0.0d, (double) DOUBLE_VALUE.get(m)); 299 } 300 301 // VarHandles 302 private volatile int int_value = 0; 303 private static final VarHandle INT_VALUE; 304 static { 305 try { 306 MethodHandles.Lookup l = MethodHandles.lookup(); 307 INT_VALUE = l.findVarHandle(Main.class, "int_value", int.class); 308 } catch (ReflectiveOperationException e) { 309 throw new ExceptionInInitializerError(e); 310 } 311 } 312 313 private volatile long long_value = 0L; 314 private static final VarHandle LONG_VALUE; 315 static { 316 try { 317 MethodHandles.Lookup l = MethodHandles.lookup(); 318 LONG_VALUE = l.findVarHandle(Main.class, "long_value", long.class); 319 } catch (ReflectiveOperationException e) { 320 throw new ExceptionInInitializerError(e); 321 } 322 } 323 324 private volatile float float_value = 0.0f; 325 private static final VarHandle FLOAT_VALUE; 326 static { 327 try { 328 MethodHandles.Lookup l = MethodHandles.lookup(); 329 FLOAT_VALUE = l.findVarHandle(Main.class, "float_value", float.class); 330 } catch (ReflectiveOperationException e) { 331 throw new ExceptionInInitializerError(e); 332 } 333 } 334 335 private volatile double double_value = 0.0d; 336 private static final VarHandle DOUBLE_VALUE; 337 static { 338 try { 339 MethodHandles.Lookup l = MethodHandles.lookup(); 340 DOUBLE_VALUE = l.findVarHandle(Main.class, "double_value", double.class); 341 } catch (ReflectiveOperationException e) { 342 throw new ExceptionInInitializerError(e); 343 } 344 } 345 346 // Check that we successfully intrinsify intrinsics (e.g. getAndAdd) by checking that there's no 347 // call to the runtime. 348 349 /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndAdd_Int(int) disassembly (after) 350 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 351 /// CHECK-NOT: call 352 /// CHECK: ReturnVoid 353 354 /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Int(int) disassembly (after) 355 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 356 /// CHECK-NOT: blx 357 /// CHECK: ReturnVoid 358 359 /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Int(int) disassembly (after) 360 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 361 /// CHECK-NOT: blr 362 /// CHECK: ReturnVoid 363 364 /// CHECK-START-RISCV64: void Main.$noinline$getAndAdd_Int(int) disassembly (after) 365 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 366 /// CHECK-NOT: jalr 367 /// CHECK: ReturnVoid $noinline$getAndAdd_Int(int value)368 private void $noinline$getAndAdd_Int(int value) { 369 INT_VALUE.getAndAdd(this, value); 370 } 371 372 /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndSet_Int(int) disassembly (after) 373 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 374 /// CHECK-NOT: call 375 /// CHECK: ReturnVoid 376 377 /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Int(int) disassembly (after) 378 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 379 /// CHECK-NOT: blx 380 /// CHECK: ReturnVoid 381 382 /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Int(int) disassembly (after) 383 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 384 /// CHECK-NOT: blr 385 /// CHECK: ReturnVoid 386 387 /// CHECK-START-RISCV64: void Main.$noinline$getAndSet_Int(int) disassembly (after) 388 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 389 /// CHECK-NOT: jalr 390 /// CHECK: ReturnVoid $noinline$getAndSet_Int(int value)391 private void $noinline$getAndSet_Int(int value) { 392 INT_VALUE.getAndSet(this, value); 393 } 394 395 /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndBitwiseAnd_Int(int) disassembly (after) 396 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 397 /// CHECK-NOT: call 398 /// CHECK: ReturnVoid 399 400 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseAnd_Int(int) disassembly (after) 401 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 402 /// CHECK-NOT: blx 403 /// CHECK: ReturnVoid 404 405 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseAnd_Int(int) disassembly (after) 406 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 407 /// CHECK-NOT: blr 408 /// CHECK: ReturnVoid 409 410 /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseAnd_Int(int) disassembly (after) 411 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 412 /// CHECK-NOT: jalr 413 /// CHECK: ReturnVoid $noinline$getAndBitwiseAnd_Int(int value)414 private void $noinline$getAndBitwiseAnd_Int(int value) { 415 INT_VALUE.getAndBitwiseAnd(this, value); 416 } 417 418 /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndBitwiseOr_Int(int) disassembly (after) 419 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 420 /// CHECK-NOT: call 421 /// CHECK: ReturnVoid 422 423 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseOr_Int(int) disassembly (after) 424 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 425 /// CHECK-NOT: blx 426 /// CHECK: ReturnVoid 427 428 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseOr_Int(int) disassembly (after) 429 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 430 /// CHECK-NOT: blr 431 /// CHECK: ReturnVoid 432 433 /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseOr_Int(int) disassembly (after) 434 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 435 /// CHECK-NOT: jalr 436 /// CHECK: ReturnVoid $noinline$getAndBitwiseOr_Int(int value)437 private void $noinline$getAndBitwiseOr_Int(int value) { 438 INT_VALUE.getAndBitwiseOr(this, value); 439 } 440 441 /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndBitwiseXor_Int(int) disassembly (after) 442 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 443 /// CHECK-NOT: call 444 /// CHECK: ReturnVoid 445 446 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseXor_Int(int) disassembly (after) 447 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 448 /// CHECK-NOT: blx 449 /// CHECK: ReturnVoid 450 451 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseXor_Int(int) disassembly (after) 452 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 453 /// CHECK-NOT: blr 454 /// CHECK: ReturnVoid 455 456 /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseXor_Int(int) disassembly (after) 457 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 458 /// CHECK-NOT: jalr 459 /// CHECK: ReturnVoid $noinline$getAndBitwiseXor_Int(int value)460 private void $noinline$getAndBitwiseXor_Int(int value) { 461 INT_VALUE.getAndBitwiseXor(this, value); 462 } 463 $noinline$assertIntEquals(int expected, int result)464 private static void $noinline$assertIntEquals(int expected, int result) { 465 if (expected != result) { 466 throw new Error("Expected: " + expected + ", found: " + result); 467 } 468 } 469 470 // Note that the Long ones do a call for X86. 471 // TODO(solanes): Add this support. 472 473 /// CHECK-START-X86: void Main.$noinline$getAndAdd_Long(long) disassembly (after) 474 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 475 /// CHECK: call 476 /// CHECK: ReturnVoid 477 478 /// CHECK-START-X86_64: void Main.$noinline$getAndAdd_Long(long) disassembly (after) 479 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 480 /// CHECK-NOT: call 481 /// CHECK: ReturnVoid 482 483 /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Long(long) disassembly (after) 484 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 485 /// CHECK-NOT: blx 486 /// CHECK: ReturnVoid 487 488 /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Long(long) disassembly (after) 489 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 490 /// CHECK-NOT: blr 491 /// CHECK: ReturnVoid 492 493 /// CHECK-START-RISCV64: void Main.$noinline$getAndAdd_Long(long) disassembly (after) 494 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 495 /// CHECK-NOT: jalr 496 /// CHECK: ReturnVoid $noinline$getAndAdd_Long(long value)497 private void $noinline$getAndAdd_Long(long value) { 498 LONG_VALUE.getAndAdd(this, value); 499 } 500 501 /// CHECK-START-X86: void Main.$noinline$getAndSet_Long(long) disassembly (after) 502 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 503 /// CHECK: call 504 /// CHECK: ReturnVoid 505 506 /// CHECK-START-X86_64: void Main.$noinline$getAndSet_Long(long) disassembly (after) 507 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 508 /// CHECK-NOT: call 509 /// CHECK: ReturnVoid 510 511 /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Long(long) disassembly (after) 512 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 513 /// CHECK-NOT: blx 514 /// CHECK: ReturnVoid 515 516 /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Long(long) disassembly (after) 517 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 518 /// CHECK-NOT: blr 519 /// CHECK: ReturnVoid 520 521 /// CHECK-START-RISCV64: void Main.$noinline$getAndSet_Long(long) disassembly (after) 522 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 523 /// CHECK-NOT: jalr 524 /// CHECK: ReturnVoid $noinline$getAndSet_Long(long value)525 private void $noinline$getAndSet_Long(long value) { 526 LONG_VALUE.getAndSet(this, value); 527 } 528 529 /// CHECK-START-X86: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after) 530 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 531 /// CHECK: call 532 /// CHECK: ReturnVoid 533 534 /// CHECK-START-X86_64: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after) 535 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 536 /// CHECK-NOT: call 537 /// CHECK: ReturnVoid 538 539 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after) 540 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 541 /// CHECK-NOT: blx 542 /// CHECK: ReturnVoid 543 544 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after) 545 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 546 /// CHECK-NOT: blr 547 /// CHECK: ReturnVoid 548 549 /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after) 550 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd 551 /// CHECK-NOT: jalr 552 /// CHECK: ReturnVoid $noinline$getAndBitwiseAnd_Long(long value)553 private void $noinline$getAndBitwiseAnd_Long(long value) { 554 LONG_VALUE.getAndBitwiseAnd(this, value); 555 } 556 557 /// CHECK-START-X86: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after) 558 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 559 /// CHECK: call 560 /// CHECK: ReturnVoid 561 562 /// CHECK-START-X86_64: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after) 563 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 564 /// CHECK-NOT: call 565 /// CHECK: ReturnVoid 566 567 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after) 568 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 569 /// CHECK-NOT: blx 570 /// CHECK: ReturnVoid 571 572 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after) 573 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 574 /// CHECK-NOT: blr 575 /// CHECK: ReturnVoid 576 577 /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after) 578 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr 579 /// CHECK-NOT: jalr 580 /// CHECK: ReturnVoid $noinline$getAndBitwiseOr_Long(long value)581 private void $noinline$getAndBitwiseOr_Long(long value) { 582 LONG_VALUE.getAndBitwiseOr(this, value); 583 } 584 585 /// CHECK-START-X86: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after) 586 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 587 /// CHECK: call 588 /// CHECK: ReturnVoid 589 590 /// CHECK-START-X86_64: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after) 591 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 592 /// CHECK-NOT: call 593 /// CHECK: ReturnVoid 594 595 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after) 596 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 597 /// CHECK-NOT: blx 598 /// CHECK: ReturnVoid 599 600 /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after) 601 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 602 /// CHECK-NOT: blr 603 /// CHECK: ReturnVoid 604 605 /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after) 606 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor 607 /// CHECK-NOT: jalr 608 /// CHECK: ReturnVoid $noinline$getAndBitwiseXor_Long(long value)609 private void $noinline$getAndBitwiseXor_Long(long value) { 610 LONG_VALUE.getAndBitwiseXor(this, value); 611 } 612 $noinline$assertLongEquals(long expected, long result)613 private static void $noinline$assertLongEquals(long expected, long result) { 614 if (expected != result) { 615 throw new Error("Expected: " + expected + ", found: " + result); 616 } 617 } 618 619 /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndAdd_Float(float) disassembly (after) 620 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 621 /// CHECK-NOT: call 622 /// CHECK: ReturnVoid 623 624 /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Float(float) disassembly (after) 625 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 626 /// CHECK-NOT: blx 627 /// CHECK: ReturnVoid 628 629 /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Float(float) disassembly (after) 630 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 631 /// CHECK-NOT: blr 632 /// CHECK: ReturnVoid 633 634 /// CHECK-START-RISCV64: void Main.$noinline$getAndAdd_Float(float) disassembly (after) 635 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 636 /// CHECK-NOT: jalr 637 /// CHECK: ReturnVoid $noinline$getAndAdd_Float(float value)638 private void $noinline$getAndAdd_Float(float value) { 639 FLOAT_VALUE.getAndAdd(this, value); 640 } 641 642 /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndSet_Float(float) disassembly (after) 643 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 644 /// CHECK-NOT: call 645 /// CHECK: ReturnVoid 646 647 /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Float(float) disassembly (after) 648 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 649 /// CHECK-NOT: blx 650 /// CHECK: ReturnVoid 651 652 /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Float(float) disassembly (after) 653 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 654 /// CHECK-NOT: blr 655 /// CHECK: ReturnVoid 656 657 /// CHECK-START-RISCV64: void Main.$noinline$getAndSet_Float(float) disassembly (after) 658 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 659 /// CHECK-NOT: jalr 660 /// CHECK: ReturnVoid $noinline$getAndSet_Float(float value)661 private void $noinline$getAndSet_Float(float value) { 662 FLOAT_VALUE.getAndSet(this, value); 663 } 664 $noinline$assertFloatEquals(float expected, float result)665 private static void $noinline$assertFloatEquals(float expected, float result) { 666 if (expected != result) { 667 throw new Error("Expected: " + expected + ", found: " + result); 668 } 669 } 670 671 // Note that the Double ones do a call for X86. 672 // TODO(solanes): Add this support. 673 674 /// CHECK-START-X86: void Main.$noinline$getAndAdd_Double(double) disassembly (after) 675 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 676 /// CHECK: call 677 /// CHECK: ReturnVoid 678 679 /// CHECK-START-X86_64: void Main.$noinline$getAndAdd_Double(double) disassembly (after) 680 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 681 /// CHECK-NOT: call 682 /// CHECK: ReturnVoid 683 684 /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Double(double) disassembly (after) 685 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 686 /// CHECK-NOT: blx 687 /// CHECK: ReturnVoid 688 689 /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Double(double) disassembly (after) 690 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 691 /// CHECK-NOT: blr 692 /// CHECK: ReturnVoid 693 694 /// CHECK-START-RISCV64: void Main.$noinline$getAndAdd_Double(double) disassembly (after) 695 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndAdd 696 /// CHECK-NOT: jalr 697 /// CHECK: ReturnVoid $noinline$getAndAdd_Double(double value)698 private void $noinline$getAndAdd_Double(double value) { 699 DOUBLE_VALUE.getAndAdd(this, value); 700 } 701 702 /// CHECK-START-X86: void Main.$noinline$getAndSet_Double(double) disassembly (after) 703 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 704 /// CHECK: call 705 /// CHECK: ReturnVoid 706 707 /// CHECK-START-X86_64: void Main.$noinline$getAndSet_Double(double) disassembly (after) 708 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 709 /// CHECK-NOT: call 710 /// CHECK: ReturnVoid 711 712 /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Double(double) disassembly (after) 713 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 714 /// CHECK-NOT: blx 715 /// CHECK: ReturnVoid 716 717 /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Double(double) disassembly (after) 718 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 719 /// CHECK-NOT: blr 720 /// CHECK: ReturnVoid 721 722 /// CHECK-START-RISCV64: void Main.$noinline$getAndSet_Double(double) disassembly (after) 723 /// CHECK: InvokePolymorphic intrinsic:VarHandleGetAndSet 724 /// CHECK-NOT: jalr 725 /// CHECK: ReturnVoid $noinline$getAndSet_Double(double value)726 private void $noinline$getAndSet_Double(double value) { 727 DOUBLE_VALUE.getAndSet(this, value); 728 } 729 $noinline$assertDoubleEquals(double expected, double result)730 private static void $noinline$assertDoubleEquals(double expected, double result) { 731 if (expected != result) { 732 throw new Error("Expected: " + expected + ", found: " + result); 733 } 734 } 735 } 736