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: "jnez.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: jnez.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: jnez.obj imm:i32 41 acc: in:ref 42 format: [op_imm_8, op_imm_16] 43 runner-options: [compile-failure] 44 description: Check 'jnez.obj' instruction with invalid offset. 45 header-template: [] 46 code-template: | 47 .function i32 main() { 48 jnez.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 'jnez.obj' instruction with uninitialized accumulator. 69 header-template: [] 70 code-template: | 71 .function i32 main() { 72 jnez.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 'jnez.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 jnez.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 'jnez.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 initobj R.ctor 145 jnez.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 'jnez.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.str "test" 217 jnez.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 'jnez.obj' instruction with invalid accumulator value 282 header-template: [] 283 code-template: | 284 .function i32 main() { 285 %s 286 jnez.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 'jnez.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 jnez.obj ng 399 ldai 0 400 return 401 ng: 402 ldai 1 403 check-type: no-check 404 405 406 - file-name: "valid_null_value_j" 407 isa: 408 description: > 409 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 410 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 411 instruction address. 412 description: Check 'jnez.obj' instruction with valid null value in PandaAssembly context. 413 runner-options: [use-pa] 414 tags: ['tsan'] 415 header-template: [PandaAssembly] 416 code-template: | 417 .function i32 main() { 418 lda.null 419 jnez.obj ng 420 ldai 0 421 return 422 ng: 423 ldai 1 424 check-type: no-check 425 426 427 - file-name: "valid_not_null_values_p" 428 isa: 429 description: > 430 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 431 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 432 instruction address. 433 description: Check 'jnez.obj' instruction with valid not null values in PandaAssembly context. 434 header-template: [] 435 tags: [tsan] 436 code-template: | 437 .record panda.String <external> 438 .record panda.Class <external> 439 .record panda.Object <external> 440 .record R {} 441 .function void R.ctor(R a0) <ctor> { 442 return.void 443 } 444 .function i32 main() { 445 %s 446 jnez.obj ng 447 ldai 1 448 return 449 ng: 450 check-type: exit-positive 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 'jnez.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 jnez.obj ng 514 ldai 1 515 return 516 ng: 517 check-type: exit-positive 518 cases: 519 - values: 520 - initobj R.ctor 521 - values: 522 - lda.str "test1" 523 - values: 524 - lda.type R 525 - values: 526 - lda.type panda.Object 527 - values: 528 - | 529 # 530 movi v2, 10 531 newarr v2, v2, i32[] 532 lda.obj v2 533 - values: 534 - | 535 # 536 movi v2, 10 537 newarr v2, v2, f64[][] 538 lda.obj v2 539 - values: 540 - | 541 # 542 movi v2, 10 543 newarr v2, v2, R[] 544 lda.obj v2 545 - values: 546 - | 547 # 548 movi v2, 10 549 newarr v2, v2, panda.Class[][] 550 lda.obj v2 551 - values: 552 - | 553 # 554 movi v2, 10 555 newarr v2, v2, panda.String[][][] 556 lda.obj v2 557 558 559 - file-name: "valid_offset_values" 560 isa: 561 description: > 562 Transfer execution to an instruction at offset bytes from the beginning of the current instruction if 563 object reference in accumulator compares with null as specified. Offset is sign extended to the size of 564 instruction address. 565 description: Check 'jnez.obj' instruction with valid offset values. 566 header-template: [] 567 code-template: | 568 .function i32 main() { 569 lda.str "test" 570 %s 571 ldai 1 # 2-byte instruction 572 return # 1-byte instruction 573 quit: 574 check-type: exit-positive 575 cases: 576 - description: Same instruction jump, offset imm8, 0 bytes 577 values: 578 - | 579 # 580 lda.null 581 lbl: 582 jnez.obj lbl 583 ldai 0 584 return 585 - description: Max forward jump for imm8, 2 + 120 + 2 + 3 = 127 bytes 586 values: 587 - | 588 # 589 jnez.obj quit # 2-byte instruction 590 movi.64 v0, 0 ##*12 591 lda.null 592 lda.null 593 tags: [tsan] 594 - description: Max backward jump for imm8, 3 + 120 + 5 = 128 bytes 595 values: 596 - | 597 # 598 jmp lbl2 599 lbl1: 600 jmp quit # 3-byte instruction 601 movi.64 v0, 0 ##*12 602 ldai 1 603 ldai 1 604 return 605 lbl2: 606 jnez.obj lbl1 607 - description: Max forward jump for imm16, 3 + 32760 + 1 + 3 = 32767 bytes 608 values: 609 - | 610 # 611 jnez.obj quit # 3-byte instruction 612 movi.64 v0, 0 ##*3276 613 lda.null 614 - description: Beyond max forward jump for imm16, 3 + 40000 + 3 = 40006 bytes. Converted to jeqz.obj + jmp by compiler. 615 values: 616 - | 617 # 618 jnez.obj quit # 3-byte instruction 619 movi.64 v0, 0 ##*4000 620 - description: Max backward jump for imm16, 5 + 32760 + 3 = 32768 bytes 621 values: 622 - | 623 # 624 jmp lbl2 625 lbl1: 626 jmp quit # 5-byte instruction 627 movi.64 v0, 0 ##*3276 628 ldai 1 629 return 630 lbl2: 631 jnez.obj lbl1 632 - description: Beyond max backward jump for imm16, 5 + 40000 = 40005 bytes. Converted to jeqz.obj + jmp by compiler. 633 values: 634 - | 635 # 636 jmp lbl2 637 lbl1: 638 jmp quit # 5-byte instruction 639 movi.64 v0, 0 ##*4000 640 ldai 1 641 return 642 lbl2: 643 jnez.obj lbl1 644 - description: Chain of forward jumps 645 values: 646 - | 647 # 648 jnez.obj lbl1 649 ldai 2 650 return 651 lbl1: 652 jnez.obj lbl2 653 ldai 3 654 return 655 lbl2: 656 jnez.obj lbl3 657 ldai 4 658 return 659 lbl3: 660 jnez.obj lbl4 661 ldai 5 662 return 663 lbl4: 664 jnez.obj quit 665 tags: [tsan] 666 - description: Chain of backward jumps 667 values: 668 - | 669 # 670 jmp lbl1 671 lbl6: 672 jmp quit 673 lbl5: 674 jnez.obj lbl6 675 ldai 5 676 return 677 lbl4: 678 jnez.obj lbl5 679 ldai 4 680 return 681 lbl3: 682 jnez.obj lbl4 683 ldai 3 684 return 685 lbl2: 686 jnez.obj lbl3 687 ldai 2 688 return 689 lbl1: 690 jnez.obj lbl2 691