# 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: "jne.obj" isa: title: Conditional object comparison jump description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object references in accumulator and source register compare as specified. Offset is sign extended to the size of instruction address. exceptions: - x_none verification: - branch_target - acc_obj_or_null - v1_obj_or_null instructions: - sig: jne.obj v:in:ref, imm:i32 acc: in:ref format: [op_v_8_imm_8, op_v_8_imm_16] commands: - file-name: "invalid_v_reg" isa: verification: - v1_obj_or_null instructions: - sig: jne.obj v:in:ref, imm:i32 acc: in:ref format: [op_v_8_imm_8, op_v_8_imm_16] runner-options: [compile-failure] description: Check 'jne.obj' instruction with invalid 'v' register. header-template: [] code-template: | .function i32 main() { jne.obj %s lbl: check-type: exit-positive cases: - values: ["v256, lbl"] - values: ["v65535, lbl"] - values: ["v65536, lbl"] - values: ["a0, lbl"] - values: ["a256, lbl"] - values: ["a65535, lbl"] - values: ["lbl"] - values: [""] - values: ["}"] - values: ["# v1, lbl"] - values: ["V1, lbl"] - file-name: "invalid_a_reg" isa: verification: - v1_obj_or_null instructions: - sig: jne.obj v:in:ref, imm:i32 acc: in:ref format: [op_v_8_imm_8, op_v_8_imm_16] runner-options: [compile-failure] description: Check 'jne.obj' instruction with invalid 'a' register. header-template: [] code-template: | .record R {} .function void foo(R a0, R a1, R a2, R a3, R a4, R a5) { jne.obj %s lbl: return.void } .function i32 main() { call.range foo, v0 check-type: exit-positive cases: - values: ["v256, lbl"] - values: ["v65535, lbl"] - values: ["v65536, lbl"] - values: ["a6, lbl"] - values: ["a256, lbl"] - values: ["a65535, lbl"] - values: ["lbl"] - values: [""] - values: ["}"] - values: ["# v1, lbl"] - values: ["V1, lbl"] - file-name: "valid_v_reg" isa: verification: - v1_obj_or_null instructions: - sig: jne.obj v:in:ref, imm:i32 acc: in:ref format: [op_v_8_imm_8, op_v_8_imm_16] description: Check 'jne.obj' instruction with valid 'v' register. header-template: [] code-template: | .function i32 main() { mov.null %s lda.null jne.obj %s, lbl ldai 0 return lbl: ldai 1 check-type: no-check cases: - values: ["v0", "v0"] - values: ["v7", "v7"] - values: ["v8", "v8"] - values: ["v15", "v15"] - values: ["v16", "v16"] tags: [tsan] - values: ["v254", "v254"] - values: ["v255", "v255"] - file-name: "valid_a_reg" isa: verification: - v1_obj_or_null instructions: - sig: jne.obj v:in:ref, imm:i32 acc: in:ref format: [op_v_8_imm_8, op_v_8_imm_16] description: Check 'jne.obj' instruction with valid 'a' register. header-template: [] code-template: | .record R {} .function void R.ctor(R a0) { return.void } .function i32 foo(%s) { lda.obj a0 jne.obj %s, lbl ldai 0 return lbl: ldai 1 return } .function i32 main() { initobj R.ctor %s call.range foo, v0 check-type: no-check cases: - values: - R a0 - a0 - | # sta.obj v0 tags: [tsan] - values: - R a0, R a1 - a1 - | # sta.obj v0 sta.obj v1 - values: - "#{[*0..255].map do |i| \" R a#{i}\" end .join(\",\")}" - a254 - "#{[*0..255].map do |i| \" sta.obj v#{i}\\n\" end .join}" bugid: ['3855'] - values: - "#{[*0..255].map do |i| \" R a#{i}\" end .join(\",\")}" - a255 - "#{[*0..255].map do |i| \" sta.obj v#{i}\\n\" end .join}" bugid: ['3855'] - file-name: "uninitialized_regs" isa: verification: - acc_obj_or_null - v1_obj_or_null runner-options: ['verifier-failure', 'verifier-config'] tags: [verifier] description: Check 'jne.obj' instruction with uninitialized registers. header-template: [] code-template: | .function i32 main() { %s jne.obj v1, lbl ldai 1 return lbl: check-type: exit-positive cases: - description: Accumulator is not initialized. values: - mov.null v1 - description: V register is not initialized. values: - lda.null - description: Accumulator and 'v' register are both not initialized. values: - "" - file-name: "invalid_branch_target" isa: verification: - branch_target runner-options: [compile-failure] description: Check 'jne.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.obj a0 jne.obj a1, %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 'jne.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 sta.obj v0 initobj R.ctor jne.obj v0, %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 'jne.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" mov.null v0 jne.obj v0, %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 'jne.obj' instruction with invalid accumulator value header-template: [] code-template: | .record R {} .function void R.ctor(R a0) { return.void } .function i32 main() { %s *s jne.obj v1, ok ldai 1 return ok: check-type: exit-positive template-cases: - values: - | # initobj R.ctor sta.obj v1 - values: - mov.null v1 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: "invalid_v_value" isa: verification: - v1_obj_or_null runner-options: ['verifier-failure', 'verifier-config'] tags: [verifier] description: Check 'jne.obj' instruction with invalid v register value header-template: [] code-template: | .record R {} .function void R.ctor(R a0) { return.void } .function i32 main() { *s %s jne.obj v1, ok ldai 1 return ok: check-type: exit-positive template-cases: - values: - initobj R.ctor - values: - lda.null cases: - values: - movi v1, 0 - values: - movi v1, 1 - values: - movi v1, 0x7fffffff - values: - movi v1, 0xffffffff - values: - movi v1, 0x80000000 - values: - movi.64 v1, 0 - values: - movi.64 v1, 1 - values: - movi.64 v1, 0x7fffffffffffffff - values: - movi.64 v1, 0xffffffffffffffff - values: - movi.64 v1, 0x8000000000000000 - values: - | # fmovi v1, 0x00000000 # Positive zero (+0.0) - values: - | # fmovi v1, 0x80000000 # Negative zero (-0.0) - values: - | # fmovi v1, 0x00000001 # Minimal positive value (1.4012985e-45) - values: - | # fmovi v1, 0x80000001 # Maximal negative value (-1.4012985e-45) - values: - | # fmovi v1, 0x7f7fffff # Maximal positive value (3.4028235e38) - values: - | # fmovi v1, 0xff7fffff # Minimal negative value (-3.4028235e38) - values: - | # fmovi v1, 0x7f800000 # Positive infinity - values: - | # fmovi v1, 0xff800000 # Negative infinity - values: - | # fmovi v1, 0x7fc00000 # NaN - values: - | # fmovi.64 v1, 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`) - values: - | # fmovi.64 v1, 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`) - values: - | # fmovi.64 v1, 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`) - values: - | # fmovi.64 v1, 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`) - values: - | # fmovi.64 v1, 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`) - values: - | # fmovi.64 v1, 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`) - values: - | # fmovi.64 v1, 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`) - values: - | # fmovi.64 v1, 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`) - values: - | # fmovi.64 v1, 0x7ff8000000000000 # NaN - file-name: "invalid_both_acc_and_v_value" isa: verification: - v1_obj_or_null - acc_obj_or_null runner-options: ['verifier-failure', 'verifier-config'] tags: [verifier] description: Check 'jne.obj' instruction with invalid accumulator and v register value header-template: [] code-template: | .record R {} .function void R.ctor(R a0) { return.void } .function i32 main() { *s %s jne.obj v1, ok ldai 1 return ok: check-type: exit-positive template-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 cases: - values: - movi v1, 0 - values: - movi v1, 1 - values: - movi v1, 0x7fffffff - values: - movi v1, 0xffffffff - values: - movi v1, 0x80000000 - values: - movi.64 v1, 0 - values: - movi.64 v1, 1 - values: - movi.64 v1, 0x7fffffffffffffff - values: - movi.64 v1, 0xffffffffffffffff - values: - movi.64 v1, 0x8000000000000000 - values: - | # fmovi v1, 0x00000000 # Positive zero (+0.0) - values: - | # fmovi v1, 0x80000000 # Negative zero (-0.0) - values: - | # fmovi v1, 0x00000001 # Minimal positive value (1.4012985e-45) - values: - | # fmovi v1, 0x80000001 # Maximal negative value (-1.4012985e-45) - values: - | # fmovi v1, 0x7f7fffff # Maximal positive value (3.4028235e38) - values: - | # fmovi v1, 0xff7fffff # Minimal negative value (-3.4028235e38) - values: - | # fmovi v1, 0x7f800000 # Positive infinity - values: - | # fmovi v1, 0xff800000 # Negative infinity - values: - | # fmovi v1, 0x7fc00000 # NaN - values: - | # fmovi.64 v1, 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`) - values: - | # fmovi.64 v1, 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`) - values: - | # fmovi.64 v1, 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`) - values: - | # fmovi.64 v1, 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`) - values: - | # fmovi.64 v1, 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`) - values: - | # fmovi.64 v1, 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`) - values: - | # fmovi.64 v1, 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`) - values: - | # fmovi.64 v1, 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`) - values: - | # fmovi.64 v1, 0x7ff8000000000000 # NaN - file-name: "valid_equal_values_p" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object references in accumulator and source register compare as specified. Offset is sign extended to the size of instruction address. description: Check 'jne.obj' instruction with valid equal values in PandaAssembly context. header-template: [] 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 jne.obj v1, ng ldai 0 return ng: ldai 1 check-type: no-check cases: - values: - | # mov.null v1 lda.null - values: - | # initobj R.ctor sta.obj v1 tags: [tsan] - values: - | # lda.str "test" sta.obj v1 lda.str "test" - values: - | # lda.type R sta.obj v1 lda.type R - values: - | # movi v1, 10 newarr v1, v1, R[] lda.obj v1 - values: - | # movi v1, 10 newarr v1, v1, panda.String[] lda.obj v1 - values: - | # movi v1, 10 newarr v1, v1, panda.Class[] lda.obj v1 tags: [tsan] - values: - | # movi v1, 10 newarr v1, v1, panda.Object[][] lda.obj v1 - file-name: "valid_equal_values_j" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object references in accumulator and source register compare as specified. Offset is sign extended to the size of instruction address. description: Check 'jne.obj' instruction with valid equal values in PandaAssembly context. runner-options: [use-pa] header-template: [PandaAssembly] 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 jne.obj v1, ng ldai 0 return ng: ldai 1 check-type: no-check cases: - values: - | # mov.null v1 lda.null - values: - | # initobj R.ctor sta.obj v1 - values: - | # lda.str "test" sta.obj v1 lda.str "test" tags: [tsan] - values: - | # lda.type R sta.obj v1 lda.type R - values: - | # movi v1, 10 newarr v1, v1, R[] lda.obj v1 - values: - | # movi v1, 10 newarr v1, v1, panda.String[] lda.obj v1 - values: - | # movi v1, 10 newarr v1, v1, panda.Class[] lda.obj v1 - values: - | # movi v1, 10 newarr v1, v1, panda.Object[][] lda.obj v1 tags: [tsan] - file-name: "valid_not_equal_values_p" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object references in accumulator and source register compare as specified. Offset is sign extended to the size of instruction address. description: Check 'jne.obj' instruction with valid not equal values in PandaAssembly context. header-template: [] code-template: | .record panda.String .record panda.Class .record panda.Object .record R {} .function void R.ctor(R a0) { return.void } .function i32 main() { # set v1 register *s # set accumulator %s jne.obj v1, ng ldai 1 return ng: check-type: exit-positive template-cases: - values: - lda.null exclude: [nul] - values: - initobj R.ctor - values: - lda.str "test1" exclude: [str1] - values: - lda.str "test2" exclude: [str2] - values: - lda.type R exclude: [tr] - values: - lda.type panda.Object exclude: [to] - values: - | # movi v2, 10 newarr v2, v2, R[] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, R[][] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, panda.String[][][] lda.obj v2 cases: - values: - mov.null v1 id: nul - values: - | # initobj R.ctor sta.obj v1 - values: - | # lda.str "test1" sta.obj v1 id: str1 - values: - | # lda.str "test2" sta.obj v1 id: str2 - values: - | # lda.type R sta.obj v1 id: tr - values: - | # lda.type panda.Object sta.obj v1 id: to - values: - | # movi v2, 10 newarr v1, v2, R[] lda.obj v1 - values: - | # movi v2, 10 newarr v1, v2, R[][] lda.obj v1 - values: - | # movi v2, 10 newarr v1, v2, panda.String[][][] lda.obj v1 - file-name: "valid_not_equal_values_j" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object references in accumulator and source register compare as specified. Offset is sign extended to the size of instruction address. description: Check 'jne.obj' instruction with valid not equal values in PandaAssembly context. runner-options: [use-pa] header-template: [] 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() { # set v1 register *s # set accumulator %s jne.obj v1, ng ldai 1 return ng: check-type: exit-positive template-cases: - values: - lda.null exclude: [nul] - values: - initobj R.ctor - values: - lda.str "test1" exclude: [str1] - values: - lda.str "test2" exclude: [str2] - values: - lda.type R exclude: [tr] - values: - lda.type panda.Object exclude: [to] - values: - | # movi v2, 10 newarr v2, v2, R[] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, R[][] lda.obj v2 - values: - | # movi v2, 10 newarr v2, v2, panda.String[][][] lda.obj v2 cases: - values: - mov.null v1 id: nul - values: - | # initobj R.ctor sta.obj v1 - values: - | # lda.str "test1" sta.obj v1 id: str1 - values: - | # lda.str "test2" sta.obj v1 id: str2 - values: - | # lda.type R sta.obj v1 id: tr - values: - | # lda.type panda.Object sta.obj v1 id: to - values: - | # movi v2, 10 newarr v1, v2, R[] lda.obj v1 - values: - | # movi v2, 10 newarr v1, v2, R[][] lda.obj v1 - values: - | # movi v2, 10 newarr v1, v2, panda.String[][][] lda.obj v1 - file-name: "valid_offset_values" isa: description: > Transfer execution to an instruction at offset bytes from the beginning of the current instruction if object references in accumulator and source register compare as specified. Offset is sign extended to the size of instruction address. description: Check 'jne.obj' instruction with valid offset values. header-template: [] code-template: | .record R {} .function void R.ctor(R a0) { return.void } .function i32 main() { lda.str "test" mov.null v1 %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: jne.obj v1, lbl ldai 0 return - description: Max forward jump for imm8, 3 + 110 + 10 + 1 + 3 = 127 bytes values: - | # jne.obj v1, quit # 3-byte instruction movi.64 v0, 0 ##*11 ldai 1 # 2-byte instruction ldai 1 # 2-byte instruction ldai 1 # 2-byte instruction ldai 1 # 2-byte instruction ldai 1 # 2-byte instruction return # 1-byte instruction tags: [tsan] - description: Max backward jump for imm8, 3 + 120 + 2 + 2 + 1 = 128 bytes values: - | # jmp lbl2 lbl1: jmp quit # 3-byte instruction movi.64 v0, 0 ##*12 ldai 1 # 2-byte instruction ldai 1 # 2-byte instruction return # 1-byte instruction lbl2: jne.obj v1, lbl1 - description: Max forward jump for imm16, 32760 + 4 + 3 = 32767 bytes values: - | # jne.obj v1, quit # 4-byte instruction movi.64 v0, 0 ##*3276 - description: Beyond max forward jump for imm16, 40000 + 4 + 3 = 40007 bytes. Converted to jeq.obj + jmp by compiler. values: - | # jne.obj v1, quit # 4-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 lda.null ##*3 lbl2: jne.obj v1, lbl1 - description: Beyond max backward jump for imm16, 5 + 40000 = 40005 bytes. Converted to jeq.obj + jmp by compiler. values: - | # jmp lbl2 lbl1: jmp quit # 5-byte instruction movi.64 v0, 0 ##*4000 lbl2: jne.obj v1, lbl1 - description: Chain of forward jumps values: - | # jne.obj v1, lbl1 ldai 2 return lbl1: jne.obj v1, lbl2 ldai 3 return lbl2: jne.obj v1, lbl3 ldai 4 return lbl3: jne.obj v1, lbl4 ldai 5 return lbl4: jne.obj v1, quit tags: [tsan] - description: Chain of backward jumps values: - | # jmp lbl1 lbl6: jmp quit lbl5: jne.obj v1, lbl6 ldai 5 return lbl4: jne.obj v1, lbl5 ldai 4 return lbl3: jne.obj v1, lbl4 ldai 3 return lbl2: jne.obj v1, lbl3 ldai 2 return lbl1: jne.obj v1, lbl2 tags: [tsan]