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:
15  - name: PandaAssembly
16    template: |
17      .language PandaAssembly
18
19tests:
20  - file-name: "jnez.obj"
21    isa:
22      title: Conditional compared to null jump
23      description: >
24        Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
25        object reference in accumulator compares with null as specified. Offset is sign extended to the size of
26        instruction address.
27      exceptions:
28        - x_none
29      instructions:
30        - sig: jnez.obj imm:i32
31          acc: in:ref
32          format: [op_imm_8, op_imm_16]
33    commands:
34
35      - file-name: "invalid_offset"
36        isa:
37          verification:
38            - branch_target
39          instructions:
40            - sig: jnez.obj imm:i32
41              acc: in:ref
42              format: [op_imm_8, op_imm_16]
43        runner-options: [compile-failure]
44        description: Check 'jnez.obj' instruction with invalid offset.
45        header-template: []
46        code-template: |
47            .function i32 main() {
48                jnez.obj %s
49            lbl:
50        check-type: exit-positive
51        cases:
52          - values: [""]
53          - values: ["main"]
54          - values: ["v1"]
55          - values: ["v1, lbl"]
56          - values: ["}"]
57          - values: ["# lbl"]
58          - values: ["Lbl"]
59          - values: ["LBL"]
60
61
62      - file-name: "uninitialized_acc"
63        isa:
64          verification:
65            - acc_obj_or_null
66        runner-options: ['verifier-failure', 'verifier-config']
67        tags: [verifier]
68        description: Check 'jnez.obj' instruction with uninitialized accumulator.
69        header-template: []
70        code-template: |
71            .function i32 main() {
72                jnez.obj lbl
73                ldai 1
74                return
75            lbl:
76        check-type: exit-positive
77
78
79      - file-name: "invalid_branch_target"
80        isa:
81          verification:
82            - branch_target
83        runner-options: [compile-failure]
84        description: Check 'jnez.obj' instruction with invalid branch target.
85        header-template: []
86        code-template: |
87            .record R {}
88
89            .function void R.ctor(R a0) <ctor> {
90            lbl_ctor:
91                return.void
92            }
93
94            .function void R.cctor() <cctor> {
95            lbl_cctor:
96                return.void
97            }
98
99            .function i32 foo() <static> {
100                lda.null
101                jnez.obj %s
102            }
103
104            .function i32 bar() <static> {
105            lbl_bar:
106                ldai 1
107                return
108            }
109
110            .function i32 main() {
111                call.short foo
112            lbl_main:
113        check-type: exit-positive
114        cases:
115          - values: ["main"]
116          - values: ["foo"]
117          - values: ["bar"]
118          - values: ["baz"]
119          - values: ["R"]
120          - values: ["lbl_main"]
121          - values: ["lbl_bar"]
122          - values: ["lbl_ctor"]
123          - values: ["lbl_cctor"]
124
125
126      - file-name: "prohibited_branch_target_p"
127        isa:
128          verification:
129            - branch_target
130        runner-options: ['verifier-failure', 'verifier-config']
131        tags: [verifier]
132        description: Check 'jnez.obj' instruction with prohibited branch target in PandaAssembly context.
133        header-template: []
134        code-template: |
135            .record E1 {}
136            .record E2 {}
137            .record R {}
138
139            .function void R.ctor(R a0) <ctor> {
140                return.void
141            }
142
143            .function i32 main() {
144                initobj R.ctor
145                jnez.obj %s
146
147            begin:
148                ldai 0
149                return
150            mid:
151                ldai 1
152                return
153            end:
154                ldai 2
155                return
156
157            catch_E1_begin:
158                ldai 3
159                return
160            catch_E1_mid:
161                ldai 4
162                return
163            catch_E1_end:
164                ldai 5
165                return
166
167            catch_E2_begin:
168                ldai 6
169                return
170            catch_E2_mid:
171                ldai 7
172                return
173            catch_E2_end:
174
175            quit:
176                ldai 8
177                return
178
179            .catch E1, begin, end, catch_E1_begin, catch_E1_end
180            .catch E2, catch_E1_begin, catch_E1_end, catch_E2_begin, catch_E2_end
181            outside:
182        check-type: none
183        cases:
184          - values: ["begin"]
185            runner-options: ['verifier-only', 'verifier-config']
186          - values: ["mid"]
187            runner-options: ['verifier-only', 'verifier-config']
188          - values: ["end"]
189            runner-options: ['verifier-only', 'verifier-config']
190          - values: ["quit"]
191            runner-options: ['verifier-only', 'verifier-config']
192          - values: ["catch_E1_begin"]
193          - values: ["catch_E1_mid"]
194          - values: ["catch_E1_end"]
195            runner-options: ['verifier-only', 'verifier-config']
196          - values: ["catch_E2_begin"]
197          - values: ["catch_E2_mid"]
198          - values: ["catch_E2_end"]
199            runner-options: ['verifier-only', 'verifier-config']
200          - values: ["outside"]
201
202
203      - file-name: "prohibited_branch_target_j"
204        isa:
205          verification:
206            - branch_target
207        runner-options: [verifier-failure, use-pa, verifier-config]
208        tags: [verifier, pa-verifier]
209        description: Check 'jnez.obj' instruction with prohibited branch target in PandaAssembly context.
210        header-template: [PandaAssembly]
211        code-template: |
212            .record panda.NullPointerException <external>
213            .record panda.Exception <external>
214
215            .function i32 main() {
216                lda.str "test"
217                jnez.obj %s
218
219            begin:
220                ldai 0
221                return
222            mid:
223                ldai 1
224                return
225            end:
226                ldai 2
227                return
228
229            catch_NPE_begin:
230                ldai 3
231                return
232            catch_NPE_mid:
233                ldai 4
234                return
235            catch_NPE_end:
236                ldai 5
237                return
238
239            catch_E_begin:
240                ldai 6
241                return
242            catch_E_mid:
243                ldai 7
244                return
245            catch_E_end:
246
247            quit:
248                ldai 8
249                return
250
251            .catch panda.NullPointerException, begin, end, catch_NPE_begin, catch_NPE_end
252            .catch panda.Exception, catch_NPE_begin, catch_NPE_end, catch_E_begin, catch_E_end
253            outside:
254        check-type: none
255        cases:
256          - values: ["begin"]
257            runner-options: [verifier-only, use-pa, verifier-config]
258          - values: ["mid"]
259            runner-options: [verifier-only, use-pa, verifier-config]
260          - values: ["end"]
261            runner-options: [verifier-only, use-pa, verifier-config]
262          - values: ["quit"]
263            runner-options: [verifier-only, use-pa, verifier-config]
264          - values: ["catch_NPE_begin"]
265          - values: ["catch_NPE_mid"]
266          - values: ["catch_NPE_end"]
267            runner-options: [verifier-only, use-pa, verifier-config]
268          - values: ["catch_E_begin"]
269          - values: ["catch_E_mid"]
270          - values: ["catch_E_end"]
271            runner-options: [verifier-only, use-pa, verifier-config]
272          - values: ["outside"]
273
274
275      - file-name: "invalid_acc_value"
276        isa:
277          verification:
278            - acc_obj_or_null
279        runner-options: ['verifier-failure', 'verifier-config']
280        tags: [verifier]
281        description: Check 'jnez.obj' instruction with invalid accumulator value
282        header-template: []
283        code-template: |
284            .function i32 main() {
285                %s
286                jnez.obj ok
287                ldai 1
288                return
289            ok:
290        check-type: exit-positive
291        cases:
292          - values:
293            - ldai 0
294          - values:
295            - ldai 1
296          - values:
297            - ldai 0x7fffffff
298          - values:
299            - ldai 0xffffffff
300          - values:
301            - ldai 0x80000000
302          - values:
303            - ldai.64 0
304          - values:
305            - ldai.64 1
306          - values:
307            - ldai.64 0x7fffffffffffffff
308          - values:
309            - ldai.64 0xffffffffffffffff
310          - values:
311            - ldai.64 0x8000000000000000
312          - values:
313            - |
314              #
315                  fldai 0x00000000 # Positive zero (+0.0)
316          - values:
317            - |
318              #
319                  fldai 0x80000000 # Negative zero (-0.0)
320          - values:
321            - |
322              #
323                  fldai 0x00000001 # Minimal positive value (1.4012985e-45)
324          - values:
325            - |
326              #
327                  fldai 0x80000001 # Maximal negative value (-1.4012985e-45)
328          - values:
329            - |
330              #
331                  fldai 0x7f7fffff # Maximal positive value (3.4028235e38)
332          - values:
333            - |
334              #
335                  fldai 0xff7fffff # Minimal negative value (-3.4028235e38)
336          - values:
337            - |
338              #
339                  fldai 0x7f800000 # Positive infinity
340          - values:
341            - |
342              #
343                  fldai 0xff800000 # Negative infinity
344          - values:
345            - |
346              #
347                  fldai 0x7fc00000 # NaN
348          - values:
349            - |
350              #
351                  fldai.64 0x0000000000000000 # Positive zero (+0.0, hexadecimal representation is `0x0000000000000000`)
352          - values:
353            - |
354              #
355                  fldai.64 0x8000000000000000 # Negative zero (-0.0, hexadecimal representation is `0x8000000000000000`)
356          - values:
357            - |
358              #
359                  fldai.64 0x0000000000000001 # Minimal positive value (4.9E-324, hexadecimal representation is `0x0000000000000001`)
360          - values:
361            - |
362              #
363                  fldai.64 0x8000000000000001 # Maximal negative value (-4.9E-324, hexadecimal representation is `0x8000000000000001`)
364          - values:
365            - |
366              #
367                  fldai.64 0x7fefffffffffffff # Maximal positive value (1.7976931348623157e308, hexadecimal representation is `0x7fefffffffffffff`)
368          - values:
369            - |
370              #
371                  fldai.64 0xffefffffffffffff # Minimal negative value (-1.7976931348623157e308, hexadecimal representation is `0xffefffffffffffff`)
372          - values:
373            - |
374              #
375                  fldai.64 0x7ff0000000000000 # Positive infinity (hexadecimal representation is `0x7ff0000000000000`)
376          - values:
377            - |
378              #
379                  fldai.64 0xfff0000000000000 # Negative infinity (hexadecimal representation is `0xfff0000000000000`)
380          - values:
381            - |
382              #
383                  fldai.64 0x7ff8000000000000 # NaN
384
385
386      - file-name: "valid_null_value_p"
387        isa:
388          description: >
389            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
390            object reference in accumulator compares with null as specified. Offset is sign extended to the size of
391            instruction address.
392        description: Check 'jnez.obj' instruction with valid null value in PandaAssembly context.
393        header-template: []
394        tags: [tsan]
395        code-template: |
396            .function i32 main() {
397                lda.null
398                jnez.obj ng
399                ldai 0
400                return
401            ng:
402                ldai 1
403        check-type: no-check
404
405
406      - file-name: "valid_null_value_j"
407        isa:
408          description: >
409            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
410            object reference in accumulator compares with null as specified. Offset is sign extended to the size of
411            instruction address.
412        description: Check 'jnez.obj' instruction with valid null value in PandaAssembly context.
413        runner-options: [use-pa]
414        tags: ['tsan']
415        header-template: [PandaAssembly]
416        code-template: |
417            .function i32 main() {
418                lda.null
419                jnez.obj ng
420                ldai 0
421                return
422            ng:
423                ldai 1
424        check-type: no-check
425
426
427      - file-name: "valid_not_null_values_p"
428        isa:
429          description: >
430            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
431            object reference in accumulator compares with null as specified. Offset is sign extended to the size of
432            instruction address.
433        description: Check 'jnez.obj' instruction with valid not null values in PandaAssembly context.
434        header-template: []
435        tags: [tsan]
436        code-template: |
437            .record panda.String <external>
438            .record panda.Class <external>
439            .record panda.Object <external>
440            .record R {}
441            .function void R.ctor(R a0) <ctor> {
442                return.void
443            }
444            .function i32 main() {
445                %s
446                jnez.obj ng
447                ldai 1
448                return
449            ng:
450        check-type: exit-positive
451        cases:
452          - values:
453            - initobj R.ctor
454          - values:
455            - lda.str "test1"
456          - values:
457            - lda.type R
458          - values:
459            - lda.type panda.Object
460          - values:
461            - |
462              #
463                  movi v2, 10
464                  newarr v2, v2, u32[]
465                  lda.obj v2
466          - values:
467            - |
468              #
469                  movi v2, 10
470                  newarr v2, v2, u64[][]
471                  lda.obj v2
472          - values:
473            - |
474              #
475                  movi v2, 10
476                  newarr v2, v2, R[]
477                  lda.obj v2
478          - values:
479            - |
480              #
481                  movi v2, 10
482                  newarr v2, v2, panda.Class[][]
483                  lda.obj v2
484          - values:
485            - |
486              #
487                  movi v2, 10
488                  newarr v2, v2, panda.String[][][]
489                  lda.obj v2
490
491
492      - file-name: "valid_not_null_values_j"
493        isa:
494          description: >
495            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
496            object reference in accumulator compares with null as specified. Offset is sign extended to the size of
497            instruction address.
498        description: Check 'jnez.obj' instruction with valid not null values in PandaAssembly context.
499        runner-options: [use-pa]
500        header-template: []
501        tags: ['tsan']
502        code-template: |
503            .language PandaAssembly
504            .record panda.String <external>
505            .record panda.Class <external>
506            .record panda.Object <external>
507            .record R {}
508            .function void R.ctor(R a0) <ctor> {
509                return.void
510            }
511            .function i32 main() {
512                %s
513                jnez.obj ng
514                ldai 1
515                return
516            ng:
517        check-type: exit-positive
518        cases:
519          - values:
520            - initobj R.ctor
521          - values:
522            - lda.str "test1"
523          - values:
524            - lda.type R
525          - values:
526            - lda.type panda.Object
527          - values:
528            - |
529              #
530                  movi v2, 10
531                  newarr v2, v2, i32[]
532                  lda.obj v2
533          - values:
534            - |
535              #
536                  movi v2, 10
537                  newarr v2, v2, f64[][]
538                  lda.obj v2
539          - values:
540            - |
541              #
542                  movi v2, 10
543                  newarr v2, v2, R[]
544                  lda.obj v2
545          - values:
546            - |
547              #
548                  movi v2, 10
549                  newarr v2, v2, panda.Class[][]
550                  lda.obj v2
551          - values:
552            - |
553              #
554                  movi v2, 10
555                  newarr v2, v2, panda.String[][][]
556                  lda.obj v2
557
558
559      - file-name: "valid_offset_values"
560        isa:
561          description: >
562            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
563            object reference in accumulator compares with null as specified. Offset is sign extended to the size of
564            instruction address.
565        description: Check 'jnez.obj' instruction with valid offset values.
566        header-template: []
567        code-template: |
568            .function i32 main() {
569                lda.str "test"
570                %s
571                ldai 1      # 2-byte instruction
572                return      # 1-byte instruction
573            quit:
574        check-type: exit-positive
575        cases:
576          - description: Same instruction jump, offset imm8, 0 bytes
577            values:
578              - |
579                #
580                    lda.null
581                lbl:
582                    jnez.obj lbl
583                    ldai 0
584                    return
585          - description: Max forward jump for imm8, 2 + 120 + 2 + 3 = 127 bytes
586            values:
587              - |
588                #
589                    jnez.obj quit          # 2-byte instruction
590                    movi.64 v0, 0 ##*12
591                    lda.null
592                    lda.null
593            tags: [tsan]
594          - description: Max backward jump for imm8, 3 + 120 + 5 = 128 bytes
595            values:
596              - |
597                #
598                    jmp lbl2
599                lbl1:
600                    jmp quit              # 3-byte instruction
601                    movi.64 v0, 0 ##*12
602                    ldai 1
603                    ldai 1
604                    return
605                lbl2:
606                    jnez.obj lbl1
607          - description: Max forward jump for imm16, 3 + 32760 + 1 + 3 = 32767 bytes
608            values:
609              - |
610                #
611                    jnez.obj quit         # 3-byte instruction
612                    movi.64 v0, 0 ##*3276
613                    lda.null
614          - description: Beyond max forward jump for imm16, 3 + 40000 + 3 = 40006 bytes. Converted to jeqz.obj + jmp by compiler.
615            values:
616              - |
617                #
618                    jnez.obj quit         # 3-byte instruction
619                    movi.64 v0, 0 ##*4000
620          - description: Max backward jump for imm16, 5 + 32760 + 3 = 32768 bytes
621            values:
622              - |
623                #
624                    jmp lbl2
625                lbl1:
626                    jmp quit              # 5-byte instruction
627                    movi.64 v0, 0 ##*3276
628                    ldai 1
629                    return
630                lbl2:
631                    jnez.obj lbl1
632          - description: Beyond max backward jump for imm16, 5 + 40000 = 40005 bytes. Converted to jeqz.obj + jmp by compiler.
633            values:
634              - |
635                #
636                    jmp lbl2
637                lbl1:
638                    jmp quit              # 5-byte instruction
639                    movi.64 v0, 0 ##*4000
640                    ldai 1
641                    return
642                lbl2:
643                    jnez.obj lbl1
644          - description: Chain of forward jumps
645            values:
646              - |
647                #
648                    jnez.obj lbl1
649                    ldai 2
650                    return
651                lbl1:
652                    jnez.obj lbl2
653                    ldai 3
654                    return
655                lbl2:
656                    jnez.obj lbl3
657                    ldai 4
658                    return
659                lbl3:
660                    jnez.obj lbl4
661                    ldai 5
662                    return
663                lbl4:
664                    jnez.obj quit
665            tags: [tsan]
666          - description: Chain of backward jumps
667            values:
668              - |
669                #
670                    jmp lbl1
671                lbl6:
672                    jmp quit
673                lbl5:
674                    jnez.obj lbl6
675                    ldai 5
676                    return
677                lbl4:
678                    jnez.obj lbl5
679                    ldai 4
680                    return
681                lbl3:
682                    jnez.obj lbl4
683                    ldai 3
684                    return
685                lbl2:
686                    jnez.obj lbl3
687                    ldai 2
688                    return
689                lbl1:
690                    jnez.obj lbl2
691