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: "jeqz.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: jeqz.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: jeqz.obj imm:i32
41              acc: in:ref
42              format: [op_imm_8, op_imm_16]
43        runner-options: [compile-failure]
44        description: Check 'jeqz.obj' instruction with invalid offset.
45        header-template: []
46        code-template: |
47            .function i32 main() {
48                jeqz.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 'jeqz.obj' instruction with uninitialized accumulator.
69        header-template: []
70        code-template: |
71            .function i32 main() {
72                jeqz.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 'jeqz.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                jeqz.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 'jeqz.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                lda.null
145                jeqz.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 'jeqz.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.null
217                jeqz.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 'jeqz.obj' instruction with invalid accumulator value
282        header-template: []
283        code-template: |
284            .function i32 main() {
285                %s
286                jeqz.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 'jeqz.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                jeqz.obj ok
399                ldai 1
400                return
401            ok:
402        check-type: exit-positive
403
404
405      - file-name: "valid_null_value_j"
406        isa:
407          description: >
408            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
409            object reference in accumulator compares with null as specified. Offset is sign extended to the size of
410            instruction address.
411        description: Check 'jeqz.obj' instruction with valid null value in PandaAssembly context.
412        runner-options: [use-pa]
413        header-template: [PandaAssembly]
414        tags: ['tsan']
415        code-template: |
416            .function i32 main() {
417                lda.null
418                jeqz.obj ok
419                ldai 1
420                return
421            ok:
422        check-type: exit-positive
423
424
425      - file-name: "valid_not_null_values_p"
426        isa:
427          description: >
428            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
429            object reference in accumulator compares with null as specified. Offset is sign extended to the size of
430            instruction address.
431        description: Check 'jeqz.obj' instruction with valid not null values in PandaAssembly context.
432        header-template: []
433        tags: [tsan]
434        code-template: |
435            .record panda.String <external>
436            .record panda.Class <external>
437            .record panda.Object <external>
438            .record R {}
439            .function void R.ctor(R a0) <ctor> {
440                return.void
441            }
442            .function i32 main() {
443                %s
444                jeqz.obj eq
445                ldai 0
446                return
447            eq:
448                ldai 1
449                return
450        check-type: none
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 'jeqz.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                jeqz.obj eq
514                ldai 0
515                return
516            eq:
517                ldai 1
518                return
519        check-type: none
520        cases:
521          - values:
522            - initobj R.ctor
523          - values:
524            - lda.str "test1"
525          - values:
526            - lda.type R
527          - values:
528            - lda.type panda.Object
529          - values:
530            - |
531              #
532                  movi v2, 10
533                  newarr v2, v2, i32[]
534                  lda.obj v2
535          - values:
536            - |
537              #
538                  movi v2, 10
539                  newarr v2, v2, f64[][]
540                  lda.obj v2
541          - values:
542            - |
543              #
544                  movi v2, 10
545                  newarr v2, v2, R[]
546                  lda.obj v2
547          - values:
548            - |
549              #
550                  movi v2, 10
551                  newarr v2, v2, panda.Class[][]
552                  lda.obj v2
553          - values:
554            - |
555              #
556                  movi v2, 10
557                  newarr v2, v2, panda.String[][][]
558                  lda.obj v2
559
560
561      - file-name: "valid_offset_values"
562        isa:
563          description: >
564            Transfer execution to an instruction at offset bytes from the beginning of the current instruction if
565            object reference in accumulator compares with null as specified. Offset is sign extended to the size of
566            instruction address.
567        description: Check 'jeqz.obj' instruction with valid offset values.
568        header-template: []
569        code-template: |
570            .function i32 main() {
571                lda.null
572                %s
573                ldai 1      # 2-byte instruction
574                return      # 1-byte instruction
575            quit:
576        check-type: exit-positive
577        cases:
578          - description: Same instruction jump, offset imm8, 0 bytes
579            values:
580              - |
581                #
582                    lda.str "test"
583                lbl:
584                    jeqz.obj lbl
585                    ldai 0
586                    return
587          - description: Max forward jump for imm8, 2 + 120 + 2 + 3 = 127 bytes
588            values:
589              - |
590                #
591                    jeqz.obj quit         # 2-byte instruction
592                    movi.64 v0, 0 ##*12
593                    lda.null
594                    lda.null
595          - description: Max backward jump for imm8, 3 + 120 + 5 = 128 bytes
596            values:
597              - |
598                #
599                    jmp lbl2
600                lbl1:
601                    jmp quit              # 3-byte instruction
602                    movi.64 v0, 0 ##*12
603                    ldai 1
604                    ldai 1
605                    return
606                lbl2:
607                    jeqz.obj lbl1
608            tags: [tsan]
609          - description: Max forward jump for imm16, 3 + 32760 + 1 + 3 = 32767 bytes
610            values:
611              - |
612                #
613                    jeqz.obj quit       # 3-byte instruction
614                    movi.64 v0, 0 ##*3276
615                    lda.null
616          - description: Beyond max forward jump for imm16, 3 + 40000 + 3 = 40006 bytes. Converted to jnez.obj + jmp by compiler.
617            values:
618              - |
619                #
620                    jeqz.obj quit      # 3-byte instruction
621                    movi.64 v0, 0 ##*4000
622            tags: [tsan]
623          - description: Max backward jump for imm16, 5 + 32760 + 3 = 32768 bytes
624            values:
625              - |
626                #
627                    jmp lbl2
628                lbl1:
629                    jmp quit              # 5-byte instruction
630                    movi.64 v0, 0 ##*3276
631                    ldai 1
632                    return
633                lbl2:
634                    jeqz.obj lbl1
635          - description: Beyond max backward jump for imm16, 5 + 40000 = 40005 bytes. Converted to jnez.obj + jmp by compiler.
636            values:
637              - |
638                #
639                    jmp lbl2
640                lbl1:
641                    jmp quit              # 5-byte instruction
642                    movi.64 v0, 0 ##*4000
643                    ldai 1
644                    return
645                lbl2:
646                    jeqz.obj lbl1
647          - description: Chain of forward jumps
648            values:
649              - |
650                #
651                    jeqz.obj lbl1
652                    ldai 2
653                    return
654                lbl1:
655                    jeqz.obj lbl2
656                    ldai 3
657                    return
658                lbl2:
659                    jeqz.obj lbl3
660                    ldai 4
661                    return
662                lbl3:
663                    jeqz.obj lbl4
664                    ldai 5
665                    return
666                lbl4:
667                    jeqz.obj quit
668          - description: Chain of backward jumps
669            values:
670              - |
671                #
672                    jmp lbl1
673                lbl6:
674                    jmp quit
675                lbl5:
676                    jeqz.obj lbl6
677                    ldai 5
678                    return
679                lbl4:
680                    jeqz.obj lbl5
681                    ldai 4
682                    return
683                lbl3:
684                    jeqz.obj lbl4
685                    ldai 3
686                    return
687                lbl2:
688                    jeqz.obj lbl3
689                    ldai 2
690                    return
691                lbl1:
692                    jeqz.obj lbl2
693            tags: [tsan]
694