• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2021 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: java
16    template: >
17      .language Java
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 java.lang.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 java.lang.AbstractMethodError <external>
38      .record java.lang.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 Java
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']
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: restore_register
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        header-template: [r_A]
571        description: >
572          Invoke virtual method and check if registers after calling is restored.
573        code-template: |
574          .function void A.foo(A a0) {
575              %s
576              lda.null
577              sta.obj v0
578              mov.obj v256, v0
579              return.void
580          }
581
582          .function i32 main() {
583              initobj.short A.constructor
584              sta.obj v0
585              %s
586              mov%s v256, %s
587              call.virt A.foo, v0
588              mov%s v100, v256
589              lda%s v100
590              %s
591        check-type: check-positive
592        cases:
593          - values:
594            - 'movi v1, 123'
595            - 'movi v1, 321'
596            - ''
597            - 'v1'
598            - ''
599            - ''
600            - |
601              #
602                  jne v1, set_failure
603                  ldai 0
604                  jmp fall_through
605              set_failure:
606                  ldai 1
607              fall_through:
608          - values:
609            - 'movi.64 v8, 123'
610            - 'movi v8, 321'
611            - ''
612            - 'v8'
613            - ''
614            - ''
615            - |
616              #
617                  jne v8, set_failure
618                  ldai 0
619                  jmp fall_through
620              set_failure:
621                  ldai 1
622              fall_through:
623          - values:
624            - 'fmovi.64 v16, 123'
625            - 'movi v16, 321'
626            - ''
627            - 'v16'
628            - ''
629            - ''
630            - |
631              #
632                  jne v16, set_failure
633                  ldai 0
634                  jmp fall_through
635              set_failure:
636                  ldai 1
637              fall_through:
638          - values:
639            - 'mov.null v128'
640            - 'movi v128, 321'
641            - ''
642            - 'v128'
643            - ''
644            - ''
645            - |
646              #
647                  jne v128, set_failure
648                  ldai 0
649                  jmp fall_through
650              set_failure:
651                  ldai 1
652              fall_through:
653          - values:
654            - |
655              #
656                  lda.str "123"
657                  sta.obj v255
658            - 'movi v255, 321'
659            - ''
660            - 'v255'
661            - ''
662            - ''
663            - |
664              #
665                  jne v255, set_failure
666                  ldai 0
667                  jmp fall_through
668              set_failure:
669                  ldai 1
670              fall_through:
671          - values: ['movi v1, 123',   'movi.64 v1, 321', '.64', 'v1', '.64', '.64', 'cmp.64 v1']
672          - values: ['movi.64 v8, 123',   'movi.64 v8, 321', '.64', 'v8', '.64', '.64', 'cmp.64 v8']
673          - values: ['fmovi.64 v16, 123',  'movi.64 v16, 321', '.64', 'v16', '.64', '.64', 'cmp.64 v16']
674          - values: ['mov.null v128', 'movi.64 v128, 321', '.64', 'v128', '.64', '.64', 'cmp.64 v128']
675          - values:
676              - |
677                #
678                    lda.str "123"
679                    sta.obj v255
680              - 'movi.64 v255, 321'
681              - '.64'
682              - 'v255'
683              - '.64'
684              - '.64'
685              - 'cmp.64 v255'
686          - values: ['movi v1, 123',   'fmovi.64 v1, 321', '.64', 'v1', '.64', '.64', 'fcmpg.64 v1']
687          - values: ['movi.64 v8, 123',   'fmovi.64 v8, 321', '.64', 'v8', '.64', '.64', 'fcmpg.64 v8']
688          - values: ['fmovi.64 v16, 123',  'fmovi.64 v16, 321', '.64', 'v16', '.64', '.64', 'fcmpg.64 v16']
689          - values: ['mov.null v128', 'fmovi.64 v128, 321', '.64', 'v128', '.64', '.64', 'fcmpg.64 v128']
690          - values:
691              - |
692                #
693                    lda.str "123"
694                    sta.obj v255
695              - 'fmovi.64 v255, 321'
696              - '.64'
697              - 'v255'
698              - '.64'
699              - '.64'
700              - 'fcmpg.64 v255'
701
702      - file-name: regs
703        isa:
704          instructions:
705            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
706              acc: out:top
707              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
708        header-template: [r_A]
709        description: >
710          Check available registers number and registers width.
711        code-template: |
712            .function void A.foo(A a0%s) {
713                return.void
714            }
715
716            .function i32 main() {
717                call.virt A.foo, %s
718            }
719        check-type: empty
720        runner-options: [compile-only]
721        cases:
722          - values: ['', 'v15']
723          - values: ['', 'v16']
724            runner-options: [compile-failure]
725          - values: ['', '0']
726            runner-options: [compile-failure]
727          - values: [',i32 a1', 'v0, v15']
728          - values: [',i32 a1', 'v0, v16']
729            runner-options: [compile-failure]
730          - values: [',i32 a1', 'v0, 0']
731            runner-options: [compile-failure]
732          - values: [',i32 a1', 'v16, v0']
733            runner-options: [compile-failure]
734          - values: [',i32 a1', 'v16, v15']
735            runner-options: [compile-failure]
736          - values: [',i32 a1', 'v16, v16']
737            runner-options: [compile-failure]
738          - values: [',i32 a1', 'v16, 0']
739            runner-options: [compile-failure]
740          - values: [',i32 a1', 'v15, v15']
741          - values: [',i32 a1', 'v15, v16']
742            runner-options: [compile-failure]
743          - values: [',i32 a1', 'v15, 0']
744            runner-options: [compile-failure]
745          - values: [',i32 a1', '0, 0']
746            runner-options: [compile-failure]
747          - values: ['', 'v0, v0, v15']
748          - values: ['', 'v0, v0, v16']
749            runner-options: [compile-failure]
750          - values: ['', '0, 0, 0']
751            runner-options: [compile-failure]
752          - values: [',i32 a1', 'v0, v0, v15']
753          - values: [',i32 a1', 'v0, v0, v16']
754            runner-options: [compile-failure]
755          - values: [',i32 a1', 'v0, v0, 0']
756            runner-options: [compile-failure]
757          - values: [',i32 a1', 'v0, v16, v0']
758            runner-options: [compile-failure]
759          - values: [',i32 a1', 'v0, v16, v15']
760            runner-options: [compile-failure]
761          - values: [',i32 a1', 'v0, v16, v16']
762            runner-options: [compile-failure]
763          - values: [',i32 a1', 'v0, v16, 0']
764            runner-options: [compile-failure]
765          - values: [',i32 a1', 'v0, v15, v15']
766          - values: [',i32 a1', 'v0, v15, v16']
767            runner-options: [compile-failure]
768          - values: [',i32 a1', 'v0, v15, 0']
769            runner-options: [compile-failure]
770          - values: [',i32 a1', 'v0, 0, 0']
771            runner-options: [compile-failure]
772          - values: [',i32 a1, i32 a2', 'v0, v0, v0, v0']
773          - values: [',i32 a1, i32 a2', 'v0, v0, v0, v15']
774          - values: [',i32 a1, i32 a2', 'v0, v0, v15, v16']
775            runner-options: [compile-failure]
776          - values: [',i32 a1, i32 a2', 'v0, v15, v16, v16']
777            runner-options: [compile-failure]
778          - values: [',i32 a1, i32 a2', 'v0, v16, v16, 0']
779            runner-options: [compile-failure]
780          - values: [',i32 a1, i32 a2', 'v0, v16, 0, 0']
781            runner-options: [compile-failure]
782          - values: [',i32 a1, i32 a2', 'v0, 0, 0, 0']
783            runner-options: [compile-failure]
784
785      - file-name: panda_npe
786        isa:
787          instructions:
788            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
789              acc: out:top
790              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
791          exceptions:
792            - x_null
793        header-template: [NPE]
794        description: >
795              Check incorrect usage of `call.virt` instruction.
796              Null reference usage causes to panda.NullPointerException. Method_id points to virtual method of base class. Use PandaAssembly language context.
797        code-template: |
798          %s
799          .record B {}
800
801          .function void B.constructor(B a0) <ctor> {
802              return.void
803          }
804
805          .function i32 B.func(B a0%s) <noimpl>
806
807          .function i32 main() {
808              mov.null v0
809              %s
810          begin:
811              call.virt B.func, v0%s
812          end:
813              ldai 1
814              return
815
816          catch_NPE:
817              ldai 0 # Expected panda.NullPointerException
818              return
819
820          catch_all:
821              ldai 2 # Unexpected exception, test failed
822              return
823
824          .catch panda.NullPointerException, begin, end, catch_NPE
825          .catchall begin, end, catch_all
826
827        check-type: none
828        cases:
829          - values:
830            - ''
831            - ''
832            - ''
833            - ''
834          - values:
835            - ''
836            - ', i32 a1'
837            - 'movi v1, 0'
838            - ', v1'
839          - values:
840            - ''
841            - ', i64 a1'
842            - 'movi.64 v1, 0'
843            - ', v1'
844          - values:
845            - ''
846            - ', f64 a1'
847            - 'fmovi.64 v1, 0'
848            - ', v1'
849          - values:
850            - ''
851            - ', B a1'
852            - |
853              initobj B.constructor
854                  sta.obj v1
855            - ', v1'
856          - values:
857            - '.record panda.String <external>'
858            - ', panda.String a1'
859            - |
860              lda.str "some string"
861                  sta.obj v1
862            - ', v1'
863
864          - values:
865              - '.record panda.Class <external>'
866              - ', panda.Class a1'
867              - |
868                #
869                    lda.type B
870                    sta.obj v1
871              - ', v1'
872          - values:
873            - ''
874            - ', i32 a1, f64 a2, i64 a3'
875            - |
876              #
877                  movi v1, 1
878                  fmovi.64 v2, 123.456
879                  movi.64 v3, 0x100000000
880            - ', v1, v2, v3'
881          - values:
882            - ''
883            - ', i64 a1, i64[] a2, i64[] a3'
884            - |
885              #
886                  movi.64 v1, 1
887                  mov.null v2
888                  mov.null v3
889            - ', v1, v2, v3'
890          - values:
891            - ''
892            - ', f64[] a1, i64[] a2, i32[] a3'
893            - |
894              #
895                  mov.null v1
896                  mov.null v2
897                  mov.null v3
898            - ', v1, v2, v3'
899
900      - file-name: panda_ame
901        isa:
902          instructions:
903            - sig: call.virt method_id, v1:in:top, v2:in:top, v3:in:top, v4:in:top
904              acc: out:top
905              format: [op_v1_4_v2_4_v3_4_v4_4_id_16]
906          exceptions:
907            - x_abstract
908        header-template: [AME]
909        description: >
910          Check incorrect usage of `call.virt` instruction. Call of abstract method, check if panda.AbstractMethodError is thrown.
911          Use PandaAssembly language context.
912
913        code-template: |
914          %s
915          .record B {}
916
917            .function void B.constructor(B a0) <ctor> {
918                return.void
919            }
920
921            .function i32 B.func(B a0%s) <noimpl>
922
923          .function i32 main() {
924              initobj.short B.constructor
925              sta.obj v0
926              %s
927          begin:
928              call.virt B.func, v0%s
929          end:
930              ldai 1
931              return
932
933          catch_AME:
934              ldai 0 # Expected panda.AbstractMethodError
935              return
936
937          catch_all:
938              ldai 2 # Unexpected exception, test failed
939              return
940
941          .catch panda.AbstractMethodError, begin, end, catch_AME
942          .catchall begin, end, catch_all
943
944        check-type: none
945        cases:
946          - values:
947            - ''
948            - ''
949            - ''
950            - ''
951          - values:
952            - ''
953            - ', i32 a1'
954            - 'movi v1, 0'
955            - ', v1'
956          - values:
957            - ''
958            - ', i64 a1'
959            - 'movi.64 v1, 0'
960            - ', v1'
961          - values:
962            - ''
963            - ', f64 a1'
964            - 'fmovi.64 v1, 0'
965            - ', v1'
966          - values:
967            - ''
968            - ', B a1'
969            - |
970              initobj.short B.constructor
971                  sta.obj v1
972            - ', v1'
973          - values:
974            - '.record panda.String <external>'
975            - ', panda.String a1'
976            - |
977              lda.str "some string"
978                  sta.obj v1
979            - ', v1'
980
981          - values:
982              - ''
983              - ', panda.Class a1'
984              - |
985                #
986                    lda.type B
987                    sta.obj v1
988              - ', v1'
989          - values:
990            - ''
991            - ', i32 a1, f64 a2, i64 a3'
992            - |
993              #
994                  movi v1, 1
995                  fmovi.64 v2, 123.456
996                  movi.64 v3, 0x100000000
997            - ', v1, v2, v3'
998          - values:
999            - ''
1000            - ', i64 a1, i64[] a2, i64[] a3'
1001            - |
1002              #
1003                  movi.64 v1, 1
1004                  mov.null v2
1005                  mov.null v3
1006            - ', v1, v2, v3'
1007          - values:
1008            - ''
1009            - ', f64[] a1, i64[] a2, i32[] a3'
1010            - |
1011              #
1012                  mov.null v1
1013                  mov.null v2
1014                  mov.null v3
1015            - ', v1, v2, v3'
1016
1017      - file-name: unused_regs
1018        isa:
1019          description: >
1020            Unused register slot values will be discarded and corresponding registers will not be
1021            passed to the callee).
1022        header-template: []
1023        description: Verifier should ignore unused register slots.
1024        code-template: |
1025            .record A {}
1026            .function void A.ctor(A a0) <ctor> {
1027                return.void
1028            }
1029            .function i32 A.foo(A a0%s) {
1030                ldai 0
1031                return
1032            }
1033            .function i32 main() {
1034                initobj A.ctor
1035                %s
1036                call.virt A.foo%s
1037        check-type: no-check
1038        cases:
1039          - values:
1040            - ""
1041            - "sta.obj v5"
1042            - ", v5, v4, v3, v2"
1043          - values:
1044            - ", i32 a1"
1045            - |
1046              #
1047                  sta.obj v9
1048                  movi v5, 123
1049            - ", v9, v5, v10"
1050          - values:
1051            - ", i64 a1, i32 a2"
1052            - |
1053              #
1054                  sta.obj v0
1055                  movi v2, 1
1056                  movi.64 v6, 123456789
1057            - ", v0, v6, v2, v0"
1058