1# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14definitions: []
15tests:
16  - file-name: "jgez"
17    isa:
18      title: Conditional compared to zero jump
19      description: >
20        Transfer execution to an instruction at offset bytes
21        from the beginning of the current instruction
22        if signed 32-bit integer in accumulator compares with 0 as specified.
23        Offset is sign extended to the size of instruction address.
24      exceptions:
25        - x_none
26    commands:
27
28      - file-name: "op"
29        isa:
30          instructions:
31            - sig: jgez imm:i32
32              acc: in:i32
33              format: [op_imm_8, op_imm_16]
34        description: >
35          Check jump occurs or not occurs, depending on `acc < 0` condition
36          for forward, backward, or current cases.
37        code-template: |
38          #
39              %s
40        check-type: exit-positive
41        cases:
42          - values:
43            - |
44              # Check forward jump
45                  ldai 0
46                  jgez label
47                  ldai 255 ##*65536
48                  return  # should be jumped over
49              label:
50          - values:
51            - |
52              # Check backward jump
53                  jmp label2
54              label1:
55                  jmp label3
56                  ldai 255 ##*65536
57              label2:
58                  ldai 1
59                  jgez label1
60                  ldai 255
61                  return  # should be jummped over
62              label3:
63          - values:
64              - |
65                # Check jump to itself
66                    ldai -1
67                loop:
68                    jgez loop
69            bugid: ['3468']
70          - values:
71              - |
72                # Check jump to itself
73                    ldai 1
74                loop:
75                    jgez loop
76            runner-options: [compile-only]
77
78      - file-name: "op_bounds_1"
79        isa:
80          instructions:
81            - sig: jgez imm:i32
82              acc: in:i32
83              format: [op_imm_8, op_imm_16]
84        description: >
85          Check jump occurs or not occurs, depending on `acc > 0` condition
86          for forward and backward cases.
87        code-template: |
88          #
89              %s
90        check-type: none
91        cases:
92          - values:
93            - |
94              # Max forward jump for imm8, 2 + 124 + 1 = 127 bytes
95                  ldai 1
96                  jgez label    # 2-byte instruction
97                  ldai 1 ##*62
98                  return
99              label:
100                  ldai 0
101                  return
102          - values:
103            - |
104              # Max backward jump for imm8, 2 + 61*2 + 1 + 1 + 2 = 128 bytes
105                  jmp label2
106              label:
107                  ldai 61
108                  subi 1 ##*61
109                  return
110                  return
111              label2:
112                  ldai 1
113                  jgez label
114                  return
115          - values:
116            - |
117              # Max forward jump for imm16, 3 + 32760 + 4 = 32767 bytes
118                  ldai 1
119                  jgez label    # 3-byte instruction
120                  movi.64 v0, 0 ##*3276
121                  addi 3
122                  return
123                  return
124              label:
125                  ldai 0
126                  return
127          - values:
128            - |
129              # Max backward jump for imm16, 1 + 4 + 32760 + 1 + 2 = 32768 bytes
130                  jmp label2
131              label:
132                  ldai 0
133                  return
134                  ldai 1
135                  movi.64 v0, 0 ##*3276
136                  return
137              label2:
138                  ldai 1
139                  jgez label
140                  return
141
142      - file-name: "op_bounds_2"
143        isa:
144          instructions:
145            - sig: jgez imm:i32
146              acc: in:i32
147              format: [op_imm_8, op_imm_16]
148        description: >
149          Check jump occurs or not occurs, depending on `acc == 0` condition
150          for forward and backward cases.
151        code-template: |
152          #
153              %s
154        check-type: none
155        cases:
156          - values:
157            - |
158              # Max forward jump for imm8, 2 + 124 + 1 = 127 bytes
159                  ldai 0
160                  jgez label    # 2-byte instruction
161                  neg
162                  ldai 2 ##*62
163              label:
164                  return
165          - values:
166            - |
167              # Max backward jump for imm8, 1 + 2 + 61*2 + 1 + 2 = 128 bytes
168                  jmp label2
169              label:
170                  neg
171                  ldai 61
172                  subi 1 ##*61
173                  return
174              label2:
175                  ldai 0
176                  jgez label
177                  ldai 1
178                  return
179          - values:
180            - |
181              # Max forward jump for imm16, 3 + 32760 + 4 = 32767 bytes
182                  ldai 0
183                  jgez label    # 3-byte instruction
184                  movi.64 v0, 0 ##*3276
185                  ldai 1
186                  ldai 1
187              label:
188                  return
189          - values:
190            - |
191              # Max backward jump for imm16, 1 + 4 + 32760 + 1 + 2 = 32768 bytes
192                  jmp label2
193              label:
194                  return
195                  ldai 2
196                  ldai 2
197                  movi.64 v0, 0 ##*3276
198                  return
199              label2:
200                  ldai 0
201                  jgez label
202                  ldai 1
203                  return
204
205      - file-name: "vals"
206        isa:
207          instructions:
208            - sig: jgez imm:i32
209              acc: in:i32
210              format: [op_imm_8, op_imm_16]
211        description: >
212          Check jump not occurs if `acc < 0`
213          for different values in acc.
214        code-template: |
215          #
216              ldai %s
217              jgez label_bad
218              ldai *s
219              jgez label_good
220          label_bad:
221              ldai 255
222              return  # should be jumped over
223          label_good:
224        check-type: exit-positive
225        template-cases:
226          - values:
227              - "-1"
228            exclude: [one]
229          - values:
230              - "0x80000000"
231            exclude: [max]
232          - values:
233              - "0xFFFFFFFF"
234            exclude: [one]
235        cases:
236          - values:
237              - "1"
238            id: one
239          - values:
240              - "0x7FFFFFFF"
241            id: max
242
243      - file-name: "type"
244        isa:
245          instructions:
246            - sig: jgez imm:i32
247              acc: in:i32
248              format: [op_imm_8, op_imm_16]
249          verification:
250              - acc_type
251        description: >
252          Check `jgez` with invalid types in acc.
253        tags: ['verifier']
254        runner-options: ['verifier-failure', 'verifier-config']
255        header-template: []
256        code-template: |
257          #
258          .record A {}
259          .record panda.String <external>
260          .record panda.Object <external>
261          .function i32 main() {
262              %s
263              jgez label
264              ldai 255
265          label:
266        check-type: exit-positive
267        cases:
268          - values:
269              - lda.null
270          - values:
271              - ldai.64 0
272          - values:
273              - fldai 0
274          - values:
275              - fldai.64 0
276          - values:
277              - lda.type A
278          - values:
279              - lda.type A[]
280          - values:
281              - lda.type panda.String
282          - values:
283              - |
284                newobj v0, A
285                lda.obj v0
286          - values:
287              - |
288                newobj v0, panda.Object
289                lda.obj v0
290          - values:
291              - lda.str "0"
292          - values:
293              - |
294                #
295                    movi v0, 10
296                    newarr v0, v0, i32[]
297                    lda.obj v0
298
299      - file-name: "outside_function"
300        isa:
301          instructions:
302            - sig: jgez imm:i32
303              acc: in:i32
304              format: [op_imm_8, op_imm_16]
305          verification:
306            - branch_target
307        description: >
308          Branch target should point to a beginning
309          of an instruction of the same method.
310        runner-options: ['compile-failure']
311        header-template: []
312        code-template: |
313          #
314          .function i32 f() {
315          label:
316              ldai 255
317              return
318          }
319          .function i32 main() {
320              ldai 1
321              jgez label
322        check-type: exit-positive
323
324      - file-name: "outside_try_catch_p"
325        isa:
326          instructions:
327            - sig: jgez imm:i32
328              acc: in:i32
329              format: [op_imm_8, op_imm_16]
330        description: Jump outside try/catch block.
331        bugid: ['3425']
332        header-template: []
333        code-template: |
334          .record panda.ArithmeticException <external>
335          .function i32 main() {
336          begin:
337              ldai 1
338              jgez outside
339              newobj v0, panda.ArithmeticException
340              throw v0
341          end:
342              ldai 1
343              return
344          catch_ae:
345              ldai 2
346              return
347          .catch panda.ArithmeticException, begin, end, catch_ae
348              ldai 3
349              return
350          outside:
351        check-type: exit-positive
352
353      - file-name: "outside_try_catch_j"
354        isa:
355          instructions:
356            - sig: jgez imm:i32
357              acc: in:i32
358              format: [op_imm_8, op_imm_16]
359        description: Jump outside try/catch block.
360        bugid: ['3425']
361        header-template: []
362        runner-options: ['use-pa']
363        code-template: |
364          .language PandaAssembly
365          .record panda.NullPointerException <external>
366          .function i32 main() {
367          begin:
368              ldai 1
369              jgez outside
370              mov.null v0
371              throw v0
372          end:
373              ldai 1
374              return
375          catch_npe:
376              ldai 2
377              return
378          .catch panda.NullPointerException, begin, end, catch_npe
379              ldai 3
380              return
381          outside:
382        check-type: exit-positive
383
384      - file-name: uninitialized_regs
385        isa:
386          instructions:
387            - sig: jgez imm:i32
388              acc: in:i32
389              format: [op_imm_8, op_imm_16]
390        description: Check `jgez` with uninitialized acc.
391        tags: ['verifier']
392        runner-options: ['verifier-failure', 'verifier-config']
393        code-template: |
394          #
395          label:
396              jgez label
397        check-type: exit-positive
398
399      - file-name: "invalid_branch_target"
400        isa:
401          verification:
402            - branch_target
403        runner-options: [compile-failure]
404        description: Check 'jgez' instruction with invalid branch target.
405        header-template: []
406        code-template: |
407            .record R {}
408
409            .function void R.ctor(R a0) <ctor> {
410            lbl_ctor:
411                return.void
412            }
413
414            .function void R.cctor() <cctor> {
415            lbl_cctor:
416                return.void
417            }
418
419            .function i32 foo(i32 a0, i32 a1) <static> {
420                lda a0
421                jgez %s
422                return
423            }
424
425            .function i32 bar() <static> {
426            lbl_bar:
427                ldai 1
428                return
429            }
430
431            .function i32 main() {
432                movi v0, 0
433                movi v1, 1
434                call.short foo, v0, v1
435            lbl_main:
436        check-type: exit-positive
437        cases:
438          - values: ["main"]
439          - values: ["foo"]
440          - values: ["bar"]
441          - values: ["baz"]
442          - values: ["R"]
443          - values: ["lbl_main"]
444          - values: ["lbl_bar"]
445          - values: ["lbl_ctor"]
446          - values: ["lbl_cctor"]
447
448
449      - file-name: "prohibited_branch_target"
450        isa:
451          verification:
452            - branch_target
453        runner-options: ['verifier-failure', 'verifier-config']
454        tags: [verifier]
455        description: Check 'jgez' instruction with prohibited branch target.
456        header-template: []
457        code-template: |
458            .record E1 {}
459            .record E2 {}
460
461            .function i32 main() {
462                ldai 0
463                jgez %s
464
465            begin:
466                ldai 0
467                return
468            mid:
469                ldai 1
470                return
471            end:
472                ldai 2
473                return
474
475            catch_E1_begin:
476                ldai 3
477                return
478            catch_E1_mid:
479                ldai 4
480                return
481            catch_E1_end:
482                ldai 5
483                return
484
485            catch_E2_begin:
486                ldai 6
487                return
488            catch_E2_mid:
489                ldai 7
490                return
491            catch_E2_end:
492
493            quit:
494                ldai 8
495                return
496
497            .catch E1, begin, end, catch_E1_begin, catch_E1_end
498            .catch E2, catch_E1_begin, catch_E1_end, catch_E2_begin, catch_E2_end
499            outside:
500        check-type: none
501        cases:
502          - values: ["begin"]
503            runner-options: ['verifier-only', 'verifier-config']
504          - values: ["mid"]
505            runner-options: ['verifier-only', 'verifier-config']
506          - values: ["end"]
507            runner-options: ['verifier-only', 'verifier-config']
508          - values: ["quit"]
509            runner-options: ['verifier-only', 'verifier-config']
510          - values: ["catch_E1_begin"]
511          - values: ["catch_E1_mid"]
512          - values: ["catch_E1_end"]
513            runner-options: ['verifier-only', 'verifier-config']
514          - values: ["catch_E2_begin"]
515          - values: ["catch_E2_mid"]
516          - values: ["catch_E2_end"]
517            runner-options: ['verifier-only', 'verifier-config']
518          - values: ["outside"]
519