# 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: call.virt.acc isa: title: Object calls with accumulator as input description: > Call indicated object method, i.e. create new frame, pass values of arguments and continue execution from the first instruction of a method. Callee should treat accumulator value as undefined and cannot use it until accumulator definition in the new frame. Result (if any) is returned in accumulator (see 'Calling sequence' chapter for more details). Method, its class and the number of argument is resolved by given method_id in runtime constant-pool based on object reference using language-specific semantics (currently only PandaAssembly virtual methods are supported, further extensions are TBD). Object reference is passed in the first source register, arguments are passed starting from the second source register in the same order as in method signature. Non-range instructions can be used to pass up to 4 arguments (including object reference). Unused register slot values will be discarded and corresponding registers will not be passed to the callee). Immediate operand encodes a position starting from 0 on which accumulator is passed. instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] commands: - file-name: op_v1_4_v2_4_v3_4_imm_4_id_16 description: Check that compiler reports an error on invalid instruction format. isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] header-template: [] check-type: exit-positive runner-options: [compile-failure] code-template: | .record R {} .function void R.f1(R a0) { return.void } .function void R.f2(R a0, i32 a1) { return.void } .function void R.f3(R a0, i32 a1, i32 a2) { return.void } .function void R.f4(R a0, i32 a1, i32 a2, i32 a3) { return.void } .function void R.f5(R a0, i32 a1, i32 a2, i32 a3, i32 a4) { return.void } .function void R.sf1(i32 a0) { return.void } .function void R.sf2(i32 a0, i32 a1) { return.void } .function void R.sf3(i32 a0, i32 a1, i32 a2) { return.void } .function void R.sf4(i32 a0, i32 a1, i32 a2, i32 a3) { return.void } .function void R.sf5(i32 a0, i32 a1, i32 a2, i32 a3, i32 a4) { return.void } .function void sf1(i32 a0) { return.void } .function void sf2(i32 a0, i32 a1) { return.void } .function void sf3(i32 a0, i32 a1, i32 a2) { return.void } .function void sf4(i32 a0, i32 a1, i32 a2, i32 a3) { return.void } .function void sf5(i32 a0, i32 a1, i32 a2, i32 a3, i32 a4) { return.void } .function i32 main() { newobj v0, R movi v1, 1 movi v2, 2 movi v3, 3 movi v4, 4 ldai 0 call.virt.acc %s cases: - values: ['R.f1, v0, 1'] - values: ['R.f1, v0, v1, 2'] - values: ['R.f1, v0, v1, v2, 3'] runner-options: [compile-only] - values: ['R.f2, v0, 1'] - values: ['R.f2, v0, v1, 2'] - values: ['R.f2, v0, v1, v2, 3'] runner-options: [compile-only] - values: ['R.f3, v0, 1'] - values: ['R.f3, v0, v1, 2'] - values: ['R.f3, v0, v1, v2, 3'] runner-options: [compile-only] - values: ['R.f4, v0, 1'] - values: ['R.f4, v0, v1, 2'] - values: ['R.f4, v0, v1, v2, 3'] runner-options: [compile-only] - values: ['R.f5, v0, 1'] - values: ['R.f5, v0, v1, 2'] - values: ['R.f5, v0, v1, v2, 3'] bugid: ['5601'] ignore: true - values: ['R.sf1, v1, 1'] - values: ['R.sf1, v2, v1, 2'] - values: ['R.sf1, v3, v2, v1, 3'] runner-options: [verifier-failure, verifier-config] tags: [verifier] - values: ['R.sf2, v1, 1'] - values: ['R.sf2, v2, v1, 2'] - values: ['R.sf2, v3, v2, v1, 3'] runner-options: [verifier-failure, verifier-config] tags: [verifier] - values: ['R.sf3, v1, 1'] - values: ['R.sf3, v2, v1, 2'] - values: ['R.sf3, v3, v2, v1, 3'] runner-options: [verifier-failure, verifier-config] tags: [verifier] - values: ['R.sf4, v1, 1'] - values: ['R.sf4, v2, v1, 2'] - values: ['R.sf4, v3, v2, v1, 3'] runner-options: [verifier-failure, verifier-config] tags: [verifier] - values: ['R.sf5, v1, 1'] - values: ['R.sf5, v2, v1, 2'] - values: ['R.sf5, v3, v2, v1, 3'] bugid: ['5601'] ignore: true - values: ['sf1, v1, 1'] - values: ['sf1, v2, v1, 2'] - values: ['sf1, v3, v2, v1, 3'] runner-options: [verifier-failure, verifier-config] tags: [verifier] - values: ['sf2, v1, 1'] - values: ['sf2, v2, v1, 2'] - values: ['sf2, v3, v2, v1, 3'] runner-options: [verifier-failure, verifier-config] tags: [verifier] - values: ['sf3, v1, 1'] - values: ['sf3, v2, v1, 2'] - values: ['sf3, v3, v2, v1, 3'] runner-options: [verifier-failure, verifier-config] tags: [verifier] - values: ['sf4, v1, 1'] - values: ['sf4, v2, v1, 2'] - values: ['sf4, v3, v2, v1, 3'] runner-options: [verifier-failure, verifier-config] tags: [verifier] - values: ['sf5, v1, 1'] - values: ['sf5, v2, v1, 2'] - values: ['sf5, v3, v2, v1, 3'] bugid: ['5601'] ignore: true - file-name: reg_v_valid description: Check with all valid 'v' register numbers. isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] runner-options: [verifier-only, verifier-config] tags: [verifier] header-template: [] check-type: exit-positive code-template: | .record R {} .function R R.foo(R a0, i32 a1, i32 a2, i32 a3) { lda.obj a0 return.obj } .function i32 main() { newobj v0, R lda.obj v0 movi v0, 0 movi v1, 1 movi v2, 2 movi v3, 3 movi v4, 4 movi v5, 5 movi v6, 6 movi v7, 7 movi v8, 8 movi v9, 9 movi v10, 10 movi v11, 11 movi v12, 12 movi v13, 13 movi v14, 14 movi v15, 15 call.virt.acc R.foo, v0, v1, v2, 0 call.virt.acc R.foo, v3, v4, v5, 0 call.virt.acc R.foo, v6, v7, v8, 0 call.virt.acc R.foo, v9, v10, v11, 0 call.virt.acc R.foo, v12, v13, v14, 0 call.virt.acc R.foo, v15, v15, v15, 0 - file-name: reg_a_valid description: Check with all valid 'a' register numbers. isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] runner-options: [verifier-only, verifier-config] tags: [verifier] header-template: [] check-type: exit-positive code-template: | .record R {} .function R R.foo(R a0, i32 a1, i32 a2, i32 a3) { lda.obj a0 return.obj } .function void f(i32 a0, i32 a1, i32 a2, i32 a3, i32 a4, i32 a5, i32 a6, i32 a7, i32 a8, i32 a9, i32 a10, i32 a11, i32 a12, i32 a13, i32 a14, R a15) { lda.obj a15 call.virt.acc R.foo, a0, a1, a2, 0 call.virt.acc R.foo, a3, a4, a5, 0 call.virt.acc R.foo, a6, a7, a8, 0 call.virt.acc R.foo, a9, a10, a11, 0 call.virt.acc R.foo, a12, a13, a14, 0 return.void } .function i32 main() { movi v0, 0 movi v1, 1 movi v2, 2 movi v3, 3 movi v4, 4 movi v5, 5 movi v6, 6 movi v7, 7 movi v8, 8 movi v9, 9 movi v10, 10 movi v11, 11 movi v12, 12 movi v13, 13 movi v14, 14 newobj v15, R call.range f, v0 - file-name: uninitialized_regs description: Check that verifier reports an error on uninitialized registers. isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] header-template: [] runner-options: [verifier-failure, verifier-config] tags: [verifier] check-type: exit-positive code-template: | .record R {} .function i32 R.foo(%s) { %s return } .function i32 main() { %s call.virt.acc R.foo, %s cases: - description: Register v0 is not initialized. values: - R a0, i32 a1, i32 a2, i32 a3 - lda a1 - | # movi v1, 0 movi v2, 0 newobj v7, R lda.obj v7 - v0, v1, v2, 0 - description: Register v1 is not initialized. values: - R a0, i32 a1, i32 a2, i32 a3 - lda a2 - | # movi v0, 0 movi v2, 0 newobj v7, R lda.obj v7 - v0, v1, v2, 0 - description: Register v2 is not initialized. values: - R a0, i32 a1, i32 a2, i32 a3 - lda a3 - | # movi v0, 0 movi v1, 0 newobj v7, R lda.obj v7 - v0, v1, v2, 0 - description: Registers v1, v2 are not initialized, but they arent used. values: - R a0, i32 a1 - lda a1 - | # movi v0, 0 newobj v7, R lda.obj v7 - v0, v1, v2, 0 runner-options: [verifier-only, verifier-config] - description: Accumulator (i32) is not initialized. values: - R a0, i32 a1 - lda a1 - | # newobj v0, R movi v1, 0 movi v2, 0 - v0, v1, v2, 1 - description: Accumulator (obj ref) is not initialized. values: - R a0, i32 a1, i32 a2 - lda a1 - | # movi v0, 0 movi v1, 0 movi v2, 0 - v0, v1, v2, 0 - description: Accumulator (i32) is not initialized, but its not used. values: - R a0 - ldai 0 - | # newobj v0, R movi v1, 0 movi v2, 0 - v0, v1, v2, 1 runner-options: [verifier-only, verifier-config] - description: Accumulator (i32) is not initialized, but its not used. values: - R a0, i32 a1, i32 a2 - lda a1 - | # newobj v0, R movi v1, 0 movi v2, 0 - v0, v1, v2, 3 runner-options: [verifier-only, verifier-config] - description: Accumulator and all regs are not initialized. values: - R a0, i32 a1, i32 a2, i32 a3 - ldai 0 - '' - v15, v14, v13, 0 - description: Regs not initialized, but they are not used. values: - 'R a0' - ldai 0 - | # newobj v15, R lda.obj v15 - v0, v1, v2, 0 runner-options: [verifier-only, verifier-config] - description: Accumulator is not initialized in function. values: - R a0, i32 a1, i32 a2, i32 a3 - call.virt.acc R.foo, a1, a2, a3, 0 - | # newobj v7, R lda.obj v7 movi v0, 0 movi v1, 0 movi v2, 0 - v0, v1, v2, 0 - file-name: static_method description: Check that verifier reports an error on a static method. isa: verification: - method_id_non_static header-template: [] runner-options: [verifier-failure, verifier-config] tags: [verifier] check-type: exit-positive code-template: | .record R {} .function void %s { return.void } .function i32 main() { newobj v0, R movi v1, 0 movi v2, 0 ldai 0 call.virt.acc %s cases: - values: - R.foo(R a0, i32 a1, i32 a2, i32 a3) - R.foo, v0, v1, v2, 3 - values: - R.foo(R a0) - R.foo, v0, v1, v2, 2 - values: - R.foo(i32 a0, R a1) - R.foo, v0, v1, v2, 0 - values: - R.foo(R a0, i32 a1) - R.foo, v0, v1, v2, 3 bugid: ['5583'] ignore: true - values: - R.foo(R a0) - R.foo, v0, v1, v2, 1 bugid: ['5583'] ignore: true - values: - foo(R a0, i32 a1) - foo, v0, v1, v2, 3 - file-name: non_accessible_method_p description: Check that verifier reports an error on non-accessible method. isa: verification: - method_id_accessible header-template: [] runner-options: [verifier-failure, verifier-config] tags: [verifier] check-type: exit-positive code-template: | .record R {} .function void %s .function i32 main() { newobj v0, R ldai 0 movi v1, 1 movi v2, 2 call.virt.acc R.foo, v0, v1, v2, 1 cases: - values: - R.foo(R a0, i32 a1, i32 a2, i32 a3) - values: - R.foo(R a0, i32 a1, i32 a2) - file-name: non_accessible_method_j description: Check that verifier reports an error on non-accessible method. isa: verification: - method_id_accessible header-template: [PandaAssembly] runner-options: [verifier-failure, verifier-config, use-pa] tags: [verifier, pa-verifier] bugid: ["6886"] check-type: exit-positive code-template: | %s .function i32 main() { newobj v0, %s ldai 0 movi v1, 1 movi v2, 2 call.virt.acc %s.foo, v0, v1, v2, 1 cases: - values: - | .record R {} .function void R.foo(R a0, i32 a1, i32 a2, i32 a3) - R - R - values: - | .record R {} .function void R.foo(R a0, i32 a1, i32 a2, i32 a3) .record Q {} .function void Q.foo(R a0, i32 a1, i32 a2, i32 a3) { return.void } - Q - R - values: - | .record R {} .function void R.foo(R a0, i32 a1, i32 a2, i32 a3) .record Q {} .function void Q.foo(Q a0, i32 a1, i32 a2, i32 a3) { return.void } - Q - Q runner-options: [verifier-only, verifier-config, use-pa] - file-name: invalid_method description: Check that verifier reports an error on invalid method. isa: verification: - method_id_non_static - method_id_accessible header-template: [] runner-options: [verifier-failure, verifier-config] tags: [verifier] check-type: exit-positive code-template: | .record R {} %s .function i32 main() { newobj v0, R lda.obj v0 call.virt.acc %s cases: - description: No return in function. values: - .function void R.foo(R a0, R a1, R a2, R a3) {} - R.foo, v0, v0, v0, 1 bugid: ['5607'] ignore: true - description: No return in function. values: - | # .function i32 R.foo(R a0, R a1, R a2, R a3) { ldai 0 } - R.foo, v0, v0, v0, 0 - file-name: incompatible_v_p description: Check 'call.virt.acc' instruction called with incompatible register arguments in PandaAssembly context. isa: verification: - compatible_arguments runner-options: [verifier-failure, verifier-config] tags: [verifier] header-template: [] check-type: exit-positive code-template: | .record panda.Object .record panda.Class .record panda.String .record R {} .function void R.foo(R a0, i32 a1, i32 a2, %s a3) { return.void } .function i32 main() { *s movi v2, 2 movi v3, 3 newobj v0, R lda.obj v0 call.virt.acc R.foo, v3, v2, v1, 0 template-cases: - values: - u1 exclude: [i32] - values: - u8 exclude: [i32] - values: - i8 exclude: [i32] - values: - u16 exclude: [i32] - values: - i16 exclude: [i32] - values: - u32 exclude: [i32] - values: - u64 exclude: [i64] - values: - f32 exclude: [f32] bugid: ['7445'] - values: - f64 exclude: [f64] - values: - u32[] exclude: [u32a, nul] - values: - u64[] exclude: [u64a, nul] - values: - f32[] exclude: [f32a, nul] - values: - u32[][] exclude: [u32aa, nul] - values: - u64[][] exclude: [u64aa, nul] - values: - f32[][] exclude: [f32aa, nul] - values: - R exclude: [nul] - values: - panda.String exclude: [str, nul] - values: - panda.Class exclude: [typ, nul] - values: - panda.Object exclude: [u32a, u64a, f32a, u32aa, u64aa, f32aa, str, typ, ra, stra, typa, obja, raa, straa, typaa, objaa, nul] - values: - R[] exclude: [ra, nul] - values: - panda.String[] exclude: [stra, nul] - values: - panda.Class[] exclude: [typa, nul] - values: - panda.Object[] exclude: [obja, u32aa, u64aa, f32aa, ra, stra, typa, raa, straa, typaa, objaa, nul] - values: - R[][] exclude: [raa, nul] - values: - panda.String[][] exclude: [straa, nul] - values: - panda.Class[][] exclude: [typaa, nul] - values: - panda.Object[][] exclude: [objaa, raa, straa, typaa, nul] cases: - values: - movi v1, 1 id: i32 - values: - movi.64 v1, 1 id: i64 - values: - fmovi v1, 1.0 id: f32 bugid: ['7445'] - values: - fmovi.64 v1, 1.0 id: f64 - values: - | # movi v1, 10 newarr v1, v1, u32[] id: u32a - values: - | # movi v1, 10 newarr v1, v1, u64[] id: u64a - values: - | # movi v1, 10 newarr v1, v1, f32[] id: f32a - values: - | # movi v1, 10 newarr v1, v1, u32[][] id: u32aa - values: - | # movi v1, 10 newarr v1, v1, u64[][] id: u64aa - values: - | # movi v1, 10 newarr v1, v1, f32[][] id: f32aa - values: - | # lda.str "test message" sta.obj v1 id: str - values: - | # lda.type R sta.obj v1 id: typ - values: - | # movi v1, 10 newarr v1, v1, R[] id: ra - values: - | # movi v1, 10 newarr v1, v1, panda.String[] id: stra - values: - | # movi v1, 10 newarr v1, v1, panda.Class[] id: typa - values: - | # movi v1, 10 newarr v1, v1, panda.Object[] id: obja - values: - | # movi v1, 10 newarr v1, v1, R[][] id: raa - values: - | # movi v1, 10 newarr v1, v1, panda.String[][] id: straa - values: - | # movi v1, 10 newarr v1, v1, panda.Class[][] id: typaa - values: - | # movi v1, 10 newarr v1, v1, panda.Object[][] id: objaa - values: - mov.null v1 id: nul - file-name: incompatible_acc_p description: Check 'call.virt.acc' instruction called with incompatible accumulator argument in PandaAssembly context. isa: verification: - compatible_arguments runner-options: [verifier-failure, verifier-config] tags: [verifier] header-template: [] check-type: exit-positive code-template: | .record panda.Object .record panda.Class .record panda.String .record R {} .function void R.foo(R a0, i32 a1, %s a2, i32 a3) { return.void } .function i32 main() { *s newobj v2, R movi v1, 0 call.virt.acc R.foo, v2, v1, v1, 2 template-cases: - values: - u1 exclude: [i32] - values: - u8 exclude: [i32] - values: - i8 exclude: [i32] - values: - u16 exclude: [i32] - values: - i16 exclude: [i32] - values: - u32 exclude: [i32] - values: - u64 exclude: [i64] - values: - f32 exclude: [f32] bugid: ['7445'] - values: - f64 exclude: [f64] - values: - u32[] exclude: [u32a, nul] - values: - u64[] exclude: [u64a, nul] - values: - f32[] exclude: [f32a, nul] - values: - u32[][] exclude: [u32aa, nul] - values: - u64[][] exclude: [u64aa, nul] - values: - f32[][] exclude: [f32aa, nul] - values: - R exclude: [nul] - values: - panda.String exclude: [str, nul] - values: - panda.Class exclude: [typ, nul] - values: - panda.Object exclude: [u32a, u64a, f32a, u32aa, u64aa, f32aa, str, typ, ra, stra, typa, obja, raa, straa, typaa, objaa, nul] - values: - R[] exclude: [ra, nul] - values: - panda.String[] exclude: [stra, nul] - values: - panda.Class[] exclude: [typa, nul] - values: - panda.Object[] exclude: [obja, u32aa, u64aa, f32aa, ra, stra, typa, raa, straa, typaa, objaa, nul] - values: - R[][] exclude: [raa, nul] - values: - panda.String[][] exclude: [straa, nul] - values: - panda.Class[][] exclude: [typaa, nul] - values: - panda.Object[][] exclude: [objaa, raa, straa, typaa, nul] cases: - values: - ldai 1 id: i32 - values: - ldai.64 1 id: i64 - values: - fldai 1.0 id: f32 bugid: ['7445'] - values: - fldai.64 1.0 id: f64 - values: - | # movi v1, 10 newarr v1, v1, u32[] lda.obj v1 id: u32a - values: - | # movi v1, 10 newarr v1, v1, u64[] lda.obj v1 id: u64a - values: - | # movi v1, 10 newarr v1, v1, f32[] lda.obj v1 id: f32a - values: - | # movi v1, 10 newarr v1, v1, u32[][] lda.obj v1 id: u32aa - values: - | # movi v1, 10 newarr v1, v1, u64[][] lda.obj v1 id: u64aa - values: - | # movi v1, 10 newarr v1, v1, f32[][] lda.obj v1 id: f32aa - values: - | # lda.str "test message" id: str - values: - | # lda.type R id: typ - values: - | # movi v1, 10 newarr v1, v1, R[] lda.obj v1 id: ra - values: - | # movi v1, 10 newarr v1, v1, panda.String[] lda.obj v1 id: stra - values: - | # movi v1, 10 newarr v1, v1, panda.Class[] lda.obj v1 id: typa - values: - | # movi v1, 10 newarr v1, v1, panda.Object[] lda.obj v1 id: obja - values: - | # movi v1, 10 newarr v1, v1, R[][] lda.obj v1 id: raa - values: - | # movi v1, 10 newarr v1, v1, panda.String[][] lda.obj v1 id: straa - values: - | # movi v1, 10 newarr v1, v1, panda.Class[][] lda.obj v1 id: typaa - values: - | # movi v1, 10 newarr v1, v1, panda.Object[][] lda.obj v1 id: objaa - values: - lda.null id: nul - file-name: incompatible_v_j isa: verification: - compatible_arguments runner-options: [verifier-failure, use-pa, verifier-config] tags: [verifier, pa-verifier] bugid: ["6886"] description: Check 'call.virt.acc' instruction with incompatible register in PandaAssembly context. header-template: [PandaAssembly] code-template: | .record panda.Object .record panda.Class .record R {} .function void R.foo(R a0, %s a1, i32 a2, R a3) { return.void } .function i32 main() { *s ldai 0 newobj v2, R newobj v3, R call.virt.acc R.foo, v3, v1, v2, 2 check-type: exit-positive template-cases: - values: - u1 exclude: [i32] - values: - i8 exclude: [i32] - values: - u16 exclude: [i32] - values: - i16 exclude: [i32] - values: - i32 exclude: [i32] - values: - i64 exclude: [i64] - values: - f32 exclude: [f32] bugid: ['7445'] - values: - f64 exclude: [f64] - values: - u1[] exclude: [u1a, nul] - values: - i8[] exclude: [i8a, nul] - values: - u16[] exclude: [u1a, u16a, nul] - values: - i16[] exclude: [i8a, i16a, nul] - values: - i32[] exclude: [i8a, i16a, i32a, nul] - values: - i64[] exclude: [i64a, nul] - values: - f32[] exclude: [f32a, nul] - values: - f64[] exclude: [f32a, f64a, nul] - values: - i32[][] exclude: [i32aa, nul] - values: - f64[][] exclude: [f64aa, nul] - values: - R exclude: [nul] - values: - panda.Class exclude: [typ, nul] - values: - panda.Object exclude: [u1a, i8a, u16a, i16a, i32a, i64a, f32a, f64a, i32aa, f64aa, typ, ra, typa, obja, raa, typaa, objaa, nul] - values: - R[] exclude: [ra, nul] - values: - panda.Class[] exclude: [typa, nul] - values: - panda.Object[] exclude: [obja, i32aa, f64aa, ra, typa, raa, typaa, objaa, nul] - values: - R[][] exclude: [raa, nul] - values: - panda.Class[][] exclude: [typaa, nul] - values: - panda.Object[][] exclude: [objaa, raa, typaa, nul] cases: - values: - movi v1, 1 id: i32 - values: - movi.64 v1, 1 id: i64 - values: - fmovi v1, 1.0 id: f32 bugid: ['7445'] - values: - fmovi.64 v1, 1.0 id: f64 - values: - | # movi v1, 10 newarr v1, v1, u1[] id: u1a - values: - | # movi v1, 10 newarr v1, v1, i8[] id: i8a - values: - | # movi v1, 10 newarr v1, v1, u16[] id: u16a - values: - | # movi v1, 10 newarr v1, v1, i16[] id: i16a - values: - | # movi v1, 10 newarr v1, v1, i32[] id: i32a - values: - | # movi v1, 10 newarr v1, v1, i64[] id: i64a - values: - | # movi v1, 10 newarr v1, v1, f32[] id: f32a - values: - | # movi v1, 10 newarr v1, v1, f64[] id: f64a - values: - | # movi v1, 10 newarr v1, v1, i32[][] id: i32aa - values: - | # movi v1, 10 newarr v1, v1, f64[][] id: f64aa - values: - | # lda.type R sta.obj v1 id: typ - values: - | # movi v1, 10 newarr v1, v1, R[] id: ra - values: - | # movi v1, 10 newarr v1, v1, panda.Class[] id: typa - values: - | # movi v1, 10 newarr v1, v1, panda.Object[] id: obja - values: - | # movi v1, 10 newarr v1, v1, R[][] id: raa - values: - | # movi v1, 10 newarr v1, v1, panda.Class[][] id: typaa - values: - | # movi v1, 10 newarr v1, v1, panda.Object[][] id: objaa - values: - mov.null v1 id: nul - file-name: incompatible_acc_j isa: verification: - compatible_arguments runner-options: [verifier-failure, use-pa, verifier-config] tags: [verifier, pa-verifier] bugid: ["6886"] description: Check 'call.virt.acc' instruction with incompatible accumulator in PandaAssembly context. header-template: [PandaAssembly] check-type: exit-positive code-template: | .record panda.Object .record panda.Class .record R {} .function void R.foo(R a0, %s a1, i32 a2, R a3) { return.void } .function i32 main() { *s movi v1, 0 newobj v2, R call.virt.acc R.foo, v2, v1, v2, 1 template-cases: - values: - u1 exclude: [i32] - values: - i8 exclude: [i32] - values: - u16 exclude: [i32] - values: - i16 exclude: [i32] - values: - i32 exclude: [i32] - values: - i64 exclude: [i64] - values: - f32 exclude: [f32] bugid: ['7445'] - values: - f64 exclude: [f64] - values: - u1[] exclude: [u1a, nul] - values: - i8[] exclude: [i8a, nul] - values: - u16[] exclude: [u1a, u16a, nul] - values: - i16[] exclude: [i8a, i16a, nul] - values: - i32[] exclude: [i8a, i16a, i32a, nul] - values: - i64[] exclude: [i64a, nul] - values: - f32[] exclude: [f32a, nul] - values: - f64[] exclude: [f32a, f64a, nul] - values: - i32[][] exclude: [i32aa, nul] - values: - f64[][] exclude: [f64aa, nul] - values: - R exclude: [nul] - values: - panda.Class exclude: [typ, nul] - values: - panda.Object exclude: [u1a, i8a, u16a, i16a, i32a, i64a, f32a, f64a, i32aa, f64aa, typ, ra, typa, obja, raa, typaa, objaa, nul] - values: - R[] exclude: [ra, nul] - values: - panda.Class[] exclude: [typa, nul] - values: - panda.Object[] exclude: [obja, i32aa, f64aa, ra, typa, raa, typaa, objaa, nul] - values: - R[][] exclude: [raa, nul] - values: - panda.Class[][] exclude: [typaa, nul] - values: - panda.Object[][] exclude: [objaa, raa, typaa, nul] cases: - values: - ldai 1 id: i32 - values: - ldai.64 1 id: i64 - values: - fldai 1.0 id: f32 bugid: ['7445'] - values: - fldai.64 1.0 id: f64 - values: - | # movi v1, 10 newarr v1, v1, u1[] lda.obj v1 id: u1a - values: - | # movi v1, 10 newarr v1, v1, i8[] lda.obj v1 id: i8a - values: - | # movi v1, 10 newarr v1, v1, u16[] lda.obj v1 id: u16a - values: - | # movi v1, 10 newarr v1, v1, i16[] lda.obj v1 id: i16a - values: - | # movi v1, 10 newarr v1, v1, i32[] lda.obj v1 id: i32a - values: - | # movi v1, 10 newarr v1, v1, i64[] lda.obj v1 id: i64a - values: - | # movi v1, 10 newarr v1, v1, f32[] lda.obj v1 id: f32a - values: - | # movi v1, 10 newarr v1, v1, f64[] lda.obj v1 id: f64a - values: - | # movi v1, 10 newarr v1, v1, i32[][] lda.obj v1 id: i32aa - values: - | # movi v1, 10 newarr v1, v1, f64[][] lda.obj v1 id: f64aa - values: - | # lda.type R id: typ - values: - | # movi v1, 10 newarr v1, v1, R[] lda.obj v1 id: ra - values: - | # movi v1, 10 newarr v1, v1, panda.Class[] lda.obj v1 id: typa - values: - | # movi v1, 10 newarr v1, v1, panda.Object[] lda.obj v1 id: obja - values: - | # movi v1, 10 newarr v1, v1, R[][] lda.obj v1 id: raa - values: - | # movi v1, 10 newarr v1, v1, panda.Class[][] lda.obj v1 id: typaa - values: - | # movi v1, 10 newarr v1, v1, panda.Object[][] lda.obj v1 id: objaa - values: - lda.null id: nul - file-name: compatible_primitive_args_p isa: verification: - compatible_arguments runner-options: [verifier-only, verifier-config] tags: [verifier] description: Check 'call.virt.acc' instruction with compatible primitive arguments in PandaAssembly context. header-template: [] check-type: exit-positive code-template: | .record R {} .function void R.foo(R a0, %s) { return.void } .function i32 main() { newobj v0, R lda.obj v0 %s call.virt.acc R.foo, v1, v2, v3, 0 cases: - values: - u1 a1, u8 a2, i8 a3 - | # movi v1, 1 movi v2, 1 movi v3, 1 - values: - u16 a1, i16 a2, u32 a3 - | # movi v1, 1 movi v2, 1 movi v3, 1 - values: - i32 a1, i64 a2, u64 a3 - | # movi v1, 1 movi.64 v2, 1 movi.64 v3, 1 - values: - f64 a1, f64 a2 - | # fmovi.64 v1, 1.1 fmovi.64 v2, 1.1 - file-name: compatible_primitive_args_j isa: verification: - compatible_arguments runner-options: [verifier-only, use-pa, verifier-config] tags: [verifier, pa-verifier] bugid: ["6886"] description: Check 'call.virt.acc' instruction with compatible primitive arguments in PandaAssembly context. header-template: [PandaAssembly] code-template: | .record R {} .function void R.foo(R a0, %s) { return.void } .function i32 main() { %s newobj v0, R call.virt.acc R.foo, v0, v1, v2, 3 check-type: exit-positive cases: - values: - u1 a1, f64 a2, u16 a3 - | # movi v1, 1 fmovi.64 v2, 1.1 ldai 1 - values: - i32 a1, i64 a2, f64 a3 - | # movi v1, 1 movi.64 v2, 1 fldai.64 1.1 - values: - i16 a1, i8 a2 - | # movi v1, 1 movi v2, 1 - file-name: compatible_prim_array_args_p isa: verification: - compatible_arguments runner-options: [verifier-only, verifier-config] tags: [verifier] description: Check 'call.virt.acc' instruction called with compatible primitive array arguments in PandaAssembly context. header-template: [] code-template: | .record R {} .function void R.foo(R a0, %s) { return.void } .function i32 main() { movi v0, 10 newarr v1, v0, %s[] newarr v2, v0, %s[] newarr v3, v0, %s[] lda.obj v3 newobj v0, R call.virt.acc R.foo, v0, v1, v2, 3 check-type: exit-positive cases: - values: - u8[] a1, i8[] a2, u16[] a3 - u8 - i8 - u16 - values: - u32[] a1, f32[][] a2, u64[] a3 - u32 - f32[] - u64 - values: - f32[] a1, f64[] a2, u1[][] a3 - f32 - f64 - u1[] - values: - i8[][] a1, u16[][] a2, i16[][] a3 - i8[] - u16[] - i16[] - values: - i32[][] a1, u64[][] a2, i64[][] a3 - i32[] - u64[] - i64[] - values: - i32[] a1, f64[][] a2 - i32 - f64[] - f64[][] - values: - u1[] a1, i16[] a2, i64[] a3 - u1 - i16 - i64 - values: - u8[][] a1, u32[][] a2 - u8[] - u32[] - u32[][] - file-name: compatible_prim_array_args_j isa: verification: - compatible_arguments runner-options: [verifier-only, use-pa, verifier-config] tags: [verifier, pa-verifier] bugid: ["6886"] description: Check 'call.virt.acc' instruction called with compatible primitive array arguments in PandaAssembly context. header-template: [PandaAssembly] code-template: | .record R {} .function void R.foo(R a0, %s) { return.void } .function i32 main() { movi v0, 10 newarr v1, v0, %s[] newarr v2, v0, %s[] newarr v3, v0, %s[] newobj v0, R lda.obj v0 call.virt.acc R.foo, v1, v2, v3, 0 check-type: exit-positive cases: - values: - f64[][] a1, u16[] a2, i16[] a3 - f64[] - u16 - i16 - values: - i64[] a1, f32[] a2, f64[] a3 - i64 - f32 - f64 - values: - i8[][] a1, u16[][] a2, i16[][] a3 - i8[] - u16[] - i16[] - values: - i32[][] a1, i64[][] a2, f32[][] a3 - i32[] - i64[] - f32[] - values: - u1[] a1, i32[] a2, u1[][] a3 - u1 - i32 - u1[] - file-name: compatible_obj_args_p isa: verification: - compatible_arguments runner-options: [verifier-only, verifier-config] tags: [verifier] description: Check 'call.virt.acc' instruction called with compatible object arguments in PandaAssembly context. header-template: [] check-type: exit-positive code-template: | .record panda.Object .record panda.Class .record panda.String .record Q {} .record R {} .function void R.foo(R a0, %s) { return.void } .function i32 main() { %s newobj v7, R lda.obj v7 call.virt.acc R.foo, v1, v2, v3, 0 cases: # Object of type O is instance of type T if O is the same as T ... - values: - R a1, panda.Class a2, panda.String a3 - | # newobj v1, R lda.type Q sta.obj v2 lda.str "test" sta.obj v3 # ... or is subtype of T - values: - panda.Object a1, panda.Object a2, panda.Object a3 - | # newobj v1, Q lda.str "test" sta.obj v2 lda.type Q sta.obj v3 bugid: ['3594'] ignore: true # For arrays T should be a root type in type hierarchy ... - values: - panda.Object a1, panda.Object a2, panda.Object a3 - | # movi v0, 10 newarr v1, v0, i32[] newarr v2, v0, f64[][] newarr v3, v0, Q[] - values: - panda.Object a1, panda.Object a2, panda.Object a3 - | # movi v0, 10 newarr v1, v0, panda.String[] newarr v2, v0, panda.Class[] newarr v3, v0, Q[][] - file-name: compatible_obj_args_j isa: verification: - compatible_arguments runner-options: [verifier-only, use-pa, verifier-config] tags: [verifier, pa-verifier] bugid: ["6886"] description: Check 'call.virt.acc' instruction called with compatible object arguments in PandaAssembly context. header-template: [PandaAssembly] check-type: exit-positive code-template: | .record panda.Object .record panda.Class .record panda.String .record panda.io.Serializable .record I {} .record E {} .record Q {} .record R {} .function void R.foo(R a0, %s) { return.void } .function i32 main() { %s newobj v0, R call.virt.acc R.foo, v0, v1, v2, 3 cases: # Object of type O is instance of type T if O is the same as T ... - values: - Q a1, panda.String a2, panda.Class a3 - | # newobj v1, Q lda.str "test" sta.obj v2 lda.type Q # ... or is subtype of T - values: - E a1, I a2, panda.Object a3 - | # newobj v1, Q newobj v2, Q lda.str "test" - values: - panda.io.Serializable a1, panda.Object a2, panda.Object a3 - | # lda.type Q sta.obj v1 newobj v2, R lda.type panda.String bugid: ['3594'] ignore: true # For arrays T should be a root type in type hierarchy ... - values: - panda.Object a1, panda.Object a2, panda.Object a3 - | # movi v0, 10 newarr v1, v0, i32[] newarr v2, v0, Q[] newarr v3, v0, panda.Object[] lda.obj v3 - values: - panda.Object a1, panda.Object a2, panda.Object a3 - | # movi v0, 10 newarr v1, v0, panda.String[] newarr v2, v0, panda.Class[] newarr v3, v0, I[][] lda.obj v3 - file-name: compatible_obj_array_args_p isa: verification: - compatible_arguments runner-options: [verifier-only, verifier-config] tags: [verifier] description: Check 'call.virt.acc' instruction called with compatible object array arguments in PandaAssembly context. header-template: [] check-type: exit-positive code-template: | .record panda.Object .record panda.Class .record panda.String .record Q {} .record R {} .function void R.foo(R a0, %s) { return.void } .function i32 main() { movi v0, 10 newarr v1, v0, %s newarr v2, v0, %s newarr v3, v0, %s lda.obj v3 newobj v0, R call.virt.acc R.foo, v0, v1, v2, 3 cases: # T is such array that O array elements are the same as T array elements - values: - Q[][] a1, panda.Object[] a2, panda.Object[][] a3 - Q[][] - panda.Object[] - panda.Object[][] - values: - panda.String[] a1, panda.Class[] a2, panda.Class[][] a3 - panda.String[] - panda.Class[] - panda.Class[][] # T is such array that O array elements are subtypes of T array elements - values: - panda.Object[] a1, panda.Object[] a2, panda.Object[] a3 - Q[] - Q[][] - panda.Class[] - values: - panda.Object[] a1, panda.Object[] a2, panda.Object[] a3 - panda.String[] - panda.String[][] - i32[][] - values: - panda.Object[][] a1, panda.Object[][] a2, panda.Object[][] a3 - panda.Object[][][] - panda.Class[][] - panda.Class[][][] - values: - panda.Object[][] a1, panda.Object[][] a2, panda.Object[][] a3 - i32[][][] - f64[][][][] - Q[][] - file-name: compatible_obj_array_args_j isa: verification: - compatible_arguments runner-options: [verifier-only, use-pa, verifier-config] tags: [verifier, pa-verifier] bugid: ["6886"] description: Check 'call.virt.acc' instruction called with compatible object array arguments in PandaAssembly context. header-template: [PandaAssembly] code-template: | .record panda.Object .record panda.Class .record panda.String .record I {} .record E {} .record Q {} .record R {} .function void R.foo(R a0, %s) { return.void } .function i32 main() { movi v0, 10 newarr v1, v0, %s newarr v2, v0, %s newarr v3, v0, %s newobj v0, R lda.obj v0 call.virt.acc R.foo, v1, v2, v3, 0 check-type: exit-positive cases: # T is such array that O array elements are the same as T array elements - values: - panda.String[] a1, Q[][] a2, panda.String[][] a3 - panda.String[] - Q[][] - panda.String[][] - values: - panda.Class[][] a1, panda.Class[] a2, panda.Object[][] a3 - panda.Class[][] - panda.Class[] - panda.Object[][] - values: - Q[] a1, R[] a2, I[] a3 - Q[] - R[] - I[] # T is such array that O array elements are subtypes of T array elements - values: - panda.Object[] a1, I[] a2, panda.Object[] a3 - Q[][] - Q[] - panda.Class[] - values: - panda.Object[] a1, panda.Object[] a2, panda.Object[] a3 - Q[] - panda.String[] - f64[][][] - values: - panda.Object[] a1, panda.Object[] a2, panda.Object[] a3 - i32[][] - I[][] - u16[][] # inherited types from object[][] - values: - panda.Object[][] a1, I[][] a2, panda.Object[][] a3 - panda.Object[][][] - Q[][] - panda.Class[][][] - values: - panda.Object[][] a1, panda.Object[][] a2, panda.Object[][] a3 - panda.Class[][] - i32[][][] - I[][][] - file-name: compatible_obj_null_args_p isa: verification: - compatible_arguments runner-options: [verifier-only, verifier-config] tags: [verifier] description: Check 'call.virt.acc' instruction called with null object ref in PandaAssembly context. header-template: [] check-type: exit-positive code-template: | .record panda.Object .record panda.Class .record panda.String .record Q {} .function void Q.foo(Q a0, %s) { return.void } .function i32 main() { mov.null v1 mov.null v2 mov.null v3 lda.null call.virt.acc Q.foo, v1, v2, v3, 0 cases: - values: ['f64[][] a1, panda.Object a2, panda.Object[] a3'] - values: ['Q a1, Q[][] a2, panda.String a3'] - values: ['panda.Class a1, panda.Class[] a2, u32[][][] a3'] - file-name: compatible_obj_null_args_j isa: verification: - compatible_arguments runner-options: [verifier-only, use-pa, verifier-config] tags: [verifier, pa-verifier] bugid: ["6886"] description: Check 'call.virt.acc' instruction called with null object ref in PandaAssembly context. header-template: [PandaAssembly] code-template: | .record panda.Object .record panda.Class .record panda.String .record Q {} .function void Q.foo(Q a0, %s) { return.void } .function i32 main() { mov.null v1 mov.null v2 mov.null v3 lda.null call.virt.acc Q.foo, v1, v2, v3, 1 check-type: exit-positive cases: - values: ['i32[] a1, panda.Object a2, panda.Object[] a3'] - values: ['panda.Object[][] a1, Q a2, panda.String a3'] - values: ['panda.String[] a1, panda.Class a2, u1[][][] a3'] - file-name: values_signed isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] runner-options: [] description: Check 'call.virt.acc' instruction called with integer values. header-template: [] check-type: empty code-template: | .record R {} .function i32 R.foo(R a0, i32 a1, i64 a2, i32 a3) { ldai %s jeq a1, ok1 ldai 1 return ok1: ldai.64 %s cmp.64 a2 jeqz ok2 ldai 2 return ok2: ldai %s jeq a3, ok3 ldai 3 return ok3: ldai 0 return } .function i32 main() { movi v1, %s movi.64 v2, %s movi v3, %s newobj v0, R lda.obj v0 call.virt.acc R.foo, v1, v2, v3, 0 return } cases: - values: [0, -1, 0x5a5a5a5a, 0, -1, 0x5a5a5a5a] - values: [0x11111111, 0xe1e1e1e1e1e1e1e1, 0x7ffffffe, 0x11111111, 0xe1e1e1e1e1e1e1e1, 0x7ffffffe] - values: [0xeeee0000, 0x8000000000000001, 0x80000001, 0xeeee0000, 0x8000000000000001, 0x80000001] - file-name: values_unsigned isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] runner-options: [] description: Check 'call.virt.acc' instruction called with unsigned values. header-template: [] check-type: empty code-template: | .record R {} .function i32 R.foo(R a0, u64 a1, u32 a2, u64 a3) { ldai.64 %s ucmp.64 a1 jeqz ok1 ldai 1 return ok1: ldai %s ucmp a2 jeqz ok2 ldai 2 return ok2: ldai.64 %s ucmp.64 a3 return } .function i32 main() { ldai.64 %s movi v2, %s movi.64 v3, %s newobj v0, R call.virt.acc R.foo, v0, v2, v3, 1 return } cases: - values: [0, 0xffffffff, 0xefffffffffffffff, 0, 0xffffffff, 0xefffffffffffffff] - values: [0xeeee1111ffffdddd, 0x5a5a5a5a, 0xa5a5a5a5a5a5a5a5, 0xeeee1111ffffdddd, 0x5a5a5a5a, 0xa5a5a5a5a5a5a5a5] - values: [1234567890123456789, 0, 0xffffffffffffffff, 1234567890123456789, 0, 0xffffffffffffffff] - file-name: values_float isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] tags: ['irtoc_ignore'] runner-options: [] description: Check 'call.virt.acc' instruction called with float values. header-template: [] check-type: empty code-template: | .record R {} .function i32 R.foo(R a0, f64 a1, f32 a2, f64 a3) { fldai.64 %s fcmpg.64 a1 jeqz ok1 ldai 1 return ok1: fldai %s fcmpg a2 jeqz ok2 ldai 3 return ok2: fldai.64 %s fcmpg.64 a3 return } .function i32 main() { fldai.64 %s fmovi v2, %s fmovi.64 v3, %s newobj v0, R call.virt.acc R.foo, v0, v2, v3, 1 return } cases: - values: [-1.1, -1.1, 0.12345678, -1.1, -1.1, 0.12345678] - values: [0.373737373737373737e37, 1.98765e14, -0.000000019e19, 0.373737373737373737e37, 1.98765e14, -0.000000019e19] - values: [0.717171717171717171717171e71, 0, 0.373737373737373737e37, 0.717171717171717171717171e71, 0, 0.373737373737373737e37] - values: [0x7ff0000000000000, 0x7f800000, 0xfff0000000000000, 0x7ff0000000000000, 0x7f800000, 0xfff0000000000000] - file-name: values_obj_p isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] runner-options: [] description: Check 'call.virt.acc' instruction called with object values in PandaAssembly context. header-template: [] check-type: empty code-template: | .record panda.Object .record panda.String .record R {} # put objects into array .function panda.Object R.foo(R a0, panda.Object a1, panda.Object a2, panda.Object a3) { movi v0, 3 newarr v0, v0, panda.Object[] lda.obj a1 movi v7, 0 starr.obj v0, v7 lda.obj a2 movi v7, 1 starr.obj v0, v7 lda.obj a3 movi v7, 2 starr.obj v0, v7 lda.obj v0 return.obj } # check that array contains correct obj refs .function i32 check(panda.Object a0, panda.Object a1, panda.Object a2, panda.Object[] a3) { ldai 0 ldarr.obj a3 jeq.obj a0, ok1 ldai 1 return ok1: ldai 1 ldarr.obj a3 jeq.obj a1, ok2 ldai 2 return ok2: ldai 2 ldarr.obj a3 jeq.obj a2, ok3 ldai 3 return ok3: ldai 0 return } .function i32 main() { newobj v7, R %s lda.obj v1 call.virt.acc R.foo, v7, v2, v3, 1 # R, acc, v2, v3 sta.obj v4 call check, v1, v2, v3, v4 jeqz pass1 return pass1: lda.obj v2 call.virt.acc R.foo, v7, v1, v3, 2 # R, v1, acc, v3 sta.obj v4 call check, v1, v2, v3, v4 jeqz pass2 return pass2: lda.obj v3 call.virt.acc R.foo, v7, v1, v2, 3 # R, v1, v2, acc sta.obj v4 call check, v1, v2, v3, v4 return } cases: - values: - | # newobj v1, panda.Object lda.str "test" sta.obj v2 lda.type panda.String sta.obj v3 - values: - | # newobj v1, R newobj v2, panda.Object mov.null v3 - values: - | # lda.str "" sta.obj v1 movi v5, 0 newarr v2, v5, R[][] newarr v3, v5, i32[] - values: - | # movi v5, 0 newarr v1, v5, panda.String[] lda.type R sta.obj v2 newarr v3, v5, panda.Object[][] - file-name: values_obj_j isa: instructions: - sig: call.virt.acc method_id, v1:in:top, v2:in:top, v3:in:top, imm:u2 acc: inout:top format: [op_v1_4_v2_4_v3_4_imm_4_id_16] runner-options: [use-pa] description: Check 'call.virt.acc' instruction called with object values in PandaAssembly context. header-template: [PandaAssembly] check-type: empty code-template: | .record panda.Object .record panda.String .record R {} # put objects into array .function panda.Object R.foo(R a0, panda.Object a1, panda.Object a2, panda.Object a3) { movi v0, 3 newarr v0, v0, panda.Object[] lda.obj a1 movi v7, 0 starr.obj v0, v7 lda.obj a2 movi v7, 1 starr.obj v0, v7 lda.obj a3 movi v7, 2 starr.obj v0, v7 lda.obj v0 return.obj } # check that array contains correct obj refs .function i32 check(panda.Object a0, panda.Object a1, panda.Object a2, panda.Object[] a3) { ldai 0 ldarr.obj a3 jeq.obj a0, ok1 ldai 1 return ok1: ldai 1 ldarr.obj a3 jeq.obj a1, ok2 ldai 2 return ok2: ldai 2 ldarr.obj a3 jeq.obj a2, ok3 ldai 3 return ok3: ldai 0 return } .function i32 main() { newobj v7, R %s lda.obj v1 call.virt.acc R.foo, v7, v2, v3, 1 # R, acc, v2, v3 sta.obj v4 call check, v1, v2, v3, v4 jeqz pass1 return pass1: lda.obj v2 call.virt.acc R.foo, v7, v1, v3, 2 # R, v1, acc, v3 sta.obj v4 call check, v1, v2, v3, v4 jeqz pass2 return pass2: lda.obj v3 call.virt.acc R.foo, v7, v1, v2, 3 # R, v1, v2, acc sta.obj v4 call check, v1, v2, v3, v4 return } cases: - values: - | # newobj v1, panda.Object lda.str "test" sta.obj v2 lda.type panda.String sta.obj v3 - values: - | # newobj v1, R newobj v2, panda.Object mov.null v3 - values: - | # movi v5, 0 newarr v1, v5, panda.String[] newarr v2, v5, R[][] newarr v3, v5, i32[] - values: - | # newobj v1, R mov.null v2 lda.str "" sta.obj v3 - file-name: regs_restored isa: description: > Call indicated object method, i.e. create new frame, pass values of arguments and continue execution from the first instruction of a method. Callee should treat accumulator value as undefined and cannot use it until accumulator definition in the new frame. description: Check 'call.virt.acc' that registers are restored after the call. tags: [tsan] header-template: [] code-template: | .record R {} .function R R.foo(R a0, i32 a1, i32 a2, i32 a3) { movi v0, 100 movi v1, 200 movi v2, 300 movi v3, 400 movi v4, 500 movi v5, 600 movi v6, 700 movi v7, 800 movi v8, 900 movi v9, 1000 movi v10, 1100 movi v11, 1200 movi v12, 1300 movi v13, 1400 movi v14, 1500 movi v15, 1600 lda.obj a0 return.obj } .function i32 main() { newobj v0, R lda.obj v0 movi v0, 1 movi v1, 2 movi v2, 3 movi v3, 4 movi v4, 5 movi v5, 6 movi v6, 7 movi v7, 8 movi v8, 9 movi v9, 10 movi v10, 11 movi v11, 12 movi v12, 13 movi v13, 14 movi v14, 15 movi v15, 16 call.virt.acc R.foo, v0, v1, v2, 0 call.virt.acc R.foo, v3, v4, v5, 0 call.virt.acc R.foo, v6, v7, v8, 0 call.virt.acc R.foo, v9, v10, v11, 0 call.virt.acc R.foo, v12, v13, v14, 0 call.virt.acc R.foo, v15, v15, v15, 0 ldai 1 jeq v0, ok1 return ok1: ldai 2 jeq v1, ok2 return ok2: ldai 3 jeq v2, ok3 return ok3: ldai 4 jeq v3, ok4 return ok4: ldai 5 jeq v4, ok5 return ok5: ldai 6 jeq v5, ok6 return ok6: ldai 7 jeq v6, ok7 return ok7: ldai 8 jeq v7, ok8 return ok8: ldai 9 jeq v8, ok9 return ok9: ldai 10 jeq v9, ok10 return ok10: ldai 11 jeq v10, ok11 return ok11: ldai 12 jeq v11, ok12 return ok12: ldai 13 jeq v12, ok13 return ok13: ldai 14 jeq v13, ok14 return ok14: ldai 15 jeq v14, ok15 return ok15: ldai 16 jeq v15, ok16 return ok16: check-type: exit-positive - file-name: ame_p isa: exceptions: - x_abstract description: Check that AbstractMethodError is thrown in PandaAssembly context. tags: ['irtoc_ignore'] header-template: [] code-template: | .record panda.AbstractMethodError .record R {} .function void R.foo1(R a0) .function void R.foo2(R a0, R a1, R a2, R a3) .function i32 main() { begin: newobj v0, R lda.obj v0 call.virt.acc %s end: ldai 1 # Should not reach this line return catch_AME: ldai 0 # Expected panda.AbstractMethodError return catch_all: ldai 2 # Unexpected exception, test failed return .catch panda.AbstractMethodError, begin, end, catch_AME .catchall begin, end, catch_all check-type: none cases: - values: - R.foo1, v0, v1, v2, 1 tags: ['tsan'] - values: - R.foo2, v0, v0, v0, 0 - file-name: ame_j isa: exceptions: - x_abstract description: Check that AbstractMethodError is thrown in PandaAssembly context. tags: ['irtoc_ignore'] header-template: [PandaAssembly] runner-options: [use-pa] code-template: | .record panda.AbstractMethodError .record R {} .record Q {} .function void R.foo(R a0, R a1, R a2, R a3) .function void Q.foo(Q a0, Q a1, Q a2, Q a3) { return.void } .function i32 main() { begin: %s call.virt.acc %s end: ldai 1 # Should not reach this line return catch_AME: ldai 0 # Expected panda.AbstractMethodError return catch_all: ldai 2 # Unexpected exception, test failed return .catch panda.AbstractMethodError, begin, end, catch_AME .catchall begin, end, catch_all check-type: none cases: - values: - | # newobj v1, R lda.null - R.foo, v1, v1, v1, 1 - values: - | # newobj v1, R lda.obj v1 newobj v1, Q - R.foo, v1, v1, v1, 0 - values: - | # newobj v2, Q lda.null - R.foo, v2, v2, v2, 1 - values: - | # newobj v2, Q lda.obj v2 - Q.foo, v2, v2, v2, 1 runner-options: [use-pa, run-failure] - file-name: npe_p isa: exceptions: - x_null description: Check that NullPointerException is thrown in PandaAssembly context. tags: ['irtoc_ignore'] header-template: [] code-template: | .record panda.NullPointerException .record R {} .function void R.foo(R a0, R a1, R a2, R a3) { return.void } .function R get_null() { lda.null return.obj } .function i32 main() { call.short get_null %s begin: call.virt.acc R.foo, %s end: ldai 1 # Should not reach this line return catch_NPE: ldai 0 # Expected panda.NullPointerException return catch_all: ldai 2 # Unexpected exception, test failed return .catch panda.NullPointerException, begin, end, catch_NPE .catchall begin, end, catch_all check-type: none cases: - values: - newobj v0, R - v0, v0, v0, 0 - values: - | # sta.obj v0 newobj v1, R lda.obj v1 - v0, v1, v1, 1 - values: - sta.obj v0 - v0, v0, v0, 1 - values: - sta.obj v0 - v0, v0, v0, 0 - values: - newobj v0, R - v0, v0, v0, 1 runner-options: [run-failure] - file-name: npe_j isa: exceptions: - x_null description: Check that NullPointerException is thrown in PandaAssembly context. tags: ['irtoc_ignore'] header-template: [PandaAssembly] runner-options: [use-pa] code-template: | .record panda.NullPointerException .record R {} .function void R.foo(R a0, R a1, R a2, R a3) { return.void } .function R get_null() { lda.null return.obj } .function i32 main() { call.short get_null %s begin: call.virt.acc R.foo, %s end: ldai 1 # Should not reach this line return catch_NPE: ldai 0 # Expected panda.NullPointerException return catch_all: ldai 2 # Unexpected exception, test failed return .catch panda.NullPointerException, begin, end, catch_NPE .catchall begin, end, catch_all check-type: none cases: - values: - newobj v0, R - v0, v0, v0, 0 - values: - | # sta.obj v0 newobj v1, R lda.obj v1 - v0, v1, v1, 1 - values: - sta.obj v0 - v0, v0, v0, 1 - values: - sta.obj v0 - v0, v0, v0, 0 - values: - newobj v0, R - v0, v0, v0, 1 runner-options: [run-failure, use-pa] - file-name: PandaAssembly_x_call isa: exceptions: - x_call header-template: [PandaAssembly] tags: ['irtoc_ignore'] runner-options: [use-pa] description: Bytecode may throw an error if an exception occures in the called bytecode. code-template: | .record panda.Throwable .record E1 {} .record R {} .record S {} .function void R.constructor(R a0) { return.void } .function void S.constructor(S a0) { return.void } .function void R.method(R a0, i32[] a1, i32[] a2, i32[] a3) .function void S.method(S a0, i32[] a1, i32[] a2, i32[] a3) { newobj v4, E1 throw v4 return.void } .function i32 main() { jmp try_begin catch_E1: ldai 0 return try_begin: mov.null v1 mov.null v2 mov.null v3 initobj.short S.constructor call.virt.acc R.method, v1, v2, v3, 0 try_end: .catch E1, try_begin, try_end, catch_E1 ldai 1 return check-type: none