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