# Copyright (c) 2021-2022 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. definitions: - name: PandaAssembly template: | .language PandaAssembly tests: - file-name: "jnez.obj" isa: title: Conditional compared to null jump description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object reference in accumulator compares with null as specified. Offset is sign extended to the size of instruction address. exceptions: - x_none instructions: - sig: jnez.obj imm:i32 acc: in:ref format: [op_imm_8, op_imm_16] commands: - file-name: "invalid_offset" isa: verification: - branch_target instructions: - sig: jnez.obj imm:i32 acc: in:ref format: [op_imm_8, op_imm_16] runner-options: [compile-failure] description: Check 'jnez.obj' instruction with invalid offset. header-template: [] code-template: | .function i32 main() { jnez.obj %s lbl: check-type: exit-positive cases: - values: [""] - values: ["main"] - values: ["v1"] - values: ["v1, lbl"] - values: ["}"] - values: ["# lbl"] - values: ["Lbl"] - values: ["LBL"] - file-name: "uninitialized_acc" isa: verification: - acc_obj_or_null runner-options: ['verifier-failure', 'verifier-config'] tags: [verifier] description: Check 'jnez.obj' instruction with uninitialized accumulator. header-template: [] code-template: | .function i32 main() { jnez.obj lbl ldai 1 return lbl: check-type: exit-positive - file-name: "invalid_branch_target" isa: verification: - branch_target runner-options: [compile-failure] description: Check 'jnez.obj' instruction with invalid branch target. header-template: [] code-template: | .record R {} .function void R.ctor(R a0) { lbl_ctor: return.void } .function void R.cctor() { lbl_cctor: return.void } .function i32 foo() { lda.null jnez.obj %s } .function i32 bar() { lbl_bar: ldai 1 return } .function i32 main() { call.short foo lbl_main: check-type: exit-positive cases: - values: ["main"] - values: ["foo"] - values: ["bar"] - values: ["baz"] - values: ["R"] - values: ["lbl_main"] - values: ["lbl_bar"] - values: ["lbl_ctor"] - values: ["lbl_cctor"] - file-name: "prohibited_branch_target_p" isa: verification: - branch_target runner-options: ['verifier-failure', 'verifier-config'] tags: [verifier] description: Check 'jnez.obj' instruction with prohibited branch target in PandaAssembly context. header-template: [] code-template: | .record E1 {} .record E2 {} .record R {} .function void R.ctor(R a0) { return.void } .function i32 main() { initobj R.ctor jnez.obj %s begin: ldai 0 return mid: ldai 1 return end: ldai 2 return catch_E1_begin: ldai 3 return catch_E1_mid: ldai 4 return catch_E1_end: ldai 5 return catch_E2_begin: ldai 6 return catch_E2_mid: ldai 7 return catch_E2_end: quit: ldai 8 return .catch E1, begin, end, catch_E1_begin, catch_E1_end .catch E2, catch_E1_begin, catch_E1_end, catch_E2_begin, catch_E2_end outside: check-type: none cases: - values: ["begin"] runner-options: ['verifier-only', 'verifier-config'] - values: ["mid"] runner-options: ['verifier-only', 'verifier-config'] - values: ["end"] runner-options: ['verifier-only', 'verifier-config'] - values: ["quit"] runner-options: ['verifier-only', 'verifier-config'] - values: ["catch_E1_begin"] - values: ["catch_E1_mid"] - values: ["catch_E1_end"] runner-options: ['verifier-only', 'verifier-config'] - values: ["catch_E2_begin"] - values: ["catch_E2_mid"] - values: ["catch_E2_end"] runner-options: ['verifier-only', 'verifier-config'] - values: ["outside"] - file-name: "prohibited_branch_target_j" isa: verification: - branch_target runner-options: [verifier-failure, use-pa, verifier-config] tags: [verifier, pa-verifier] description: Check 'jnez.obj' instruction with prohibited branch target in PandaAssembly context. header-template: [PandaAssembly] code-template: | .record panda.NullPointerException .record panda.Exception .function i32 main() { lda.str "test" jnez.obj %s begin: ldai 0 return mid: ldai 1 return end: ldai 2 return catch_NPE_begin: ldai 3 return catch_NPE_mid: ldai 4 return catch_NPE_end: ldai 5 return catch_E_begin: ldai 6 return catch_E_mid: ldai 7 return catch_E_end: quit: ldai 8 return .catch panda.NullPointerException, begin, end, catch_NPE_begin, catch_NPE_end .catch panda.Exception, catch_NPE_begin, catch_NPE_end, catch_E_begin, catch_E_end outside: check-type: none cases: - values: ["begin"] runner-options: [verifier-only, use-pa, verifier-config] - values: ["mid"] runner-options: [verifier-only, use-pa, verifier-config] - values: ["end"] runner-options: [verifier-only, use-pa, verifier-config] - values: ["quit"] runner-options: [verifier-only, use-pa, verifier-config] - values: ["catch_NPE_begin"] - values: ["catch_NPE_mid"] - values: ["catch_NPE_end"] runner-options: [verifier-only, use-pa, verifier-config] - values: ["catch_E_begin"] - values: ["catch_E_mid"] - values: ["catch_E_end"] runner-options: [verifier-only, use-pa, verifier-config] - values: ["outside"] - file-name: "invalid_acc_value" isa: verification: - acc_obj_or_null runner-options: ['verifier-failure', 'verifier-config'] tags: [verifier] description: Check 'jnez.obj' instruction with invalid accumulator value header-template: [] code-template: | .function i32 main() { %s jnez.obj ok ldai 1 return ok: check-type: exit-positive cases: - values: - ldai 0 - values: - ldai 1 - values: - ldai 0x7fffffff - values: - ldai 0xffffffff - values: - ldai 0x80000000 - values: - ldai.64 0 - values: - ldai.64 1 - values: - ldai.64 0x7fffffffffffffff - values: - ldai.64 0xffffffffffffffff - values: - ldai.64 0x8000000000000000 - values: - | # fldai 0x00000000 # Positive zero (+0.0) - values: - | # fldai 0x80000000 # Negative zero (-0.0) - values: - | # fldai 0x00000001 # Minimal positive value (1.4012985e-45) - values: - | # fldai 0x80000001 # Maximal negative value (-1.4012985e-45) - values: - | # fldai 0x7f7fffff # Maximal positive value (3.4028235e38) - values: - | # fldai 0xff7fffff # Minimal negative value (-3.4028235e38) - values: - | # fldai 0x7f800000 # Positive infinity - values: - | # fldai 0xff800000 # Negative infinity - values: - | # fldai 0x7fc00000 # NaN - values: - | # fldai.64 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`) - values: - | # fldai.64 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`) - values: - | # fldai.64 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`) - values: - | # fldai.64 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`) - values: - | # fldai.64 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`) - values: - | # fldai.64 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`) - values: - | # fldai.64 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`) - values: - | # fldai.64 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`) - values: - | # fldai.64 0x7ff8000000000000 # NaN - file-name: "valid_null_value_p" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object reference in accumulator compares with null as specified. Offset is sign extended to the size of instruction address. description: Check 'jnez.obj' instruction with valid null value in PandaAssembly context. header-template: [] tags: [tsan] code-template: | .function i32 main() { lda.null jnez.obj ng ldai 0 return ng: ldai 1 check-type: no-check - file-name: "valid_null_value_j" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object reference in accumulator compares with null as specified. Offset is sign extended to the size of instruction address. description: Check 'jnez.obj' instruction with valid null value in PandaAssembly context. runner-options: [use-pa] tags: ['tsan'] header-template: [PandaAssembly] code-template: | .function i32 main() { lda.null jnez.obj ng ldai 0 return ng: ldai 1 check-type: no-check - file-name: "valid_not_null_values_p" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object reference in accumulator compares with null as specified. Offset is sign extended to the size of instruction address. description: Check 'jnez.obj' instruction with valid not null values in PandaAssembly context. header-template: [] tags: [tsan] code-template: | .record panda.String .record panda.Class .record panda.Object .record R {} .function void R.ctor(R a0) { return.void } .function i32 main() { %s jnez.obj ng ldai 1 return ng: check-type: exit-positive cases: - values: - initobj R.ctor - values: - lda.str "test1" - values: - lda.type R - values: - lda.type panda.Object - values: - | # movi v2, 10 newarr v2, v2, u32[] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, u64[][] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, R[] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, panda.Class[][] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, panda.String[][][] lda.obj v2 - file-name: "valid_not_null_values_j" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object reference in accumulator compares with null as specified. Offset is sign extended to the size of instruction address. description: Check 'jnez.obj' instruction with valid not null values in PandaAssembly context. runner-options: [use-pa] header-template: [] tags: ['tsan'] code-template: | .language PandaAssembly .record panda.String .record panda.Class .record panda.Object .record R {} .function void R.ctor(R a0) { return.void } .function i32 main() { %s jnez.obj ng ldai 1 return ng: check-type: exit-positive cases: - values: - initobj R.ctor - values: - lda.str "test1" - values: - lda.type R - values: - lda.type panda.Object - values: - | # movi v2, 10 newarr v2, v2, i32[] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, f64[][] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, R[] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, panda.Class[][] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, panda.String[][][] lda.obj v2 - file-name: "valid_offset_values" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object reference in accumulator compares with null as specified. Offset is sign extended to the size of instruction address. description: Check 'jnez.obj' instruction with valid offset values. header-template: [] code-template: | .function i32 main() { lda.str "test" %s ldai 1 # 2-byte instruction return # 1-byte instruction quit: check-type: exit-positive cases: - description: Same instruction jump, offset imm8, 0 bytes values: - | # lda.null lbl: jnez.obj lbl ldai 0 return - description: Max forward jump for imm8, 2 + 120 + 2 + 3 = 127 bytes values: - | # jnez.obj quit # 2-byte instruction movi.64 v0, 0 ##*12 lda.null lda.null tags: [tsan] - description: Max backward jump for imm8, 3 + 120 + 5 = 128 bytes values: - | # jmp lbl2 lbl1: jmp quit # 3-byte instruction movi.64 v0, 0 ##*12 ldai 1 ldai 1 return lbl2: jnez.obj lbl1 - description: Max forward jump for imm16, 3 + 32760 + 1 + 3 = 32767 bytes values: - | # jnez.obj quit # 3-byte instruction movi.64 v0, 0 ##*3276 lda.null - description: Beyond max forward jump for imm16, 3 + 40000 + 3 = 40006 bytes. Converted to jeqz.obj + jmp by compiler. values: - | # jnez.obj quit # 3-byte instruction movi.64 v0, 0 ##*4000 - description: Max backward jump for imm16, 5 + 32760 + 3 = 32768 bytes values: - | # jmp lbl2 lbl1: jmp quit # 5-byte instruction movi.64 v0, 0 ##*3276 ldai 1 return lbl2: jnez.obj lbl1 - description: Beyond max backward jump for imm16, 5 + 40000 = 40005 bytes. Converted to jeqz.obj + jmp by compiler. values: - | # jmp lbl2 lbl1: jmp quit # 5-byte instruction movi.64 v0, 0 ##*4000 ldai 1 return lbl2: jnez.obj lbl1 - description: Chain of forward jumps values: - | # jnez.obj lbl1 ldai 2 return lbl1: jnez.obj lbl2 ldai 3 return lbl2: jnez.obj lbl3 ldai 4 return lbl3: jnez.obj lbl4 ldai 5 return lbl4: jnez.obj quit tags: [tsan] - description: Chain of backward jumps values: - | # jmp lbl1 lbl6: jmp quit lbl5: jnez.obj lbl6 ldai 5 return lbl4: jnez.obj lbl5 ldai 4 return lbl3: jnez.obj lbl4 ldai 3 return lbl2: jnez.obj lbl3 ldai 2 return lbl1: jnez.obj lbl2