# 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
  - name: aoobe_p
    template: |
      .record panda.ArrayIndexOutOfBoundsException <external>
      .record R {}
      .function void R.ctor(R a0) <ctor> {
          return.void
      }
  - name: aoobe_j
    template: |
      .record panda.ArrayIndexOutOfBoundsException <external>
      .record panda.String <external>
      .record R {}
      .function void R.ctor(R a0) <ctor> {
          return.void
      }
  - name: npe_p
    template: |
      .record panda.NullPointerException <external>
  - name: npe_j
    template: |
      .record panda.NullPointerException <external>
  - name: ase_p
    template: |
      .record panda.ArrayStoreException <external>
  - name: ase_j
    template: |
      .record panda.ArrayStoreException <external>

tests:
  - file-name: "starr.obj"
    isa:
      title: Store to array
      description: >
        Store accumulator content into array slot pointed by index.
      instructions:
        - sig: starr.obj v1:in:ref[], v2:in:i32
          acc: in:ref
          format: [op_v1_4_v2_4]
    commands:


      - file-name: "reg_valid"
        isa:
          instructions:
            - sig: starr.obj v1:in:ref[], v2:in:i32
              acc: in:ref
              format: [op_v1_4_v2_4]
        check-type: empty
        runner-options: [compile-only]
        description: Check 'starr.obj' instruction with valid register numbers.
        header-template: []
        code-template: |
          #
          .function i32 main() {
              starr.obj %s, %s
              ldai 0
              return
          }
        cases:
          - values: [v0, v15]
          - values: [v15, v0]
          - values: [v15, v15]
          - case-template: |
              #
              .record A {}
              .function i32 f1(A[] a0, i32 a1) {
                  starr.obj a0, a1   # valid registers
                  ldai 0
                  return
              }

              .function i32 main() {
                  call.short f1, v1, v2
                  return
              }


      - file-name: "reg_v_invalid"
        isa:
          instructions:
            - sig: starr.obj v1:in:ref[], v2:in:i32
              acc: in:ref
              format: [op_v1_4_v2_4]
        runner-options: [compile-failure]
        description: Check 'starr.obj' instruction with invalid register numbers.
        code-template: |
          #
              starr.obj %s, *s
        check-type: exit-positive
        template-cases:
          - values: [v0]
            exclude: [v0, v15]
          - values: [v15]
            exclude: [v0, v15]
          - values: [v255]
          - values: [v256]
          - values: [v65536]
          - values: [a0]
          - values: ['V1']
          - values: ['null']
          - values: [0]
        cases:
          - values: [v0]
            id: v0
          - values: [v15]
            id: v15
          - values: [v255]
          - values: [v256]
          - values: [v65536]
          - values: [a0]
          - values: ['V1']
          - values: ['null']
          - values: [0]


      - file-name: "reg_a_invalid"
        isa:
          instructions:
            - sig: starr.obj v1:in:ref[], v2:in:i32
              acc: in:ref
              format: [op_v1_4_v2_4]
        runner-options: [compile-failure]
        description: Check 'starr.obj' instruction with invalid register numbers.
        header-template: []
        code-template: |
              #
              .record A {}
              .function void f1(A[] a0, i32 a1) {
                  starr.obj %s
                  return.void
              }

              .function i32 main() {
                  call.short f1, v1, v2
        check-type: exit-positive
        cases:
          - values:
            - 'a0, a2'
          - values:
            - 'a2, a1'


      - file-name: null_pointer_p
        isa:
          exceptions:
            - x_null
        description: Check 'starr.obj' behavior when array is null reference.
        header-template: [npe_p]
        tags: ['irtoc_ignore']
        bugid: ['3228']
        code-template: |
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .function A[] get_null() {
              lda.null
              return.obj
          }
          .function i32 main() {
              call.short get_null
              sta.obj v0
              movi v1, %s
              initobj A.ctor
          begin:
              starr.obj v0, v1
          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: [0]
            tags: ['tsan']
          - values: [1]
          - values: [10]
          - values: [128]
          - values: [255]
          - values: [65535]
            tags: ['tsan']
          - values: [0x7FFFFFFF]
          - values: [0xFFFFFFFF]
          - values: [0x80000000]


      - file-name: null_pointer_j
        isa:
          exceptions:
            - x_null
        description: Check 'starr.obj' behavior when array is null reference.
        header-template: [PandaAssembly, npe_j]
        runner-options: [use-pa]
        tags: ['irtoc_ignore']
        bugid: ['3228']
        code-template: |
          .record panda.String <external>
          .function panda.String[] get_null() {
              lda.null
              return.obj
          }
          .function i32 main() {
              call.short get_null
              sta.obj v0
              movi v1, %s
              lda.str "test"
          begin:
              starr.obj v0, v1
          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: [0]
            tags: ['tsan']
          - values: [1]
          - values: [10]
          - values: [128]
          - values: [255]
          - values: [65535]
            tags: ['tsan']
          - values: [0x7FFFFFFF]
          - values: [0xFFFFFFFF]
          - values: [0x80000000]


      - file-name: array_out_of_bounds_exception_p
        isa:
          exceptions:
            - x_bounds
        description: Check 'starr.obj' behavior when index is out of array bounds.
        header-template: [aoobe_p, main]
        tags: ['irtoc_ignore']
        code-template: |
          #
              movi v0, *s
              newarr v1, v0, %s
              movi v2, *s
              %s
          begin:
              starr.obj v1, v2
          end:
              ldai 1 # Should not reach this line
              return

          catch_AOOBE:
              ldai 0 # Expected panda.ArrayIndexOutOfBoundsException
              return

          catch_all:
              ldai 2 # Unexpected exception, test failed
              return

          .catch panda.ArrayIndexOutOfBoundsException, begin, end, catch_AOOBE
          .catchall begin, end, catch_all
        check-type: none
        template-cases:
            - values:
              - 'R[]'
              - initobj R.ctor
            - values:
              - 'R[][][]'
              - |
                #
                    movi v0, 1
                    newarr v0, v0, R[][]
                    lda.obj v0
        cases:
          - values: [0, 0]
            tags: ['tsan']
          - values: [0, 1]
          - values: [10, -10]
          - values: [10, 128]
          - values: [255, 255]
          - values: [254, 255]
          - values: [65535, 65535]
            tags: ['tsan']
          - values: [65535, 65536]
          - values: [10, 0xFFFFFFFF]
          - values: [256, 0xFFFFFFFE]
          - values: [65536, 0xFFFFFFFD]
            tags: ['tsan']
          - values: [0x100000, 0xFFFFFFFC]
          - values: [10, 0x80000000]
          - values: [256, 0x80000001]
          - values: [65536, 0x80000002]
            tags: ['tsan']
          - values: [0x100000, 0x80000003]


      - file-name: array_out_of_bounds_exception_j
        isa:
          exceptions:
            - x_bounds
        description: Check 'starr.obj' behavior when index is out of array bounds.
        runner-options: [use-pa]
        tags: ['irtoc_ignore']
        header-template: [PandaAssembly, aoobe_j, main]
        bugid: ['3227']
        code-template: |
          #
              movi v0, *s
              newarr v1, v0, %s
              movi v2, *s
              %s
          begin:
              starr.obj v1, v2
          end:
              ldai 1 # Should not reach this line
              return

          catch_AOOBE:
              ldai 0 # Expected panda.ArrayIndexOutOfBoundsException
              return

          catch_all:
              ldai 2 # Unexpected exception, test failed
              return

          .catch panda.ArrayIndexOutOfBoundsException, begin, end, catch_AOOBE
          .catchall begin, end, catch_all
        check-type: none
        template-cases:
            - values:
              - 'R[]'
              - initobj R.ctor
            - values:
              - 'panda.String[][][]'
              - |
                #
                    movi v0, 1
                    newarr v0, v0, panda.String[][]
                    lda.obj v0
        cases:
          - values: [0, 0]
            tags: ['tsan']
          - values: [0, 1]
          - values: [10, -10]
          - values: [10, 128]
          - values: [255, 255]
          - values: [254, 255]
          - values: [65535, 65535]
            tags: ['tsan']
          - values: [65535, 65536]
          - values: [10, 0xFFFFFFFF]
          - values: [256, 0xFFFFFFFE]
          - values: [65536, 0xFFFFFFFD]
            tags: ['tsan']
          - values: [0x100000, 0xFFFFFFFC]
          - values: [10, 0x80000000]
          - values: [256, 0x80000001]
          - values: [65536, 0x80000002]
            tags: ['tsan']
          - values: [0x100000, 0x80000003]


      - file-name: ase_p
        isa:
          exceptions:
            - x_store
        description: Check 'starr.obj' behavior when element isn't an instance of array's element type
        bugid: ['3362']
        header-template: [ase_p]
        tags: ['irtoc_ignore']
        code-template: |
          .record panda.Object <external>
          .record panda.String <external>
          .record panda.Class <external>
          .record A {}
          .record B {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .function void B.ctor(B a0) <ctor> {
              return.void
          }
          .function panda.Object getObj() {
              %s
              return.obj
          }
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, *s
              movi v2, 0
              call.short getObj
          begin:
              starr.obj v1, v2
          end:
              ldai 1 # Should not reach this line
              return

          catch_ASE:
              ldai 0 # Expected panda.ArrayStoreException
              return

          catch_all:
              ldai 2 # Unexpected exception, test failed
              return

          .catch panda.ArrayStoreException, begin, end, catch_ASE
          .catchall begin, end, catch_all
        check-type: none
        template-cases:
          - values:
            - initobj A.ctor
            exclude: [a]
          - values:
            - initobj B.ctor
            exclude: [b]
          - values:
            - lda.str "test string"
            exclude: [string]
          - values:
            - lda.type B
            exclude: [class]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, A[]
                  lda.obj v0
            exclude: [a_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, B[]
                  lda.obj v0
            exclude: [b_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, panda.String[]
                  lda.obj v0
            exclude: [string_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, panda.Object[]
                  lda.obj v0
        cases:
          - values:
            - A[]
            id: a
          - values:
            - B[]
            id: b
          - values:
            - panda.String[]
            id: string
            tags: ['tsan']
          - values:
            - panda.Class[]
            id: class
          - values:
            - A[][]
            id: a_array
          - values:
            - B[][]
            id: b_array
          - values:
            - panda.String[][]
            id: string_array
          - values:
            - panda.Class[][]
            id: class_array
            tags: ['tsan']


      - file-name: ase_j
        isa:
          exceptions:
            - x_store
        description: Check 'starr.obj' behavior when element isn't an instance of array's element type
        runner-options: [use-pa]
        bugid: ['3362']
        header-template: [PandaAssembly, ase_j]
        tags: ['irtoc_ignore']
        code-template: |
          .record R {}
          .record I <panda.interface> {}
          .record Q <panda.implements=I> {}
          .record E <panda.extends=Q> {}
          .record A <panda.annotation, panda.annotation.type=runtime> {}
          .record panda.Object <external>
          .record panda.String <external>
          .record panda.Class <external>

          .function void R.ctor(R a0) <ctor> {
              return.void
          }
          .function void Q.ctor(Q a0) <ctor> {
              return.void
          }
          .function void E.ctor(E a0) <ctor> {
              return.void
          }
          .function panda.Object getObj() {
              %s
              return.obj
          }
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, *s
              movi v2, 0
              call.short getObj
          begin:
              starr.obj v1, v2
          end:
              ldai 1 # Should not reach this line
              return

          catch_ASE:
              ldai 0 # Expected panda.ArrayStoreException
              return

          catch_all:
              ldai 2 # Unexpected exception, test failed
              return

          .catch panda.ArrayStoreException, begin, end, catch_ASE
          .catchall begin, end, catch_all
        check-type: none
        template-cases:
          - values:
            - initobj R.ctor
            exclude: [r]
          - values:
            - initobj Q.ctor
            exclude: [i, q]
          - values:
            - initobj E.ctor
            exclude: [i, q, e]
          - values:
            - lda.str "test string"
            exclude: [string]
          - values:
            - lda.type R
            exclude: [class]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, R[]
                  lda.obj v0
            exclude: [r_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, I[]
                  lda.obj v0
            exclude: [i_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, Q[]
                  lda.obj v0
            exclude: [q_array, i_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, E[]
                  lda.obj v0
            exclude: [q_array, i_array, e_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, A[]
                  lda.obj v0
            exclude: [a_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, panda.String[]
                  lda.obj v0
            exclude: [string_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, panda.Class[]
                  lda.obj v0
            exclude: [class_array]
          - values:
            - |
              #
                  movi v0, 1
                  newarr v0, v0, panda.Object[]
                  lda.obj v0
        cases:
          - values:
            - R[]
            id: r
          - values:
            - I[]
            id: i
          - values:
            - Q[]
            id: q
          - values:
            - E[]
            id: e
            tags: ['tsan']
          - values:
            - A[]
          - values:
            - panda.String[]
            id: string
          - values:
            - panda.Class[]
            id: class
          - values:
            - R[][]
            id: r_array
          - values:
            - I[][]
            id: i_array
          - values:
            - Q[][]
            id: q_array
          - values:
            - E[][]
            id: e_array
          - values:
            - A[][]
            id: a_array
          - values:
            - panda.String[][]
            id: string_array
            tags: ['tsan']
          - values:
            - panda.Class[][]
            id: class_array


      - file-name: uninitialized_regs
        isa:
          verification:
            - v1_array_type
            - v2_i32
            - acc_type
        description: Check 'starr.obj' with uninitialized register
        tags: ['verifier']
        runner-options: ['verifier-failure', 'verifier-config']
        header-template: []
        code-template: |
            #
            .record R {}
            .function i32 main() {
                %s
                starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values:
              - |
                # acc is not initialized
                    movi v0, 10
                    newarr v1, v0, R[]
                    movi v2, 0
          - values:
              - |
                # v1 is not initialized
                    movi v2, 0
                    lda.null
          - values:
              - |
                # v2 is not initialized
                    movi v0, 10
                    newarr v1, v0, R[]
                    lda.null
          - values:
              - |
                # all regs are not initialized


      - file-name: "acceptable_types_p"
        isa:
          verification:
            - v1_array_type
        description: Check acceptable array types for starr.obj instruction in Panda Assembly context.
        runner-options: ['verifier-only', 'verifier-config']
        tags: ['verifier']
        header-template: []
        code-template: |
          .record R {}
          .record panda.Object <external>
          .record panda.String <external>
          .record panda.Class <external>
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, %s
              movi v2, 0
              lda.null
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values: ['panda.Object[]']
          - values: ['panda.String[]']
          - values: ['panda.Class[]']
          - values: ['R[]']
          - values: ['panda.Object[][]']
          - values: ['panda.String[][]']
          - values: ['panda.Class[][]']
          - values: ['R[][]']
          - values: ['u1[][]']
          - values: ['u32[][]']
          - values: ['u64[][]']


      - file-name: "acceptable_types_j"
        isa:
          verification:
            - v1_array_type
        description: Check acceptable array types for starr.obj instruction in PandaAssembly context.
        runner-options: [verifier-only, use-pa, verifier-config]
        tags: [verifier, pa-verifier]
        bugid: ['3227']
        header-template: [PandaAssembly]
        code-template: |
          .record R {}
          .record I <panda.interface> {}
          .record Q <panda.implements=I> {}
          .record E <panda.extends=Q> {}
          .record A <panda.annotation, panda.annotation.type=runtime> {}
          .record panda.Object <external>
          .record panda.String <external>
          .record panda.Class <external>
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, %s
              movi v2, 0
              lda.null
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values: ['R[]']
          - values: ['I[]']
          - values: ['Q[]']
          - values: ['E[]']
          - values: ['A[]']
          - values: ['panda.Object[]']
          - values: ['panda.String[]']
          - values: ['panda.Class[]']
          - values: ['R[][]']
          - values: ['I[][]']
          - values: ['Q[][]']
          - values: ['E[][]']
          - values: ['A[][]']
          - values: ['panda.Object[][]']
          - values: ['panda.String[][]']
          - values: ['panda.Class[][]']
          - values: ['i8[][]']
          - values: ['i32[][]']
          - values: ['f64[][]']


      - file-name: "rejectable_primitive_types_p"
        isa:
          verification:
            - v1_array_type
        description: Check rejectable array of primitive types for starr.obj instruction in Panda Assembly context.
        runner-options: ['verifier-failure', 'verifier-config']
        tags: ['verifier']
        header-template: [main]
        code-template: |
          #
              movi v0, 1
              newarr v1, v0, %s
              movi v2, 0
              lda.null
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values: ['u1[]']
          - values: ['i8[]']
          - values: ['u8[]']
          - values: ['i16[]']
          - values: ['u16[]']
          - values: ['i32[]']
          - values: ['u32[]']
          - values: ['i64[]']
          - values: ['u64[]']
          - values: ['f32[]']
          - values: ['f64[]']


      - file-name: "rejectable_primitive_types_j"
        isa:
          verification:
            - v1_array_type
        description: Check rejectable array of primitive types for starr.obj instruction in PandaAssembly context.
        runner-options: [verifier-failure, use-pa, verifier-config]
        tags: [verifier, pa-verifier]
        bugid: ['3293', '5271']
        header-template: [PandaAssembly, main]
        code-template: |
          #
              movi v0, 1
              newarr v1, v0, %s
              movi v2, 0
              lda.null
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values: ['u1[]']
          - values: ['i8[]']
          - values: ['u8[]']
          - values: ['i16[]']
          - values: ['u16[]']
          - values: ['i32[]']
          - values: ['u32[]']
          - values: ['i64[]']
          - values: ['u64[]']
          - values: ['f32[]']
          - values: ['f64[]']


      - file-name: "arr_type_p"
        isa:
          verification:
            - v1_array_type
        description: Check 'starr.obj' with incorrect array type in Panda Assembly context. See also "rejectable_primitive_types" tests.
        runner-options: ['verifier-failure', 'verifier-config']
        tags: ['verifier']
        header-template: []
        code-template: |
          #
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.String <external>
          .record panda.Object <external>
          .function i32 main() {
              %s
              movi v1, 0
              lda.null
              starr.obj v0, v1
        check-type: exit-positive
        cases:
          - values:
              - movi v0, 0
          - values:
              - movi.64 v0, 0
          - values:
              - fmovi v0, 0
          - values:
              - fmovi.64 v0, 0
          - values:
              - |
                #
                    initobj A.ctor
                    sta.obj v0
          - values:
              - |
                #
                    lda.type A
                    sta.obj v0
          - values:
              - |
                #
                    lda.type A[]
                    sta.obj v0
          - values:
              - |
                #
                    lda.type panda.String
                    sta.obj v0
          - values:
              - |
                #
                    lda.type panda.String[]
                    sta.obj v0
          - values:
              - |
                #
                    lda.type panda.Object
                    sta.obj v0
          - values:
              - |
                #
                    lda.type panda.Object[]
                    sta.obj v0
          - values:
              - |
                #
                    lda.str "string"
                    sta.obj v0


      - file-name: "arr_type_j"
        isa:
          verification:
            - v1_array_type
        description: Check 'starr.obj' with incorrect array type in PandaAssembly context. See also "rejectable_primitive_types" tests.
        runner-options: [verifier-failure, use-pa, verifier-config]
        tags: [verifier, pa-verifier]
        bugid: ['3293', '5271']
        header-template: [PandaAssembly]
        code-template: |
          #
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.Object <external>
          .function void panda.Object.ctor(panda.Object a0) <external,ctor>
          .function i32 main() {
              %s
              movi v1, 0
              lda.null
              starr.obj v0, v1
        check-type: exit-positive
        cases:
          - values:
              - movi v0, 0
          - values:
              - movi.64 v0, 0
          - values:
              - fmovi v0, 0
          - values:
              - fmovi.64 v0, 0
          - values:
              - |
                #
                    initobj A.ctor
                    sta.obj v0
          - values:
              - |
                #
                    initobj panda.Object.ctor
                    sta.obj v0
          - values:
              - |
                #
                    lda.type A
                    sta.obj v0
          - values:
              - |
                #
                    lda.type A[]
                    sta.obj v0
          - values:
              - |
                #
                    lda.type panda.Object
                    sta.obj v0
          - values:
              - |
                #
                    lda.type panda.Object[]
                    sta.obj v0
          - values:
              - |
                #
                    lda.str "string"
                    sta.obj v0


      - file-name: "index_type_p"
        isa:
          verification:
            - v2_i32
        description: Check 'starr.obj' with incorrect array index type in Panda Assembly context.
        runner-options: ['verifier-failure', 'verifier-config']
        tags: ['verifier']
        header-template: []
        code-template: |
          #
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.String <external>
          .record panda.Object <external>
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, *s
              %s
              *s
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values:
              - A[]
              - initobj A.ctor
          - values:
              - panda.String[]
              - lda.str "test string"
        template-cases:
          - values:
              - mov.null v2
          - values:
              - movi.64 v2, 0
          - values:
              - fmovi v2, 0
          - values:
              - fmovi.64 v2, 0
          - values:
              - |
                #
                    initobj A.ctor
                    sta.obj v1
          - values:
              - |
                #
                    movi v0, 1
                    newarr v2, v0, A[]
          - values:
              - |
                #
                    lda.type A
                    sta.obj v2
          - values:
              - |
                #
                    lda.type A[]
                    sta.obj v2
          - values:
              - |
                #
                    lda.type panda.String
                    sta.obj v2
          - values:
              - |
                #
                    lda.type panda.String[]
                    sta.obj v2
          - values:
              - |
                #
                    lda.type panda.Object
                    sta.obj v2
          - values:
              - |
                #
                    lda.type panda.Object[]
                    sta.obj v2
          - values:
              - |
                #
                    lda.str "string"
                    sta.obj v2
          - values:
              - |
                #
                    movi v0, 1
                    newarr v2, v0, panda.Object[]
          - values:
              - |
                #
                    movi v0, 1
                    newarr v2, v0, panda.String[]


      - file-name: "index_type_j"
        isa:
          verification:
            - v2_i32
        description: Check 'starr.obj' with incorrect array index type in PandaAssembly context.
        runner-options: [verifier-failure, use-pa, verifier-config]
        tags: [verifier, pa-verifier]
        bugid: ['3293', '5271']
        header-template: [PandaAssembly]
        code-template: |
          #
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.Object <external>
          .function void panda.Object.ctor(panda.Object a0) <external,ctor>
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, *s
              %s
              *s
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values:
              - A[]
              - initobj A.ctor
          - values:
              - panda.Object[]
              - initobj panda.Object.ctor
        template-cases:
          - values:
              - mov.null v2
          - values:
              - movi.64 v2, 0
          - values:
              - fmovi v2, 0
          - values:
              - fmovi.64 v2, 0
          - values:
              - |
                #
                    initobj A.ctor
                    sta.obj v2
          - values:
              - |
                #
                    movi v0, 1
                    newarr v2, v0, A[]
          - values:
              - |
                #
                    initobj panda.Object.ctor
                    sta.obj v2
          - values:
              - |
                #
                    movi v0, 1
                    newarr v2, v0, panda.Object[]
          - values:
              - |
                #
                    lda.type A
                    sta.obj v2
          - values:
              - |
                #
                    lda.type A[]
                    sta.obj v2
          - values:
              - |
                #
                    lda.type panda.Object
                    sta.obj v2
          - values:
              - |
                #
                    lda.type panda.Object[]
                    sta.obj v2
          - values:
              - |
                #
                    lda.str "string"
                    sta.obj v2


      - file-name: "acc_incorrect_type_p"
        isa:
          verification:
            - acc_type
        description: Check 'starr.obj' with incorrect accumulator type in Panda Assembly context.
        runner-options: ['verifier-failure', 'verifier-config']
        tags: ['verifier']
        header-template: []
        code-template: |
          #
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.String <external>
          .record panda.Object <external>
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, *s
              movi v2, 0
              %s
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values: ['A[]']
          - values: ['panda.Object[]']
        template-cases:
          - values:
              - ldai 0
          - values:
              - ldai.64 0
          - values:
              - fldai 0
          - values:
              - fldai.64 0


      - file-name: "acc_correct_type_p"
        isa:
          verification:
            - acc_type
        description: Check 'starr.obj' with correct accumulator type in Panda Assembly context.
        runner-options: ['verifier-only', 'verifier-config']
        tags: ['verifier']
        header-template: []
        code-template: |
          #
          .record Z {}
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.Object <external>
          .function panda.Object getObj() {
              %s
              return.obj
          }
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, %s
              movi v2, 0
              call.short getObj
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values:
            - initobj A.ctor
            - A[]
            bugid: ['7423']
            ignore: true
          - values:
            - initobj A.ctor
            - panda.Object[]
          - values:
            - |
              #
                  newobj v3, Z
                  lda.obj v3
            - A[]
            runner-options: [verifier-failure, verifier-config]


      - file-name: "acc_incorrect_type_j"
        isa:
          verification:
            - acc_type
        description: Check 'starr.obj' with incorrect accumulator type in PandaAssembly context.
        runner-options: [verifier-failure, use-pa, verifier-config]
        tags: [verifier, pa-verifier]
        bugid: ['3293', '5271']
        header-template: [PandaAssembly]
        code-template: |
          #
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.Object <external>
          .function void panda.Object.ctor(panda.Object a0) <external,ctor>
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, *s
              movi v2, 0
              %s
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values: ['A[]']
          - values: ['panda.Object[]']
        template-cases:
          - values:
              - ldai 0
          - values:
              - ldai.64 0
          - values:
              - fldai 0
          - values:
              - fldai.64 0


      - file-name: "acc_correct_type_j"
        isa:
          verification:
            - acc_type
        description: Check 'starr.obj' with correct accumulator type in PandaAssembly context.
        runner-options: [verifier-only, use-pa, verifier-config]
        tags: [verifier, pa-verifier]
        bugid: ['3293', '5271']
        header-template: [PandaAssembly]
        code-template: |
          #
          .record Z {}
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.Object <external>
          .function panda.Object getObj() {
              %s
              return.obj
          }
          .function i32 main() {
              movi v0, 1
              newarr v1, v0, %s
              movi v2, 0
              call.short getObj
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values:
            - initobj A.ctor
            - A[]
            bugid: ['7423']
            ignore: true
          - values:
            - initobj A.ctor
            - panda.Object[]
          - values:
            - |
              #
                  newobj v3, Z
                  lda.obj v3
            - A[]
            runner-options: [verifier-failure, use-pa, verifier-config]


      - file-name: "mult_regs_types_p"
        isa:
          verification:
            - v1_array_type
            - v2_i32
            - acc_type
        description: Check 'starr.obj' with multiple incorrect register types in Panda Assembly context.
        runner-options: ['verifier-failure', 'verifier-config']
        tags: ['verifier']
        header-template: []
        code-template: |
          #
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.String <external>
          .record panda.Object <external>
          .function void panda.Object.ctor(panda.Object a0) <external,ctor>
          .function i32 main() {
              %s
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values:
              - |
                # all registers invalid
                    initobj panda.Object.ctor
                    sta.obj v1
                    movi.64 v2, 0
                    ldai 0
          - values:
              - |
                # v1 and v2 invalid
                    lda.str "test string"
                    sta.obj v1
                    fmovi.64 v2, 1
                    initobj panda.Object.ctor
          - values:
              - |
                # v1 and acc invalid
                    lda.type panda.Object
                    sta.obj v1
                    movi v2, 0
                    fldai.64 0
          - values:
              - |
                # v2 and acc invalid
                    movi v0, 1
                    newarr v1, v0, A[]
                    sta.obj v2
                    ldai 0


      - file-name: "mult_regs_types_j"
        isa:
          verification:
            - v1_array_type
            - v2_i32
            - acc_type
        description: Check 'starr.obj' with multiple incorrect register types in PandaAssembly context.
        runner-options: [verifier-failure, use-pa, verifier-config]
        tags: [verifier, pa-verifier]
        bugid: ['3293', '5271']
        header-template: [PandaAssembly]
        code-template: |
          #
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.Object <external>
          .function void panda.Object.ctor(panda.Object a0) <external,ctor>
          .function i32 main() {
              %s
              starr.obj v1, v2
        check-type: exit-positive
        cases:
          - values:
              - |
                # all registers invalid
                    initobj panda.Object.ctor
                    sta.obj v1
                    movi.64 v2, 0
                    ldai 0
          - values:
              - |
                # v1 and v2 invalid
                    lda.str "test string"
                    sta.obj v1
                    fmovi.64 v2, 1
                    initobj panda.Object.ctor
          - values:
              - |
                # v1 and acc invalid
                    lda.type panda.Object
                    sta.obj v1
                    movi v2, 0
                    fldai.64 0
          - values:
              - |
                # v2 and acc invalid
                    movi v0, 1
                    newarr v1, v0, A[]
                    sta.obj v2
                    ldai 0


      - file-name: "store_arr_p"
        isa:
          instructions:
            - sig: starr.obj v1:in:ref[], v2:in:i32
              acc: in:ref
              format: [op_v1_4_v2_4]
        description: Check starr.obj stores items to array of different size and type in Panda Assembly context.
        header-template: []
        code-template: |
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.String <external>
          .record panda.Class <external>
          .function i32 main() {
              movi v0, *s
              newarr v1, v0, %s
              movi v2, *s
              %s
              starr.obj v1, v2
        check-type: exit-positive
        template-cases:
          - values: ['A[]', 'initobj A.ctor']
          - values: ['panda.Class[]', 'lda.type A']
          - values: ['panda.String[]', 'lda.str "test string"']
        cases:
          - values: ['1', '0']
          - values: ['255', '254']
            tags: ['tsan']
          - values: ['65536', '65535']


      - file-name: "store_arr_j"
        isa:
          instructions:
            - sig: starr.obj v1:in:ref[], v2:in:i32
              acc: in:ref
              format: [op_v1_4_v2_4]
        description: Check starr.obj stores items to array of different size and type in PandaAssembly context.
        runner-options: ['use-pa']
        bugid: ['3227']
        header-template: [PandaAssembly]
        code-template: |
          .record A {}
          .function void A.ctor(A a0) <ctor> {
              return.void
          }
          .record panda.String <external>
          .record panda.Object <external>
          .function void panda.Object.ctor(panda.Object a0) <external,ctor>
          .function i32 main() {
              movi v0, *s
              newarr v1, v0, %s
              movi v2, *s
              %s
              starr.obj v1, v2
        check-type: exit-positive
        template-cases:
          - values: ['A[]', 'initobj A.ctor']
          - values: ['panda.Object[]', 'initobj panda.Object.ctor']
          - values: ['panda.String[]', 'lda.str "test string"']
        cases:
          - values: ['1', '0']
          - values: ['255', '254']
          - values: ['65536', '65535']
            tags: ['tsan']


      - file-name: "store_all_values_p"
        isa:
          description: >
            Store accumulator content into array slot pointed by index.
        description: Check starr.obj stores correct items into array of objects.
        header-template: []
        tags: ['irtoc_ignore']
        check-type: exit-positive
        code-template: |
            %s
            .function i32 main() {
                movi v7, *s
                newarr v1, v7, A[]      # v7 is array size          # v1 - testable array

                movi v2, 0          # v2 - index
            fill_array:
                lda v2
                initobj A.ctor, v2
                starr.obj v1, v2    # v1[v2] = acc
                inci v2, 1          # v2 = v2 + 1
                lda v2
                jne v7, fill_array

                movi v2, 0          # reset index
            check_array:
                lda v2
                ldarr.obj v1        # acc = v1[acc]
                sta.obj v3          # v3 = acc
                call.virt.short A.cmp, v3, v2
                jeqz ok
                ldai 1
                return
            ok:
                inci v2, 1
                lda v2
                jne v7, check_array
        template-cases:
          - values:
            - |
              #
              .record A {
                  i32 fi32
              }
              .function void A.ctor(A a0, i32 a1) <ctor> {
                  lda a1
                  stobj a0, A.fi32
                  return.void
              }
              .function i32 A.cmp(A a0, i32 a1) {
                  ldobj a0, A.fi32
                  jne a1, exit_failure
                  ldai 0
                  return
              exit_failure: ldai 1
                  return
              }
            tags: ['tsan']
          - values:
            - |
              #
              .record A {
                  A fA
              }
              .function void A.ctor(A a0, i32 a1) <ctor> {
                  lda.obj a0
                  stobj.obj a0, A.fA
                  return.void
              }
              .function i32 A.cmp(A a0, i32 a1) {
                  ldobj.obj a0, A.fA
                  jeq.obj a0, ret0
                  ldai 1
                  return
              ret0:
                  ldai 0
                  return
              }
        cases:
          - values:
            - 10000


      - file-name: "store_all_values_j"
        isa:
          description: >
            Store accumulator content into array slot pointed by index.
        description: Check starr.obj stores correct items into array of objects.
        runner-options: ['use-pa']
        header-template: [PandaAssembly]
        tags: ['irtoc_ignore']
        check-type: exit-positive
        code-template: |
            %s
            .function i32 main() {
                movi v7, *s
                newarr v1, v7, %s      # v7 is array size          # v1 - testable array

                movi v2, 0          # v2 - index
            fill_array:
                lda v2
                call.short create, v2
                starr.obj v1, v2    # v1[v2] = acc
                inci v2, 1          # v2 = v2 + 1
                lda v2
                jne v7, fill_array

                movi v2, 0          # reset index
            check_array:
                lda v2
                ldarr.obj v1        # acc = v1[acc]
                sta.obj v3          # v3 = acc
                call.short compare, v2, v3
                jeqz ok
                ldai 1
                return
            ok:
                inci v2, 1
                lda v2
                jne v7, check_array
        template-cases:
          - values:
            - |
              #
              .record panda.Long <external>
              .function void panda.Long.ctor(panda.Long a0, i64 a1) <external,ctor>
              .function i64 panda.Long.longValue(panda.Long a0) <external>
              .function panda.Long create(i32 a0) <static> {
                  lda a0
                  i32toi64
                  sta.64 v0
                  initobj panda.Long.ctor, v0
                  return.obj
              }
              .function i32 compare(i32 a0, panda.Long a1) <static> {
                  call.virt.short panda.Long.longValue, a1
                  i64toi32
                  jne a0, exit_failure
                  ldai 0
                  return
              exit_failure: ldai 1
                  return
              }
            - panda.Long[]
            tags: ['tsan']
          - values:
            - |
              #
              .record panda.Integer <external>
              .function void panda.Integer.ctor(panda.Integer a0, i32 a1) <external,ctor>
              .function i32 panda.Integer.intValue(panda.Integer a0) <external>
              .function panda.Integer[] create(i32 a0) <static> {
                  movi v0, 1
                  newarr v1, v0, panda.Integer[]
                  initobj panda.Integer.ctor, a0
                  movi v2, 0
                  starr.obj v1, v2
                  lda.obj v1
                  return.obj
              }
              .function i32 compare(i32 a0, panda.Integer[] a1) <static> {
                  ldai 0
                  ldarr.obj a1
                  sta.obj v0
                  call.virt.short panda.Integer.intValue, v0
                  jne a0, exit_failure
                  ldai 0
                  return
              exit_failure: ldai 1
                  return
              }
            - panda.Integer[][]
            bugid: ['3348']
        cases:
          - values:
            - 5000


      - file-name: "store_different_type_values_p"
        isa:
          description: >
            Store accumulator content into array slot pointed by index.
        description: Check starr.obj stores correct items with various types to array of objects.
        header-template: []
        check-type: exit-positive
        code-template: |
            %s
            .function i32 main() {
                movi v7, 1
                newarr v1, v7, %s          # v1 - testable array
                movi v2, 0          # v2 - index = 0

            check_null:
                lda v2
                ldarr.obj v1        # acc = v1[acc]
                jeqz.obj fill_array
                ldai 1
                return

            fill_array:
                %s
                sta.obj v10         # v10 - saved object ref
                starr.obj v1, v2    # v1[v2] = acc

            check_ref:
                lda v2
                ldarr.obj v1        # acc = v1[acc]
                jeq.obj v10, ok
                ldai 2
                return
            ok:
        cases:
          - values:
            - .record A {}
            - A[]
            - lda.null
          - values:
            - |
                  .record A {}
                  .function void A.ctor(A a0) <ctor> {
                    return.void
                  }
            - A[]
            - initobj A.ctor
            tags: ['tsan']
          - values:
            - |
                  .record panda.Class <external>
                  .record A {}
            - panda.Class[]
            - lda.type A
          - values:
            - .record panda.String <external>
            - panda.String[]
            - lda.str "test string"
          - values:
            - |
                  .record panda.Object <external>
                  .record A {}
                  .function void A.ctor(A a0) <ctor> {
                    return.void
                  }
            - panda.Object[]
            - initobj A.ctor
            tags: ['tsan']
          - values:
            - .record A {}
            - A[][]
            - |
              #
                  movi v4, 10
                  newarr v4, v4, A[]
                  lda.obj v4


      - file-name: "store_different_type_values_j"
        isa:
          description: >
            Store accumulator content into array slot pointed by index.
        description: Check starr.obj stores correct items with various types to array of objects.
        header-template: [PandaAssembly]
        runner-options: [use-pa]
        check-type: exit-positive
        code-template: |
            %s
            .function i32 main() {
                movi v7, 1
                newarr v1, v7, %s          # v1 - testable array
                movi v2, 0          # v2 - index = 0

            check_null:
                lda v2
                ldarr.obj v1        # acc = v1[acc]
                jeqz.obj fill_array
                ldai 1
                return

            fill_array:
                %s
                sta.obj v10         # v10 - saved object ref
                starr.obj v1, v2    # v1[v2] = acc

            check_ref:
                lda v2
                ldarr.obj v1        # acc = v1[acc]
                jeq.obj v10, ok
                ldai 2
                return
            ok:
        cases:
          - values:
            - .record panda.Object <external>
            - panda.Object[]
            - lda.null
          - values:
            - |
                  .record panda.Long <external>
                  .function void panda.Long.ctor(panda.Long a0, i64 a1) <external,ctor>
            - panda.Long[]
            - |
              #
                  movi.64 v7, 0x7FFFFFFFFFFFFFFF
                  initobj panda.Long.ctor, v7
            tags: ['tsan']
          - values:
            - .record panda.Class <external>
            - panda.Class[]
            - lda.type panda.Class
          - values:
            - .record panda.Object <external>
            - panda.Object[]
            - lda.str "test string"
            tags: ['tsan']
          - values:
            - .record panda.String <external>
            - panda.String[][]
            - |
              #
                  movi v4, 10
                  newarr v4, v4, panda.String[]
                  lda.obj v4
            bugid: ['3348']