1# Copyright (c) 2021 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13--- 14definitions: 15 - name: java 16 template: > 17 .language Java 18 - name: R_xorshift32 19 template: | 20 # 21 # Next random number 22 # x = R.currentValue 23 # x ^= x << 13; 24 # x ^= x >> 17; 25 # x ^= x << 5; 26 # R.currentValue = x 27 # return x 28 .function i32 R.nextRand(R a0) { 29 ldobj a0, R.currentValue 30 sta v0 31 sta v1 32 movi v2, 0xd 33 shl v1, v2 34 sta v1 35 xor v0, v1 36 sta v0 37 sta v1 38 movi v2, 0x11 39 ashr v1, v2 40 sta v1 41 xor v0, v1 42 sta v0 43 sta v1 44 movi v2, 0x5 45 shl v1, v2 46 sta v1 47 xor v0, v1 48 stobj a0, R.currentValue 49 return 50 } 51tests: 52 - file-name: call.virt.range 53 isa: 54 instructions: 55 - sig: call.virt.range method_id, v:in:top 56 acc: out:top 57 format: [op_v_8_id_16] 58 title: Object calls 59 description: > 60 Call indicated object method, i.e. create new frame, pass values of arguments and 61 continue execution from the first instruction of a method. 62 Callee should treat accumulator value as undefined and cannot use it until accumulator 63 definition in the new frame. 64 Result (if any) is returned in accumulator (see 'Calling sequence' chapter for more details). 65 Method, its class and the number of argument is resolved by given method_id in runtime 66 constant-pool based on object reference using language-specific semantics (currently only Java 67 virtual methods are supported, further extensions are TBD). 68 Object reference is passed in the first source register, arguments are passed starting from 69 the second source register in the same order as in method signature. 70 Non-range instructions can be used to pass up to 4 arguments (including object reference). 71 Unused register slot values will be discarded and corresponding registers will not be 72 passed to the callee). 73 For methods with more arguments range kinds of instruction are to be used, which takes 74 the needed number of arguments starting from 'vs' register (including object reference). 75 verification: 76 - method_id_non_static 77 - compatible_arguments 78 - method_id_accessible 79 exceptions: 80 - x_null 81 - x_abstract 82 commands: 83 - file-name: incorrect_type 84 isa: 85 instructions: 86 - sig: call.virt.range method_id, v:in:top 87 acc: out:top 88 format: [op_v_8_id_16] 89 description: > 90 Call indicated object method, i.e. create new frame, pass values of arguments and 91 continue execution from the first instruction of a method. 92 header-template: [] 93 description: > 94 Compiler test for call.virt.range that check virtual or static method with incorrect type of object in register. 95 code-template: | 96 %s 97 98 .record A {} 99 100 .function void A.constructor(A a0) <ctor> { 101 return.void 102 } 103 104 *s 105 .function void A.foo(A a0*s) %s { 106 return.void 107 } 108 109 .function i32 main() { 110 initobj.short A.constructor 111 *s 112 call.virt.range A.foo*s 113 check-type: none 114 runner-options: [compile-only] 115 template-cases: 116 - values: ['', ''] 117 exclude: ['jobj'] 118 - values: ['', '<static>'] 119 exclude: ['jstr'] 120 121 cases: 122 - values: 123 - '' 124 - ', i32 a1' 125 - movi v0, 0 126 - ', v0' 127 - values: ['','','',''] 128 runner-options: [compile-failure] 129 - values: 130 - '' 131 - ', f64 a1' 132 - fmovi.64 v0, 0 133 - ', v0' 134 - values: 135 - '' 136 - ', i64 a1' 137 - movi.64 v0, 0 138 - ', v0' 139 - values: 140 - '.record java.lang.Object <external>' 141 - ', java.lang.Object a1' 142 - | 143 # 144 newobj v0, java.lang.Object 145 - ', v0' 146 id: jobj 147 - values: 148 - '.record java.lang.String <external>' 149 - ', java.lang.String a1' 150 - 'lda.str "some string"' 151 - ', v0' 152 id: jstr 153 - values: 154 - '.record panda.Object <external>' 155 - ', panda.Object a1' 156 - | 157 # 158 newobj v0, panda.Object 159 - ', v0' 160 id: pobj 161 - values: 162 - '.record panda.String <external>' 163 - ', panda.String a1' 164 - 'lda.str "some string"' 165 - ', v0' 166 id: pstr 167 168 - file-name: p_method_call_args_many 169 isa: 170 instructions: 171 - sig: call.virt.range method_id, v:in:top 172 acc: out:top 173 format: [op_v_8_id_16] 174 header-template: [R_xorshift32] 175 description: > 176 Invoke virtual method with different pseudo-random values and check if correct value is stored in object field. Check i32, i64, f64 and reference types. 177 Use PandaAssembly language context. 178 tags: ['tsan'] 179 code-template: | 180 ##- Object definition 181 .record R { 182 i32 currentValue 183 %s 184 } 185 186 .function void R.constructor(R a0) <ctor> { 187 return.void 188 } 189 190 ##- Template of function that get several arguments and stores to Object 191 .function void R.storeValues(R a0, %s) { 192 %s 193 return.void 194 } 195 196 .function u32 R.test(R a0) { 197 ##- Test - generate pseudo-random values, store to registers as primitive/objects and invoke R.storeValue 198 %s 199 } 200 201 .function u32 main() { 202 # Create R object 203 initobj.short R.constructor 204 # Keep it in v0 205 sta.obj v0 206 # Iterations 207 movi v1, 10 208 ##- First value of pseudorandom generator - store to R.currentValue 209 ldai *s 210 stobj v0, R.currentValue 211 loop: 212 call.virt.range R.test, v0 213 jnez exit_err 214 inci v1, -1 215 lda v1 216 jnez loop 217 ldai 0 218 return 219 exit_err: 220 ldai 1 221 return 222 check-type: none 223 template-cases: 224 - values: 225 - | 226 # 227 i32 f1 228 i32 f2 229 i32 f3 230 - i32 a1, i32 a2, i32 a3 231 - | 232 # 233 lda a1 234 stobj a0, R.f1 235 lda a2 236 stobj a0, R.f2 237 lda a3 238 stobj a0, R.f3 239 - | 240 # Get next random number 241 mov.obj v0, a0 242 call.virt.range R.nextRand, v0 243 sta v0 244 mov v4, v0 245 mov.obj v0, a0 246 call.virt.range R.nextRand, v0 247 sta v0 248 mov v5, v0 249 mov.obj v0, a0 250 call.virt.range R.nextRand, v0 251 sta v0 252 mov v6, v0 253 mov.obj v0, a0 254 mov v1, v4 255 mov v2, v5 256 mov v3, v6 257 call.virt.range R.storeValues, v0 258 mov v0, v4 259 mov.obj v1, a0 260 ldobj v1, R.f1 261 sta v1 262 lda v0 263 jeq v1, jump_label_0 264 movi v0, 0x1 265 lda v0 266 return 267 jump_label_0: mov v0, v5 268 mov.obj v1, a0 269 ldobj v1, R.f2 270 sta v1 271 lda v0 272 jeq v1, jump_label_1 273 movi v0, 0x1 274 lda v0 275 return 276 jump_label_1: mov v0, v6 277 mov.obj v1, a0 278 ldobj v1, R.f3 279 sta v1 280 lda v0 281 jeq v1, jump_label_2 282 movi v0, 0x1 283 lda v0 284 return 285 jump_label_2: movi v0, 0x0 286 lda v0 287 return 288 - values: 289 - | 290 # 291 i32 f1 292 i32 f2 293 i32[] f3 294 f64[] f4 295 i32[] f5 296 f64 f6 297 f64[] f7 298 - i32 a1, i32 a2, i32[] a3, f64[] a4, i32[] a5, f64 a6, f64[] a7 299 - | 300 # 301 lda a1 302 stobj a0, R.f1 303 lda a2 304 stobj a0, R.f2 305 lda.obj a3 306 stobj.obj a0, R.f3 307 lda.obj a4 308 stobj.obj a0, R.f4 309 lda.obj a5 310 stobj.obj a0, R.f5 311 lda.64 a6 312 stobj.64 a0, R.f6 313 lda.obj a7 314 stobj.obj a0, R.f7 315 - | 316 # Get next random number 317 mov.obj v0, a0 318 call.virt.range R.nextRand, a0 319 sta v0 320 mov v9, v0 321 mov.obj v0, a0 322 call.virt.range R.nextRand, a0 323 sta v0 324 mov v10, v0 325 mov.obj v0, a0 326 call.virt.range R.nextRand, a0 327 sta v0 328 movi v1, 0xff 329 and v1, v0 330 sta v0 331 newarr v0, v0, i32[] 332 mov.obj v11, v0 333 mov.obj v0, a0 334 call.virt.range R.nextRand, a0 335 sta v0 336 movi v1, 0xff 337 and v1, v0 338 sta v0 339 newarr v0, v0, f64[] 340 mov.obj v12, v0 341 mov.obj v0, a0 342 call.virt.range R.nextRand, a0 343 sta v0 344 movi v1, 0xff 345 and v1, v0 346 sta v0 347 newarr v0, v0, i32[] 348 mov.obj v13, v0 349 mov.obj v0, a0 350 call.virt.range R.nextRand, a0 351 sta v0 352 lda v0 353 i32tof64 354 sta.64 v0 355 sta.64 v1 356 mov.64 v14, v0 357 mov.obj v0, a0 358 call.virt.range R.nextRand, a0 359 sta v0 360 movi v1, 0xff 361 and v1, v0 362 sta v0 363 newarr v0, v0, f64[] 364 mov.obj v16, v0 365 mov.obj v0, a0 366 mov v1, v9 367 mov v2, v10 368 mov.obj v3, v11 369 mov.obj v4, v12 370 mov.obj v5, v13 371 mov.64 v6, v14 372 mov.64 v7, v14 373 mov.obj v8, v16 374 mov.obj v7, v8 375 call.virt.range R.storeValues, v0 376 mov v0, v9 377 mov.obj v1, a0 378 ldobj v1, R.f1 379 sta v1 380 lda v0 381 jeq v1, jump_label_0 382 ldai 1 383 return 384 jump_label_0: 385 mov v0, v10 386 mov.obj v1, a0 387 ldobj v1, R.f2 388 sta v1 389 lda v0 390 jeq v1, jump_label_1 391 ldai 1 392 return 393 jump_label_1: 394 mov.obj v0, v11 395 mov.obj v1, a0 396 ldobj.obj v1, R.f3 397 sta.obj v1 398 lda.obj v0 399 jeq.obj v1, jump_label_2 400 ldai 1 401 return 402 jump_label_2: 403 mov.obj v0, v12 404 mov.obj v1, a0 405 ldobj.obj v1, R.f4 406 sta.obj v1 407 lda.obj v0 408 jeq.obj v1, jump_label_3 409 ldai 1 410 return 411 jump_label_3: 412 mov.obj v0, v13 413 mov.obj v1, a0 414 ldobj.obj v1, R.f5 415 sta.obj v1 416 lda.obj v0 417 jeq.obj v1, jump_label_4 418 ldai 1 419 return 420 jump_label_4: 421 mov.64 v0, v14 422 mov.64 v1, v14 423 mov.obj v2, a0 424 ldobj.64 v2, R.f6 425 sta.64 v2 426 mov.64 v3, v2 427 lda.64 v0 428 fcmpl.64 v2 429 sta v0 430 lda v0 431 jeqz jump_label_5 432 ldai 1 433 return 434 jump_label_5: 435 mov.obj v0, v16 436 mov.obj v1, a0 437 ldobj.obj v1, R.f7 438 sta.obj v1 439 lda.obj v0 440 jeq.obj v1, jump_label_6 441 ldai 1 442 return 443 jump_label_6: 444 ldai 0 445 return 446 - values: 447 - | 448 # 449 f64 f1 450 f64 f2 451 i64 f3 452 f64 f4 453 f64 f5 454 i64 f6 455 f64 f7 456 f64 f8 457 i64 f9 458 - f64 a1, f64 a2, i64 a3, f64 a4, f64 a5, i64 a6, f64 a7, f64 a8, i64 a9 459 - | 460 # 461 mov.obj v0, a0 462 mov.64 v1, a1 463 lda.64 v1 464 stobj.64 v0, R.f1 465 mov.obj v0, a0 466 mov.64 v1, a2 467 mov.64 v2, a2 468 lda.64 v1 469 stobj.64 v0, R.f2 470 mov.obj v0, a0 471 mov.64 v1, a3 472 mov.64 v2, a3 473 lda.64 v1 474 stobj.64 v0, R.f3 475 mov.obj v0, a0 476 mov.64 v1, a4 477 lda.64 v1 478 stobj.64 v0, R.f4 479 mov.obj v0, a0 480 mov.64 v1, a5 481 mov.64 v2, a5 482 lda.64 v1 483 stobj.64 v0, R.f5 484 mov.obj v0, a0 485 mov.64 v1, a6 486 mov.64 v2, a6 487 lda.64 v1 488 stobj.64 v0, R.f6 489 mov.obj v0, a0 490 mov.64 v1, a7 491 lda.64 v1 492 stobj.64 v0, R.f7 493 mov.obj v0, a0 494 mov.64 v1, a8 495 mov.64 v2, a8 496 lda.64 v1 497 stobj.64 v0, R.f8 498 mov.obj v0, a0 499 mov.64 v1, a9 500 mov.64 v2, a9 501 lda.64 v1 502 stobj.64 v0, R.f9 503 504 - | 505 # 506 mov.obj v0, a0 507 call.virt.range R.nextRand, v0 508 sta v0 509 lda v0 510 i32tof64 511 sta.64 v0 512 sta.64 v1 513 mov.64 v19, v0 514 mov.obj v0, a0 515 call.virt.range R.nextRand, v0 516 sta v0 517 lda v0 518 i32tof64 519 sta.64 v0 520 sta.64 v1 521 mov.64 v21, v0 522 mov.obj v0, a0 523 call.virt.range R.nextRand, v0 524 sta v0 525 lda v0 526 i32toi64 527 sta.64 v0 528 sta.64 v1 529 mov.64 v23, v0 530 mov.obj v0, a0 531 call.virt.range R.nextRand, v0 532 sta v0 533 lda v0 534 i32tof64 535 sta.64 v0 536 sta.64 v1 537 mov.64 v25, v0 538 mov.obj v0, a0 539 call.virt.range R.nextRand, v0 540 sta v0 541 lda v0 542 i32tof64 543 sta.64 v0 544 sta.64 v1 545 mov.64 v27, v0 546 mov.obj v0, a0 547 call.virt.range R.nextRand, v0 548 sta v0 549 lda v0 550 i32toi64 551 sta.64 v0 552 sta.64 v1 553 mov.64 v29, v0 554 mov.obj v0, a0 555 call.virt.range R.nextRand, v0 556 sta v0 557 lda v0 558 i32tof64 559 sta.64 v0 560 sta.64 v1 561 mov.64 v31, v0 562 mov.obj v0, a0 563 call.virt.range R.nextRand, v0 564 sta v0 565 lda v0 566 i32tof64 567 sta.64 v0 568 sta.64 v1 569 mov.64 v33, v0 570 mov.obj v0, a0 571 call.virt.range R.nextRand, v0 572 sta v0 573 lda v0 574 i32toi64 575 sta.64 v0 576 sta.64 v1 577 mov.64 v35, v0 578 mov.obj v0, a0 579 # Don't panic, this is c2p + pandadisasm generated sources 580 mov.64 v1, v19 581 mov.64 v2, v19 582 mov.64 v3, v21 583 mov.64 v4, v21 584 mov.64 v5, v23 585 mov.64 v6, v23 586 mov.64 v7, v25 587 mov.64 v8, v25 588 mov.64 v9, v27 589 mov.64 v10, v27 590 mov.64 v11, v29 591 mov.64 v12, v29 592 mov.64 v13, v31 593 mov.64 v14, v31 594 mov.64 v15, v33 595 mov.64 v16, v33 596 mov.64 v17, v35 597 mov.64 v18, v35 598 mov.64 v2, v3 599 mov.64 v3, v4 600 mov.64 v4, v5 601 mov.64 v5, v6 602 mov.64 v6, v7 603 mov.64 v7, v8 604 mov.64 v8, v9 605 mov.64 v9, v10 606 mov.64 v10, v11 607 mov.64 v11, v12 608 mov.64 v12, v13 609 mov.64 v13, v14 610 mov.64 v14, v15 611 mov.64 v15, v16 612 mov.64 v16, v17 613 mov.64 v17, v18 614 mov.64 v3, v4 615 mov.64 v4, v5 616 mov.64 v5, v6 617 mov.64 v6, v7 618 mov.64 v7, v8 619 mov.64 v8, v9 620 mov.64 v9, v10 621 mov.64 v10, v11 622 mov.64 v11, v12 623 mov.64 v12, v13 624 mov.64 v13, v14 625 mov.64 v14, v15 626 mov.64 v15, v16 627 mov.64 v16, v17 628 mov.64 v4, v5 629 mov.64 v5, v6 630 mov.64 v6, v7 631 mov.64 v7, v8 632 mov.64 v8, v9 633 mov.64 v9, v10 634 mov.64 v10, v11 635 mov.64 v11, v12 636 mov.64 v12, v13 637 mov.64 v13, v14 638 mov.64 v14, v15 639 mov.64 v15, v16 640 mov.64 v5, v6 641 mov.64 v6, v7 642 mov.64 v7, v8 643 mov.64 v8, v9 644 mov.64 v9, v10 645 mov.64 v10, v11 646 mov.64 v11, v12 647 mov.64 v12, v13 648 mov.64 v13, v14 649 mov.64 v14, v15 650 mov.64 v6, v7 651 mov.64 v7, v8 652 mov.64 v8, v9 653 mov.64 v9, v10 654 mov.64 v10, v11 655 mov.64 v11, v12 656 mov.64 v12, v13 657 mov.64 v13, v14 658 mov.64 v7, v8 659 mov.64 v8, v9 660 mov.64 v9, v10 661 mov.64 v10, v11 662 mov.64 v11, v12 663 mov.64 v12, v13 664 mov.64 v8, v9 665 mov.64 v9, v10 666 mov.64 v10, v11 667 mov.64 v11, v12 668 mov.64 v9, v10 669 mov.64 v10, v11 670 call.virt.range R.storeValues, v0 671 mov.64 v0, v19 672 mov.64 v1, v19 673 mov.obj v2, a0 674 ldobj.64 v2, R.f1 675 sta.64 v2 676 mov.64 v3, v2 677 lda.64 v0 678 fcmpl.64 v2 679 sta v0 680 lda v0 681 jeqz jump_label_0 682 movi v0, 0x1 683 lda v0 684 return 685 jump_label_0: mov.64 v0, v21 686 mov.64 v1, v21 687 mov.obj v2, a0 688 ldobj.64 v2, R.f2 689 sta.64 v2 690 mov.64 v3, v2 691 lda.64 v0 692 fcmpl.64 v2 693 sta v0 694 lda v0 695 jeqz jump_label_1 696 movi v0, 0x1 697 lda v0 698 return 699 jump_label_1: mov.64 v0, v23 700 mov.64 v1, v23 701 mov.obj v2, a0 702 ldobj.64 v2, R.f3 703 sta.64 v2 704 mov.64 v3, v2 705 lda.64 v0 706 cmp.64 v3 707 sta v0 708 lda v0 709 jeqz jump_label_2 710 movi v0, 0x1 711 lda v0 712 return 713 jump_label_2: mov.64 v0, v25 714 mov.64 v1, v25 715 mov.obj v2, a0 716 ldobj.64 v2, R.f4 717 sta.64 v2 718 mov.64 v3, v2 719 lda.64 v0 720 fcmpl.64 v2 721 sta v0 722 lda v0 723 jeqz jump_label_3 724 movi v0, 0x1 725 lda v0 726 return 727 jump_label_3: mov.64 v0, v27 728 mov.64 v1, v27 729 mov.obj v2, a0 730 ldobj.64 v2, R.f5 731 sta.64 v2 732 mov.64 v3, v2 733 lda.64 v0 734 fcmpl.64 v2 735 sta v0 736 lda v0 737 jeqz jump_label_4 738 movi v0, 0x1 739 lda v0 740 return 741 jump_label_4: mov.64 v0, v29 742 mov.64 v1, v29 743 mov.obj v2, a0 744 ldobj.64 v2, R.f6 745 sta.64 v2 746 mov.64 v3, v2 747 lda.64 v0 748 cmp.64 v3 749 sta v0 750 lda v0 751 jeqz jump_label_5 752 movi v0, 0x1 753 lda v0 754 return 755 jump_label_5: mov.64 v0, v31 756 mov.64 v1, v31 757 mov.obj v2, a0 758 ldobj.64 v2, R.f7 759 sta.64 v2 760 mov.64 v3, v2 761 lda.64 v0 762 fcmpl.64 v2 763 sta v0 764 lda v0 765 jeqz jump_label_6 766 movi v0, 0x1 767 lda v0 768 return 769 jump_label_6: mov.64 v0, v33 770 mov.64 v1, v33 771 mov.obj v2, a0 772 ldobj.64 v2, R.f8 773 sta.64 v2 774 mov.64 v3, v2 775 lda.64 v0 776 fcmpl.64 v2 777 sta v0 778 lda v0 779 jeqz jump_label_7 780 movi v0, 0x1 781 lda v0 782 return 783 jump_label_7: mov.64 v0, v35 784 mov.64 v1, v35 785 mov.obj v2, a0 786 ldobj.64 v2, R.f9 787 sta.64 v2 788 mov.64 v3, v2 789 lda.64 v0 790 cmp.64 v3 791 sta v0 792 lda v0 793 jeqz jump_label_8 794 movi v0, 0x1 795 lda v0 796 return 797 jump_label_8: movi v0, 0x0 798 lda v0 799 return 800 cases: 801 - values: 802 - "0xBADC0FFE" 803 - values: 804 - "0x12345678" 805 - values: 806 - "0xFEDCBA98" 807 - values: 808 - "1" 809 - values: 810 - "0xFFFFFFFF" 811 - values: 812 - "0x80000000" 813 - values: 814 - "0x7FFFFFFF" 815 816