1# Copyright (c) 2021-2022 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: PandaAssembly 16 template: | 17 .language PandaAssembly 18 19tests: 20 - file-name: "jeqz.obj" 21 isa: 22 title: Conditional compared to null jump 23 description: > 24 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 25 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 26 instruction address. 27 exceptions: 28 - x_none 29 instructions: 30 - sig: jeqz.obj imm:i32 31 acc: in:ref 32 format: [op_imm_8, op_imm_16] 33 commands: 34 35 - file-name: "invalid_offset" 36 isa: 37 verification: 38 - branch_target 39 instructions: 40 - sig: jeqz.obj imm:i32 41 acc: in:ref 42 format: [op_imm_8, op_imm_16] 43 runner-options: [compile-failure] 44 description: Check 'jeqz.obj' instruction with invalid offset. 45 header-template: [] 46 code-template: | 47 .function i32 main() { 48 jeqz.obj %s 49 lbl: 50 check-type: exit-positive 51 cases: 52 - values: [""] 53 - values: ["main"] 54 - values: ["v1"] 55 - values: ["v1, lbl"] 56 - values: ["}"] 57 - values: ["# lbl"] 58 - values: ["Lbl"] 59 - values: ["LBL"] 60 61 62 - file-name: "uninitialized_acc" 63 isa: 64 verification: 65 - acc_obj_or_null 66 runner-options: ['verifier-failure', 'verifier-config'] 67 tags: [verifier] 68 description: Check 'jeqz.obj' instruction with uninitialized accumulator. 69 header-template: [] 70 code-template: | 71 .function i32 main() { 72 jeqz.obj lbl 73 ldai 1 74 return 75 lbl: 76 check-type: exit-positive 77 78 79 - file-name: "invalid_branch_target" 80 isa: 81 verification: 82 - branch_target 83 runner-options: [compile-failure] 84 description: Check 'jeqz.obj' instruction with invalid branch target. 85 header-template: [] 86 code-template: | 87 .record R {} 88 89 .function void R.ctor(R a0) <ctor> { 90 lbl_ctor: 91 return.void 92 } 93 94 .function void R.cctor() <cctor> { 95 lbl_cctor: 96 return.void 97 } 98 99 .function i32 foo() <static> { 100 lda.null 101 jeqz.obj %s 102 } 103 104 .function i32 bar() <static> { 105 lbl_bar: 106 ldai 1 107 return 108 } 109 110 .function i32 main() { 111 call.short foo 112 lbl_main: 113 check-type: exit-positive 114 cases: 115 - values: ["main"] 116 - values: ["foo"] 117 - values: ["bar"] 118 - values: ["baz"] 119 - values: ["R"] 120 - values: ["lbl_main"] 121 - values: ["lbl_bar"] 122 - values: ["lbl_ctor"] 123 - values: ["lbl_cctor"] 124 125 126 - file-name: "prohibited_branch_target_p" 127 isa: 128 verification: 129 - branch_target 130 runner-options: ['verifier-failure', 'verifier-config'] 131 tags: [verifier] 132 description: Check 'jeqz.obj' instruction with prohibited branch target in PandaAssembly context. 133 header-template: [] 134 code-template: | 135 .record E1 {} 136 .record E2 {} 137 .record R {} 138 139 .function void R.ctor(R a0) <ctor> { 140 return.void 141 } 142 143 .function i32 main() { 144 lda.null 145 jeqz.obj %s 146 147 begin: 148 ldai 0 149 return 150 mid: 151 ldai 1 152 return 153 end: 154 ldai 2 155 return 156 157 catch_E1_begin: 158 ldai 3 159 return 160 catch_E1_mid: 161 ldai 4 162 return 163 catch_E1_end: 164 ldai 5 165 return 166 167 catch_E2_begin: 168 ldai 6 169 return 170 catch_E2_mid: 171 ldai 7 172 return 173 catch_E2_end: 174 175 quit: 176 ldai 8 177 return 178 179 .catch E1, begin, end, catch_E1_begin, catch_E1_end 180 .catch E2, catch_E1_begin, catch_E1_end, catch_E2_begin, catch_E2_end 181 outside: 182 check-type: none 183 cases: 184 - values: ["begin"] 185 runner-options: ['verifier-only', 'verifier-config'] 186 - values: ["mid"] 187 runner-options: ['verifier-only', 'verifier-config'] 188 - values: ["end"] 189 runner-options: ['verifier-only', 'verifier-config'] 190 - values: ["quit"] 191 runner-options: ['verifier-only', 'verifier-config'] 192 - values: ["catch_E1_begin"] 193 - values: ["catch_E1_mid"] 194 - values: ["catch_E1_end"] 195 runner-options: ['verifier-only', 'verifier-config'] 196 - values: ["catch_E2_begin"] 197 - values: ["catch_E2_mid"] 198 - values: ["catch_E2_end"] 199 runner-options: ['verifier-only', 'verifier-config'] 200 - values: ["outside"] 201 202 203 - file-name: "prohibited_branch_target_j" 204 isa: 205 verification: 206 - branch_target 207 runner-options: [verifier-failure, use-pa, verifier-config] 208 tags: [verifier, pa-verifier] 209 description: Check 'jeqz.obj' instruction with prohibited branch target in PandaAssembly context. 210 header-template: [PandaAssembly] 211 code-template: | 212 .record panda.NullPointerException <external> 213 .record panda.Exception <external> 214 215 .function i32 main() { 216 lda.null 217 jeqz.obj %s 218 219 begin: 220 ldai 0 221 return 222 mid: 223 ldai 1 224 return 225 end: 226 ldai 2 227 return 228 229 catch_NPE_begin: 230 ldai 3 231 return 232 catch_NPE_mid: 233 ldai 4 234 return 235 catch_NPE_end: 236 ldai 5 237 return 238 239 catch_E_begin: 240 ldai 6 241 return 242 catch_E_mid: 243 ldai 7 244 return 245 catch_E_end: 246 247 quit: 248 ldai 8 249 return 250 251 .catch panda.NullPointerException, begin, end, catch_NPE_begin, catch_NPE_end 252 .catch panda.Exception, catch_NPE_begin, catch_NPE_end, catch_E_begin, catch_E_end 253 outside: 254 check-type: none 255 cases: 256 - values: ["begin"] 257 runner-options: [verifier-only, use-pa, verifier-config] 258 - values: ["mid"] 259 runner-options: [verifier-only, use-pa, verifier-config] 260 - values: ["end"] 261 runner-options: [verifier-only, use-pa, verifier-config] 262 - values: ["quit"] 263 runner-options: [verifier-only, use-pa, verifier-config] 264 - values: ["catch_NPE_begin"] 265 - values: ["catch_NPE_mid"] 266 - values: ["catch_NPE_end"] 267 runner-options: [verifier-only, use-pa, verifier-config] 268 - values: ["catch_E_begin"] 269 - values: ["catch_E_mid"] 270 - values: ["catch_E_end"] 271 runner-options: [verifier-only, use-pa, verifier-config] 272 - values: ["outside"] 273 274 275 - file-name: "invalid_acc_value" 276 isa: 277 verification: 278 - acc_obj_or_null 279 runner-options: ['verifier-failure', 'verifier-config'] 280 tags: [verifier] 281 description: Check 'jeqz.obj' instruction with invalid accumulator value 282 header-template: [] 283 code-template: | 284 .function i32 main() { 285 %s 286 jeqz.obj ok 287 ldai 1 288 return 289 ok: 290 check-type: exit-positive 291 cases: 292 - values: 293 - ldai 0 294 - values: 295 - ldai 1 296 - values: 297 - ldai 0x7fffffff 298 - values: 299 - ldai 0xffffffff 300 - values: 301 - ldai 0x80000000 302 - values: 303 - ldai.64 0 304 - values: 305 - ldai.64 1 306 - values: 307 - ldai.64 0x7fffffffffffffff 308 - values: 309 - ldai.64 0xffffffffffffffff 310 - values: 311 - ldai.64 0x8000000000000000 312 - values: 313 - | 314 # 315 fldai 0x00000000 # Positive zero (+0.0) 316 - values: 317 - | 318 # 319 fldai 0x80000000 # Negative zero (-0.0) 320 - values: 321 - | 322 # 323 fldai 0x00000001 # Minimal positive value (1.4012985e-45) 324 - values: 325 - | 326 # 327 fldai 0x80000001 # Maximal negative value (-1.4012985e-45) 328 - values: 329 - | 330 # 331 fldai 0x7f7fffff # Maximal positive value (3.4028235e38) 332 - values: 333 - | 334 # 335 fldai 0xff7fffff # Minimal negative value (-3.4028235e38) 336 - values: 337 - | 338 # 339 fldai 0x7f800000 # Positive infinity 340 - values: 341 - | 342 # 343 fldai 0xff800000 # Negative infinity 344 - values: 345 - | 346 # 347 fldai 0x7fc00000 # NaN 348 - values: 349 - | 350 # 351 fldai.64 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`) 352 - values: 353 - | 354 # 355 fldai.64 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`) 356 - values: 357 - | 358 # 359 fldai.64 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`) 360 - values: 361 - | 362 # 363 fldai.64 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`) 364 - values: 365 - | 366 # 367 fldai.64 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`) 368 - values: 369 - | 370 # 371 fldai.64 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`) 372 - values: 373 - | 374 # 375 fldai.64 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`) 376 - values: 377 - | 378 # 379 fldai.64 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`) 380 - values: 381 - | 382 # 383 fldai.64 0x7ff8000000000000 # NaN 384 385 386 - file-name: "valid_null_value_p" 387 isa: 388 description: > 389 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 390 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 391 instruction address. 392 description: Check 'jeqz.obj' instruction with valid null value in PandaAssembly context. 393 header-template: [] 394 tags: [tsan] 395 code-template: | 396 .function i32 main() { 397 lda.null 398 jeqz.obj ok 399 ldai 1 400 return 401 ok: 402 check-type: exit-positive 403 404 405 - file-name: "valid_null_value_j" 406 isa: 407 description: > 408 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 409 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 410 instruction address. 411 description: Check 'jeqz.obj' instruction with valid null value in PandaAssembly context. 412 runner-options: [use-pa] 413 header-template: [PandaAssembly] 414 tags: ['tsan'] 415 code-template: | 416 .function i32 main() { 417 lda.null 418 jeqz.obj ok 419 ldai 1 420 return 421 ok: 422 check-type: exit-positive 423 424 425 - file-name: "valid_not_null_values_p" 426 isa: 427 description: > 428 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 429 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 430 instruction address. 431 description: Check 'jeqz.obj' instruction with valid not null values in PandaAssembly context. 432 header-template: [] 433 tags: [tsan] 434 code-template: | 435 .record panda.String <external> 436 .record panda.Class <external> 437 .record panda.Object <external> 438 .record R {} 439 .function void R.ctor(R a0) <ctor> { 440 return.void 441 } 442 .function i32 main() { 443 %s 444 jeqz.obj eq 445 ldai 0 446 return 447 eq: 448 ldai 1 449 return 450 check-type: none 451 cases: 452 - values: 453 - initobj R.ctor 454 - values: 455 - lda.str "test1" 456 - values: 457 - lda.type R 458 - values: 459 - lda.type panda.Object 460 - values: 461 - | 462 # 463 movi v2, 10 464 newarr v2, v2, u32[] 465 lda.obj v2 466 - values: 467 - | 468 # 469 movi v2, 10 470 newarr v2, v2, u64[][] 471 lda.obj v2 472 - values: 473 - | 474 # 475 movi v2, 10 476 newarr v2, v2, R[] 477 lda.obj v2 478 - values: 479 - | 480 # 481 movi v2, 10 482 newarr v2, v2, panda.Class[][] 483 lda.obj v2 484 - values: 485 - | 486 # 487 movi v2, 10 488 newarr v2, v2, panda.String[][][] 489 lda.obj v2 490 491 492 - file-name: "valid_not_null_values_j" 493 isa: 494 description: > 495 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 496 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 497 instruction address. 498 description: Check 'jeqz.obj' instruction with valid not null values in PandaAssembly context. 499 runner-options: [use-pa] 500 header-template: [] 501 tags: ['tsan'] 502 code-template: | 503 .language PandaAssembly 504 .record panda.String <external> 505 .record panda.Class <external> 506 .record panda.Object <external> 507 .record R {} 508 .function void R.ctor(R a0) <ctor> { 509 return.void 510 } 511 .function i32 main() { 512 %s 513 jeqz.obj eq 514 ldai 0 515 return 516 eq: 517 ldai 1 518 return 519 check-type: none 520 cases: 521 - values: 522 - initobj R.ctor 523 - values: 524 - lda.str "test1" 525 - values: 526 - lda.type R 527 - values: 528 - lda.type panda.Object 529 - values: 530 - | 531 # 532 movi v2, 10 533 newarr v2, v2, i32[] 534 lda.obj v2 535 - values: 536 - | 537 # 538 movi v2, 10 539 newarr v2, v2, f64[][] 540 lda.obj v2 541 - values: 542 - | 543 # 544 movi v2, 10 545 newarr v2, v2, R[] 546 lda.obj v2 547 - values: 548 - | 549 # 550 movi v2, 10 551 newarr v2, v2, panda.Class[][] 552 lda.obj v2 553 - values: 554 - | 555 # 556 movi v2, 10 557 newarr v2, v2, panda.String[][][] 558 lda.obj v2 559 560 561 - file-name: "valid_offset_values" 562 isa: 563 description: > 564 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 565 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 566 instruction address. 567 description: Check 'jeqz.obj' instruction with valid offset values. 568 header-template: [] 569 code-template: | 570 .function i32 main() { 571 lda.null 572 %s 573 ldai 1 # 2-byte instruction 574 return # 1-byte instruction 575 quit: 576 check-type: exit-positive 577 cases: 578 - description: Same instruction jump, offset imm8, 0 bytes 579 values: 580 - | 581 # 582 lda.str "test" 583 lbl: 584 jeqz.obj lbl 585 ldai 0 586 return 587 - description: Max forward jump for imm8, 2 + 120 + 2 + 3 = 127 bytes 588 values: 589 - | 590 # 591 jeqz.obj quit # 2-byte instruction 592 movi.64 v0, 0 ##*12 593 lda.null 594 lda.null 595 - description: Max backward jump for imm8, 3 + 120 + 5 = 128 bytes 596 values: 597 - | 598 # 599 jmp lbl2 600 lbl1: 601 jmp quit # 3-byte instruction 602 movi.64 v0, 0 ##*12 603 ldai 1 604 ldai 1 605 return 606 lbl2: 607 jeqz.obj lbl1 608 tags: [tsan] 609 - description: Max forward jump for imm16, 3 + 32760 + 1 + 3 = 32767 bytes 610 values: 611 - | 612 # 613 jeqz.obj quit # 3-byte instruction 614 movi.64 v0, 0 ##*3276 615 lda.null 616 - description: Beyond max forward jump for imm16, 3 + 40000 + 3 = 40006 bytes. Converted to jnez.obj + jmp by compiler. 617 values: 618 - | 619 # 620 jeqz.obj quit # 3-byte instruction 621 movi.64 v0, 0 ##*4000 622 tags: [tsan] 623 - description: Max backward jump for imm16, 5 + 32760 + 3 = 32768 bytes 624 values: 625 - | 626 # 627 jmp lbl2 628 lbl1: 629 jmp quit # 5-byte instruction 630 movi.64 v0, 0 ##*3276 631 ldai 1 632 return 633 lbl2: 634 jeqz.obj lbl1 635 - description: Beyond max backward jump for imm16, 5 + 40000 = 40005 bytes. Converted to jnez.obj + jmp by compiler. 636 values: 637 - | 638 # 639 jmp lbl2 640 lbl1: 641 jmp quit # 5-byte instruction 642 movi.64 v0, 0 ##*4000 643 ldai 1 644 return 645 lbl2: 646 jeqz.obj lbl1 647 - description: Chain of forward jumps 648 values: 649 - | 650 # 651 jeqz.obj lbl1 652 ldai 2 653 return 654 lbl1: 655 jeqz.obj lbl2 656 ldai 3 657 return 658 lbl2: 659 jeqz.obj lbl3 660 ldai 4 661 return 662 lbl3: 663 jeqz.obj lbl4 664 ldai 5 665 return 666 lbl4: 667 jeqz.obj quit 668 - description: Chain of backward jumps 669 values: 670 - | 671 # 672 jmp lbl1 673 lbl6: 674 jmp quit 675 lbl5: 676 jeqz.obj lbl6 677 ldai 5 678 return 679 lbl4: 680 jeqz.obj lbl5 681 ldai 4 682 return 683 lbl3: 684 jeqz.obj lbl4 685 ldai 3 686 return 687 lbl2: 688 jeqz.obj lbl3 689 ldai 2 690 return 691 lbl1: 692 jeqz.obj lbl2 693 tags: [tsan] 694