# 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.

tests:
  - file-name: "jle"
    isa:
      title: Conditional compared to register jump
      description: >
        Transfer execution to an instruction at offset bytes from the beginning of the current instruction if signed
        32-bit integers in accumulator and register compare as specified. Offset is sign extended to the size of
        instruction address.
      exceptions:
        - x_none
      instructions:
        - sig: jle v:in:i32, imm:i32
          acc: in:i32
          format: [op_v_8_imm_8, op_v_8_imm_16]
    commands:

      - file-name: "invalid_v_reg"
        isa:
          verification:
            - v1_type
        runner-options: [compile-failure]
        description: Check 'jle' instruction with invalid 'v' register.
        header-template: []
        code-template: |
            .function i32 main() {
                jle %s
            lbl:
        check-type: exit-positive
        cases:
          - values: ["v256, lbl"]
          - values: ["v65535, lbl"]
          - values: ["v65536, lbl"]
          - values: ["a0, lbl"]
          - values: ["a256, lbl"]
          - values: ["a65535, lbl"]
          - values: ["lbl"]
          - values: [""]
          - values: ["}"]
          - values: ["# v1, lbl"]
          - values: ["V1, lbl"]
          - values: ["v1, Lbl"]


      - file-name: "invalid_a_reg"
        isa:
          verification:
            - v1_type
        runner-options: [compile-failure]
        description: Check 'jle' instruction with invalid 'a' register.
        header-template: []
        code-template: |
            .function void foo(i32 a0, i32 a1, i32 a2, i32 a3, i32 a4, i32 a5) <static> {
                jle %s
            lbl:
                return.void
            }
            .function i32 main() {
                call.range foo, v0
        check-type: exit-positive
        cases:
          - values: ["v256, lbl"]
          - values: ["v65535, lbl"]
          - values: ["v65536, lbl"]
          - values: ["a6, lbl"]
          - values: ["a256, lbl"]
          - values: ["a65535, lbl"]
          - values: ["lbl"]
          - values: [""]
          - values: ["}"]
          - values: ["# a1, lbl"]
          - values: ["A1, lbl"]
          - values: ["a1, Lbl"]


      - file-name: "valid_v_reg"
        isa:
          verification:
            - v1_type
          instructions:
            - sig: jle v:in:i32, imm:i32
              acc: in:i32
              format: [op_v_8_imm_8, op_v_8_imm_16]
        description: Check 'jle' instruction with valid 'v' register.
        header-template: []
        code-template: |
            .function i32 main() {
                movi %s, 2
                ldai 2
                jle %s, lbl
                ldai 1
                return
            lbl:
        check-type: exit-positive
        cases:
          - values: ["v0", "v0"]
          - values: ["v7", "v7"]
          - values: ["v8", "v8"]
          - values: ["v15", "v15"]
          - values: ["v16", "v16"]
          - values: ["v254", "v254"]
          - values: ["v255", "v255"]
            tags: [tsan]


      - file-name: "valid_a_reg"
        isa:
          verification:
            - v1_type
          instructions:
            - sig: jle v:in:i32, imm:i32
              acc: in:i32
              format: [op_v_8_imm_8, op_v_8_imm_16]
        description: Check 'jle' instruction with valid 'a' register.
        header-template: []
        code-template: |
            .function i32 foo(%s) <static> {
                ldai 2
                jle %s, lbl
                ldai 1
                return
            lbl:
                ldai 0
                return
            }
            .function i32 main() {
            %s
                call.range foo, v0
        check-type: no-check
        cases:
          - values:
            - i32 a0
            - a0
            - |
              #
                  movi v0, 2
          - values:
            - i16 a0, i32 a1
            - a1
            - |
              #
                  movi v0, 2
                  movi v1, 3
            tags: [tsan]
          - values:
            - "#{[*0..255].map do |i| \" i32 a#{i}\" end .join(\",\")}"
            - a254
            - "#{[*0..255].map do |i| \"    movi v#{i}, #{i}\\n\" end .join}"
            bugid: ['3855']
          - values:
            - "#{[*0..255].map do |i| \" i32 a#{i}\" end .join(\",\")}"
            - a255
            - "#{[*0..255].map do |i| \"    movi v#{i}, #{i}\\n\" end .join}"
            bugid: ['3855']


      - file-name: "uninitialized_regs"
        isa:
          verification:
            - acc_type
            - v1_type
        runner-options: ['verifier-failure', 'verifier-config']
        tags: [verifier]
        description: Check 'jle' instruction with uninitialized registers.
        header-template: []
        code-template: |
            .function i32 main() {
                %s
                jle v1, lbl
                ldai 1
                return
            lbl:
        check-type: exit-positive
        cases:
          - description: Accumulator is not initialized.
            values:
              - movi v1, 1
          - description: V register is not initialized.
            values:
              - ldai 1
          - description: Accumulator and 'v' register are both not initialized.
            values:
              - ""


      - file-name: "invalid_branch_target"
        isa:
          verification:
            - branch_target
        runner-options: [compile-failure]
        description: Check 'jle' instruction with invalid branch target.
        header-template: []
        code-template: |
            .record R {}

            .function void R.ctor(R a0) <ctor> {
            lbl_ctor:
                return.void
            }

            .function void R.cctor() <cctor> {
            lbl_cctor:
                return.void
            }

            .function i32 foo(i32 a0, i32 a1) <static> {
                lda a0
                jle a1, %s
                return
            }

            .function i32 bar() <static> {
            lbl_bar:
                ldai 1
                return
            }

            .function i32 main() {
                movi v0, 0
                movi v1, 1
                call.short foo, v0, v1
            lbl_main:
        check-type: exit-positive
        cases:
          - values: ["main"]
          - values: ["foo"]
          - values: ["bar"]
          - values: ["baz"]
          - values: ["R"]
          - values: ["lbl_main"]
          - values: ["lbl_bar"]
          - values: ["lbl_ctor"]
          - values: ["lbl_cctor"]


      - file-name: "prohibited_branch_target"
        isa:
          verification:
            - branch_target
        runner-options: ['verifier-failure', 'verifier-config']
        tags: [verifier]
        description: Check 'jle' instruction with prohibited branch target.
        header-template: []
        code-template: |
            .record E1 {}
            .record E2 {}

            .function i32 main() {
                ldai 1
                movi v0, 1
                jle v0, %s

            begin:
                ldai 0
                return
            mid:
                ldai 1
                return
            end:
                ldai 2
                return

            catch_E1_begin:
                ldai 3
                return
            catch_E1_mid:
                ldai 4
                return
            catch_E1_end:
                ldai 5
                return

            catch_E2_begin:
                ldai 6
                return
            catch_E2_mid:
                ldai 7
                return
            catch_E2_end:

            quit:
                ldai 8
                return

            .catch E1, begin, end, catch_E1_begin, catch_E1_end
            .catch E2, catch_E1_begin, catch_E1_end, catch_E2_begin, catch_E2_end
            outside:
        check-type: none
        cases:
          - values: ["begin"]
            runner-options: ['verifier-only', 'verifier-config']
          - values: ["mid"]
            runner-options: ['verifier-only', 'verifier-config']
          - values: ["end"]
            runner-options: ['verifier-only', 'verifier-config']
          - values: ["quit"]
            runner-options: ['verifier-only', 'verifier-config']
          - values: ["catch_E1_begin"]
          - values: ["catch_E1_mid"]
          - values: ["catch_E1_end"]
            runner-options: ['verifier-only', 'verifier-config']
          - values: ["catch_E2_begin"]
          - values: ["catch_E2_mid"]
          - values: ["catch_E2_end"]
            runner-options: ['verifier-only', 'verifier-config']
          - values: ["outside"]


      - file-name: "invalid_acc_value"
        isa:
          verification:
            - acc_type
        runner-options: ['verifier-failure', 'verifier-config']
        tags: [verifier]
        description: Check 'jle' instruction with invalid accumulator value
        header-template: []
        code-template: |
            .record panda.Object <external>
            .record panda.String <external>
            .record panda.Class <external>
            .record R {}
            .function void R.ctor(R a0) <ctor> {
                return.void
            }
            .function i32 main() {
                %s
                movi v1, 1
                jle v1, ok
                ldai 1
                return
            ok:
        check-type: exit-positive
        cases:
          - values:
            - lda.null
          - values:
            - initobj R.ctor
          - values:
            - lda.str "test"
          - values:
            - lda.type panda.Object
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, i32[]
                  lda.obj v0
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, f64[]
                  lda.obj v0
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, R[]
                  lda.obj v0
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, panda.Class[][]
                  lda.obj v0
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, panda.String[]
                  lda.obj v0
          - values:
            - ldai.64 0
          - values:
            - ldai.64 1
          - values:
            - ldai.64 0x7fffffffffffffff
          - values:
            - ldai.64 0xffffffffffffffff
          - values:
            - ldai.64 0x8000000000000000
          - values:
            - |
              #
                  fldai 0x00000000 # Positive zero (+0.0)
          - values:
            - |
              #
                  fldai 0x80000000 # Negative zero (-0.0)
          - values:
            - |
              #
                  fldai 0x00000001 # Minimal positive value (1.4012985e-45)
          - values:
            - |
              #
                  fldai 0x80000001 # Maximal negative value (-1.4012985e-45)
          - values:
            - |
              #
                  fldai 0x7f7fffff # Maximal positive value (3.4028235e38)
          - values:
            - |
              #
                  fldai 0xff7fffff # Minimal negative value (-3.4028235e38)
          - values:
            - |
              #
                  fldai 0x7f800000 # Positive infinity
          - values:
            - |
              #
                  fldai 0xff800000 # Negative infinity
          - values:
            - |
              #
                  fldai 0x7fc00000 # NaN
          - values:
            - |
              #
                  fldai.64 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`)
          - values:
            - |
              #
                  fldai.64 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`)
          - values:
            - |
              #
                  fldai.64 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`)
          - values:
            - |
              #
                  fldai.64 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`)
          - values:
            - |
              #
                  fldai.64 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`)
          - values:
            - |
              #
                  fldai.64 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`)
          - values:
            - |
              #
                  fldai.64 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`)
          - values:
            - |
              #
                  fldai.64 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`)
          - values:
            - |
              #
                  fldai.64 0x7ff8000000000000 # NaN


      - file-name: "invalid_v_value"
        isa:
          verification:
            - v1_type
        runner-options: ['verifier-failure', 'verifier-config']
        tags: [verifier]
        description: Check 'jle' instruction with invalid v register value
        header-template: []
        code-template: |
            .record panda.Object <external>
            .record panda.String <external>
            .record panda.Class <external>
            .record R {}
            .function void R.ctor(R a0) <ctor> {
                return.void
            }
            .function i32 main() {
                %s
                ldai 1
                jle v1, ok
                ldai 1
                return
            ok:
        check-type: exit-positive
        cases:
          - values:
            - mov.null v1
          - values:
            - |
              #
                  initobj R.ctor
                  sta.obj v1
          - values:
            - |
              #
                  lda.str "test"
                  sta.obj v1
          - values:
            - |
              #
                  lda.type panda.Object
                  sta.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, i32[]
                  lda.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, f64[]
                  lda.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, R[]
                  lda.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, panda.Class[][]
                  lda.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, panda.String[]
                  lda.obj v1
          - values:
            - movi.64 v1, 0
          - values:
            - movi.64 v1, 1
          - values:
            - movi.64 v1, 0x7fffffffffffffff
          - values:
            - movi.64 v1, 0xffffffffffffffff
          - values:
            - movi.64 v1, 0x8000000000000000
          - values:
            - |
              #
                  fmovi v1, 0x00000000 # Positive zero (+0.0)
          - values:
            - |
              #
                  fmovi v1, 0x80000000 # Negative zero (-0.0)
          - values:
            - |
              #
                  fmovi v1, 0x00000001 # Minimal positive value (1.4012985e-45)
          - values:
            - |
              #
                  fmovi v1, 0x80000001 # Maximal negative value (-1.4012985e-45)
          - values:
            - |
              #
                  fmovi v1, 0x7f7fffff # Maximal positive value (3.4028235e38)
          - values:
            - |
              #
                  fmovi v1, 0xff7fffff # Minimal negative value (-3.4028235e38)
          - values:
            - |
              #
                  fmovi v1, 0x7f800000 # Positive infinity
          - values:
            - |
              #
                  fmovi v1, 0xff800000 # Negative infinity
          - values:
            - |
              #
                  fmovi v1, 0x7fc00000 # NaN
          - values:
            - |
              #
                  fmovi.64 v1, 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`)
          - values:
            - |
              #
                  fmovi.64 v1, 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`)
          - values:
            - |
              #
                  fmovi.64 v1, 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x7ff8000000000000 # NaN


      - file-name: "invalid_both_acc_and_v_value"
        isa:
          verification:
            - v1_type
            - acc_type
        runner-options: ['verifier-failure', 'verifier-config']
        tags: [verifier]
        description: Check 'jle' instruction with invalid accumulator and v register value
        header-template: []
        code-template: |
            .record panda.Object <external>
            .record panda.String <external>
            .record panda.Class <external>
            .record R {}
            .function void R.ctor(R a0) <ctor> {
                return.void
            }
            .function i32 main() {
                *s
                %s
                jle v1, ok
                ldai 1
                return
            ok:
        check-type: exit-positive
        template-cases:
          - values:
            - lda.null
          - values:
            - initobj R.ctor
          - values:
            - lda.str "test"
          - values:
            - lda.type panda.Object
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, i32[]
                  lda.obj v0
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, f64[]
                  lda.obj v0
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, R[]
                  lda.obj v0
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, panda.Class[][]
                  lda.obj v0
          - values:
            - |
              #
                  movi v0, 10
                  newarr v0, v0, panda.String[]
                  lda.obj v0
          - values:
            - ldai.64 0
          - values:
            - ldai.64 1
          - values:
            - ldai.64 0x7fffffffffffffff
          - values:
            - ldai.64 0xffffffffffffffff
          - values:
            - ldai.64 0x8000000000000000
          - values:
            - |
              #
                  fldai 0x00000000 # Positive zero (+0.0)
          - values:
            - |
              #
                  fldai 0x80000000 # Negative zero (-0.0)
          - values:
            - |
              #
                  fldai 0x00000001 # Minimal positive value (1.4012985e-45)
          - values:
            - |
              #
                  fldai 0x80000001 # Maximal negative value (-1.4012985e-45)
          - values:
            - |
              #
                  fldai 0x7f7fffff # Maximal positive value (3.4028235e38)
          - values:
            - |
              #
                  fldai 0xff7fffff # Minimal negative value (-3.4028235e38)
          - values:
            - |
              #
                  fldai 0x7f800000 # Positive infinity
          - values:
            - |
              #
                  fldai 0xff800000 # Negative infinity
          - values:
            - |
              #
                  fldai 0x7fc00000 # NaN
          - values:
            - |
              #
                  fldai.64 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`)
          - values:
            - |
              #
                  fldai.64 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`)
          - values:
            - |
              #
                  fldai.64 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`)
          - values:
            - |
              #
                  fldai.64 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`)
          - values:
            - |
              #
                  fldai.64 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`)
          - values:
            - |
              #
                  fldai.64 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`)
          - values:
            - |
              #
                  fldai.64 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`)
          - values:
            - |
              #
                  fldai.64 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`)
          - values:
            - |
              #
                  fldai.64 0x7ff8000000000000 # NaN
        cases:
          - values:
            - mov.null v1
          - values:
            - |
              #
                  initobj R.ctor
                  sta.obj v1
          - values:
            - |
              #
                  lda.str "test"
                  sta.obj v1
          - values:
            - |
              #
                  lda.type panda.Object
                  sta.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, i32[]
                  lda.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, f64[]
                  lda.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, R[]
                  lda.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, panda.Class[][]
                  lda.obj v1
          - values:
            - |
              #
                  movi v0, 10
                  newarr v1, v0, panda.String[]
                  lda.obj v1
          - values:
            - movi.64 v1, 0
          - values:
            - movi.64 v1, 1
          - values:
            - movi.64 v1, 0x7fffffffffffffff
          - values:
            - movi.64 v1, 0xffffffffffffffff
          - values:
            - movi.64 v1, 0x8000000000000000
          - values:
            - |
              #
                  fmovi v1, 0x00000000 # Positive zero (+0.0)
          - values:
            - |
              #
                  fmovi v1, 0x80000000 # Negative zero (-0.0)
          - values:
            - |
              #
                  fmovi v1, 0x00000001 # Minimal positive value (1.4012985e-45)
          - values:
            - |
              #
                  fmovi v1, 0x80000001 # Maximal negative value (-1.4012985e-45)
          - values:
            - |
              #
                  fmovi v1, 0x7f7fffff # Maximal positive value (3.4028235e38)
          - values:
            - |
              #
                  fmovi v1, 0xff7fffff # Minimal negative value (-3.4028235e38)
          - values:
            - |
              #
                  fmovi v1, 0x7f800000 # Positive infinity
          - values:
            - |
              #
                  fmovi v1, 0xff800000 # Negative infinity
          - values:
            - |
              #
                  fmovi v1, 0x7fc00000 # NaN
          - values:
            - |
              #
                  fmovi.64 v1, 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`)
          - values:
            - |
              #
                  fmovi.64 v1, 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`)
          - values:
            - |
              #
                  fmovi.64 v1, 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`)
          - values:
            - |
              #
                  fmovi.64 v1, 0x7ff8000000000000 # NaN


      - file-name: "valid_values"
        isa:
          description: >
            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if signed
            32-bit integers in accumulator and register compare as specified. Offset is sign extended to the size of
            instruction address.
        description: Check 'jle' instruction with valid values in registers.
        header-template: []
        code-template: |
            .function i32 main() {
                ldai %s
                movi v1, %s
                jle v1, lbl
                ldai %s
                return
            lbl:
                ldai %s
        check-type: no-check
        cases:
          - values: [-2147483648, -2147483648, 1, 0]
          - values: [-2147483648, -1, 1, 0]
          - values: [-2147483648, 0, 1, 0]
          - values: [-2147483648, 1, 1, 0]
          - values: [-2147483648, 2147483647, 1, 0]

          - values: [-1, -2147483648, 0, 1]
          - values: [-1, -1, 1, 0]
          - values: [-1, 0, 1, 0]
          - values: [-1, 1, 1, 0]
          - values: [-1, 2147483647, 1, 0]

          - values: [0, -2147483648, 0, 1]
          - values: [0, -1, 0, 1]
          - values: [0, 0, 1, 0]
          - values: [0, 1, 1, 0]
          - values: [0, 2147483647, 1, 0]

          - values: [1, -2147483648, 0, 1]
          - values: [1, -1, 0, 1]
          - values: [1, 0, 0, 1]
          - values: [1, 1, 1, 0]
          - values: [1, 2147483647, 1, 0]

          - values: [2147483647, -2147483648, 0, 1]
          - values: [2147483647, -1, 0, 1]
          - values: [2147483647, 0, 0, 1]
          - values: [2147483647, 1, 0, 1]
          - values: [2147483647, 2147483647, 1, 0]


      - file-name: "valid_offset_values"
        isa:
          description: >
            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if signed
            32-bit integers in accumulator and register compare as specified. Offset is sign extended to the size of
            instruction address.
        description: Check 'jle' instruction with valid offset values.
        header-template: []
        code-template: |
            .function i32 main() {
                ldai 1
                movi v1, 2
                %s
                ldai 1      # 2-byte instruction
                return      # 1-byte instruction
            quit:
        check-type: exit-positive
        cases:
          - description: Same instruction jump, offset imm8, 0 bytes
            values:
              - |
                #
                    ldai 10
                lbl:
                    jle v1, lbl
                    ldai 0
                    return
            tags: [tsan]
            bugid: ['3828']
          - description: Max forward jump for imm8, 3 + 120 + 1 + 3 = 127 bytes
            values:
              - |
                #
                    jle v1, quit      # 3-byte instruction
                    movi.64 v0, 0 ##*12
                    neg               # 1-byte instruction
            tags: [tsan]
          - description: Max backward jump for imm8, 3 + 120 + 2 + 2 + 1 = 128 bytes
            values:
              - |
                #
                    jmp lbl2
                lbl1:
                    jmp quit      # 3-byte instruction
                    movi.64 v0, 0 ##*12
                    ldai 1        # 2-byte instruction
                    ldai 1        # 2-byte instruction
                    return        # 1-byte instruction
                lbl2:
                    jle v1, lbl1
          - description: Max forward jump for imm16, 32760 + 4 + 3 = 32767 bytes
            values:
              - |
                #
                    jle v1, quit      # 4-byte instruction
                    movi.64 v0, 0 ##*3276
          - description: Beyond max forward jump for imm16, 40000 + 4 + 3 = 40007 bytes. Converted to jgt + jmp by compiler.
            values:
              - |
                #
                    jle v1, quit      # 4-byte instruction
                    movi.64 v0, 0 ##*4000
          - description: Max backward jump for imm16, 5 + 32760 + 3 = 32768 bytes
            values:
              - |
                #
                    jmp lbl2
                lbl1:
                    jmp quit              # 5-byte instruction
                    movi.64 v0, 0 ##*3276
                    ldai 1
                    return
                lbl2:
                    jle v1, lbl1
          - description: Beyond max backward jump for imm16, 5 + 40000 = 40005 bytes. Converted to jgt + jmp by compiler.
            values:
              - |
                #
                    jmp lbl2
                lbl1:
                    jmp quit              # 5-byte instruction
                    movi.64 v0, 0 ##*4000
                    ldai 1
                    return
                lbl2:
                    jle v1, lbl1
          - description: Chain of forward jumps
            values:
              - |
                #
                    jle v1, lbl1
                    ldai 2
                    return
                lbl1:
                    jle v1, lbl2
                    ldai 3
                    return
                lbl2:
                    jle v1, lbl3
                    ldai 4
                    return
                lbl3:
                    jle v1, lbl4
                    ldai 5
                    return
                lbl4:
                    jle v1, quit
            tags: [tsan]
          - description: Chain of backward jumps
            values:
              - |
                #
                    jmp lbl1
                lbl6:
                    jmp quit
                lbl5:
                    jle v1, lbl6
                    ldai 5
                    return
                lbl4:
                    jle v1, lbl5
                    ldai 4
                    return
                lbl3:
                    jle v1, lbl4
                    ldai 3
                    return
                lbl2:
                    jle v1, lbl3
                    ldai 2
                    return
                lbl1:
                    jle v1, lbl2
            tags: [tsan]