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  - name: r_A
19    template: |
20      .record A {}
21
22      .function void A.constructor(A a0) <ctor> {
23          return.void
24      }
25  - name: NPE
26    template: |
27      .record panda.NullPointerException <external>
28  - name: j_NPE
29    template: |
30      .record panda.NullPointerException <external>
31  - name: AME
32    template: |
33      .record panda.AbstractMethodError <external>
34      .record panda.Class <external>
35  - name: j_AME
36    template: |
37      .record panda.AbstractMethodError <external>
38      .record panda.Class <external>
39tests:
40  - file-name: call.virt
41    isa:
42      instructions:
43        - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
44          acc: out:top
45          format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
46      title: Object calls
47      description: >
48        Call indicated object method, i.e. create new frame, pass values of arguments and
49        continue execution from the first instruction of a method.
50        Callee should treat accumulator value as undefined and cannot use it until accumulator
51        definition in the new frame.
52        Result (if any) is returned in accumulator (see 'Calling sequence' chapter for more details).
53        Method, its class and the number of argument is resolved by given method_id in runtime
54        constant-pool based on object reference using language-specific semantics (currently only PandaAssembly
55        virtual methods are supported, further extensions are TBD).
56        Object reference is passed in the first source register, arguments are passed starting from
57        the second source register in the same order as in method signature.
58        Non-range instructions can be used to pass up to 4 arguments (including object reference).
59        Unused register slot values will be discarded and corresponding registers will not be
60        passed to the callee).
61        For methods with more arguments range kinds of instruction are to be used, which takes
62        the needed number of arguments starting from 'vs' register (including object reference).
63      verification:
64        - method_id_non_static
65        - compatible_arguments
66        - method_id_accessible
67      exceptions:
68        - x_null
69        - x_abstract
70    commands:
71      - file-name: method_call
72
73        isa:
74          instructions:
75            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
76              acc: out:top
77              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
78        header-template: [r_A]
79        description: >
80          Invoke virtual method with different amount (0, 1, 2 or 3) and type of argument. Primitives and reference types are used as second argument.
81          Check return value.
82        tags: ['tsan']
83        code-template: |
84          *s
85          .function %s A.foo(A a0*s) {
86              %s
87          }
88
89          .function i32 main() {
90              initobj.short A.constructor
91              sta.obj v0
92              *s
93              call.virt A.foo, v0*s
94              %s
95        template-cases:
96            - values:
97              - i32
98              - |
99                #
100                    ldai 123456789
101                    return
102              - |
103                #
104                    movi v0, 123456789
105                    jne v0, set_failure
106                    ldai 0
107                    jmp fall_through
108                set_failure:
109                    ldai 1
110                fall_through:
111            - values:
112              - i64
113              - |
114                #
115                    ldai.64 123456789
116                    return.64
117              - |
118                #
119                    movi.64 v0, 123456789
120                    cmp.64 v0
121            - values:
122              - f64
123              - |
124                #
125                    fldai.64 1234567.89
126                    return.64
127              - |
128                #
129                    fmovi.64 v0, 1234567.89
130                    fcmpg.64 v0
131        check-type: check-positive
132        cases:
133          - values:
134            - ''
135            - ''
136            - ''
137            - ''
138          - values:
139            - ''
140            - ', i32 a1'
141            - 'movi v1, 123'
142            - ', v1'
143          - values:
144            - ''
145            - ',i64 a1'
146            - 'movi.64 v1, 123'
147            - ', v1'
148          - values:
149            - ''
150            - ',i64[] a1'
151            - |
152              #
153                  movi v1, 123
154                  newarr v1, v1, i64[]
155            - ', v1'
156          - values:
157            - ''
158            - ',A a1'
159            - |
160              #
161                  initobj.short A.constructor
162                  sta.obj v1
163            - ', v1'
164          - values:
165            - ''
166            - ', i32[] a1, i64 a2'
167            - |
168              #
169                  movi v1, 123
170                  newarr v1, v1, i32[]
171                  movi.64 v2, 0x100000000
172            - ', v1, v2'
173          - values:
174            - ''
175            - ', i64[] a1, A a2'
176            - |
177              #
178                  movi v1, 123
179                  newarr v1, v1, i64[]
180                  initobj.short A.constructor
181                  sta.obj v2
182            - ', v1, v2'
183          - values:
184            - ''
185            - ',A[] a1, f64 a2'
186            - |
187              #
188                  movi v1, 123
189                  newarr v1, v1, A[]
190                  fmovi.64 v2, 123.321
191            - ', v1, v2'
192          - values:
193            - '.record panda.String <external>'
194            - ', f64[] a1, panda.String a2'
195            - |
196              #
197                  movi v1, 123
198                  newarr v1, v1, f64[]
199                  lda.str "some string"
200                  sta.obj v2
201            - ', v1, v2'
202          - values:
203            - |
204              .record panda.String <external>
205              .record panda.Object <external>
206            - ', panda.String[] a1, panda.Object[] a2'
207            - |
208              #
209                  movi v1, 123
210                  newarr v1, v1, panda.String[]
211                  movi v2, 321
212                  newarr v2, v2, panda.Object[]
213            - ', v1, v2'
214          - values:
215            - '.record panda.Object <external>'
216            - ', panda.Object[] a1, panda.Object a2'
217            - |
218              #
219                  movi v1, 123
220                  newarr v1, v1, panda.Object[]
221                  mov.null v2
222            - ', v1, v2'
223          - values:
224            - '.record panda.Object <external>'
225            - ', i32[] a1, i64 a2, panda.Object[] a3'
226            - |
227              #
228                  movi v1, 123
229                  newarr v1, v1, i32[]
230                  movi.64 v2, 0x100000000
231                  movi v3, 333
232                  newarr v3, v3, panda.Object[]
233            - ', v1, v2, v3'
234          - values:
235            - '.record panda.String <external>'
236            - ', i64[] a1, A a2, panda.String a3'
237            - |
238              #
239                  movi v1, 123
240                  newarr v1, v1, i64[]
241                  initobj.short A.constructor
242                  sta.obj v2
243                  lda.str "some string"
244                  sta.obj v3
245            - ', v1, v2, v3'
246          - values:
247            - '.record panda.Object <external>'
248            - ',A[] a1, f64 a2, panda.Object a3'
249            - |
250              #
251                  movi v1, 123
252                  newarr v1, v1, A[]
253                  fmovi.64 v2, 123.321
254                  mov.null v3
255            - ', v1, v2, v3'
256          - values:
257            - '.record panda.String <external>'
258            - ', f64[] a1, panda.String a2, panda.String[] a3'
259            - |
260              #
261                  movi v1, 123
262                  newarr v1, v1, f64[]
263                  lda.str "some string"
264                  sta.obj v2
265                  movi v3, 123
266                  newarr v3, v3, panda.String[]
267            - ', v1, v2, v3'
268          - values:
269            - |
270              .record panda.String <external>
271              .record panda.Object <external>
272            - ', panda.String[] a1, panda.Object[] a2, panda.String[] a3'
273            - |
274              #
275                  movi v1, 123
276                  newarr v1, v1, panda.String[]
277                  movi v2, 321
278                  newarr v2, v2, panda.Object[]
279                  movi v3, 333
280                  newarr v3, v3, panda.String[]
281            - ', v1, v2, v3'
282          - values:
283            - '.record panda.Object <external>'
284            - ', panda.Object[] a1, panda.Object a2, f64[] a3'
285            - |
286              #
287                  movi v1, 123
288                  newarr v1, v1, panda.Object[]
289                  mov.null v2
290                  movi v3, 321
291                  newarr v3, v3, f64[]
292            - ', v1, v2, v3'
293
294      - file-name: p_method_call_args
295        isa:
296          instructions:
297            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
298              acc: out:top
299              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
300        header-template: [xorshift32]
301        description: >
302            Invoke virtual method with different pseudo-random values and check if correct value is stored in object field. Check i32, i64, f64 and reference types.
303            Use PandaAssembly language context.
304        tags: ['tsan', 'irtoc_ignore']
305        code-template: |
306            %s
307
308            .function void R.constructor(R a0) <ctor> {
309                return.void
310            }
311
312            .function void R.storeValue(R a0, %s) {
313                %s
314                return.void
315            }
316
317            .function i32 main() {
318                # Create R object
319                initobj.short R.constructor
320                # Keep them in v0
321                sta.obj v0
322                # Iterations
323                movi v2, 10
324                # Start value
325                movi v3, *s
326            loop:
327                %s
328                inci v2, -1
329                lda v2
330                jnez loop
331                ldai 0
332                return
333            exit_err:
334                ldai 1
335                return
336
337        check-type: none
338
339        template-cases:
340            - values:
341              - |
342                .record R {
343                    i32            f1
344                    i32            f2
345                    i32            f3
346                }
347              - i32 a1, i32 a2, i32 a3
348              - |
349                #
350                    lda a1
351                    stobj a0, R.f1
352                    lda a2
353                    stobj a0, R.f2
354                    lda a3
355                    stobj a0, R.f3
356              - |
357                # Get next random number
358                    call.short nextRand, v3
359                    sta v4
360                    call.short nextRand, v4
361                    sta v5
362                    call.short nextRand, v5
363                    sta v6
364                    sta v3
365                # Store in object
366                    call.virt R.storeValue, v0, v4, v5, v6
367                # Check record R content
368                    ldobj v0, R.f1
369                    jne v4, exit_err
370                    ldobj v0, R.f2
371                    jne v5, exit_err
372                    ldobj v0, R.f3
373                    jne v6, exit_err
374            - values:
375              - |
376                .record R {
377                    i32[]          f1
378                    i32            f2
379                    i32[]          f3
380                }
381              - i32[] a1, i32 a2, i32[] a3
382              - |
383                #
384                    lda.obj a1
385                    stobj.obj a0, R.f1
386                    lda a2
387                    stobj a0, R.f2
388                    lda.obj a3
389                    stobj.obj a0, R.f3
390              - |
391                # Get next random number
392                    call.short nextRand, v3
393                    sta v4
394                    andi 0x7f
395                    sta v5
396                    newarr v5, v5, i32[]
397                    call.short nextRand, v4
398                    sta v6
399                    call.short nextRand, v6
400                    sta v7
401                    andi 0x7f
402                    sta v8
403                    newarr v8, v8, i32[]
404                # Store in object
405                    call.virt R.storeValue, v0, v5, v6, v8
406                # Check R content
407                    ldobj.obj v0, R.f1
408                    jne.obj v5, exit_err
409                    ldobj v0, R.f2
410                    jne v6, exit_err
411                    ldobj.obj v0, R.f3
412                    jne.obj v8, exit_err
413            - values:
414              - |
415                .record R {
416                    i64[]          f1
417                    i32            f2
418                    f64[]          f3
419                }
420              - i64[] a1, i32 a2, f64[] a3
421              - |
422                #
423                    lda.obj a1
424                    stobj.obj a0, R.f1
425                    lda a2
426                    stobj a0, R.f2
427                    lda.obj a3
428                    stobj.obj a0, R.f3
429              - |
430                # Get next random number
431                    call.short nextRand, v3
432                    sta v4
433                    andi 0x7f
434                    sta v5
435                    newarr v5, v5, i64[]
436                    call.short nextRand, v4
437                    sta v6
438                    call.short nextRand, v6
439                    sta v7
440                    andi 0x7f
441                    sta v8
442                    newarr v8, v8, f64[]
443                # Store in object
444                    call.virt R.storeValue, v0, v5, v6, v8
445                # Check R content
446                    ldobj.obj v0, R.f1
447                    jne.obj v5, exit_err
448                    ldobj v0, R.f2
449                    jne v6, exit_err
450                    ldobj.obj v0, R.f3
451                    jne.obj v8, exit_err
452
453            - values:
454              - |
455                .record R {
456                    i64          f1
457                    i32          f2
458                    f64          f3
459                }
460              - i64 a1, i32 a2, f64 a3
461              - |
462                #
463                    lda.64 a1
464                    stobj.64 a0, R.f1
465                    lda a2
466                    stobj a0, R.f2
467                    lda.64 a3
468                    stobj.64 a0, R.f3
469              - |
470                # Get next random number
471                    call.short nextRand, v3
472                    sta v3
473                    u32toi64
474                    movi.64 v4, 32
475                    shl2.64 v4
476                    sta.64 v4
477                    call.short nextRand, v3
478                    sta v3
479                    u32toi64
480                    or2.64 v4
481                    sta.64 v4
482
483                    call.short nextRand, v3
484                    sta v3
485                    sta v5
486                    call.short nextRand, v3
487                    sta v3
488                    u32toi64
489                    movi.64 v6, 32
490                    shl2.64 v6
491                    sta.64 v6
492                    call.short nextRand, v3
493                    sta v3
494                    u32toi64
495                    or2.64 v6
496                    i64tof64
497                    sta.64 v6
498
499                    call.virt R.storeValue, v0, v4, v5, v6
500                # Check R content
501                    ldobj.64 v0, R.f1
502                    cmp.64 v4
503                    jnez exit_err
504                    ldobj v0, R.f2
505                    jne v5, exit_err
506                    ldobj.64 v0, R.f3
507                    fcmpg.64 v6
508                    jnez exit_err
509
510            - values:
511              - |
512                .record R {
513                    f64[]        f1
514                    R[]          f2
515                    R            f3
516                }
517              - f64[] a1, R[] a2, R a3
518              - |
519                #
520                    lda.obj a1
521                    stobj.obj a0, R.f1
522                    lda.obj a2
523                    stobj.obj a0, R.f2
524                    lda.obj a3
525                    stobj.obj a0, R.f3
526              - |
527                # Get next random number
528                    call.short nextRand, v3
529                    sta v3
530                    andi 0x7f
531                    sta v4
532                    newarr v4, v4, f64[]
533                    call.short nextRand, v3
534                    sta v3
535                    andi 0x7f
536                    sta v5
537                    newarr v5, v5, R[]
538                    mov.null v6
539                # Store in object
540                    call.virt R.storeValue, v0, v4, v5, v6
541                # Check R content
542                    ldobj.obj v0, R.f1
543                    jne.obj v4, exit_err
544                    ldobj.obj v0, R.f2
545                    jne.obj v5, exit_err
546                    ldobj.obj v0, R.f3
547                    jne.obj v6, exit_err
548        cases:
549          - values:
550              - "0xBADC0FFE"
551          - values:
552              - "0x12345678"
553          - values:
554              - "0xFEDCBA98"
555          - values:
556              - "1"
557          - values:
558              - "0xFFFFFFFF"
559          - values:
560              - "0x80000000"
561          - values:
562              - "0x7FFFFFFF"
563
564      - file-name: j_method_call_args
565        isa:
566          instructions:
567            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
568              acc: out:top
569              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
570        runner-options: [use-pa]
571        header-template: [PandaAssembly, xorshift32]
572        description: >
573            Invoke virtual method with different pseudo-random values and check if correct value is stored in object field. Check i32, i64, f64 and reference types.
574            Use PandaAssembly language context.
575        tags: ['tsan', 'irtoc_ignore']
576        code-template: |
577            %s
578
579            .record S<panda.extends=R> {}
580
581            .function void R.constructor(R a0) <ctor> {
582                return.void
583            }
584
585            .function void S.constructor(S a0) <ctor> {
586                return.void
587            }
588
589            .function void R.storeValue(R a0, %s) <noimpl>
590
591            .function void S.storeValue(S a0, %s) {
592                %s
593                return.void
594            }
595
596            .function i32 main() {
597                # Create S object
598                initobj.short S.constructor
599                # Keep them in v0
600                sta.obj v0
601                # Iterations
602                movi v2, 10
603                # Start value
604                movi v3, *s
605            loop:
606                %s
607                inci v2, -1
608                lda v2
609                jnez loop
610                ldai 0
611                return
612            exit_err:
613                ldai 1
614                return
615        check-type: none
616        template-cases:
617            - values:
618              - |
619                .record R {
620                    i32            f1
621                    i32            f2
622                    i32            f3
623                }
624              - i32 a1, i32 a2, i32 a3
625              - i32 a1, i32 a2, i32 a3
626              - |
627                #
628                    lda a1
629                    stobj a0, R.f1
630                    lda a2
631                    stobj a0, R.f2
632                    lda a3
633                    stobj a0, R.f3
634              - |
635                # Get next random number
636                    call.short nextRand, v3
637                    sta v4
638                    call.short nextRand, v4
639                    sta v5
640                    call.short nextRand, v5
641                    sta v6
642                    sta v3
643                # Store in object
644                    call.virt %s.storeValue, v0, v4, v5, v6
645                # Check record R content
646                    ldobj v0, R.f1
647                    jne v4, exit_err
648                    ldobj v0, R.f2
649                    jne v5, exit_err
650                    ldobj v0, R.f3
651                    jne v6, exit_err
652            - values:
653              - |
654                .record R {
655                    i32[]          f1
656                    i32            f2
657                    i32[]          f3
658                }
659              - i32[] a1, i32 a2, i32[] a3
660              - i32[] a1, i32 a2, i32[] a3
661              - |
662                #
663                    lda.obj a1
664                    stobj.obj a0, R.f1
665                    lda a2
666                    stobj a0, R.f2
667                    lda.obj a3
668                    stobj.obj a0, R.f3
669              - |
670                # Get next random number
671                    call.short nextRand, v3
672                    sta v4
673                    andi 0x7f
674                    sta v5
675                    newarr v5, v5, i32[]
676                    call.short nextRand, v4
677                    sta v6
678                    call.short nextRand, v6
679                    sta v7
680                    andi 0x7f
681                    sta v8
682                    newarr v8, v8, i32[]
683                # Store in object
684                    call.virt %s.storeValue, v0, v5, v6, v8
685                # Check R content
686                    ldobj.obj v0, R.f1
687                    jne.obj v5, exit_err
688                    ldobj v0, R.f2
689                    jne v6, exit_err
690                    ldobj.obj v0, R.f3
691                    jne.obj v8, exit_err
692            - values:
693              - |
694                .record R {
695                    i64[]          f1
696                    i32            f2
697                    f64[]          f3
698                }
699              - i64[] a1, i32 a2, f64[] a3
700              - i64[] a1, i32 a2, f64[] a3
701              - |
702                #
703                    lda.obj a1
704                    stobj.obj a0, R.f1
705                    lda a2
706                    stobj a0, R.f2
707                    lda.obj a3
708                    stobj.obj a0, R.f3
709              - |
710                # Get next random number
711                    call.short nextRand, v3
712                    sta v4
713                    andi 0x7f
714                    sta v5
715                    newarr v5, v5, i64[]
716                    call.short nextRand, v4
717                    sta v6
718                    call.short nextRand, v6
719                    sta v7
720                    andi 0x7f
721                    sta v8
722                    newarr v8, v8, f64[]
723                # Store in object
724                    call.virt %s.storeValue, v0, v5, v6, v8
725                # Check R content
726                    ldobj.obj v0, R.f1
727                    jne.obj v5, exit_err
728                    ldobj v0, R.f2
729                    jne v6, exit_err
730                    ldobj.obj v0, R.f3
731                    jne.obj v8, exit_err
732            - values:
733              - |
734                .record R {
735                    i64          f1
736                    i32          f2
737                    f64          f3
738                }
739              - i64 a1, i32 a2, f64 a3
740              - i64 a1, i32 a2, f64 a3
741              - |
742                #
743                    lda.64 a1
744                    stobj.64 a0, R.f1
745                    lda a2
746                    stobj a0, R.f2
747                    lda.64 a3
748                    stobj.64 a0, R.f3
749              - |
750                # Get next random number
751                    call.short nextRand, v3
752                    sta v3
753                    u32toi64
754                    movi.64 v4, 32
755                    shl2.64 v4
756                    sta.64 v4
757                    call.short nextRand, v3
758                    sta v3
759                    u32toi64
760                    or2.64 v4
761                    sta.64 v4
762                    call.short nextRand, v3
763                    sta v3
764                    sta v5
765                    call.short nextRand, v3
766                    sta v3
767                    u32toi64
768                    movi.64 v6, 32
769                    shl2.64 v6
770                    sta.64 v6
771                    call.short nextRand, v3
772                    sta v3
773                    u32toi64
774                    or2.64 v6
775                    i64tof64
776                    sta.64 v6
777
778                    call.virt %s.storeValue, v0, v4, v5, v6
779                # Check R content
780                    ldobj.64 v0, R.f1
781                    cmp.64 v4
782                    jnez exit_err
783                    ldobj v0, R.f2
784                    jne v5, exit_err
785                    ldobj.64 v0, R.f3
786                    fcmpg.64 v6
787                    jnez exit_err
788            - values:
789              - |
790                .record R {
791                    f64[]        f1
792                    R[]          f2
793                    R            f3
794                }
795              - f64[] a1, R[] a2, R a3
796              - f64[] a1, R[] a2, R a3
797              - |
798                #
799                    lda.obj a1
800                    stobj.obj a0, R.f1
801                    lda.obj a2
802                    stobj.obj a0, R.f2
803                    lda.obj a3
804                    stobj.obj a0, R.f3
805              - |
806                # Get next random number
807                    call.short nextRand, v3
808                    sta v3
809                    andi 0x7f
810                    sta v4
811                    newarr v4, v4, f64[]
812                    call.short nextRand, v3
813                    sta v3
814                    andi 0x7f
815                    sta v5
816                    newarr v5, v5, R[]
817                    mov.null v6
818                # Store in object
819                    call.virt %s.storeValue, v0, v4, v5, v6
820                # Check R content
821                    ldobj.obj v0, R.f1
822                    jne.obj v4, exit_err
823                    ldobj.obj v0, R.f2
824                    jne.obj v5, exit_err
825                    ldobj.obj v0, R.f3
826                    jne.obj v6, exit_err
827        cases:
828          - values:
829              - "0xBADC0FFE"
830              - "R"
831            description: Call using parent object method.
832          - values:
833              - "0xBADC0FFE"
834              - "S"
835            description: Call using current object method.
836          - values:
837              - "0x12345678"
838              - "R"
839            description: Call using parent object method.
840          - values:
841              - "0x12345678"
842              - "S"
843            description: Call using current object method.
844          - values:
845              - "0xFEDCBA98"
846              - "R"
847            description: Call using parent object method.
848          - values:
849              - "0xFEDCBA98"
850              - "S"
851            description: Call using current object method.
852          - values:
853              - "1"
854              - "R"
855            description: Call using parent object method.
856          - values:
857              - "1"
858              - "S"
859            description: Call using current object method.
860          - values:
861              - "0xFFFFFFFF"
862              - "R"
863            description: Call using parent object method.
864          - values:
865              - "0xFFFFFFFF"
866              - "S"
867            description: Call using current object method.
868          - values:
869              - "0x80000000"
870              - "R"
871            description: Call using parent object method.
872          - values:
873              - "0x80000000"
874              - "S"
875            description: Call using current object method.
876          - values:
877              - "0x7FFFFFFF"
878              - "R"
879            description: Call using parent object method.
880          - values:
881              - "0x7FFFFFFF"
882              - "S"
883            description: Call using current object method.
884
885      - file-name: restore_register
886        isa:
887          instructions:
888            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
889              acc: out:top
890              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
891        header-template: [r_A]
892        description: >
893          Invoke virtual method and check if registers after calling is restored.
894        code-template: |
895          .function void A.foo(A a0) {
896              %s
897              lda.null
898              sta.obj v0
899              mov.obj v256, v0
900              return.void
901          }
902
903          .function i32 main() {
904              initobj.short A.constructor
905              sta.obj v0
906              %s
907              mov%s v256, %s
908              call.virt A.foo, v0
909              mov%s v100, v256
910              lda%s v100
911              %s
912        check-type: check-positive
913        cases:
914          - values:
915            - 'movi v1, 123'
916            - 'movi v1, 321'
917            - ''
918            - 'v1'
919            - ''
920            - ''
921            - |
922              #
923                  jne v1, set_failure
924                  ldai 0
925                  jmp fall_through
926              set_failure:
927                  ldai 1
928              fall_through:
929          - values:
930            - 'movi.64 v8, 123'
931            - 'movi v8, 321'
932            - ''
933            - 'v8'
934            - ''
935            - ''
936            - |
937              #
938                  jne v8, set_failure
939                  ldai 0
940                  jmp fall_through
941              set_failure:
942                  ldai 1
943              fall_through:
944          - values:
945            - 'fmovi.64 v16, 123'
946            - 'movi v16, 321'
947            - ''
948            - 'v16'
949            - ''
950            - ''
951            - |
952              #
953                  jne v16, set_failure
954                  ldai 0
955                  jmp fall_through
956              set_failure:
957                  ldai 1
958              fall_through:
959          - values:
960            - 'mov.null v128'
961            - 'movi v128, 321'
962            - ''
963            - 'v128'
964            - ''
965            - ''
966            - |
967              #
968                  jne v128, set_failure
969                  ldai 0
970                  jmp fall_through
971              set_failure:
972                  ldai 1
973              fall_through:
974          - values:
975            - |
976              #
977                  lda.str "123"
978                  sta.obj v255
979            - 'movi v255, 321'
980            - ''
981            - 'v255'
982            - ''
983            - ''
984            - |
985              #
986                  jne v255, set_failure
987                  ldai 0
988                  jmp fall_through
989              set_failure:
990                  ldai 1
991              fall_through:
992          - values: ['movi v1, 123',   'movi.64 v1, 321', '.64', 'v1', '.64', '.64', 'cmp.64 v1']
993          - values: ['movi.64 v8, 123',   'movi.64 v8, 321', '.64', 'v8', '.64', '.64', 'cmp.64 v8']
994          - values: ['fmovi.64 v16, 123',  'movi.64 v16, 321', '.64', 'v16', '.64', '.64', 'cmp.64 v16']
995          - values: ['mov.null v128', 'movi.64 v128, 321', '.64', 'v128', '.64', '.64', 'cmp.64 v128']
996          - values:
997              - |
998                #
999                    lda.str "123"
1000                    sta.obj v255
1001              - 'movi.64 v255, 321'
1002              - '.64'
1003              - 'v255'
1004              - '.64'
1005              - '.64'
1006              - 'cmp.64 v255'
1007          - values: ['movi v1, 123',   'fmovi.64 v1, 321', '.64', 'v1', '.64', '.64', 'fcmpg.64 v1']
1008          - values: ['movi.64 v8, 123',   'fmovi.64 v8, 321', '.64', 'v8', '.64', '.64', 'fcmpg.64 v8']
1009          - values: ['fmovi.64 v16, 123',  'fmovi.64 v16, 321', '.64', 'v16', '.64', '.64', 'fcmpg.64 v16']
1010          - values: ['mov.null v128', 'fmovi.64 v128, 321', '.64', 'v128', '.64', '.64', 'fcmpg.64 v128']
1011          - values:
1012              - |
1013                #
1014                    lda.str "123"
1015                    sta.obj v255
1016              - 'fmovi.64 v255, 321'
1017              - '.64'
1018              - 'v255'
1019              - '.64'
1020              - '.64'
1021              - 'fcmpg.64 v255'
1022
1023      - file-name: regs
1024        isa:
1025          instructions:
1026            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
1027              acc: out:top
1028              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
1029        header-template: [r_A]
1030        description: >
1031          Check available registers number and registers width.
1032        code-template: |
1033            .function void A.foo(A a0%s) {
1034                return.void
1035            }
1036
1037            .function i32 main() {
1038                call.virt A.foo, %s
1039            }
1040        check-type: empty
1041        runner-options: [compile-only]
1042        cases:
1043          - values: ['', 'v15']
1044          - values: ['', 'v16']
1045            runner-options: [compile-failure]
1046          - values: ['', '0']
1047            runner-options: [compile-failure]
1048          - values: [',i32 a1', 'v0, v15']
1049          - values: [',i32 a1', 'v0, v16']
1050            runner-options: [compile-failure]
1051          - values: [',i32 a1', 'v0, 0']
1052            runner-options: [compile-failure]
1053          - values: [',i32 a1', 'v16, v0']
1054            runner-options: [compile-failure]
1055          - values: [',i32 a1', 'v16, v15']
1056            runner-options: [compile-failure]
1057          - values: [',i32 a1', 'v16, v16']
1058            runner-options: [compile-failure]
1059          - values: [',i32 a1', 'v16, 0']
1060            runner-options: [compile-failure]
1061          - values: [',i32 a1', 'v15, v15']
1062          - values: [',i32 a1', 'v15, v16']
1063            runner-options: [compile-failure]
1064          - values: [',i32 a1', 'v15, 0']
1065            runner-options: [compile-failure]
1066          - values: [',i32 a1', '0, 0']
1067            runner-options: [compile-failure]
1068          - values: ['', 'v0, v0, v15']
1069          - values: ['', 'v0, v0, v16']
1070            runner-options: [compile-failure]
1071          - values: ['', '0, 0, 0']
1072            runner-options: [compile-failure]
1073          - values: [',i32 a1', 'v0, v0, v15']
1074          - values: [',i32 a1', 'v0, v0, v16']
1075            runner-options: [compile-failure]
1076          - values: [',i32 a1', 'v0, v0, 0']
1077            runner-options: [compile-failure]
1078          - values: [',i32 a1', 'v0, v16, v0']
1079            runner-options: [compile-failure]
1080          - values: [',i32 a1', 'v0, v16, v15']
1081            runner-options: [compile-failure]
1082          - values: [',i32 a1', 'v0, v16, v16']
1083            runner-options: [compile-failure]
1084          - values: [',i32 a1', 'v0, v16, 0']
1085            runner-options: [compile-failure]
1086          - values: [',i32 a1', 'v0, v15, v15']
1087          - values: [',i32 a1', 'v0, v15, v16']
1088            runner-options: [compile-failure]
1089          - values: [',i32 a1', 'v0, v15, 0']
1090            runner-options: [compile-failure]
1091          - values: [',i32 a1', 'v0, 0, 0']
1092            runner-options: [compile-failure]
1093          - values: [',i32 a1, i32 a2', 'v0, v0, v0, v0']
1094          - values: [',i32 a1, i32 a2', 'v0, v0, v0, v15']
1095          - values: [',i32 a1, i32 a2', 'v0, v0, v15, v16']
1096            runner-options: [compile-failure]
1097          - values: [',i32 a1, i32 a2', 'v0, v15, v16, v16']
1098            runner-options: [compile-failure]
1099          - values: [',i32 a1, i32 a2', 'v0, v16, v16, 0']
1100            runner-options: [compile-failure]
1101          - values: [',i32 a1, i32 a2', 'v0, v16, 0, 0']
1102            runner-options: [compile-failure]
1103          - values: [',i32 a1, i32 a2', 'v0, 0, 0, 0']
1104            runner-options: [compile-failure]
1105
1106      - file-name: panda_npe
1107        isa:
1108          instructions:
1109            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
1110              acc: out:top
1111              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
1112          exceptions:
1113            - x_null
1114        header-template: [NPE]
1115        tags: ['irtoc_ignore']
1116        description: >
1117              Check incorrect usage of `call.virt` instruction.
1118              Null reference usage causes to panda.NullPointerException. Method_id points to virtual method of base class. Use PandaAssembly language context.
1119        code-template: |
1120          %s
1121          .record B {}
1122
1123          .function void B.constructor(B a0) <ctor> {
1124              return.void
1125          }
1126
1127          .function i32 B.func(B a0%s) <noimpl>
1128
1129          .function i32 main() {
1130              mov.null v0
1131              %s
1132          begin:
1133              call.virt B.func, v0%s
1134          end:
1135              ldai 1
1136              return
1137
1138          catch_NPE:
1139              ldai 0 # Expected panda.NullPointerException
1140              return
1141
1142          catch_all:
1143              ldai 2 # Unexpected exception, test failed
1144              return
1145
1146          .catch panda.NullPointerException, begin, end, catch_NPE
1147          .catchall begin, end, catch_all
1148
1149        check-type: none
1150        cases:
1151          - values:
1152            - ''
1153            - ''
1154            - ''
1155            - ''
1156          - values:
1157            - ''
1158            - ', i32 a1'
1159            - 'movi v1, 0'
1160            - ', v1'
1161          - values:
1162            - ''
1163            - ', i64 a1'
1164            - 'movi.64 v1, 0'
1165            - ', v1'
1166          - values:
1167            - ''
1168            - ', f64 a1'
1169            - 'fmovi.64 v1, 0'
1170            - ', v1'
1171          - values:
1172            - ''
1173            - ', B a1'
1174            - |
1175              initobj B.constructor
1176                  sta.obj v1
1177            - ', v1'
1178          - values:
1179            - '.record panda.String <external>'
1180            - ', panda.String a1'
1181            - |
1182              lda.str "some string"
1183                  sta.obj v1
1184            - ', v1'
1185
1186          - values:
1187              - '.record panda.Class <external>'
1188              - ', panda.Class a1'
1189              - |
1190                #
1191                    lda.type B
1192                    sta.obj v1
1193              - ', v1'
1194          - values:
1195            - ''
1196            - ', i32 a1, f64 a2, i64 a3'
1197            - |
1198              #
1199                  movi v1, 1
1200                  fmovi.64 v2, 123.456
1201                  movi.64 v3, 0x100000000
1202            - ', v1, v2, v3'
1203          - values:
1204            - ''
1205            - ', i64 a1, i64[] a2, i64[] a3'
1206            - |
1207              #
1208                  movi.64 v1, 1
1209                  mov.null v2
1210                  mov.null v3
1211            - ', v1, v2, v3'
1212          - values:
1213            - ''
1214            - ', f64[] a1, i64[] a2, i32[] a3'
1215            - |
1216              #
1217                  mov.null v1
1218                  mov.null v2
1219                  mov.null v3
1220            - ', v1, v2, v3'
1221
1222      - file-name: PandaAssembly_npe
1223        isa:
1224          instructions:
1225            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
1226              acc: out:top
1227              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
1228          exceptions:
1229            - x_null
1230        header-template: [PandaAssembly, j_NPE]
1231        tags: ['irtoc_ignore']
1232        runner-options: [use-pa]
1233        description: >
1234              Check incorrect usage of `call.virt` instruction.
1235              Null reference usage causes to panda.NullPointerException. Method_id points to virtual method of base class. Use PandaAssembly language context.
1236        template-cases:
1237          - values:
1238            - |
1239              *s
1240              .record B {}
1241
1242              .function void B.constructor(B a0) <ctor> {
1243                  return.void
1244              }
1245
1246              .function i32 B.func(B a0%s) <noimpl>
1247              ##- %s This line will be removed
1248          - values:
1249            - |
1250              *s
1251              .record A {}
1252              .record B <panda.extends=A> {}
1253
1254              .function void B.constructor(B a0) <ctor> {
1255                  return.void
1256              }
1257
1258              .function i32 B.func(B a0*s) <noimpl>
1259              .function i32 A.func(B a0*s) <noimpl>
1260          - values:
1261            - |
1262              *s
1263              .record A {}
1264              .record C <panda.extends=A> {}
1265              .record B <panda.extends=C> {}
1266
1267              .function void B.constructor(B a0) <ctor> {
1268                  return.void
1269              }
1270
1271              .function i32 B.func(B a0*s) <noimpl>
1272              .function i32 A.func(B a0*s) <noimpl>
1273        code-template: |
1274          %s
1275
1276          .function i32 main() {
1277              mov.null v0
1278              *s
1279          begin:
1280              call.virt B.func, v0*s
1281          end:
1282              ldai 1
1283              return
1284
1285          catch_NPE:
1286              ldai 0 # Expected panda.NullPointerException
1287              return
1288
1289          catch_all:
1290              ldai 2 # Unexpected exception, test failed
1291              return
1292
1293          .catch panda.NullPointerException, begin, end, catch_NPE
1294          .catchall begin, end, catch_all
1295
1296        check-type: none
1297        cases:
1298          - values:
1299            - ''
1300            - ''
1301            - ''
1302            - ''
1303            - ''
1304          - values:
1305            - ''
1306            - ', i32 a1'
1307            - ', i32 a1'
1308            - 'movi v1, 0'
1309            - ', v1'
1310          - values:
1311            - ''
1312            - ', i64 a1'
1313            - ', i64 a1'
1314            - 'movi.64 v1, 0'
1315            - ', v1'
1316          - values:
1317            - ''
1318            - ', f64 a1'
1319            - ', f64 a1'
1320            - 'fmovi.64 v1, 0'
1321            - ', v1'
1322          - values:
1323            - ''
1324            - ', B a1'
1325            - ', B a1'
1326            - |
1327              initobj B.constructor
1328                  sta.obj v1
1329            - ', v1'
1330          - values:
1331            - '.record panda.String <external>'
1332            - ', panda.String a1'
1333            - ', panda.String a1'
1334            - |
1335              lda.str "some string"
1336                  sta.obj v1
1337            - ', v1'
1338
1339          - values:
1340              - '.record panda.Object <external>'
1341              - ', panda.Object a1'
1342              - ', panda.Object a1'
1343              - |
1344                #
1345                    lda.type B
1346                    sta.obj v1
1347              - ', v1'
1348          - values:
1349            - ''
1350            - ', i32 a1, f64 a2, i64 a3'
1351            - ', i32 a1, f64 a2, i64 a3'
1352            - |
1353              #
1354                  movi v1, 1
1355                  fmovi.64 v2, 123.456
1356                  movi.64 v3, 0x100000000
1357            - ', v1, v2, v3'
1358          - values:
1359            - ''
1360            - ', i64 a1, i64[] a2, i64[] a3'
1361            - ', i64 a1, i64[] a2, i64[] a3'
1362            - |
1363              #
1364                  movi.64 v1, 1
1365                  mov.null v2
1366                  mov.null v3
1367            - ', v1, v2, v3'
1368          - values:
1369            - ''
1370            - ', f64[] a1, i64[] a2, i32[] a3'
1371            - ', f64[] a1, i64[] a2, i32[] a3'
1372            - |
1373              #
1374                  mov.null v1
1375                  mov.null v2
1376                  mov.null v3
1377            - ', v1, v2, v3'
1378
1379      - file-name: panda_ame
1380        isa:
1381          instructions:
1382            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
1383              acc: out:top
1384              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
1385          exceptions:
1386            - x_abstract
1387        header-template: [AME]
1388        tags: ['irtoc_ignore']
1389        description: >
1390          Check incorrect usage of `call.virt` instruction. Call of abstract method, check if panda.AbstractMethodError is thrown.
1391          Use PandaAssembly language context.
1392
1393        code-template: |
1394          %s
1395          .record B {}
1396
1397            .function void B.constructor(B a0) <ctor> {
1398                return.void
1399            }
1400
1401            .function i32 B.func(B a0%s) <noimpl>
1402
1403          .function i32 main() {
1404              initobj.short B.constructor
1405              sta.obj v0
1406              %s
1407          begin:
1408              call.virt B.func, v0%s
1409          end:
1410              ldai 1
1411              return
1412
1413          catch_AME:
1414              ldai 0 # Expected panda.AbstractMethodError
1415              return
1416
1417          catch_all:
1418              ldai 2 # Unexpected exception, test failed
1419              return
1420
1421          .catch panda.AbstractMethodError, begin, end, catch_AME
1422          .catchall begin, end, catch_all
1423
1424        check-type: none
1425        cases:
1426          - values:
1427            - ''
1428            - ''
1429            - ''
1430            - ''
1431          - values:
1432            - ''
1433            - ', i32 a1'
1434            - 'movi v1, 0'
1435            - ', v1'
1436          - values:
1437            - ''
1438            - ', i64 a1'
1439            - 'movi.64 v1, 0'
1440            - ', v1'
1441          - values:
1442            - ''
1443            - ', f64 a1'
1444            - 'fmovi.64 v1, 0'
1445            - ', v1'
1446          - values:
1447            - ''
1448            - ', B a1'
1449            - |
1450              initobj.short B.constructor
1451                  sta.obj v1
1452            - ', v1'
1453          - values:
1454            - '.record panda.String <external>'
1455            - ', panda.String a1'
1456            - |
1457              lda.str "some string"
1458                  sta.obj v1
1459            - ', v1'
1460
1461          - values:
1462              - ''
1463              - ', panda.Class a1'
1464              - |
1465                #
1466                    lda.type B
1467                    sta.obj v1
1468              - ', v1'
1469          - values:
1470            - ''
1471            - ', i32 a1, f64 a2, i64 a3'
1472            - |
1473              #
1474                  movi v1, 1
1475                  fmovi.64 v2, 123.456
1476                  movi.64 v3, 0x100000000
1477            - ', v1, v2, v3'
1478          - values:
1479            - ''
1480            - ', i64 a1, i64[] a2, i64[] a3'
1481            - |
1482              #
1483                  movi.64 v1, 1
1484                  mov.null v2
1485                  mov.null v3
1486            - ', v1, v2, v3'
1487          - values:
1488            - ''
1489            - ', f64[] a1, i64[] a2, i32[] a3'
1490            - |
1491              #
1492                  mov.null v1
1493                  mov.null v2
1494                  mov.null v3
1495            - ', v1, v2, v3'
1496
1497      - file-name: PandaAssembly_ame
1498        isa:
1499          instructions:
1500            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
1501              acc: out:top
1502              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
1503          exceptions:
1504            - x_abstract
1505        header-template: [PandaAssembly, j_AME]
1506        tags: ['irtoc_ignore']
1507        description: >
1508          Check incorrect usage of `call.virt` instruction. Call of abstract method, check if panda.AbstractMethodError is thrown.
1509          Use PandaAssembly language context.
1510        runner-options: [use-pa]
1511        template-cases:
1512          - values:
1513            - |
1514              *s
1515              .record B {}
1516
1517              .function void B.constructor(B a0) <ctor> {
1518                  return.void
1519              }
1520
1521              .function i32 B.func(B a0*s) <noimpl>
1522          - values:
1523            - |
1524              *s
1525              .record A {}
1526              .record B <panda.extends=A> {}
1527
1528              .function void B.constructor(B a0) <ctor> {
1529                  return.void
1530              }
1531
1532              .function i32 B.func(B a0*s) <noimpl>
1533          - values:
1534            - |
1535              *s
1536              .record A {}
1537              .record C <panda.extends=A> {}
1538              .record B <panda.extends=C> {}
1539
1540              .function void B.constructor(B a0) <ctor> {
1541                  return.void
1542              }
1543
1544              .function i32 B.func(B a0*s) <noimpl>
1545
1546        code-template: |
1547          %s
1548
1549          .function i32 main() {
1550              initobj.short B.constructor
1551              sta.obj v0
1552              *s
1553          begin:
1554              call.virt B.func, v0*s
1555          end:
1556              ldai 1
1557              return
1558
1559          catch_AME:
1560              ldai 0 # Expected panda.AbstractMethodError
1561              return
1562
1563          catch_all:
1564              ldai 2 # Unexpected exception, test failed
1565              return
1566
1567          .catch panda.AbstractMethodError, begin, end, catch_AME
1568          .catchall begin, end, catch_all
1569
1570        check-type: none
1571        cases:
1572          - values:
1573            - ''
1574            - ''
1575            - ''
1576            - ''
1577          - values:
1578            - ''
1579            - ', i32 a1'
1580            - 'movi v1, 0'
1581            - ', v1'
1582          - values:
1583            - ''
1584            - ', i64 a1'
1585            - 'movi.64 v1, 0'
1586            - ', v1'
1587          - values:
1588            - ''
1589            - ', f64 a1'
1590            - 'fmovi.64 v1, 0'
1591            - ', v1'
1592          - values:
1593            - ''
1594            - ', B a1'
1595            - |
1596              initobj.short B.constructor
1597                  sta.obj v1
1598            - ', v1'
1599          - values:
1600            - '.record panda.String <external>'
1601            - ', panda.String a1'
1602            - |
1603              lda.str "some string"
1604                  sta.obj v1
1605            - ', v1'
1606          - values:
1607              - ''
1608              - ', panda.Class a1'
1609              - |
1610                #
1611                    lda.type B
1612                    sta.obj v1
1613              - ', v1'
1614          - values:
1615            - ''
1616            - ', i32 a1, f64 a2, i64 a3'
1617            - |
1618              #
1619                  movi v1, 1
1620                  fmovi.64 v2, 123.456
1621                  movi.64 v3, 0x100000000
1622            - ', v1, v2, v3'
1623          - values:
1624            - ''
1625            - ', i64 a1, i64[] a2, i64[] a3'
1626            - |
1627              #
1628                  movi.64 v1, 1
1629                  mov.null v2
1630                  mov.null v3
1631            - ', v1, v2, v3'
1632          - values:
1633            - ''
1634            - ', f64[] a1, i64[] a2, i32[] a3'
1635            - |
1636              #
1637                  mov.null v1
1638                  mov.null v2
1639                  mov.null v3
1640            - ', v1, v2, v3'
1641
1642
1643      - file-name: unused_regs
1644        isa:
1645          description: >
1646            Unused register slot values will be discarded and corresponding registers will not be
1647            passed to the callee).
1648        header-template: []
1649        description: Verifier should ignore unused register slots.
1650        code-template: |
1651            .record A {}
1652            .function void A.ctor(A a0) <ctor> {
1653                return.void
1654            }
1655            .function i32 A.foo(A a0%s) {
1656                ldai 0
1657                return
1658            }
1659            .function i32 main() {
1660                initobj A.ctor
1661                %s
1662                call.virt A.foo%s
1663        check-type: no-check
1664        cases:
1665          - values:
1666            - ""
1667            - "sta.obj v5"
1668            - ", v5, v4, v3, v2"
1669          - values:
1670            - ", i32 a1"
1671            - |
1672              #
1673                  sta.obj v9
1674                  movi v5, 123
1675            - ", v9, v5, v10"
1676          - values:
1677            - ", i64 a1, i32 a2"
1678            - |
1679              #
1680                  sta.obj v0
1681                  movi v2, 1
1682                  movi.64 v6, 123456789
1683            - ", v0, v6, v2, v0"
1684
1685      - file-name: PandaAssembly_x_call
1686        isa:
1687          exceptions:
1688            - x_call
1689        header-template: [PandaAssembly]
1690        runner-options: [use-pa]
1691        tags: ['irtoc_ignore']
1692        description: Bytecode may throw an error if an exception occures in the called bytecode.
1693        code-template: |
1694          .record panda.Throwable <external>
1695          .record E1 <panda.extends=panda.Throwable> {}
1696          .record R {}
1697          .record S<panda.extends=R> {}
1698          .function void R.constructor(R a0) <ctor> {
1699              return.void
1700          }
1701          .function void S.constructor(S a0) <ctor> {
1702              return.void
1703          }
1704          .function void R.method(R a0) <noimpl>
1705          .function void S.method(S a0) {
1706              newobj v1, E1
1707              throw v1
1708              return.void
1709          }
1710          .function i32 main() {
1711              jmp try_begin
1712          catch_E1:
1713              ldai 0
1714              return
1715          try_begin:
1716              initobj.short S.constructor
1717              sta.obj v0
1718              call.virt R.method, v0
1719          try_end:
1720          .catch E1, try_begin, try_end, catch_E1
1721              ldai 1
1722              return
1723        check-type: none
1724